diff -u linux-lowlatency-hwe-6.5-6.5.0/Documentation/admin-guide/kernel-parameters.txt linux-lowlatency-hwe-6.5-6.5.0/Documentation/admin-guide/kernel-parameters.txt --- linux-lowlatency-hwe-6.5-6.5.0/Documentation/admin-guide/kernel-parameters.txt +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/admin-guide/kernel-parameters.txt @@ -5838,6 +5838,18 @@ sonypi.*= [HW] Sony Programmable I/O Control Device driver See Documentation/admin-guide/laptops/sonypi.rst + spectre_bhi= [X86] Control mitigation of Branch History Injection + (BHI) vulnerability. Syscalls are hardened against BHI + reglardless of this setting. This setting affects the + deployment of the HW BHI control and the SW BHB + clearing sequence. + + on - unconditionally enable. + off - unconditionally disable. + auto - (default) enable hardware mitigation + (BHI_DIS_S) if available, otherwise enable + alternate mitigation in KVM. + spectre_v2= [X86] Control mitigation of Spectre variant 2 (indirect branch speculation) vulnerability. The default operation protects the kernel from diff -u linux-lowlatency-hwe-6.5-6.5.0/Documentation/arch/arm64/silicon-errata.rst linux-lowlatency-hwe-6.5-6.5.0/Documentation/arch/arm64/silicon-errata.rst --- linux-lowlatency-hwe-6.5-6.5.0/Documentation/arch/arm64/silicon-errata.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/arch/arm64/silicon-errata.rst @@ -63,6 +63,8 @@ +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A510 | #1902691 | ARM64_ERRATUM_1902691 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A510 | #3117295 | ARM64_ERRATUM_3117295 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A520 | #2966298 | ARM64_ERRATUM_2966298 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 | diff -u linux-lowlatency-hwe-6.5-6.5.0/Documentation/sphinx/cdomain.py linux-lowlatency-hwe-6.5-6.5.0/Documentation/sphinx/cdomain.py --- linux-lowlatency-hwe-6.5-6.5.0/Documentation/sphinx/cdomain.py +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/sphinx/cdomain.py @@ -110,7 +110,7 @@ # RE_expr = re.compile(r':c:(expr|texpr):`([^\`]+)`') def markup_c_expr(match): - return '\ ``' + match.group(2) + '``\ ' + return '\\ ``' + match.group(2) + '``\\ ' # # Parse Sphinx 3.x C markups, replacing them by backward-compatible ones diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx7s.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx7s.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx7s.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx7s.dtsi @@ -190,7 +190,11 @@ clock-names = "apb_pclk"; ca_funnel_in_ports: in-ports { - port { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; ca_funnel_in_port0: endpoint { remote-endpoint = <&etm0_out_port>; }; @@ -814,7 +818,7 @@ }; lcdif: lcdif@30730000 { - compatible = "fsl,imx7d-lcdif", "fsl,imx28-lcdif"; + compatible = "fsl,imx7d-lcdif", "fsl,imx6sx-lcdif"; reg = <0x30730000 0x10000>; interrupts = ; clocks = <&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>, @@ -1278,7 +1282,7 @@ gpmi: nand-controller@33002000{ compatible = "fsl,imx7d-gpmi-nand"; #address-cells = <1>; - #size-cells = <1>; + #size-cells = <0>; reg = <0x33002000 0x2000>, <0x33004000 0x4000>; reg-names = "gpmi-nand", "bch"; interrupts = ; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8026-samsung-matisse-wifi.dts @@ -7,7 +7,7 @@ #include #include "qcom-msm8226.dtsi" -#include "qcom-pm8226.dtsi" +#include "pm8226.dtsi" /delete-node/ &adsp_region; /delete-node/ &smem_region; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-mdm9615.dtsi @@ -244,7 +244,7 @@ reg = <0x500000 0x1000>; qcom,controller-type = "pmic-arbiter"; - pmicintc: pmic { + pm8018: pmic { compatible = "qcom,pm8018", "qcom,pm8921"; interrupts = ; #interrupt-cells = <2>; @@ -255,38 +255,38 @@ pwrkey@1c { compatible = "qcom,pm8018-pwrkey", "qcom,pm8921-pwrkey"; reg = <0x1c>; - interrupt-parent = <&pmicintc>; + interrupt-parent = <&pm8018>; interrupts = <50 IRQ_TYPE_EDGE_RISING>, <51 IRQ_TYPE_EDGE_RISING>; debounce = <15625>; pull-up; }; - pmicmpp: mpps@50 { + pm8018_mpps: mpps@50 { compatible = "qcom,pm8018-mpp", "qcom,ssbi-mpp"; interrupt-controller; #interrupt-cells = <2>; reg = <0x50>; gpio-controller; #gpio-cells = <2>; - gpio-ranges = <&pmicmpp 0 0 6>; + gpio-ranges = <&pm8018_mpps 0 0 6>; }; rtc@11d { compatible = "qcom,pm8018-rtc", "qcom,pm8921-rtc"; - interrupt-parent = <&pmicintc>; + interrupt-parent = <&pm8018>; interrupts = <39 IRQ_TYPE_EDGE_RISING>; reg = <0x11d>; allow-set-time; }; - pmicgpio: gpio@150 { + pm8018_gpio: gpio@150 { compatible = "qcom,pm8018-gpio", "qcom,ssbi-gpio"; reg = <0x150>; interrupt-controller; #interrupt-cells = <2>; gpio-controller; - gpio-ranges = <&pmicgpio 0 0 6>; + gpio-ranges = <&pm8018_gpio 0 0 6>; #gpio-cells = <2>; }; }; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-msm8974pro-sony-xperia-shinano-castor.dts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "qcom-msm8974pro.dtsi" -#include "qcom-pm8841.dtsi" -#include "qcom-pm8941.dtsi" +#include "pm8841.dtsi" +#include "pm8941.dtsi" #include #include #include diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-sdx65-mtp.dts @@ -8,7 +8,7 @@ #include #include #include -#include "qcom-pmx65.dtsi" +#include "pmx65.dtsi" / { model = "Qualcomm Technologies, Inc. SDX65 MTP"; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/samsung/exynos4210-i9100.dts linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/samsung/exynos4210-i9100.dts --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/samsung/exynos4210-i9100.dts @@ -527,6 +527,14 @@ regulator-name = "VT_CAM_1.8V"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + + /* + * Force-enable this regulator; otherwise the + * kernel hangs very early in the boot process + * for about 12 seconds, without apparent + * reason. + */ + regulator-always-on; }; vcclcd_reg: LDO13 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/Kconfig linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/Kconfig --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/Kconfig +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/Kconfig @@ -1038,8 +1038,12 @@ If unsure, say Y. +config ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD + bool + config ARM64_ERRATUM_2966298 bool "Cortex-A520: 2966298: workaround for speculatively executed unprivileged load" + select ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD default y help This option adds the workaround for ARM Cortex-A520 erratum 2966298. @@ -1048,6 +1052,20 @@ load might leak data from a privileged level via a cache side channel. Work around this problem by executing a TLBI before returning to EL0. + + If unsure, say Y. + +config ARM64_ERRATUM_3117295 + bool "Cortex-A510: 3117295: workaround for speculatively executed unprivileged load" + select ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD + default y + help + This option adds the workaround for ARM Cortex-A510 erratum 3117295. + + On an affected Cortex-A510 core, a speculatively executed unprivileged + load might leak data from a privileged level via a cache side channel. + + Work around this problem by executing a TLBI before returning to EL0. If unsure, say Y. diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/freescale/imx8mm.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/freescale/imx8mm.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/freescale/imx8mm.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/freescale/imx8mm.dtsi @@ -1408,7 +1408,7 @@ assigned-clocks = <&clk IMX8MM_CLK_GPU3D_CORE>, <&clk IMX8MM_GPU_PLL_OUT>; assigned-clock-parents = <&clk IMX8MM_GPU_PLL_OUT>; - assigned-clock-rates = <0>, <1000000000>; + assigned-clock-rates = <0>, <800000000>; power-domains = <&pgc_gpu>; }; @@ -1423,7 +1423,7 @@ assigned-clocks = <&clk IMX8MM_CLK_GPU2D_CORE>, <&clk IMX8MM_GPU_PLL_OUT>; assigned-clock-parents = <&clk IMX8MM_GPU_PLL_OUT>; - assigned-clock-rates = <0>, <1000000000>; + assigned-clock-rates = <0>, <800000000>; power-domains = <&pgc_gpu>; }; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8183.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8183.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8183.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8183.dtsi @@ -1660,7 +1660,7 @@ mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0 0x1000>; }; - mdp3-rdma0@14001000 { + dma-controller0@14001000 { compatible = "mediatek,mt8183-mdp3-rdma"; reg = <0 0x14001000 0 0x1000>; mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; @@ -1672,6 +1672,7 @@ iommus = <&iommu M4U_PORT_MDP_RDMA0>; mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST 0>, <&gce 21 CMDQ_THR_PRIO_LOWEST 0>; + #dma-cells = <1>; }; mdp3-rsz0@14003000 { @@ -1692,7 +1693,7 @@ clocks = <&mmsys CLK_MM_MDP_RSZ1>; }; - mdp3-wrot0@14005000 { + dma-controller@14005000 { compatible = "mediatek,mt8183-mdp3-wrot"; reg = <0 0x14005000 0 0x1000>; mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; @@ -1701,6 +1702,7 @@ power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; clocks = <&mmsys CLK_MM_MDP_WROT0>; iommus = <&iommu M4U_PORT_MDP_WROT0>; + #dma-cells = <1>; }; mdp3-wdma@14006000 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8186.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8186.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8186.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8186.dtsi @@ -22,7 +22,7 @@ aliases { ovl0 = &ovl0; - ovl_2l0 = &ovl_2l0; + ovl-2l0 = &ovl_2l0; rdma0 = &rdma0; rdma1 = &rdma1; }; @@ -1160,14 +1160,14 @@ status = "disabled"; }; - adsp_mailbox0: mailbox@10686000 { + adsp_mailbox0: mailbox@10686100 { compatible = "mediatek,mt8186-adsp-mbox"; #mbox-cells = <0>; reg = <0 0x10686100 0 0x1000>; interrupts = ; }; - adsp_mailbox1: mailbox@10687000 { + adsp_mailbox1: mailbox@10687100 { compatible = "mediatek,mt8186-adsp-mbox"; #mbox-cells = <0>; reg = <0 0x10687100 0 0x1000>; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8195.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8195.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8195.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/mediatek/mt8195.dtsi @@ -2873,7 +2873,7 @@ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; }; - vdo1_rdma0: rdma@1c104000 { + vdo1_rdma0: dma-controller@1c104000 { compatible = "mediatek,mt8195-vdo1-rdma"; reg = <0 0x1c104000 0 0x1000>; interrupts = ; @@ -2881,9 +2881,10 @@ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA0>; mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x4000 0x1000>; + #dma-cells = <1>; }; - vdo1_rdma1: rdma@1c105000 { + vdo1_rdma1: dma-controller@1c105000 { compatible = "mediatek,mt8195-vdo1-rdma"; reg = <0 0x1c105000 0 0x1000>; interrupts = ; @@ -2891,9 +2892,10 @@ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA1>; mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x5000 0x1000>; + #dma-cells = <1>; }; - vdo1_rdma2: rdma@1c106000 { + vdo1_rdma2: dma-controller@1c106000 { compatible = "mediatek,mt8195-vdo1-rdma"; reg = <0 0x1c106000 0 0x1000>; interrupts = ; @@ -2901,9 +2903,10 @@ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA2>; mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x6000 0x1000>; + #dma-cells = <1>; }; - vdo1_rdma3: rdma@1c107000 { + vdo1_rdma3: dma-controller@1c107000 { compatible = "mediatek,mt8195-vdo1-rdma"; reg = <0 0x1c107000 0 0x1000>; interrupts = ; @@ -2911,9 +2914,10 @@ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA3>; mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x7000 0x1000>; + #dma-cells = <1>; }; - vdo1_rdma4: rdma@1c108000 { + vdo1_rdma4: dma-controller@1c108000 { compatible = "mediatek,mt8195-vdo1-rdma"; reg = <0 0x1c108000 0 0x1000>; interrupts = ; @@ -2921,9 +2925,10 @@ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA4>; mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x8000 0x1000>; + #dma-cells = <1>; }; - vdo1_rdma5: rdma@1c109000 { + vdo1_rdma5: dma-controller@1c109000 { compatible = "mediatek,mt8195-vdo1-rdma"; reg = <0 0x1c109000 0 0x1000>; interrupts = ; @@ -2931,9 +2936,10 @@ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA5>; mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0x9000 0x1000>; + #dma-cells = <1>; }; - vdo1_rdma6: rdma@1c10a000 { + vdo1_rdma6: dma-controller@1c10a000 { compatible = "mediatek,mt8195-vdo1-rdma"; reg = <0 0x1c10a000 0 0x1000>; interrupts = ; @@ -2941,9 +2947,10 @@ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; iommus = <&iommu_vdo M4U_PORT_L2_MDP_RDMA6>; mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xa000 0x1000>; + #dma-cells = <1>; }; - vdo1_rdma7: rdma@1c10b000 { + vdo1_rdma7: dma-controller@1c10b000 { compatible = "mediatek,mt8195-vdo1-rdma"; reg = <0 0x1c10b000 0 0x1000>; interrupts = ; @@ -2951,6 +2958,7 @@ power-domains = <&spm MT8195_POWER_DOMAIN_VDOSYS1>; iommus = <&iommu_vpp M4U_PORT_L3_MDP_RDMA7>; mediatek,gce-client-reg = <&gce0 SUBSYS_1c10XXXX 0xb000 0x1000>; + #dma-cells = <1>; }; merge1: vpp-merge@1c10c000 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/ipq6018.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/ipq6018.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/ipq6018.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/ipq6018.dtsi @@ -561,7 +561,7 @@ <&gcc GCC_USB0_MOCK_UTMI_CLK>; assigned-clock-rates = <133330000>, <133330000>, - <20000000>; + <24000000>; resets = <&gcc GCC_USB0_BCR>; status = "disabled"; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts @@ -88,6 +88,7 @@ #size-cells = <0>; vcc-supply = <&pm8916_l17>; + vio-supply = <&pm8916_l6>; led@0 { reg = <0>; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8916.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8916.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8916.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8916.dtsi @@ -2077,6 +2077,7 @@ clock-names = "bam_clk"; #dma-cells = <1>; qcom,ee = <0>; + qcom,controlled-remotely; }; blsp_uart1: serial@78af000 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8939.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8939.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8939.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8939.dtsi @@ -1663,6 +1663,7 @@ clock-names = "bam_clk"; #dma-cells = <1>; qcom,ee = <0>; + qcom,controlled-remotely; }; blsp_uart1: serial@78af000 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8953-xiaomi-vince.dts @@ -113,6 +113,7 @@ reg = <0x45>; vcc-supply = <&pm8953_l10>; + vio-supply = <&pm8953_l5>; #address-cells = <1>; #size-cells = <0>; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8996.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8996.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -393,6 +393,19 @@ reg = <0x0 0x80000000 0x0 0x0>; }; + etm { + compatible = "qcom,coresight-remote-etm"; + + out-ports { + port { + modem_etm_out_funnel_in2: endpoint { + remote-endpoint = + <&funnel_in2_in_modem_etm>; + }; + }; + }; + }; + psci { compatible = "arm,psci-1.0"; method = "smc"; @@ -2592,6 +2605,14 @@ clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>; clock-names = "apb_pclk", "atclk"; + in-ports { + port { + funnel_in2_in_modem_etm: endpoint { + remote-endpoint = + <&modem_etm_out_funnel_in2>; + }; + }; + }; out-ports { port { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8998.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8998.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8998.dtsi @@ -2009,9 +2009,11 @@ cpu = <&CPU4>; - port { - etm4_out: endpoint { - remote-endpoint = <&apss_funnel_in4>; + out-ports { + port { + etm4_out: endpoint { + remote-endpoint = <&apss_funnel_in4>; + }; }; }; }; @@ -2026,9 +2028,11 @@ cpu = <&CPU5>; - port { - etm5_out: endpoint { - remote-endpoint = <&apss_funnel_in5>; + out-ports { + port { + etm5_out: endpoint { + remote-endpoint = <&apss_funnel_in5>; + }; }; }; }; @@ -2043,9 +2047,11 @@ cpu = <&CPU6>; - port { - etm6_out: endpoint { - remote-endpoint = <&apss_funnel_in6>; + out-ports { + port { + etm6_out: endpoint { + remote-endpoint = <&apss_funnel_in6>; + }; }; }; }; @@ -2060,9 +2066,11 @@ cpu = <&CPU7>; - port { - etm7_out: endpoint { - remote-endpoint = <&apss_funnel_in7>; + out-ports { + port { + etm7_out: endpoint { + remote-endpoint = <&apss_funnel_in7>; + }; }; }; }; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc7280.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc7280.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -925,6 +925,7 @@ bus-width = <8>; supports-cqe; + dma-coherent; qcom,dll-config = <0x0007642c>; qcom,ddr-config = <0x80040868>; @@ -2255,6 +2256,7 @@ clocks = <&gcc GCC_CFG_NOC_LPASS_CLK>; clock-names = "iface"; #clock-cells = <1>; + status = "reserved"; /* Owned by ADSP firmware */ }; lpass_rx_macro: codec@3200000 { @@ -2406,6 +2408,7 @@ clock-names = "bi_tcxo", "bi_tcxo_ao", "iface"; #clock-cells = <1>; #power-domain-cells = <1>; + status = "reserved"; /* Owned by ADSP firmware */ }; lpass_core: clock-controller@3900000 { @@ -2416,6 +2419,7 @@ power-domains = <&lpass_hm LPASS_CORE_CC_LPASS_CORE_HM_GDSC>; #clock-cells = <1>; #power-domain-cells = <1>; + status = "reserved"; /* Owned by ADSP firmware */ }; lpass_cpu: audio@3987000 { @@ -2486,6 +2490,7 @@ clock-names = "bi_tcxo"; #clock-cells = <1>; #power-domain-cells = <1>; + status = "reserved"; /* Owned by ADSP firmware */ }; lpass_ag_noc: interconnect@3c40000 { @@ -2554,7 +2559,8 @@ "cx_mem", "cx_dbgc"; interrupts = ; - iommus = <&adreno_smmu 0 0x401>; + iommus = <&adreno_smmu 0 0x400>, + <&adreno_smmu 1 0x400>; operating-points-v2 = <&gpu_opp_table>; qcom,gmu = <&gmu>; interconnects = <&gem_noc MASTER_GFX3D 0 &mc_virt SLAVE_EBI1 0>; @@ -2728,6 +2734,7 @@ "gpu_cc_hub_aon_clk"; power-domains = <&gpucc GPU_CC_CX_GDSC>; + dma-coherent; }; remoteproc_mpss: remoteproc@4080000 { @@ -3285,6 +3292,7 @@ operating-points-v2 = <&sdhc2_opp_table>; bus-width = <4>; + dma-coherent; qcom,dll-config = <0x0007642c>; @@ -3405,8 +3413,8 @@ assigned-clock-rates = <19200000>, <200000000>; interrupts-extended = <&intc GIC_SPI 240 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 12 IRQ_TYPE_EDGE_RISING>, - <&pdc 13 IRQ_TYPE_EDGE_RISING>; + <&pdc 12 IRQ_TYPE_EDGE_BOTH>, + <&pdc 13 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "dp_hs_phy_irq", "dm_hs_phy_irq"; @@ -3660,9 +3668,9 @@ assigned-clock-rates = <19200000>, <200000000>; interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 14 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 14 IRQ_TYPE_EDGE_BOTH>, <&pdc 15 IRQ_TYPE_EDGE_BOTH>, - <&pdc 17 IRQ_TYPE_EDGE_BOTH>; + <&pdc 17 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "hs_phy_irq", "dp_hs_phy_irq", "dm_hs_phy_irq", @@ -4199,6 +4207,7 @@ compatible = "qcom,sc7280-pdc-global"; reg = <0 0x0b5e0000 0 0x20000>; #reset-cells = <1>; + status = "reserved"; /* Owned by firmware */ }; tsens0: thermal-sensor@c263000 { @@ -5195,11 +5204,12 @@ }; }; - watchdog@17c10000 { + watchdog: watchdog@17c10000 { compatible = "qcom,apss-wdt-sc7280", "qcom,kpss-wdt"; reg = <0 0x17c10000 0 0x1000>; clocks = <&sleep_clk>; - interrupts = ; + interrupts = ; + status = "reserved"; /* Owned by Gunyah hyp */ }; timer@17c20000 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8180x.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8180x.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8180x.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8180x.dtsi @@ -1749,23 +1749,29 @@ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; interconnect-names = "pcie-mem", "cpu-pcie"; - phys = <&pcie0_lane>; + phys = <&pcie0_phy>; phy-names = "pciephy"; + dma-coherent; status = "disabled"; }; - pcie0_phy: phy-wrapper@1c06000 { + pcie0_phy: phy@1c06000 { compatible = "qcom,sc8180x-qmp-pcie-phy"; - reg = <0 0x1c06000 0 0x1c0>; - #address-cells = <2>; - #size-cells = <2>; - ranges; + reg = <0 0x01c06000 0 0x1000>; clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, <&gcc GCC_PCIE_0_CFG_AHB_CLK>, <&gcc GCC_PCIE_0_CLKREF_CLK>, - <&gcc GCC_PCIE1_PHY_REFGEN_CLK>; - clock-names = "aux", "cfg_ahb", "ref", "refgen"; + <&gcc GCC_PCIE0_PHY_REFGEN_CLK>, + <&gcc GCC_PCIE_0_PIPE_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "refgen", + "pipe"; + #clock-cells = <0>; + clock-output-names = "pcie_0_pipe_clk"; + #phy-cells = <0>; resets = <&gcc GCC_PCIE_0_PHY_BCR>; reset-names = "phy"; @@ -1774,21 +1780,6 @@ assigned-clock-rates = <100000000>; status = "disabled"; - - pcie0_lane: phy@1c06200 { - reg = <0 0x1c06200 0 0x170>, /* tx0 */ - <0 0x1c06400 0 0x200>, /* rx0 */ - <0 0x1c06a00 0 0x1f0>, /* pcs */ - <0 0x1c06600 0 0x170>, /* tx1 */ - <0 0x1c06800 0 0x200>, /* rx1 */ - <0 0x1c06e00 0 0xf4>; /* pcs_com */ - clocks = <&gcc GCC_PCIE_0_PIPE_CLK>; - clock-names = "pipe0"; - - #clock-cells = <0>; - clock-output-names = "pcie_0_pipe_clk"; - #phy-cells = <0>; - }; }; pcie3: pci@1c08000 { @@ -1856,23 +1847,30 @@ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; interconnect-names = "pcie-mem", "cpu-pcie"; - phys = <&pcie3_lane>; + phys = <&pcie3_phy>; phy-names = "pciephy"; + dma-coherent; status = "disabled"; }; - pcie3_phy: phy-wrapper@1c0c000 { + pcie3_phy: phy@1c0c000 { compatible = "qcom,sc8180x-qmp-pcie-phy"; - reg = <0 0x1c0c000 0 0x1c0>; - #address-cells = <2>; - #size-cells = <2>; - ranges; + reg = <0 0x01c0c000 0 0x1000>; clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, <&gcc GCC_PCIE_3_CFG_AHB_CLK>, <&gcc GCC_PCIE_3_CLKREF_CLK>, - <&gcc GCC_PCIE2_PHY_REFGEN_CLK>; - clock-names = "aux", "cfg_ahb", "ref", "refgen"; + <&gcc GCC_PCIE3_PHY_REFGEN_CLK>, + <&gcc GCC_PCIE_3_PIPE_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "refgen", + "pipe"; + #clock-cells = <0>; + clock-output-names = "pcie_3_pipe_clk"; + + #phy-cells = <0>; resets = <&gcc GCC_PCIE_3_PHY_BCR>; reset-names = "phy"; @@ -1881,21 +1879,6 @@ assigned-clock-rates = <100000000>; status = "disabled"; - - pcie3_lane: phy@1c0c200 { - reg = <0 0x1c0c200 0 0x170>, /* tx0 */ - <0 0x1c0c400 0 0x200>, /* rx0 */ - <0 0x1c0ca00 0 0x1f0>, /* pcs */ - <0 0x1c0c600 0 0x170>, /* tx1 */ - <0 0x1c0c800 0 0x200>, /* rx1 */ - <0 0x1c0ce00 0 0xf4>; /* pcs_com */ - clocks = <&gcc GCC_PCIE_3_PIPE_CLK>; - clock-names = "pipe0"; - - #clock-cells = <0>; - clock-output-names = "pcie_3_pipe_clk"; - #phy-cells = <0>; - }; }; pcie1: pci@1c10000 { @@ -1963,23 +1946,30 @@ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; interconnect-names = "pcie-mem", "cpu-pcie"; - phys = <&pcie1_lane>; + phys = <&pcie1_phy>; phy-names = "pciephy"; + dma-coherent; status = "disabled"; }; - pcie1_phy: phy-wrapper@1c16000 { + pcie1_phy: phy@1c16000 { compatible = "qcom,sc8180x-qmp-pcie-phy"; - reg = <0 0x1c16000 0 0x1c0>; - #address-cells = <2>; - #size-cells = <2>; - ranges; + reg = <0 0x01c16000 0 0x1000>; clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, <&gcc GCC_PCIE_1_CFG_AHB_CLK>, <&gcc GCC_PCIE_1_CLKREF_CLK>, - <&gcc GCC_PCIE1_PHY_REFGEN_CLK>; - clock-names = "aux", "cfg_ahb", "ref", "refgen"; + <&gcc GCC_PCIE1_PHY_REFGEN_CLK>, + <&gcc GCC_PCIE_1_PIPE_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "refgen", + "pipe"; + #clock-cells = <0>; + clock-output-names = "pcie_1_pipe_clk"; + + #phy-cells = <0>; resets = <&gcc GCC_PCIE_1_PHY_BCR>; reset-names = "phy"; @@ -1988,21 +1978,6 @@ assigned-clock-rates = <100000000>; status = "disabled"; - - pcie1_lane: phy@1c0e200 { - reg = <0 0x1c16200 0 0x170>, /* tx0 */ - <0 0x1c16400 0 0x200>, /* rx0 */ - <0 0x1c16a00 0 0x1f0>, /* pcs */ - <0 0x1c16600 0 0x170>, /* tx1 */ - <0 0x1c16800 0 0x200>, /* rx1 */ - <0 0x1c16e00 0 0xf4>; /* pcs_com */ - clocks = <&gcc GCC_PCIE_1_PIPE_CLK>; - clock-names = "pipe0"; - #clock-cells = <0>; - clock-output-names = "pcie_1_pipe_clk"; - - #phy-cells = <0>; - }; }; pcie2: pci@1c18000 { @@ -2070,23 +2045,30 @@ <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; interconnect-names = "pcie-mem", "cpu-pcie"; - phys = <&pcie2_lane>; + phys = <&pcie2_phy>; phy-names = "pciephy"; + dma-coherent; status = "disabled"; }; - pcie2_phy: phy-wrapper@1c1c000 { + pcie2_phy: phy@1c1c000 { compatible = "qcom,sc8180x-qmp-pcie-phy"; - reg = <0 0x1c1c000 0 0x1c0>; - #address-cells = <2>; - #size-cells = <2>; - ranges; + reg = <0 0x01c1c000 0 0x1000>; clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>, <&gcc GCC_PCIE_2_CFG_AHB_CLK>, <&gcc GCC_PCIE_2_CLKREF_CLK>, - <&gcc GCC_PCIE2_PHY_REFGEN_CLK>; - clock-names = "aux", "cfg_ahb", "ref", "refgen"; + <&gcc GCC_PCIE2_PHY_REFGEN_CLK>, + <&gcc GCC_PCIE_2_PIPE_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "refgen", + "pipe"; + #clock-cells = <0>; + clock-output-names = "pcie_2_pipe_clk"; + + #phy-cells = <0>; resets = <&gcc GCC_PCIE_2_PHY_BCR>; reset-names = "phy"; @@ -2095,22 +2077,6 @@ assigned-clock-rates = <100000000>; status = "disabled"; - - pcie2_lane: phy@1c0e200 { - reg = <0 0x1c1c200 0 0x170>, /* tx0 */ - <0 0x1c1c400 0 0x200>, /* rx0 */ - <0 0x1c1ca00 0 0x1f0>, /* pcs */ - <0 0x1c1c600 0 0x170>, /* tx1 */ - <0 0x1c1c800 0 0x200>, /* rx1 */ - <0 0x1c1ce00 0 0xf4>; /* pcs_com */ - clocks = <&gcc GCC_PCIE_2_PIPE_CLK>; - clock-names = "pipe0"; - - #clock-cells = <0>; - clock-output-names = "pcie_2_pipe_clk"; - - #phy-cells = <0>; - }; }; ufs_mem_hc: ufshc@1d84000 { @@ -2560,10 +2526,10 @@ usb_prim: usb@a6f8800 { compatible = "qcom,sc8180x-dwc3", "qcom,dwc3"; reg = <0 0x0a6f8800 0 0x400>; - interrupts = , - , - , - ; + interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 6 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 8 IRQ_TYPE_EDGE_BOTH>, + <&pdc 9 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", @@ -2629,10 +2595,10 @@ "xo"; resets = <&gcc GCC_USB30_SEC_BCR>; power-domains = <&gcc USB30_SEC_GDSC>; - interrupts = , - , - , - ; + interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 7 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 10 IRQ_TYPE_EDGE_BOTH>, + <&pdc 11 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq"; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts @@ -460,6 +460,8 @@ }; &mdss0_dp3_phy { + compatible = "qcom,sc8280xp-edp-phy"; + vdda-phy-supply = <&vreg_l6b>; vdda-pll-supply = <&vreg_l3b>; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts @@ -82,6 +82,9 @@ leds { compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&cam_indicator_en>; + led-camera-indicator { label = "white:camera-indicator"; function = LED_FUNCTION_INDICATOR; @@ -603,6 +606,7 @@ }; &mdss0_dp3_phy { + compatible = "qcom,sc8280xp-edp-phy"; vdda-phy-supply = <&vreg_l6b>; vdda-pll-supply = <&vreg_l3b>; @@ -1279,6 +1283,13 @@ }; }; + cam_indicator_en: cam-indicator-en-state { + pins = "gpio28"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + edp_reg_en: edp-reg-en-state { pins = "gpio25"; function = "gpio"; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8280xp.dtsi @@ -4224,7 +4224,7 @@ compatible = "qcom,apss-wdt-sc8280xp", "qcom,kpss-wdt"; reg = <0 0x17c10000 0 0x1000>; clocks = <&sleep_clk>; - interrupts = ; + interrupts = ; }; timer@17c20000 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sdm845-db845c.dts linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sdm845-db845c.dts --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -67,8 +67,8 @@ function = LED_FUNCTION_INDICATOR; color = ; gpios = <&pm8998_gpios 13 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "panic-indicator"; default-state = "off"; + panic-indicator; }; led-1 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sdm845.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sdm845.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -3551,11 +3551,8 @@ }; in-ports { - #address-cells = <1>; - #size-cells = <0>; - port@1 { - reg = <1>; + port { etf_in: endpoint { remote-endpoint = <&merge_funnel_out>; @@ -4080,10 +4077,10 @@ <&gcc GCC_USB30_PRIM_MASTER_CLK>; assigned-clock-rates = <19200000>, <150000000>; - interrupts = , - , - , - ; + interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <&pdc_intc 6 IRQ_TYPE_LEVEL_HIGH>, + <&pdc_intc 8 IRQ_TYPE_EDGE_BOTH>, + <&pdc_intc 9 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq"; @@ -4131,10 +4128,10 @@ <&gcc GCC_USB30_SEC_MASTER_CLK>; assigned-clock-rates = <19200000>, <150000000>; - interrupts = , - , - , - ; + interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <&pdc_intc 7 IRQ_TYPE_LEVEL_HIGH>, + <&pdc_intc 10 IRQ_TYPE_EDGE_BOTH>, + <&pdc_intc 11 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq"; @@ -5114,7 +5111,7 @@ compatible = "qcom,apss-wdt-sdm845", "qcom,kpss-wdt"; reg = <0 0x17980000 0 0x1000>; clocks = <&sleep_clk>; - interrupts = ; + interrupts = ; }; apss_shared: mailbox@17990000 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm6125.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm6125.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm6125.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm6125.dtsi @@ -1161,6 +1161,10 @@ <&gcc GCC_USB30_PRIM_MASTER_CLK>; assigned-clock-rates = <19200000>, <66666667>; + interrupts = , + ; + interrupt-names = "hs_phy_irq", "ss_phy_irq"; + power-domains = <&gcc USB30_PRIM_GDSC>; qcom,select-utmi-as-pipe-clk; status = "disabled"; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm6350.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm6350.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm6350.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm6350.dtsi @@ -2042,7 +2042,7 @@ compatible = "qcom,apss-wdt-sm6350", "qcom,kpss-wdt"; reg = <0 0x17c10000 0 0x1000>; clocks = <&sleep_clk>; - interrupts = ; + interrupts = ; }; timer@17c20000 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8150.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8150.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -2973,11 +2973,8 @@ }; in-ports { - #address-cells = <1>; - #size-cells = <0>; - port@1 { - reg = <1>; + port { replicator1_in: endpoint { remote-endpoint = <&replicator_out1>; }; @@ -3592,10 +3589,10 @@ <&gcc GCC_USB30_PRIM_MASTER_CLK>; assigned-clock-rates = <19200000>, <200000000>; - interrupts = , - , - , - ; + interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 6 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 8 IRQ_TYPE_EDGE_BOTH>, + <&pdc 9 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq"; @@ -3645,10 +3642,10 @@ <&gcc GCC_USB30_SEC_MASTER_CLK>; assigned-clock-rates = <19200000>, <200000000>; - interrupts = , - , - , - ; + interrupts-extended = <&intc GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 7 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 10 IRQ_TYPE_EDGE_BOTH>, + <&pdc 11 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq"; @@ -3959,6 +3956,7 @@ "dp_phy_pll_link_clk", "dp_phy_pll_vco_div_clk"; power-domains = <&rpmhpd SM8150_MMCX>; + required-opps = <&rpmhpd_opp_low_svs>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -4197,7 +4195,7 @@ compatible = "qcom,apss-wdt-sm8150", "qcom,kpss-wdt"; reg = <0 0x17c10000 0 0x1000>; clocks = <&sleep_clk>; - interrupts = ; + interrupts = ; }; timer@17c20000 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8250.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8250.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -2825,11 +2825,8 @@ clock-names = "apb_pclk"; out-ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; + port { tpda_out_funnel_qatb: endpoint { remote-endpoint = <&funnel_qatb_in_tpda>; }; @@ -2872,11 +2869,7 @@ }; in-ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; + port { funnel_qatb_in_tpda: endpoint { remote-endpoint = <&tpda_out_funnel_qatb>; }; @@ -3085,11 +3078,8 @@ }; in-ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - reg = <0>; + port { etf_in_funnel_swao_out: endpoint { remote-endpoint = <&funnel_swao_out_etf>; }; @@ -3173,8 +3163,6 @@ clock-names = "apb_pclk"; out-ports { - #address-cells = <1>; - #size-cells = <0>; port { tpdm_mm_out_tpda9: endpoint { remote-endpoint = <&tpda_9_in_tpdm_mm>; @@ -3440,11 +3428,7 @@ }; in-ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; + port { funnel_apss_merg_in_funnel_apss: endpoint { remote-endpoint = <&funnel_apss_out_funnel_apss_merg>; }; @@ -5537,7 +5521,7 @@ compatible = "qcom,apss-wdt-sm8250", "qcom,kpss-wdt"; reg = <0 0x17c10000 0 0x1000>; clocks = <&sleep_clk>; - interrupts = ; + interrupts = ; }; timer@17c20000 { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8350.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8350.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -907,9 +907,9 @@ }; }; - gpi_dma0: dma-controller@9800000 { + gpi_dma0: dma-controller@900000 { compatible = "qcom,sm8350-gpi-dma", "qcom,sm6350-gpi-dma"; - reg = <0 0x09800000 0 0x60000>; + reg = <0 0x00900000 0 0x60000>; interrupts = , , , @@ -1995,7 +1995,7 @@ compatible = "qcom,sm8350-mpss-pas"; reg = <0x0 0x04080000 0x0 0x4040>; - interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 264 IRQ_TYPE_EDGE_RISING>, <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_modem_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_modem_in 2 IRQ_TYPE_EDGE_RISING>, @@ -2037,7 +2037,7 @@ compatible = "qcom,sm8350-slpi-pas"; reg = <0 0x05c00000 0 0x4000>; - interrupts-extended = <&pdc 9 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&pdc 9 IRQ_TYPE_EDGE_RISING>, <&smp2p_slpi_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_slpi_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_slpi_in 2 IRQ_TYPE_EDGE_RISING>, @@ -3181,7 +3181,7 @@ compatible = "qcom,sm8350-adsp-pas"; reg = <0 0x17300000 0 0x100>; - interrupts-extended = <&pdc 6 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, @@ -3417,7 +3417,7 @@ compatible = "qcom,sm8350-cdsp-pas"; reg = <0 0x98900000 0 0x1400000>; - interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_LEVEL_HIGH>, + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8450.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8450.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -2169,7 +2169,7 @@ #sound-dai-cells = <1>; }; - swr4: soundwire-controller@31f0000 { + swr4: soundwire@31f0000 { compatible = "qcom,soundwire-v1.7.0"; reg = <0 0x031f0000 0 0x2000>; interrupts = ; @@ -2217,7 +2217,7 @@ #sound-dai-cells = <1>; }; - swr1: soundwire-controller@3210000 { + swr1: soundwire@3210000 { compatible = "qcom,soundwire-v1.7.0"; reg = <0 0x03210000 0 0x2000>; interrupts = ; @@ -2284,7 +2284,7 @@ #sound-dai-cells = <1>; }; - swr0: soundwire-controller@3250000 { + swr0: soundwire@3250000 { compatible = "qcom,soundwire-v1.7.0"; reg = <0 0x03250000 0 0x2000>; interrupts = ; @@ -2311,14 +2311,14 @@ status = "disabled"; }; - swr2: soundwire-controller@33b0000 { + swr2: soundwire@33b0000 { compatible = "qcom,soundwire-v1.7.0"; reg = <0 0x033b0000 0 0x2000>; interrupts = , ; interrupt-names = "core", "wakeup"; - clocks = <&vamacro>; + clocks = <&txmacro>; clock-names = "iface"; label = "TX"; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8550.dtsi linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8550.dtsi --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8550.dtsi @@ -282,9 +282,9 @@ compatible = "arm,idle-state"; idle-state-name = "silver-rail-power-collapse"; arm,psci-suspend-param = <0x40000004>; - entry-latency-us = <800>; + entry-latency-us = <550>; exit-latency-us = <750>; - min-residency-us = <4090>; + min-residency-us = <6700>; local-timer-stop; }; @@ -293,8 +293,18 @@ idle-state-name = "gold-rail-power-collapse"; arm,psci-suspend-param = <0x40000004>; entry-latency-us = <600>; - exit-latency-us = <1550>; - min-residency-us = <4791>; + exit-latency-us = <1300>; + min-residency-us = <8136>; + local-timer-stop; + }; + + PRIME_CPU_SLEEP_0: cpu-sleep-2-0 { + compatible = "arm,idle-state"; + idle-state-name = "goldplus-rail-power-collapse"; + arm,psci-suspend-param = <0x40000004>; + entry-latency-us = <500>; + exit-latency-us = <1350>; + min-residency-us = <7480>; local-timer-stop; }; }; @@ -303,17 +313,17 @@ CLUSTER_SLEEP_0: cluster-sleep-0 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x41000044>; - entry-latency-us = <1050>; - exit-latency-us = <2500>; - min-residency-us = <5309>; + entry-latency-us = <750>; + exit-latency-us = <2350>; + min-residency-us = <9144>; }; CLUSTER_SLEEP_1: cluster-sleep-1 { compatible = "domain-idle-state"; arm,psci-suspend-param = <0x4100c344>; - entry-latency-us = <2700>; - exit-latency-us = <3500>; - min-residency-us = <13959>; + entry-latency-us = <2800>; + exit-latency-us = <4400>; + min-residency-us = <10150>; }; }; }; @@ -397,7 +407,7 @@ CPU_PD7: power-domain-cpu7 { #power-domain-cells = <0>; power-domains = <&CLUSTER_PD>; - domain-idle-states = <&BIG_CPU_SLEEP_0>; + domain-idle-states = <&PRIME_CPU_SLEEP_0>; }; CLUSTER_PD: power-domain-cluster { @@ -2033,7 +2043,7 @@ #sound-dai-cells = <1>; }; - swr3: soundwire-controller@6ab0000 { + swr3: soundwire@6ab0000 { compatible = "qcom,soundwire-v2.0.0"; reg = <0 0x06ab0000 0 0x10000>; interrupts = ; @@ -2079,7 +2089,7 @@ #sound-dai-cells = <1>; }; - swr1: soundwire-controller@6ad0000 { + swr1: soundwire@6ad0000 { compatible = "qcom,soundwire-v2.0.0"; reg = <0 0x06ad0000 0 0x10000>; interrupts = ; @@ -2144,7 +2154,7 @@ #sound-dai-cells = <1>; }; - swr0: soundwire-controller@6b10000 { + swr0: soundwire@6b10000 { compatible = "qcom,soundwire-v2.0.0"; reg = <0 0x06b10000 0 0x10000>; interrupts = ; @@ -2171,13 +2181,13 @@ status = "disabled"; }; - swr2: soundwire-controller@6d30000 { + swr2: soundwire@6d30000 { compatible = "qcom,soundwire-v2.0.0"; reg = <0 0x06d30000 0 0x10000>; interrupts = , ; interrupt-names = "core", "wakeup"; - clocks = <&lpass_vamacro>; + clocks = <&lpass_txmacro>; clock-names = "iface"; label = "TX"; @@ -2866,8 +2876,8 @@ interrupts-extended = <&intc GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>, <&pdc 17 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 15 IRQ_TYPE_EDGE_RISING>, - <&pdc 14 IRQ_TYPE_EDGE_RISING>; + <&pdc 15 IRQ_TYPE_EDGE_BOTH>, + <&pdc 14 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/cpu_errata.c linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/cpu_errata.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/cpu_errata.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/cpu_errata.c @@ -432,6 +432,19 @@ }; #endif /* CONFIG_ARM64_WORKAROUND_TRBE_WRITE_OUT_OF_RANGE */ +#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD +static const struct midr_range erratum_spec_unpriv_load_list[] = { +#ifdef CONFIG_ARM64_ERRATUM_3117295 + MIDR_ALL_VERSIONS(MIDR_CORTEX_A510), +#endif +#ifdef CONFIG_ARM64_ERRATUM_2966298 + /* Cortex-A520 r0p0 to r0p1 */ + MIDR_REV_RANGE(MIDR_CORTEX_A520, 0, 0, 1), +#endif + {}, +}; +#endif + const struct arm64_cpu_capabilities arm64_errata[] = { #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE { @@ -730,12 +743,12 @@ .cpu_enable = cpu_clear_bf16_from_user_emulation, }, #endif -#ifdef CONFIG_ARM64_ERRATUM_2966298 +#ifdef CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD { - .desc = "ARM erratum 2966298", - .capability = ARM64_WORKAROUND_2966298, + .desc = "ARM errata 2966298, 3117295", + .capability = ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD, /* Cortex-A520 r0p0 - r0p1 */ - ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A520, 0, 0, 1), + ERRATA_MIDR_RANGE_LIST(erratum_spec_unpriv_load_list), }, #endif #ifdef CONFIG_AMPERE_ERRATUM_AC03_CPU_38 diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/entry.S linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/entry.S --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/entry.S +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/entry.S @@ -428,16 +428,9 @@ ldp x28, x29, [sp, #16 * 14] .if \el == 0 -alternative_if ARM64_WORKAROUND_2966298 - tlbi vale1, xzr - dsb nsh -alternative_else_nop_endif -alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0 - ldr lr, [sp, #S_LR] - add sp, sp, #PT_REGS_SIZE // restore sp - eret -alternative_else_nop_endif #ifdef CONFIG_UNMAP_KERNEL_AT_EL0 + alternative_insn "b .L_skip_tramp_exit_\@", nop, ARM64_UNMAP_KERNEL_AT_EL0 + msr far_el1, x29 ldr_this_cpu x30, this_cpu_vector, x29 @@ -446,7 +439,18 @@ ldr lr, [sp, #S_LR] // restore x30 add sp, sp, #PT_REGS_SIZE // restore sp br x29 + +.L_skip_tramp_exit_\@: #endif + ldr lr, [sp, #S_LR] + add sp, sp, #PT_REGS_SIZE // restore sp + + /* This must be after the last explicit memory access */ +alternative_if ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD + tlbi vale1, xzr + dsb nsh +alternative_else_nop_endif + eret .else ldr lr, [sp, #S_LR] add sp, sp, #PT_REGS_SIZE // restore sp diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/fpsimd.c linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/fpsimd.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/fpsimd.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/fpsimd.c @@ -1280,8 +1280,10 @@ */ void sme_alloc(struct task_struct *task, bool flush) { - if (task->thread.sme_state && flush) { - memset(task->thread.sme_state, 0, sme_state_size(task)); + if (task->thread.sme_state) { + if (flush) + memset(task->thread.sme_state, 0, + sme_state_size(task)); return; } diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/ptrace.c linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/ptrace.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/ptrace.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/ptrace.c @@ -1107,12 +1107,13 @@ } } - /* Allocate/reinit ZA storage */ - sme_alloc(target, true); - if (!target->thread.sme_state) { - ret = -ENOMEM; - goto out; - } + /* + * Only flush the storage if PSTATE.ZA was not already set, + * otherwise preserve any existing data. + */ + sme_alloc(target, !thread_za_enabled(&target->thread)); + if (!target->thread.sme_state) + return -ENOMEM; /* If there is no data then disable ZA */ if (!count) { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kvm/vgic/vgic-mmio-v3.c linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kvm/vgic/vgic-mmio-v3.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kvm/vgic/vgic-mmio-v3.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kvm/vgic/vgic-mmio-v3.c @@ -365,19 +365,26 @@ struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i); raw_spin_lock_irqsave(&irq->irq_lock, flags); - if (test_bit(i, &val)) { - /* - * pending_latch is set irrespective of irq type - * (level or edge) to avoid dependency that VM should - * restore irq config before pending info. - */ - irq->pending_latch = true; - vgic_queue_irq_unlock(vcpu->kvm, irq, flags); - } else { + + /* + * pending_latch is set irrespective of irq type + * (level or edge) to avoid dependency that VM should + * restore irq config before pending info. + */ + irq->pending_latch = test_bit(i, &val); + + if (irq->hw && vgic_irq_is_sgi(irq->intid)) { + irq_set_irqchip_state(irq->host_irq, + IRQCHIP_STATE_PENDING, + irq->pending_latch); irq->pending_latch = false; - raw_spin_unlock_irqrestore(&irq->irq_lock, flags); } + if (irq->pending_latch) + vgic_queue_irq_unlock(vcpu->kvm, irq, flags); + else + raw_spin_unlock_irqrestore(&irq->irq_lock, flags); + vgic_put_irq(vcpu->kvm, irq); } diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/tools/cpucaps linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/tools/cpucaps --- linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/tools/cpucaps +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/tools/cpucaps @@ -83,7 +83,6 @@ WORKAROUND_2457168 WORKAROUND_2645198 WORKAROUND_2658417 -WORKAROUND_2966298 WORKAROUND_AMPERE_AC03_CPU_38 WORKAROUND_TRBE_OVERWRITE_FILL_MODE WORKAROUND_TSB_FLUSH_FAILURE @@ -101,0 +101 @@ +WORKAROUND_SPECULATIVE_UNPRIV_LOAD diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/include/asm/elf.h linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/include/asm/elf.h --- linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/include/asm/elf.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/include/asm/elf.h @@ -241,8 +241,6 @@ do { \ current->thread.vdso = &vdso_info; \ \ - loongarch_set_personality_fcsr(state); \ - \ if (personality(current->personality) != PER_LINUX) \ set_personality(PER_LINUX); \ } while (0) @@ -259,7 +257,6 @@ clear_thread_flag(TIF_32BIT_ADDR); \ \ current->thread.vdso = &vdso_info; \ - loongarch_set_personality_fcsr(state); \ \ p = personality(current->personality); \ if (p != PER_LINUX32 && p != PER_LINUX) \ @@ -342,4 +339,2 @@ -extern void loongarch_set_personality_fcsr(struct arch_elf_state *state); - #endif /* _ASM_ELF_H */ diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/kernel/process.c linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/kernel/process.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/kernel/process.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/kernel/process.c @@ -82,6 +82,7 @@ euen = regs->csr_euen & ~(CSR_EUEN_FPEN); regs->csr_euen = euen; lose_fpu(0); + current->thread.fpu.fcsr = boot_cpu_data.fpu_csr0; clear_thread_flag(TIF_LSX_CTX_LIVE); clear_thread_flag(TIF_LASX_CTX_LIVE); diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/net/bpf_jit.c linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/net/bpf_jit.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/net/bpf_jit.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/net/bpf_jit.c @@ -461,7 +461,6 @@ const u8 dst = regmap[insn->dst_reg]; const s16 off = insn->off; const s32 imm = insn->imm; - const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm; const bool is32 = BPF_CLASS(insn->code) == BPF_ALU || BPF_CLASS(insn->code) == BPF_JMP32; switch (code) { @@ -865,8 +864,12 @@ /* dst = imm64 */ case BPF_LD | BPF_IMM | BPF_DW: + { + const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm; + move_imm(ctx, dst, imm64, is32); return 1; + } /* dst = *(size *)(src + off) */ case BPF_LDX | BPF_MEM | BPF_B: diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/mips/alchemy/devboards/db1200.c linux-lowlatency-hwe-6.5-6.5.0/arch/mips/alchemy/devboards/db1200.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/mips/alchemy/devboards/db1200.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/mips/alchemy/devboards/db1200.c @@ -847,7 +847,7 @@ i2c_register_board_info(0, db1200_i2c_devs, ARRAY_SIZE(db1200_i2c_devs)); spi_register_board_info(db1200_spi_devs, - ARRAY_SIZE(db1200_i2c_devs)); + ARRAY_SIZE(db1200_spi_devs)); /* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI) * S6.7 AC97/I2S selector (OFF=AC97 ON=I2S) diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/kernel/traps.c linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/kernel/traps.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/kernel/traps.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/kernel/traps.c @@ -1439,10 +1439,12 @@ return -EINVAL; } +#ifdef CONFIG_GENERIC_BUG int is_valid_bugaddr(unsigned long addr) { return is_kernel_addr(addr); } +#endif #ifdef CONFIG_MATH_EMULATION static int emulate_math(struct pt_regs *regs) diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/lib/sstep.c linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/lib/sstep.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/lib/sstep.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/lib/sstep.c @@ -587,6 +587,8 @@ } u; nb = GETSIZE(op->type); + if (nb > sizeof(u)) + return -EINVAL; if (!address_ok(regs, ea, nb)) return -EFAULT; rn = op->reg; @@ -637,6 +639,8 @@ } u; nb = GETSIZE(op->type); + if (nb > sizeof(u)) + return -EINVAL; if (!address_ok(regs, ea, nb)) return -EFAULT; rn = op->reg; @@ -681,6 +685,9 @@ u8 b[sizeof(__vector128)]; } u = {}; + if (size > sizeof(u)) + return -EINVAL; + if (!address_ok(regs, ea & ~0xfUL, 16)) return -EFAULT; /* align to multiple of size */ @@ -708,6 +715,9 @@ u8 b[sizeof(__vector128)]; } u; + if (size > sizeof(u)) + return -EINVAL; + if (!address_ok(regs, ea & ~0xfUL, 16)) return -EFAULT; /* align to multiple of size */ diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/perf/imc-pmu.c linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/perf/imc-pmu.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/perf/imc-pmu.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/perf/imc-pmu.c @@ -299,6 +299,8 @@ attr_group->attrs = attrs; do { ev_val_str = kasprintf(GFP_KERNEL, "event=0x%x", pmu->events[i].value); + if (!ev_val_str) + continue; dev_str = device_str_attr_create(pmu->events[i].name, ev_val_str); if (!dev_str) continue; @@ -306,6 +308,8 @@ attrs[j++] = dev_str; if (pmu->events[i].scale) { ev_scale_str = kasprintf(GFP_KERNEL, "%s.scale", pmu->events[i].name); + if (!ev_scale_str) + continue; dev_str = device_str_attr_create(ev_scale_str, pmu->events[i].scale); if (!dev_str) continue; @@ -315,6 +319,8 @@ if (pmu->events[i].unit) { ev_unit_str = kasprintf(GFP_KERNEL, "%s.unit", pmu->events[i].name); + if (!ev_unit_str) + continue; dev_str = device_str_attr_create(ev_unit_str, pmu->events[i].unit); if (!dev_str) continue; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/mm/init.c linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/mm/init.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/mm/init.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/mm/init.c @@ -172,6 +172,9 @@ /* Limit the memory size via mem. */ static phys_addr_t memory_limit; +#ifdef CONFIG_XIP_KERNEL +#define memory_limit (*(phys_addr_t *)XIP_FIXUP(&memory_limit)) +#endif /* CONFIG_XIP_KERNEL */ static int __init early_mem(char *p) { @@ -958,7 +961,7 @@ * setup_vm_final installs the linear mapping. For 32-bit kernel, as the * kernel is mapped in the linear mapping, that makes no difference. */ - dtb_early_va = kernel_mapping_pa_to_va(XIP_FIXUP(dtb_pa)); + dtb_early_va = kernel_mapping_pa_to_va(dtb_pa); #endif dtb_early_pa = dtb_pa; @@ -1027,9 +1030,13 @@ pmd_t __maybe_unused fix_bmap_spmd, fix_bmap_epmd; kernel_map.virt_addr = KERNEL_LINK_ADDR; - kernel_map.page_offset = _AC(CONFIG_PAGE_OFFSET, UL); #ifdef CONFIG_XIP_KERNEL +#ifdef CONFIG_64BIT + kernel_map.page_offset = PAGE_OFFSET_L3; +#else + kernel_map.page_offset = _AC(CONFIG_PAGE_OFFSET, UL); +#endif kernel_map.xiprom = (uintptr_t)CONFIG_XIP_PHYS_ADDR; kernel_map.xiprom_sz = (uintptr_t)(&_exiprom) - (uintptr_t)(&_xiprom); @@ -1039,6 +1046,7 @@ kernel_map.va_kernel_xip_pa_offset = kernel_map.virt_addr - kernel_map.xiprom; #else + kernel_map.page_offset = _AC(CONFIG_PAGE_OFFSET, UL); kernel_map.phys_addr = (uintptr_t)(&_start); kernel_map.size = (uintptr_t)(&_end) - kernel_map.phys_addr; #endif diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/s390/boot/startup.c linux-lowlatency-hwe-6.5-6.5.0/arch/s390/boot/startup.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/s390/boot/startup.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/s390/boot/startup.c @@ -211,7 +211,8 @@ VMALLOC_END = MODULES_VADDR; /* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */ - vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE)); + vsize = round_down(VMALLOC_END / 2, _SEGMENT_SIZE); + vmalloc_size = min(vmalloc_size, vsize); VMALLOC_START = VMALLOC_END - vmalloc_size; /* split remaining virtual space between 1:1 mapping & vmemmap array */ diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/s390/crypto/paes_s390.c linux-lowlatency-hwe-6.5-6.5.0/arch/s390/crypto/paes_s390.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/s390/crypto/paes_s390.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/s390/crypto/paes_s390.c @@ -693,9 +693,11 @@ * final block may be < AES_BLOCK_SIZE, copy only nbytes */ if (nbytes) { + memset(buf, 0, AES_BLOCK_SIZE); + memcpy(buf, walk.src.virt.addr, nbytes); while (1) { if (cpacf_kmctr(ctx->fc, ¶m, buf, - walk.src.virt.addr, AES_BLOCK_SIZE, + buf, AES_BLOCK_SIZE, walk.iv) == AES_BLOCK_SIZE) break; if (__paes_convert_key(ctx)) diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/s390/kvm/kvm-s390.c linux-lowlatency-hwe-6.5-6.5.0/arch/s390/kvm/kvm-s390.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/s390/kvm/kvm-s390.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/s390/kvm/kvm-s390.c @@ -4307,10 +4307,6 @@ vcpu_load(vcpu); - if (test_fp_ctl(fpu->fpc)) { - ret = -EINVAL; - goto out; - } vcpu->run->s.regs.fpc = fpu->fpc; if (MACHINE_HAS_VX) convert_fp_to_vx((__vector128 *) vcpu->run->s.regs.vrs, @@ -4318,7 +4314,6 @@ else memcpy(vcpu->run->s.regs.fprs, &fpu->fprs, sizeof(fpu->fprs)); -out: vcpu_put(vcpu); return ret; } diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/sh/boards/mach-ecovec24/setup.c linux-lowlatency-hwe-6.5-6.5.0/arch/sh/boards/mach-ecovec24/setup.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/sh/boards/mach-ecovec24/setup.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/sh/boards/mach-ecovec24/setup.c @@ -1220,7 +1220,7 @@ lcdc_info.ch[0].num_modes = ARRAY_SIZE(ecovec_dvi_modes); /* No backlight */ - gpio_backlight_data.fbdev = NULL; + gpio_backlight_data.dev = NULL; gpio_set_value(GPIO_PTA2, 1); gpio_set_value(GPIO_PTU1, 1); diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/um/drivers/virt-pci.c linux-lowlatency-hwe-6.5-6.5.0/arch/um/drivers/virt-pci.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/um/drivers/virt-pci.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/um/drivers/virt-pci.c @@ -971,7 +971,7 @@ *ops = &um_pci_device_bar_ops; *priv = &um_pci_platform_device->resptr[0]; - return 0; + return offset; } static const struct logic_iomem_region_ops um_pci_platform_ops = { diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/Kconfig linux-lowlatency-hwe-6.5-6.5.0/arch/x86/Kconfig --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/Kconfig +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/Kconfig @@ -2629,6 +2629,31 @@ If in doubt, say N. +choice + prompt "Clear branch history" + depends on CPU_SUP_INTEL + default SPECTRE_BHI_AUTO + help + Enable BHI mitigations. BHI attacks are a form of Spectre V2 attacks + where the branch history buffer is poisoned to speculatively steer + indirect branches. + See + +config SPECTRE_BHI_ON + bool "on" + help + Equivalent to setting spectre_bhi=on command line parameter. +config SPECTRE_BHI_OFF + bool "off" + help + Equivalent to setting spectre_bhi=off command line parameter. +config SPECTRE_BHI_AUTO + bool "auto" + help + Equivalent to setting spectre_bhi=auto command line parameter. + +endchoice + endif config ARCH_HAS_ADD_PAGES diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/boot/compressed/ident_map_64.c linux-lowlatency-hwe-6.5-6.5.0/arch/x86/boot/compressed/ident_map_64.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/boot/compressed/ident_map_64.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/boot/compressed/ident_map_64.c @@ -387,0 +388,5 @@ + +void do_boot_nmi_trap(struct pt_regs *regs, unsigned long error_code) +{ + /* Empty handler to ignore NMI during early boot */ +} diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/common.c linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/common.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/common.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/common.c @@ -48,7 +48,7 @@ if (likely(unr < NR_syscalls)) { unr = array_index_nospec(unr, NR_syscalls); - regs->ax = sys_call_table[unr](regs); + regs->ax = x64_sys_call(regs, unr); return true; } return false; @@ -65,7 +65,7 @@ if (IS_ENABLED(CONFIG_X86_X32_ABI) && likely(xnr < X32_NR_syscalls)) { xnr = array_index_nospec(xnr, X32_NR_syscalls); - regs->ax = x32_sys_call_table[xnr](regs); + regs->ax = x32_sys_call(regs, xnr); return true; } return false; @@ -114,7 +114,7 @@ if (likely(unr < IA32_NR_syscalls)) { unr = array_index_nospec(unr, IA32_NR_syscalls); - regs->ax = ia32_sys_call_table[unr](regs); + regs->ax = ia32_sys_call(regs, unr); } else if (nr != -1) { regs->ax = __ia32_sys_ni_syscall(regs); } @@ -141,7 +141,7 @@ } /** - * int80_emulation - 32-bit legacy syscall entry + * do_int80_emulation - 32-bit legacy syscall C entry from asm * * This entry point can be used by 32-bit and 64-bit programs to perform * 32-bit system calls. Instances of INT $0x80 can be found inline in @@ -159,7 +159,7 @@ * eax: system call number * ebx, ecx, edx, esi, edi, ebp: arg1 - arg 6 */ -DEFINE_IDTENTRY_RAW(int80_emulation) +__visible noinstr void do_int80_emulation(struct pt_regs *regs) { int nr; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/entry_64_compat.S linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/entry_64_compat.S --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/entry_64_compat.S +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/entry_64_compat.S @@ -92,6 +92,7 @@ IBRS_ENTER UNTRAIN_RET + CLEAR_BRANCH_HISTORY /* * SYSENTER doesn't filter flags, so we need to clear NT and AC @@ -209,6 +210,7 @@ IBRS_ENTER UNTRAIN_RET + CLEAR_BRANCH_HISTORY movq %rsp, %rdi call do_fast_syscall_32 @@ -278,0 +281,14 @@ + +/* + * int 0x80 is used by 32 bit mode as a system call entry. Normally idt entries + * point to C routines, however since this is a system call interface the branch + * history needs to be scrubbed to protect against BHI attacks, and that + * scrubbing needs to take place in assembly code prior to entering any C + * routines. + */ +SYM_CODE_START(int80_emulation) + ANNOTATE_NOENDBR + UNWIND_HINT_FUNC + CLEAR_BRANCH_HISTORY + jmp do_int80_emulation +SYM_CODE_END(int80_emulation) diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/events/intel/uncore_snbep.c linux-lowlatency-hwe-6.5-6.5.0/arch/x86/events/intel/uncore_snbep.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/events/intel/uncore_snbep.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/events/intel/uncore_snbep.c @@ -5596,7 +5596,7 @@ struct pci_dev *ubox = NULL; struct pci_dev *dev = NULL; u32 nid, gid; - int i, idx, ret = -EPERM; + int i, idx, lgc_pkg, ret = -EPERM; struct intel_uncore_topology *upi; unsigned int devfn; @@ -5614,8 +5614,13 @@ for (i = 0; i < 8; i++) { if (nid != GIDNIDMAP(gid, i)) continue; + lgc_pkg = topology_phys_to_logical_pkg(i); + if (lgc_pkg < 0) { + ret = -EPERM; + goto err; + } for (idx = 0; idx < type->num_boxes; idx++) { - upi = &type->topology[nid][idx]; + upi = &type->topology[lgc_pkg][idx]; devfn = PCI_DEVFN(dev_link0 + idx, ICX_UPI_REGS_ADDR_FUNCTION); dev = pci_get_domain_bus_and_slot(pci_domain_nr(ubox->bus), ubox->bus->number, @@ -5626,6 +5631,7 @@ goto err; } } + break; } } err: diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/msr-index.h linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/msr-index.h --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/msr-index.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/msr-index.h @@ -50,10 +50,13 @@ #define SPEC_CTRL_SSBD BIT(SPEC_CTRL_SSBD_SHIFT) /* Speculative Store Bypass Disable */ #define SPEC_CTRL_RRSBA_DIS_S_SHIFT 6 /* Disable RRSBA behavior */ #define SPEC_CTRL_RRSBA_DIS_S BIT(SPEC_CTRL_RRSBA_DIS_S_SHIFT) +#define SPEC_CTRL_BHI_DIS_S_SHIFT 10 /* Disable Branch History Injection behavior */ +#define SPEC_CTRL_BHI_DIS_S BIT(SPEC_CTRL_BHI_DIS_S_SHIFT) /* A mask for bits which the kernel toggles when controlling mitigations */ #define SPEC_CTRL_MITIGATIONS_MASK (SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD \ - | SPEC_CTRL_RRSBA_DIS_S) + | SPEC_CTRL_RRSBA_DIS_S \ + | SPEC_CTRL_BHI_DIS_S) #define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */ #define PRED_CMD_IBPB BIT(0) /* Indirect Branch Prediction Barrier */ @@ -152,6 +155,10 @@ * are restricted to targets in * kernel. */ +#define ARCH_CAP_BHI_NO BIT(20) /* + * CPU is not affected by Branch + * History Injection. + */ #define ARCH_CAP_PBRSB_NO BIT(24) /* * Not susceptible to Post-Barrier * Return Stack Buffer Predictions. diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/nospec-branch.h linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/nospec-branch.h --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/nospec-branch.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/nospec-branch.h @@ -329,6 +329,19 @@ #endif .endm +#ifdef CONFIG_X86_64 +.macro CLEAR_BRANCH_HISTORY + ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP +.endm + +.macro CLEAR_BRANCH_HISTORY_VMEXIT + ALTERNATIVE "", "call clear_bhb_loop", X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT +.endm +#else +#define CLEAR_BRANCH_HISTORY +#define CLEAR_BRANCH_HISTORY_VMEXIT +#endif + #else /* __ASSEMBLY__ */ #define ANNOTATE_RETPOLINE_SAFE \ @@ -359,6 +372,10 @@ extern void entry_untrain_ret(void); extern void entry_ibpb(void); +#ifdef CONFIG_X86_64 +extern void clear_bhb_loop(void); +#endif + extern void (*x86_return_thunk)(void); #ifdef CONFIG_CALL_DEPTH_TRACKING diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/syscall_wrapper.h linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/syscall_wrapper.h --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/syscall_wrapper.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/syscall_wrapper.h @@ -58,12 +58,29 @@ ,,regs->di,,regs->si,,regs->dx \ ,,regs->r10,,regs->r8,,regs->r9) \ + +/* SYSCALL_PT_ARGS is Adapted from s390x */ +#define SYSCALL_PT_ARG6(m, t1, t2, t3, t4, t5, t6) \ + SYSCALL_PT_ARG5(m, t1, t2, t3, t4, t5), m(t6, (regs->bp)) +#define SYSCALL_PT_ARG5(m, t1, t2, t3, t4, t5) \ + SYSCALL_PT_ARG4(m, t1, t2, t3, t4), m(t5, (regs->di)) +#define SYSCALL_PT_ARG4(m, t1, t2, t3, t4) \ + SYSCALL_PT_ARG3(m, t1, t2, t3), m(t4, (regs->si)) +#define SYSCALL_PT_ARG3(m, t1, t2, t3) \ + SYSCALL_PT_ARG2(m, t1, t2), m(t3, (regs->dx)) +#define SYSCALL_PT_ARG2(m, t1, t2) \ + SYSCALL_PT_ARG1(m, t1), m(t2, (regs->cx)) +#define SYSCALL_PT_ARG1(m, t1) m(t1, (regs->bx)) +#define SYSCALL_PT_ARGS(x, ...) SYSCALL_PT_ARG##x(__VA_ARGS__) + +#define __SC_COMPAT_CAST(t, a) \ + (__typeof(__builtin_choose_expr(__TYPE_IS_L(t), 0, 0U))) \ + (unsigned int)a + /* Mapping of registers to parameters for syscalls on i386 */ #define SC_IA32_REGS_TO_ARGS(x, ...) \ - __MAP(x,__SC_ARGS \ - ,,(unsigned int)regs->bx,,(unsigned int)regs->cx \ - ,,(unsigned int)regs->dx,,(unsigned int)regs->si \ - ,,(unsigned int)regs->di,,(unsigned int)regs->bp) + SYSCALL_PT_ARGS(x, __SC_COMPAT_CAST, \ + __MAP(x, __SC_TYPE, __VA_ARGS__)) \ #define __SYS_STUB0(abi, name) \ long __##abi##_##name(const struct pt_regs *regs); \ diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/bugs.c linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/bugs.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/bugs.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/bugs.c @@ -1541,6 +1541,79 @@ dump_stack(); } +/* + * Set BHI_DIS_S to prevent indirect branches in kernel to be influenced by + * branch history in userspace. Not needed if BHI_NO is set. + */ +static bool __init spec_ctrl_bhi_dis(void) +{ + if (!boot_cpu_has(X86_FEATURE_BHI_CTRL)) + return false; + + x86_spec_ctrl_base |= SPEC_CTRL_BHI_DIS_S; + update_spec_ctrl(x86_spec_ctrl_base); + setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_HW); + + return true; +} + +enum bhi_mitigations { + BHI_MITIGATION_OFF, + BHI_MITIGATION_ON, + BHI_MITIGATION_AUTO, +}; + +static enum bhi_mitigations bhi_mitigation __ro_after_init = + IS_ENABLED(CONFIG_SPECTRE_BHI_ON) ? BHI_MITIGATION_ON : + IS_ENABLED(CONFIG_SPECTRE_BHI_OFF) ? BHI_MITIGATION_OFF : + BHI_MITIGATION_AUTO; + +static int __init spectre_bhi_parse_cmdline(char *str) +{ + if (!str) + return -EINVAL; + + if (!strcmp(str, "off")) + bhi_mitigation = BHI_MITIGATION_OFF; + else if (!strcmp(str, "on")) + bhi_mitigation = BHI_MITIGATION_ON; + else if (!strcmp(str, "auto")) + bhi_mitigation = BHI_MITIGATION_AUTO; + else + pr_err("Ignoring unknown spectre_bhi option (%s)", str); + + return 0; +} +early_param("spectre_bhi", spectre_bhi_parse_cmdline); + +static void __init bhi_select_mitigation(void) +{ + if (bhi_mitigation == BHI_MITIGATION_OFF) + return; + + /* Retpoline mitigates against BHI unless the CPU has RRSBA behavior */ + if (cpu_feature_enabled(X86_FEATURE_RETPOLINE) && + !(x86_read_arch_cap_msr() & ARCH_CAP_RRSBA)) + return; + + if (spec_ctrl_bhi_dis()) + return; + + if (!IS_ENABLED(CONFIG_X86_64)) + return; + + /* Mitigate KVM by default */ + setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT); + pr_info("Spectre BHI mitigation: SW BHB clearing on vm exit\n"); + + if (bhi_mitigation == BHI_MITIGATION_AUTO) + return; + + /* Mitigate syscalls when the mitigation is forced =on */ + setup_force_cpu_cap(X86_FEATURE_CLEAR_BHB_LOOP); + pr_info("Spectre BHI mitigation: SW BHB clearing on syscall\n"); +} + static void __init spectre_v2_select_mitigation(void) { enum spectre_v2_mitigation_cmd cmd = spectre_v2_parse_cmdline(); @@ -1652,6 +1725,9 @@ mode == SPECTRE_V2_RETPOLINE) spec_ctrl_disable_kernel_rrsba(); + if (boot_cpu_has(X86_BUG_BHI)) + bhi_select_mitigation(); + spectre_v2_enabled = mode; pr_info("%s\n", spectre_v2_strings[mode]); @@ -2626,15 +2702,15 @@ switch (spectre_v2_user_stibp) { case SPECTRE_V2_USER_NONE: - return ", STIBP: disabled"; + return "; STIBP: disabled"; case SPECTRE_V2_USER_STRICT: - return ", STIBP: forced"; + return "; STIBP: forced"; case SPECTRE_V2_USER_STRICT_PREFERRED: - return ", STIBP: always-on"; + return "; STIBP: always-on"; case SPECTRE_V2_USER_PRCTL: case SPECTRE_V2_USER_SECCOMP: if (static_key_enabled(&switch_to_cond_stibp)) - return ", STIBP: conditional"; + return "; STIBP: conditional"; } return ""; } @@ -2643,10 +2719,10 @@ { if (boot_cpu_has(X86_FEATURE_IBPB)) { if (static_key_enabled(&switch_mm_always_ibpb)) - return ", IBPB: always-on"; + return "; IBPB: always-on"; if (static_key_enabled(&switch_mm_cond_ibpb)) - return ", IBPB: conditional"; - return ", IBPB: disabled"; + return "; IBPB: conditional"; + return "; IBPB: disabled"; } return ""; } @@ -2656,14 +2732,31 @@ if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) { if (boot_cpu_has(X86_FEATURE_RSB_VMEXIT_LITE) || boot_cpu_has(X86_FEATURE_RSB_VMEXIT)) - return ", PBRSB-eIBRS: SW sequence"; + return "; PBRSB-eIBRS: SW sequence"; else - return ", PBRSB-eIBRS: Vulnerable"; + return "; PBRSB-eIBRS: Vulnerable"; } else { - return ", PBRSB-eIBRS: Not affected"; + return "; PBRSB-eIBRS: Not affected"; } } +static const char * const spectre_bhi_state(void) +{ + if (!boot_cpu_has_bug(X86_BUG_BHI)) + return "; BHI: Not affected"; + else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_HW)) + return "; BHI: BHI_DIS_S"; + else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP)) + return "; BHI: SW loop, KVM: SW loop"; + else if (boot_cpu_has(X86_FEATURE_RETPOLINE) && + !(x86_read_arch_cap_msr() & ARCH_CAP_RRSBA)) + return "; BHI: Retpoline"; + else if (boot_cpu_has(X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT)) + return "; BHI: Syscall hardening, KVM: SW loop"; + + return "; BHI: Vulnerable (Syscall hardening enabled)"; +} + static ssize_t spectre_v2_show_state(char *buf) { if (spectre_v2_enabled == SPECTRE_V2_LFENCE) @@ -2676,13 +2769,15 @@ spectre_v2_enabled == SPECTRE_V2_EIBRS_LFENCE) return sysfs_emit(buf, "Vulnerable: eIBRS+LFENCE with unprivileged eBPF and SMT\n"); - return sysfs_emit(buf, "%s%s%s%s%s%s%s\n", + return sysfs_emit(buf, "%s%s%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], ibpb_state(), - boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", + boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? "; IBRS_FW" : "", stibp_state(), - boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? ", RSB filling" : "", + boot_cpu_has(X86_FEATURE_RSB_CTXSW) ? "; RSB filling" : "", pbrsb_eibrs_state(), + spectre_bhi_state(), + /* this should always be at the end */ spectre_v2_module_string()); } diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/common.c linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/common.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/common.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/common.c @@ -1150,6 +1150,7 @@ #define NO_SPECTRE_V2 BIT(8) #define NO_MMIO BIT(9) #define NO_EIBRS_PBRSB BIT(10) +#define NO_BHI BIT(11) #define VULNWL(vendor, family, model, whitelist) \ X86_MATCH_VENDOR_FAM_MODEL(vendor, family, model, whitelist) @@ -1212,18 +1213,18 @@ VULNWL_INTEL(ATOM_TREMONT_D, NO_ITLB_MULTIHIT | NO_EIBRS_PBRSB), /* AMD Family 0xf - 0x12 */ - VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), - VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), - VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), - VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO), + VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), + VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), + VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), + VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_BHI), /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ - VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB), - VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB), + VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB | NO_BHI), + VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO | NO_EIBRS_PBRSB | NO_BHI), /* Zhaoxin Family 7 */ - VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO), - VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO), + VULNWL(CENTAUR, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO | NO_BHI), + VULNWL(ZHAOXIN, 7, X86_MODEL_ANY, NO_SPECTRE_V2 | NO_SWAPGS | NO_MMIO | NO_BHI), {} }; @@ -1428,6 +1429,13 @@ boot_cpu_has(X86_FEATURE_AVX)) setup_force_cpu_bug(X86_BUG_GDS); + /* When virtualized, eIBRS could be hidden, assume vulnerable */ + if (!(ia32_cap & ARCH_CAP_BHI_NO) && + !cpu_matches(cpu_vuln_whitelist, NO_BHI) && + (boot_cpu_has(X86_FEATURE_IBRS_ENHANCED) || + boot_cpu_has(X86_FEATURE_HYPERVISOR))) + setup_force_cpu_bug(X86_BUG_BHI); + if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) return; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/mce/core.c linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/mce/core.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/mce/core.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/mce/core.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -233,6 +234,7 @@ struct llist_node *pending; struct mce_evt_llist *l; int apei_err = 0; + struct page *p; /* * Allow instrumentation around external facilities usage. Not that it @@ -286,6 +288,20 @@ if (!fake_panic) { if (panic_timeout == 0) panic_timeout = mca_cfg.panic_timeout; + + /* + * Kdump skips the poisoned page in order to avoid + * touching the error bits again. Poison the page even + * if the error is fatal and the machine is about to + * panic. + */ + if (kexec_crash_loaded()) { + if (final && (final->status & MCI_STATUS_ADDRV)) { + p = pfn_to_online_page(final->addr >> PAGE_SHIFT); + if (p) + SetPageHWPoison(p); + } + } panic(msg); } else pr_emerg(HW_ERR "Fake kernel panic: %s\n", msg); diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/pmu.h linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/pmu.h --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/pmu.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/pmu.h @@ -82,20 +82,2 @@ -static inline void pmc_release_perf_event(struct kvm_pmc *pmc) -{ - if (pmc->perf_event) { - perf_event_release_kernel(pmc->perf_event); - pmc->perf_event = NULL; - pmc->current_config = 0; - pmc_to_pmu(pmc)->event_count--; - } -} - -static inline void pmc_stop_counter(struct kvm_pmc *pmc) -{ - if (pmc->perf_event) { - pmc->counter = pmc_read_counter(pmc); - pmc_release_perf_event(pmc); - } -} - static inline bool pmc_is_gp(struct kvm_pmc *pmc) diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/svm/nested.c linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/svm/nested.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/svm/nested.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/svm/nested.c @@ -247,18 +247,6 @@ kvm_vcpu_is_legal_gpa(vcpu, addr + size - 1); } -static bool nested_svm_check_tlb_ctl(struct kvm_vcpu *vcpu, u8 tlb_ctl) -{ - /* Nested FLUSHBYASID is not supported yet. */ - switch(tlb_ctl) { - case TLB_CONTROL_DO_NOTHING: - case TLB_CONTROL_FLUSH_ALL_ASID: - return true; - default: - return false; - } -} - static bool __nested_vmcb_check_controls(struct kvm_vcpu *vcpu, struct vmcb_ctrl_area_cached *control) { @@ -278,9 +266,6 @@ IOPM_SIZE))) return false; - if (CC(!nested_svm_check_tlb_ctl(vcpu, control->tlb_ctl))) - return false; - if (CC((control->int_ctl & V_NMI_ENABLE_MASK) && !vmcb12_is_intercept(control, INTERCEPT_NMI))) { return false; diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/svm/pmu.c linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/svm/pmu.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/svm/pmu.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/svm/pmu.c @@ -233,21 +233,6 @@ } } -static void amd_pmu_reset(struct kvm_vcpu *vcpu) -{ - struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); - int i; - - for (i = 0; i < KVM_AMD_PMC_MAX_GENERIC; i++) { - struct kvm_pmc *pmc = &pmu->gp_counters[i]; - - pmc_stop_counter(pmc); - pmc->counter = pmc->prev_counter = pmc->eventsel = 0; - } - - pmu->global_ctrl = pmu->global_status = 0; -} - struct kvm_pmu_ops amd_pmu_ops __initdata = { .hw_event_available = amd_hw_event_available, .pmc_idx_to_pmc = amd_pmc_idx_to_pmc, @@ -259,7 +244,6 @@ .set_msr = amd_pmu_set_msr, .refresh = amd_pmu_refresh, .init = amd_pmu_init, - .reset = amd_pmu_reset, .EVENTSEL_EVENT = AMD64_EVENTSEL_EVENT, .MAX_NR_GP_COUNTERS = KVM_AMD_PMC_MAX_GENERIC, .MIN_NR_GP_COUNTERS = AMD64_NUM_COUNTERS, diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/vmx/pmu_intel.c linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/vmx/pmu_intel.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/vmx/pmu_intel.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/vmx/pmu_intel.c @@ -603,26 +603,6 @@ static void intel_pmu_reset(struct kvm_vcpu *vcpu) { - struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); - struct kvm_pmc *pmc = NULL; - int i; - - for (i = 0; i < KVM_INTEL_PMC_MAX_GENERIC; i++) { - pmc = &pmu->gp_counters[i]; - - pmc_stop_counter(pmc); - pmc->counter = pmc->prev_counter = pmc->eventsel = 0; - } - - for (i = 0; i < KVM_PMC_MAX_FIXED; i++) { - pmc = &pmu->fixed_counters[i]; - - pmc_stop_counter(pmc); - pmc->counter = pmc->prev_counter = 0; - } - - pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = 0; - intel_pmu_release_guest_lbr_event(vcpu); } diff -u linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/x86.c linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/x86.c --- linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/x86.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/x86.c @@ -1616,7 +1616,8 @@ ARCH_CAP_SKIP_VMENTRY_L1DFLUSH | ARCH_CAP_SSB_NO | ARCH_CAP_MDS_NO | \ ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \ ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \ - ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO) + ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \ + ARCH_CAP_BHI_NO) static u64 kvm_get_arch_capabilities(void) { diff -u linux-lowlatency-hwe-6.5-6.5.0/block/bio.c linux-lowlatency-hwe-6.5-6.5.0/block/bio.c --- linux-lowlatency-hwe-6.5-6.5.0/block/bio.c +++ linux-lowlatency-hwe-6.5-6.5.0/block/bio.c @@ -944,7 +944,7 @@ if ((addr1 | mask) != (addr2 | mask)) return false; - if (bv->bv_len + len > queue_max_segment_size(q)) + if (len > queue_max_segment_size(q) - bv->bv_len) return false; return bvec_try_merge_page(bv, page, len, offset, same_page); } @@ -1147,13 +1147,22 @@ void __bio_release_pages(struct bio *bio, bool mark_dirty) { - struct bvec_iter_all iter_all; - struct bio_vec *bvec; + struct folio_iter fi; - bio_for_each_segment_all(bvec, bio, iter_all) { - if (mark_dirty && !PageCompound(bvec->bv_page)) - set_page_dirty_lock(bvec->bv_page); - bio_release_page(bio, bvec->bv_page); + bio_for_each_folio_all(fi, bio) { + struct page *page; + size_t done = 0; + + if (mark_dirty) { + folio_lock(fi.folio); + folio_mark_dirty(fi.folio); + folio_unlock(fi.folio); + } + page = folio_page(fi.folio, fi.offset / PAGE_SIZE); + do { + bio_release_page(bio, page++); + done += PAGE_SIZE; + } while (done < fi.length); } } EXPORT_SYMBOL_GPL(__bio_release_pages); @@ -1439,18 +1448,12 @@ * bio_set_pages_dirty() and bio_check_pages_dirty() are support functions * for performing direct-IO in BIOs. * - * The problem is that we cannot run set_page_dirty() from interrupt context + * The problem is that we cannot run folio_mark_dirty() from interrupt context * because the required locks are not interrupt-safe. So what we can do is to * mark the pages dirty _before_ performing IO. And in interrupt context, * check that the pages are still dirty. If so, fine. If not, redirty them * in process context. * - * We special-case compound pages here: normally this means reads into hugetlb - * pages. The logic in here doesn't really work right for compound pages - * because the VM does not uniformly chase down the head page in all cases. - * But dirtiness of compound pages is pretty meaningless anyway: the VM doesn't - * handle them at all. So we skip compound pages here at an early stage. - * * Note that this code is very hard to test under normal circumstances because * direct-io pins the pages with get_user_pages(). This makes * is_page_cache_freeable return false, and the VM will not clean the pages. @@ -1466,12 +1469,12 @@ */ void bio_set_pages_dirty(struct bio *bio) { - struct bio_vec *bvec; - struct bvec_iter_all iter_all; + struct folio_iter fi; - bio_for_each_segment_all(bvec, bio, iter_all) { - if (!PageCompound(bvec->bv_page)) - set_page_dirty_lock(bvec->bv_page); + bio_for_each_folio_all(fi, bio) { + folio_lock(fi.folio); + folio_mark_dirty(fi.folio); + folio_unlock(fi.folio); } } @@ -1514,12 +1517,11 @@ void bio_check_pages_dirty(struct bio *bio) { - struct bio_vec *bvec; + struct folio_iter fi; unsigned long flags; - struct bvec_iter_all iter_all; - bio_for_each_segment_all(bvec, bio, iter_all) { - if (!PageDirty(bvec->bv_page) && !PageCompound(bvec->bv_page)) + bio_for_each_folio_all(fi, bio) { + if (!folio_test_dirty(fi.folio)) goto defer; } diff -u linux-lowlatency-hwe-6.5-6.5.0/block/blk-cgroup.h linux-lowlatency-hwe-6.5-6.5.0/block/blk-cgroup.h --- linux-lowlatency-hwe-6.5-6.5.0/block/blk-cgroup.h +++ linux-lowlatency-hwe-6.5-6.5.0/block/blk-cgroup.h @@ -252,7 +252,8 @@ if (blkcg == &blkcg_root) return q->root_blkg; - blkg = rcu_dereference(blkcg->blkg_hint); + blkg = rcu_dereference_check(blkcg->blkg_hint, + lockdep_is_held(&q->queue_lock)); if (blkg && blkg->q == q) return blkg; diff -u linux-lowlatency-hwe-6.5-6.5.0/block/blk-mq.c linux-lowlatency-hwe-6.5-6.5.0/block/blk-mq.c --- linux-lowlatency-hwe-6.5-6.5.0/block/blk-mq.c +++ linux-lowlatency-hwe-6.5-6.5.0/block/blk-mq.c @@ -1874,6 +1874,22 @@ __add_wait_queue(wq, wait); /* + * Add one explicit barrier since blk_mq_get_driver_tag() may + * not imply barrier in case of failure. + * + * Order adding us to wait queue and allocating driver tag. + * + * The pair is the one implied in sbitmap_queue_wake_up() which + * orders clearing sbitmap tag bits and waitqueue_active() in + * __sbitmap_queue_wake_up(), since waitqueue_active() is lockless + * + * Otherwise, re-order of adding wait queue and getting driver tag + * may cause __sbitmap_queue_wake_up() to wake up nothing because + * the waitqueue_active() may not observe us in wait queue. + */ + smp_mb(); + + /* * It's possible that a tag was freed in the window between the * allocation failure and adding the hardware queue to the wait * queue. @@ -2967,12 +2983,6 @@ blk_status_t ret; bio = blk_queue_bounce(bio, q); - if (bio_may_exceed_limits(bio, &q->limits)) { - bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); - if (!bio) - return; - } - bio_set_ioprio(bio); if (plug) { @@ -2981,6 +2991,11 @@ rq = NULL; } if (rq) { + if (unlikely(bio_may_exceed_limits(bio, &q->limits))) { + bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); + if (!bio) + return; + } if (!bio_integrity_prep(bio)) return; if (blk_mq_attempt_bio_merge(q, bio, nr_segs)) @@ -2991,6 +3006,11 @@ } else { if (unlikely(bio_queue_enter(bio))) return; + if (unlikely(bio_may_exceed_limits(bio, &q->limits))) { + bio = __bio_split_to_limits(bio, &q->limits, &nr_segs); + if (!bio) + goto fail; + } if (!bio_integrity_prep(bio)) goto fail; } diff -u linux-lowlatency-hwe-6.5-6.5.0/crypto/af_alg.c linux-lowlatency-hwe-6.5-6.5.0/crypto/af_alg.c --- linux-lowlatency-hwe-6.5-6.5.0/crypto/af_alg.c +++ linux-lowlatency-hwe-6.5-6.5.0/crypto/af_alg.c @@ -1116,9 +1116,13 @@ void af_alg_free_resources(struct af_alg_async_req *areq) { struct sock *sk = areq->sk; + struct af_alg_ctx *ctx; af_alg_free_areq_sgls(areq); sock_kfree_s(sk, areq, areq->areqlen); + + ctx = alg_sk(sk)->private; + ctx->inflight = false; } EXPORT_SYMBOL_GPL(af_alg_free_resources); @@ -1188,11 +1192,19 @@ struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, unsigned int areqlen) { - struct af_alg_async_req *areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); + struct af_alg_ctx *ctx = alg_sk(sk)->private; + struct af_alg_async_req *areq; + + /* Only one AIO request can be in flight. */ + if (ctx->inflight) + return ERR_PTR(-EBUSY); + areq = sock_kmalloc(sk, areqlen, GFP_KERNEL); if (unlikely(!areq)) return ERR_PTR(-ENOMEM); + ctx->inflight = true; + areq->areqlen = areqlen; areq->sk = sk; areq->first_rsgl.sgl.sgt.sgl = areq->first_rsgl.sgl.sgl; diff -u linux-lowlatency-hwe-6.5-6.5.0/crypto/algapi.c linux-lowlatency-hwe-6.5-6.5.0/crypto/algapi.c --- linux-lowlatency-hwe-6.5-6.5.0/crypto/algapi.c +++ linux-lowlatency-hwe-6.5-6.5.0/crypto/algapi.c @@ -341,6 +341,7 @@ } if (!strcmp(q->cra_driver_name, alg->cra_name) || + !strcmp(q->cra_driver_name, alg->cra_driver_name) || !strcmp(q->cra_name, alg->cra_driver_name)) goto err; } diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/changelog linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/changelog --- linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/changelog +++ linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/changelog @@ -1,3 +1,1328 @@ +linux-lowlatency-hwe-6.5 (6.5.0-34.34.1~22.04.1) jammy; urgency=medium + + * jammy/linux-lowlatency-hwe-6.5: 6.5.0-34.34.1~22.04.1 -proposed tracker + (LP: #2059429) + + [ Ubuntu: 6.5.0-34.34.1 ] + + * mantic/linux-lowlatency: 6.5.0-34.34.1 -proposed tracker (LP: #2059430) + * mantic/linux: 6.5.0-34.34 -proposed tracker (LP: #2061443) + * CVE-2024-2201 + - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file + - x86/syscall: Don't force use of indirect calls for system calls + - x86/bhi: Add support for clearing branch history at syscall entry + - x86/bhi: Define SPEC_CTRL_BHI_DIS_S + - x86/bhi: Enumerate Branch History Injection (BHI) bug + - x86/bhi: Add BHI mitigation knob + - x86/bhi: Mitigate KVM by default + - KVM: x86: Add BHI_NO + - [Config] Set CONFIG_BHI to enabled (auto) + * mantic/linux: 6.5.0-33.33 -proposed tracker (LP: #2060448) + * [Mantic] Compile broken on armhf (cc1 out of memory) (LP: #2060446) + - Revert "minmax: relax check to allow comparison between unsigned arguments + and signed constants" + - Revert "minmax: allow comparisons of 'int' against 'unsigned char/short'" + - Revert "minmax: allow min()/max()/clamp() if the arguments have the same + signedness." + - Revert "minmax: add umin(a, b) and umax(a, b)" + * mantic/linux: 6.5.0-32.32 -proposed tracker (LP: #2059443) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * Drop fips-checks script from trees (LP: #2055083) + - [Packaging] Remove fips-checks script + * alsa/realtek: adjust max output valume for headphone on 2 LG machines + (LP: #2058573) + - ALSA: hda/realtek: fix the hp playback volume issue for LG machines + * Remove getabis scripts (LP: #2059143) + - [Packaging] Remove getabis + * Mantic update: upstream stable patchset 2024-03-27 (LP: #2059284) + - asm-generic: make sparse happy with odd-sized put_unaligned_*() + - powerpc/mm: Fix null-pointer dereference in pgtable_cache_add + - arm64: irq: set the correct node for VMAP stack + - drivers/perf: pmuv3: don't expose SW_INCR event in sysfs + - powerpc: Fix build error due to is_valid_bugaddr() + - powerpc/mm: Fix build failures due to arch_reserved_kernel_pages() + - powerpc/64s: Fix CONFIG_NUMA=n build due to create_section_mapping() + - x86/boot: Ignore NMIs during very early boot + - powerpc: pmd_move_must_withdraw() is only needed for + CONFIG_TRANSPARENT_HUGEPAGE + - powerpc/lib: Validate size for vector operations + - x86/mce: Mark fatal MCE's page as poison to avoid panic in the kdump kernel + - perf/core: Fix narrow startup race when creating the perf nr_addr_filters + sysfs file + - debugobjects: Stop accessing objects after releasing hash bucket lock + - regulator: core: Only increment use_count when enable_count changes + - audit: Send netlink ACK before setting connection in auditd_set + - ACPI: video: Add quirk for the Colorful X15 AT 23 Laptop + - PNP: ACPI: fix fortify warning + - ACPI: extlog: fix NULL pointer dereference check + - ACPI: NUMA: Fix the logic of getting the fake_pxm value + - PM / devfreq: Synchronize devfreq_monitor_[start/stop] + - ACPI: APEI: set memory failure flags as MF_ACTION_REQUIRED on synchronous + events + - FS:JFS:UBSAN:array-index-out-of-bounds in dbAdjTree + - jfs: fix slab-out-of-bounds Read in dtSearch + - jfs: fix array-index-out-of-bounds in dbAdjTree + - pstore/ram: Fix crash when setting number of cpus to an odd number + - crypto: octeontx2 - Fix cptvf driver cleanup + - erofs: fix ztailpacking for subpage compressed blocks + - crypto: stm32/crc32 - fix parsing list of devices + - afs: fix the usage of read_seqbegin_or_lock() in afs_lookup_volume_rcu() + - afs: fix the usage of read_seqbegin_or_lock() in afs_find_server*() + - rxrpc_find_service_conn_rcu: fix the usage of read_seqbegin_or_lock() + - jfs: fix array-index-out-of-bounds in diNewExt + - arch: consolidate arch_irq_work_raise prototypes + - s390/vfio-ap: fix sysfs status attribute for AP queue devices + - s390/ptrace: handle setting of fpc register correctly + - KVM: s390: fix setting of fpc register + - SUNRPC: Fix a suspicious RCU usage warning + - ecryptfs: Reject casefold directory inodes + - ext4: fix inconsistent between segment fstrim and full fstrim + - ext4: unify the type of flexbg_size to unsigned int + - ext4: remove unnecessary check from alloc_flex_gd() + - ext4: avoid online resizing failures due to oversized flex bg + - wifi: rt2x00: restart beacon queue when hardware reset + - selftests/bpf: satisfy compiler by having explicit return in btf test + - selftests/bpf: Fix pyperf180 compilation failure with clang18 + - wifi: rt2x00: correct wrong BBP register in RxDCOC calibration + - selftests/bpf: Fix issues in setup_classid_environment() + - soc: xilinx: Fix for call trace due to the usage of smp_processor_id() + - soc: xilinx: fix unhandled SGI warning message + - scsi: lpfc: Fix possible file string name overflow when updating firmware + - PCI: Add no PM reset quirk for NVIDIA Spectrum devices + - bonding: return -ENOMEM instead of BUG in alb_upper_dev_walk + - net: usb: ax88179_178a: avoid two consecutive device resets + - scsi: arcmsr: Support new PCI device IDs 1883 and 1886 + - ARM: dts: imx7d: Fix coresight funnel ports + - ARM: dts: imx7s: Fix lcdif compatible + - ARM: dts: imx7s: Fix nand-controller #size-cells + - wifi: ath9k: Fix potential array-index-out-of-bounds read in + ath9k_htc_txstatus() + - wifi: ath11k: fix race due to setting ATH11K_FLAG_EXT_IRQ_ENABLED too early + - bpf: Check rcu_read_lock_trace_held() before calling bpf map helpers + - scsi: libfc: Don't schedule abort twice + - scsi: libfc: Fix up timeout error in fc_fcp_rec_error() + - bpf: Set uattr->batch.count as zero before batched update or deletion + - wifi: wfx: fix possible NULL pointer dereference in wfx_set_mfp_ap() + - ARM: dts: rockchip: fix rk3036 hdmi ports node + - ARM: dts: imx25/27-eukrea: Fix RTC node name + - ARM: dts: imx: Use flash@0,0 pattern + - ARM: dts: imx27: Fix sram node + - ARM: dts: imx1: Fix sram node + - net: phy: at803x: fix passing the wrong reference for config_intr + - ionic: pass opcode to devcmd_wait + - ionic: bypass firmware cmds when stuck in reset + - block/rnbd-srv: Check for unlikely string overflow + - ARM: dts: imx25: Fix the iim compatible string + - ARM: dts: imx25/27: Pass timing0 + - ARM: dts: imx27-apf27dev: Fix LED name + - ARM: dts: imx23-sansa: Use preferred i2c-gpios properties + - ARM: dts: imx23/28: Fix the DMA controller node name + - scsi: hisi_sas: Set .phy_attached before notifing phyup event + HISI_PHYE_PHY_UP_PM + - ice: fix ICE_AQ_VSI_Q_OPT_RSS_* register values + - net: atlantic: eliminate double free in error handling logic + - net: dsa: mv88e6xxx: Fix mv88e6352_serdes_get_stats error path + - block: prevent an integer overflow in bvec_try_merge_hw_page + - md: Whenassemble the array, consult the superblock of the freshest device + - arm64: dts: qcom: msm8996: Fix 'in-ports' is a required property + - arm64: dts: qcom: msm8998: Fix 'out-ports' is a required property + - ice: fix pre-shifted bit usage + - arm64: dts: amlogic: fix format for s4 uart node + - wifi: rtl8xxxu: Add additional USB IDs for RTL8192EU devices + - libbpf: Fix NULL pointer dereference in bpf_object__collect_prog_relos + - wifi: rtlwifi: rtl8723{be,ae}: using calculate_bit_shift() + - wifi: cfg80211: free beacon_ies when overridden from hidden BSS + - Bluetooth: qca: Set both WIDEBAND_SPEECH and LE_STATES quirks for QCA2066 + - Bluetooth: hci_sync: fix BR/EDR wakeup bug + - Bluetooth: L2CAP: Fix possible multiple reject send + - net/smc: disable SEID on non-s390 archs where virtual ISM may be used + - bridge: cfm: fix enum typo in br_cc_ccm_tx_parse + - i40e: Fix VF disable behavior to block all traffic + - octeontx2-af: Fix max NPC MCAM entry check while validating ref_entry + - net: dsa: qca8k: put MDIO bus OF node on qca8k_mdio_register() failure + - f2fs: fix to check return value of f2fs_reserve_new_block() + - ALSA: hda: Refer to correct stream index at loops + - ASoC: doc: Fix undefined SND_SOC_DAPM_NOPM argument + - fast_dput(): handle underflows gracefully + - RDMA/IPoIB: Fix error code return in ipoib_mcast_join + - drm/panel-edp: Add override_edid_mode quirk for generic edp + - drm/bridge: anx7625: Fix Set HPD irq detect window to 2ms + - drm/amd/display: Fix tiled display misalignment + - f2fs: fix write pointers on zoned device after roll forward + - drm/drm_file: fix use of uninitialized variable + - drm/framebuffer: Fix use of uninitialized variable + - drm/mipi-dsi: Fix detach call without attach + - media: stk1160: Fixed high volume of stk1160_dbg messages + - media: rockchip: rga: fix swizzling for RGB formats + - PCI: add INTEL_HDA_ARL to pci_ids.h + - ALSA: hda: Intel: add HDA_ARL PCI ID support + - media: rkisp1: Fix IRQ handler return values + - media: rkisp1: Store IRQ lines + - media: rkisp1: Fix IRQ disable race issue + - f2fs: fix to tag gcing flag on page during block migration + - drm/exynos: Call drm_atomic_helper_shutdown() at shutdown/unbind time + - IB/ipoib: Fix mcast list locking + - media: amphion: remove mutext lock in condition of wait_event + - media: ddbridge: fix an error code problem in ddb_probe + - media: i2c: imx335: Fix hblank min/max values + - drm/amd/display: For prefetch mode > 0, extend prefetch if possible + - drm/msm/dpu: Ratelimit framedone timeout msgs + - drm/msm/dpu: fix writeback programming for YUV cases + - drm/amdgpu: fix ftrace event amdgpu_bo_move always move on same heap + - clk: hi3620: Fix memory leak in hi3620_mmc_clk_init() + - clk: mmp: pxa168: Fix memory leak in pxa168_clk_init() + - watchdog: it87_wdt: Keep WDTCTRL bit 3 unmodified for IT8784/IT8786 + - drm/amd/display: make flip_timestamp_in_us a 64-bit variable + - clk: imx: clk-imx8qxp: fix LVDS bypass, pixel and phy clocks + - drm/amdgpu: Fix ecc irq enable/disable unpaired + - drm/amdgpu: Let KFD sync with VM fences + - drm/amdgpu: Fix '*fw' from request_firmware() not released in + 'amdgpu_ucode_request()' + - drm/amdgpu: Drop 'fence' check in 'to_amdgpu_amdkfd_fence()' + - drm/amdkfd: Fix iterator used outside loop in 'kfd_add_peer_prop()' + - ALSA: hda/conexant: Fix headset auto detect fail in cx8070 and SN6140 + - leds: trigger: panic: Don't register panic notifier if creating the trigger + failed + - um: Fix naming clash between UML and scheduler + - um: Don't use vfprintf() for os_info() + - um: net: Fix return type of uml_net_start_xmit() + - um: time-travel: fix time corruption + - i3c: master: cdns: Update maximum prescaler value for i2c clock + - xen/gntdev: Fix the abuse of underlying struct page in DMA-buf import + - mfd: ti_am335x_tscadc: Fix TI SoC dependencies + - [Config] updateconfigs for MFD_TI_AM335X_TSCADC + - mailbox: arm_mhuv2: Fix a bug for mhuv2_sender_interrupt + - PCI: Only override AMD USB controller if required + - PCI: switchtec: Fix stdev_release() crash after surprise hot remove + - perf cs-etm: Bump minimum OpenCSD version to ensure a bugfix is present + - usb: hub: Replace hardcoded quirk value with BIT() macro + - usb: hub: Add quirk to decrease IN-ep poll interval for Microchip USB491x + hub + - selftests/sgx: Fix linker script asserts + - tty: allow TIOCSLCKTRMIOS with CAP_CHECKPOINT_RESTORE + - fs/kernfs/dir: obey S_ISGID + - spmi: mediatek: Fix UAF on device remove + - PCI: Fix 64GT/s effective data rate calculation + - PCI/AER: Decode Requester ID when no error info found + - 9p: Fix initialisation of netfs_inode for 9p + - misc: lis3lv02d_i2c: Add missing setting of the reg_ctrl callback + - libsubcmd: Fix memory leak in uniq() + - drm/amdkfd: Fix lock dependency warning + - drm/amdkfd: Fix lock dependency warning with srcu + - virtio_net: Fix "‘%d’ directive writing between 1 and 11 bytes into a region + of size 10" warnings + - blk-mq: fix IO hang from sbitmap wakeup race + - ceph: reinitialize mds feature bit even when session in open + - ceph: fix deadlock or deadcode of misusing dget() + - ceph: fix invalid pointer access if get_quota_realm return ERR_PTR + - drm/amd/powerplay: Fix kzalloc parameter 'ATOM_Tonga_PPM_Table' in + 'get_platform_power_management_table()' + - drm/amdgpu: Fix with right return code '-EIO' in + 'amdgpu_gmc_vram_checking()' + - drm/amdgpu: Release 'adev->pm.fw' before return in + 'amdgpu_device_need_post()' + - drm/amdkfd: Fix 'node' NULL check in 'svm_range_get_range_boundaries()' + - perf: Fix the nr_addr_filters fix + - wifi: cfg80211: fix RCU dereference in __cfg80211_bss_update + - drm: using mul_u32_u32() requires linux/math64.h + - scsi: isci: Fix an error code problem in isci_io_request_build() + - regulator: ti-abb: don't use devm_platform_ioremap_resource_byname for + shared interrupt register + - scsi: core: Move scsi_host_busy() out of host lock for waking up EH handler + - HID: hidraw: fix a problem of memory leak in hidraw_release() + - selftests: net: give more time for GRO aggregation + - ip6_tunnel: make sure to pull inner header in __ip6_tnl_rcv() + - ipmr: fix kernel panic when forwarding mcast packets + - net: lan966x: Fix port configuration when using SGMII interface + - tcp: add sanity checks to rx zerocopy + - ixgbe: Refactor returning internal error codes + - ixgbe: Refactor overtemp event handling + - ixgbe: Fix an error handling path in ixgbe_read_iosf_sb_reg_x550() + - net: dsa: qca8k: fix illegal usage of GPIO + - ipv6: Ensure natural alignment of const ipv6 loopback and router addresses + - llc: call sock_orphan() at release time + - bridge: mcast: fix disabled snooping after long uptime + - selftests: net: add missing config for GENEVE + - netfilter: conntrack: correct window scaling with retransmitted SYN + - netfilter: nf_tables: restrict tunnel object to NFPROTO_NETDEV + - netfilter: nf_log: replace BUG_ON by WARN_ON_ONCE when putting logger + - netfilter: nft_ct: sanitize layer 3 and 4 protocol number in custom + expectations + - net: ipv4: fix a memleak in ip_setup_cork + - af_unix: fix lockdep positive in sk_diag_dump_icons() + - SAUCE: Sync apparmor copy of af_unix.c + - selftests: net: fix available tunnels detection + - net: sysfs: Fix /sys/class/net/ path + - selftests: team: Add missing config options + - selftests: bonding: Check initial state + - arm64: irq: set the correct node for shadow call stack + - mm, kmsan: fix infinite recursion due to RCU critical section + - Revert "drm/amd/display: Disable PSR-SU on Parade 0803 TCON again" + - drm/msm/dsi: Enable runtime PM + - LoongArch/smp: Call rcutree_report_cpu_starting() at tlb_init() + - gve: Fix use-after-free vulnerability + - bonding: remove print in bond_verify_device_path + - ASoC: codecs: lpass-wsa-macro: fix compander volume hack + - ASoC: codecs: wsa883x: fix PA volume control + - drm/amdgpu: Fix missing error code in 'gmc_v6/7/8/9_0_hw_init()' + - Documentation/sphinx: fix Python string escapes + - kunit: tool: fix parsing of test attributes + - thermal: core: Fix thermal zone suspend-resume synchronization + - hwrng: starfive - Fix dev_err_probe return error + - crypto: p10-aes-gcm - Avoid -Wstringop-overflow warnings + - erofs: fix up compacted indexes for block size < 4096 + - crypto: starfive - Fix dev_err_probe return error + - s390/boot: always align vmalloc area on segment boundary + - ext4: treat end of range as exclusive in ext4_zero_range() + - wifi: rtw89: fix timeout calculation in rtw89_roc_end() + - ARM: dts: qcom: strip prefix from PMIC files + - ARM: dts: qcom: mdm9615: fix PMIC node labels + - ARM: dts: qcom: msm8660: fix PMIC node labels + - ARM: dts: samsung: exynos4: fix camera unit addresses/ranges + - ARM: dts: samsung: s5pv210: fix camera unit addresses/ranges + - net: phy: micrel: fix ts_info value in case of no phc + - bpf: Prevent inlining of bpf_fentry_test7() + - bpf: Fix a few selftest failures due to llvm18 change + - wifi: rtw89: fix misbehavior of TX beacon in concurrent mode + - bpf: Set need_defer as false when clearing fd array during map free + - wifi: ath12k: fix and enable AP mode for WCN7850 + - minmax: add umin(a, b) and umax(a, b) + - minmax: allow min()/max()/clamp() if the arguments have the same signedness. + - minmax: allow comparisons of 'int' against 'unsigned char/short' + - minmax: relax check to allow comparison between unsigned arguments and + signed constants + - net: mvmdio: Avoid excessive sleeps in polled mode + - arm64: dts: qcom: sm8550: fix soundwire controllers node name + - arm64: dts: qcom: sm8450: fix soundwire controllers node name + - arm64: dts: qcom: sm8350: Fix remoteproc interrupt type + - wifi: mt76: connac: fix EHT phy mode check + - wifi: mt76: mt7996: add PCI IDs for mt7992 + - wifi: ath12k: fix the issue that the multicast/broadcast indicator is not + read correctly for WCN7850 + - arm64: zynqmp: Move fixed clock to / for kv260 + - arm64: zynqmp: Fix clock node name in kv260 cards + - selftests/bpf: fix compiler warnings in RELEASE=1 mode + - scsi: lpfc: Reinitialize an NPIV's VMID data structures after FDISC + - scsi: lpfc: Move determination of vmid_flag after VMID reinitialization + completes + - arm64: dts: qcom: Fix coresight warnings in in-ports and out-ports + - wifi: rtw89: coex: Fix wrong Wi-Fi role info and FDDT parameter members + - Bluetooth: ISO: Avoid creating child socket if PA sync is terminating + - arm64: dts: sprd: Add clock reference for pll2 on UMS512 + - arm64: dts: sprd: Change UMS512 idle-state nodename to match bindings + - net: kcm: fix direct access to bv_len + - reiserfs: Avoid touching renamed directory if parent does not change + - drm/amd/display: Fix MST PBN/X.Y value calculations + - drm/drm_file: fix use of uninitialized variable + - drm/msm/dp: Add DisplayPort controller for SM8650 + - media: uvcvideo: Fix power line control for a Chicony camera + - media: uvcvideo: Fix power line control for SunplusIT camera + - media: rkisp1: resizer: Stop manual allocation of v4l2_subdev_state + - hwmon: (hp-wmi-sensors) Fix failure to load on EliteDesk 800 G6 + - drm/amd/display: Force p-state disallow if leaving no plane config + - drm/amdkfd: fix mes set shader debugger process management + - drm/msm/dpu: enable writeback on SM8350 + - drm/msm/dpu: enable writeback on SM8450 + - watchdog: starfive: add lock annotations to fix context imbalances + - accel/habanalabs: add support for Gaudi2C device + - drm/amd/display: Only clear symclk otg flag for HDMI + - drm/amd/display: Fix minor issues in BW Allocation Phase2 + - drm/amdgpu: apply the RV2 system aperture fix to RN/CZN as well + - pinctrl: baytrail: Fix types of config value in byt_pin_config_set() + - riscv: Make XIP bootable again + - extcon: fix possible name leak in extcon_dev_register() + - usb: xhci-plat: fix usb disconnect issue after s4 + - i2c: rk3x: Adjust mask/value offset for i2c2 on rv1126 + - drm/amdkfd: only flush mes process context if mes support is there + - riscv: Fix build error on rv32 + XIP + - selftests: net: remove dependency on ebpf tests + - selftests: net: explicitly wait for listener ready + - gve: Fix skb truesize underestimation + - net: phy: phy_device: Call into the PHY driver to set LED offload + - net: phy: mediatek-ge-soc: support PHY LEDs + - net: phy: mediatek-ge-soc: sync driver with MediaTek SDK + - selftests: net: add missing config for big tcp tests + - selftests: net: add missing required classifier + - net: dsa: mt7530: fix 10M/100M speed on MT7988 switch + - e1000e: correct maximum frequency adjustment values + - selftests: net: Add missing matchall classifier + - devlink: Fix referring to hw_addr attribute during state validation + - pds_core: Cancel AQ work on teardown + - pds_core: Use struct pdsc for the pdsc_adminq_isr private data + - pds_core: implement pci reset handlers + - pds_core: Prevent race issues involving the adminq + - pds_core: Clear BARs on reset + - pds_core: Rework teardown/setup flow to be more common + - selftests: net: add missing config for nftables-backed iptables + - selftests: net: add missing config for pmtu.sh tests + - selftests: net: don't access /dev/stdout in pmtu.sh + - octeontx2-pf: Remove xdp queues on program detach + - selftests: net: add missing config for NF_TARGET_TTL + - selftests: net: enable some more knobs + - selftests/bpf: Remove flaky test_btf_id test + - ASoC: qcom: sc8280xp: limit speaker volumes + - ASoC: codecs: wcd938x: fix headphones volume controls + - pds_core: Prevent health thread from running during reset/remove + - Upstream stable to v6.1.77, v6.6.16 + * Mantic update: upstream stable patchset 2024-03-27 (LP: #2059284) // + CVE-2023-52603 + - UBSAN: array-index-out-of-bounds in dtSplitRoot + * iwlwifi disconnect and crash - intel wifi7 (LP: #2058808) + - wifi: iwlwifi: pcie: fix RB status reading + * Mantic update: upstream stable patchset 2024-03-26 (LP: #2059068) + - iio: adc: ad7091r: Set alert bit in config register + - iio: adc: ad7091r: Allow users to configure device events + - ext4: allow for the last group to be marked as trimmed + - arm64: properly install vmlinuz.efi + - OPP: Pass rounded rate to _set_opp() + - btrfs: sysfs: validate scrub_speed_max value + - crypto: api - Disallow identical driver names + - PM: hibernate: Enforce ordering during image compression/decompression + - hwrng: core - Fix page fault dead lock on mmap-ed hwrng + - crypto: s390/aes - Fix buffer overread in CTR mode + - s390/vfio-ap: unpin pages on gisc registration failure + - PM / devfreq: Fix buffer overflow in trans_stat_show + - media: imx355: Enable runtime PM before registering async sub-device + - rpmsg: virtio: Free driver_override when rpmsg_remove() + - media: ov9734: Enable runtime PM before registering async sub-device + - s390/vfio-ap: always filter entire AP matrix + - s390/vfio-ap: loop over the shadow APCB when filtering guest's AP + configuration + - s390/vfio-ap: let on_scan_complete() callback filter matrix and update + guest's APCB + - mips: Fix max_mapnr being uninitialized on early stages + - bus: mhi: host: Add alignment check for event ring read pointer + - bus: mhi: host: Drop chan lock before queuing buffers + - bus: mhi: host: Add spinlock to protect WP access when queueing TREs + - parisc/firmware: Fix F-extend for PDC addresses + - parisc/power: Fix power soft-off button emulation on qemu + - async: Split async_schedule_node_domain() + - async: Introduce async_schedule_dev_nocall() + - iio: adc: ad7091r: Enable internal vref if external vref is not supplied + - dmaengine: fix NULL pointer in channel unregistration function + - scsi: ufs: core: Remove the ufshcd_hba_exit() call from ufshcd_async_scan() + - arm64: dts: qcom: sc7180: fix USB wakeup interrupt types + - arm64: dts: qcom: sdm845: fix USB wakeup interrupt types + - arm64: dts: qcom: sm8150: fix USB wakeup interrupt types + - arm64: dts: qcom: sc7280: fix usb_1 wakeup interrupt types + - arm64: dts: qcom: sdm845: fix USB DP/DM HS PHY interrupts + - arm64: dts: qcom: sm8150: fix USB DP/DM HS PHY interrupts + - lsm: new security_file_ioctl_compat() hook + - docs: kernel_abi.py: fix command injection + - scripts/get_abi: fix source path leak + - media: videobuf2-dma-sg: fix vmap callback + - mmc: core: Use mrq.sbc in close-ended ffu + - mmc: mmc_spi: remove custom DMA mapped buffers + - media: mtk-jpeg: Fix use after free bug due to error path handling in + mtk_jpeg_dec_device_run + - arm64: Rename ARM64_WORKAROUND_2966298 + - rtc: cmos: Use ACPI alarm for non-Intel x86 systems too + - rtc: Adjust failure return code for cmos_set_alarm() + - rtc: mc146818-lib: Adjust failure return code for mc146818_get_time() + - rtc: Add support for configuring the UIP timeout for RTC reads + - rtc: Extend timeout for waiting for UIP to clear to 1s + - nouveau/vmm: don't set addr on the fail path to avoid warning + - ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path + - mm/rmap: fix misplaced parenthesis of a likely() + - mm/sparsemem: fix race in accessing memory_section->usage + - rename(): fix the locking of subdirectories + - serial: sc16is7xx: improve regmap debugfs by using one regmap per port + - serial: sc16is7xx: remove wasteful static buffer in sc16is7xx_regmap_name() + - serial: sc16is7xx: remove global regmap from struct sc16is7xx_port + - serial: sc16is7xx: remove unused line structure member + - serial: sc16is7xx: change EFR lock to operate on each channels + - serial: sc16is7xx: convert from _raw_ to _noinc_ regmap functions for FIFO + - serial: sc16is7xx: fix invalid sc16is7xx_lines bitfield in case of probe + error + - serial: sc16is7xx: remove obsolete loop in sc16is7xx_port_irq() + - serial: sc16is7xx: improve do/while loop in sc16is7xx_irq() + - LoongArch/smp: Call rcutree_report_cpu_starting() earlier + - mm: page_alloc: unreserve highatomic page blocks before oom + - ksmbd: set v2 lease version on lease upgrade + - ksmbd: fix potential circular locking issue in smb2_set_ea() + - ksmbd: don't increment epoch if current state and request state are same + - ksmbd: send lease break notification on FILE_RENAME_INFORMATION + - ksmbd: Add missing set_freezable() for freezable kthread + - Revert "drm/amd: Enable PCIe PME from D3" + - wifi: mac80211: fix potential sta-link leak + - net/smc: fix illegal rmb_desc access in SMC-D connection dump + - tcp: make sure init the accept_queue's spinlocks once + - bnxt_en: Wait for FLR to complete during probe + - vlan: skip nested type that is not IFLA_VLAN_QOS_MAPPING + - llc: make llc_ui_sendmsg() more robust against bonding changes + - llc: Drop support for ETH_P_TR_802_2. + - udp: fix busy polling + - net: fix removing a namespace with conflicting altnames + - tun: fix missing dropped counter in tun_xdp_act + - tun: add missing rx stats accounting in tun_xdp_act + - net: micrel: Fix PTP frame parsing for lan8814 + - net/rds: Fix UBSAN: array-index-out-of-bounds in rds_cmsg_recv + - netfs, fscache: Prevent Oops in fscache_put_cache() + - tracing: Ensure visibility when inserting an element into tracing_map + - afs: Hide silly-rename files from userspace + - tcp: Add memory barrier to tcp_push() + - netlink: fix potential sleeping issue in mqueue_flush_file + - ipv6: init the accept_queue's spinlocks in inet6_create + - net/mlx5: DR, Use the right GVMI number for drop action + - net/mlx5: DR, Can't go to uplink vport on RX rule + - net/mlx5: Use mlx5 device constant for selecting CQ period mode for ASO + - net/mlx5e: Allow software parsing when IPsec crypto is enabled + - net/mlx5e: fix a double-free in arfs_create_groups + - net/mlx5e: fix a potential double-free in fs_any_create_groups + - rcu: Defer RCU kthreads wakeup when CPU is dying + - netfilter: nft_limit: reject configurations that cause integer overflow + - netfilter: nf_tables: restrict anonymous set and map names to 16 bytes + - netfilter: nf_tables: validate NFPROTO_* family + - net: stmmac: Wait a bit for the reset to take effect + - net: mvpp2: clear BM pool before initialization + - selftests: netdevsim: fix the udp_tunnel_nic test + - fjes: fix memleaks in fjes_hw_setup + - net: fec: fix the unhandled context fault from smmu + - nbd: always initialize struct msghdr completely + - btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of subvolume + being deleted + - btrfs: ref-verify: free ref cache before clearing mount opt + - btrfs: tree-checker: fix inline ref size in error messages + - btrfs: don't warn if discard range is not aligned to sector + - btrfs: defrag: reject unknown flags of btrfs_ioctl_defrag_range_args + - btrfs: don't abort filesystem when attempting to snapshot deleted subvolume + - rbd: don't move requests to the running list on errors + - exec: Fix error handling in begin_new_exec() + - wifi: iwlwifi: fix a memory corruption + - hv_netvsc: Calculate correct ring size when PAGE_SIZE is not 4 Kbytes + - netfilter: nft_chain_filter: handle NETDEV_UNREGISTER for inet/ingress + basechain + - platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe + - ksmbd: fix global oob in ksmbd_nl_policy + - firmware: arm_scmi: Check mailbox/SMT channel for consistency + - xfs: read only mounts with fsopen mount API are busted + - gpiolib: acpi: Ignore touchpad wakeup on GPD G1619-04 + - cpufreq: intel_pstate: Refine computation of P-state for given frequency + - drm: Don't unref the same fb many times by mistake due to deadlock handling + - drm/bridge: nxp-ptn3460: fix i2c_master_send() error checking + - drm/tidss: Fix atomic_flush check + - drm/bridge: nxp-ptn3460: simplify some error checking + - drm/amd/display: Port DENTIST hang and TDR fixes to OTG disable W/A + - drm/amdgpu/pm: Fix the power source flag error + - erofs: fix lz4 inplace decompression + - media: ov13b10: Enable runtime PM before registering async sub-device + - PM: sleep: Fix possible deadlocks in core system-wide PM code + - thermal: intel: hfi: Refactor enabling code into helper functions + - thermal: intel: hfi: Disable an HFI instance when all its CPUs go offline + - thermal: intel: hfi: Add syscore callbacks for system-wide PM + - fs/pipe: move check to pipe_has_watch_queue() + - pipe: wakeup wr_wait after setting max_usage + - ARM: dts: qcom: sdx55: fix USB wakeup interrupt types + - ARM: dts: samsung: exynos4210-i9100: Unconditionally enable LDO12 + - ARM: dts: qcom: sdx55: fix pdc '#interrupt-cells' + - ARM: dts: qcom: sdx55: fix USB DP/DM HS PHY interrupts + - ARM: dts: qcom: sdx55: fix USB SS wakeup + - dlm: use kernel_connect() and kernel_bind() + - serial: core: Provide port lock wrappers + - serial: sc16is7xx: Use port lock wrappers + - serial: sc16is7xx: fix unconditional activation of THRI interrupt + - btrfs: zoned: factor out prepare_allocation_zoned() + - btrfs: zoned: optimize hint byte for zoned allocator + - drm/panel-edp: drm/panel-edp: Fix AUO B116XAK01 name and timing + - Revert "powerpc/64s: Increase default stack size to 32KB" + - drm/bridge: parade-ps8640: Wait for HPD when doing an AUX transfer + - drm: panel-simple: add missing bus flags for Tianma tm070jvhg[30/33] + - drm/bridge: sii902x: Fix probing race issue + - drm/bridge: sii902x: Fix audio codec unregistration + - drm/bridge: parade-ps8640: Ensure bridge is suspended in .post_disable() + - drm/bridge: parade-ps8640: Make sure we drop the AUX mutex in the error case + - drm/exynos: fix accidental on-stack copy of exynos_drm_plane + - drm/exynos: gsc: minor fix for loop iteration in gsc_runtime_resume + - gpio: eic-sprd: Clear interrupt after set the interrupt type + - drm/bridge: anx7625: Ensure bridge is suspended in disable() + - spi: bcm-qspi: fix SFDP BFPT read by usig mspi read + - spi: fix finalize message on error return + - MIPS: lantiq: register smp_ops on non-smp platforms + - cxl/region:Fix overflow issue in alloc_hpa() + - mips: Call lose_fpu(0) before initializing fcr31 in mips_set_personality_nan + - tick/sched: Preserve number of idle sleeps across CPU hotplug events + - x86/entry/ia32: Ensure s32 is sign extended to s64 + - serial: core: fix kernel-doc for uart_port_unlock_irqrestore() + - docs: sparse: move TW sparse.txt to TW dev-tools + - docs: sparse: add sparse.rst to toctree + - serial: core: Simplify uart_get_rs485_mode() + - serial: core: set missing supported flag for RX during TX GPIO + - soundwire: bus: introduce controller_id + - soundwire: fix initializing sysfs for same devices on different buses + - net: stmmac: Tx coe sw fallback + - net: stmmac: Prevent DSA tags from breaking COE + - dmaengine: idxd: Move dma_free_coherent() out of spinlocked context + - riscv: Fix an off-by-one in get_early_cmdline() + - scsi: core: Kick the requeue list after inserting when flushing + - sh: ecovec24: Rename missed backlight field from fbdev to dev + - smb: client: fix parsing of SMB3.1.1 POSIX create context + - cifs: do not pass cifs_sb when trying to add channels + - cifs: handle cases where a channel is closed + - cifs: reconnect work should have reference on server struct + - cifs: handle when server starts supporting multichannel + - cifs: handle when server stops supporting multichannel + - cifs: reconnect worker should take reference on server struct + unconditionally + - cifs: handle servers that still advertise multichannel after disabling + - cifs: update iface_last_update on each query-and-update + - powerpc/ps3_defconfig: Disable PPC64_BIG_ENDIAN_ELF_ABI_V2 + - crypto: lib/mpi - Fix unexpected pointer access in mpi_ec_init + - mtd: maps: vmu-flash: Fix the (mtd core) switch to ref counters + - mtd: rawnand: Prevent crossing LUN boundaries during sequential reads + - mtd: rawnand: Fix core interference with sequential reads + - mtd: rawnand: Prevent sequential reads with on-die ECC engines + - mtd: rawnand: Clarify conditions to enable continuous reads + - soc: qcom: pmic_glink_altmode: fix port sanity check + - media: ov01a10: Enable runtime PM before registering async sub-device + - soc: fsl: cpm1: tsa: Fix __iomem addresses declaration + - soc: fsl: cpm1: qmc: Fix __iomem addresses declaration + - soc: fsl: cpm1: qmc: Fix rx channel reset + - s390/vfio-ap: reset queues filtered from the guest's AP config + - s390/vfio-ap: reset queues associated with adapter for queue unbound from + driver + - s390/vfio-ap: do not reset queue removed from host config + - ARM: dts: imx6q-apalis: add can power-up delay on ixora board + - arm64: dts: qcom: sc8280xp-crd: fix eDP phy compatible + - arm64: dts: sprd: fix the cpu node for UMS512 + - arm64: dts: rockchip: configure eth pad driver strength for orangepi r1 plus + lts + - arm64: dts: rockchip: Fix rk3588 USB power-domain clocks + - arm64: dts: qcom: msm8916: Make blsp_dma controlled-remotely + - arm64: dts: qcom: msm8939: Make blsp_dma controlled-remotely + - arm64: dts: qcom: sdm670: fix USB wakeup interrupt types + - arm64: dts: qcom: sc8180x: fix USB wakeup interrupt types + - arm64: dts: qcom: Add missing vio-supply for AW2013 + - arm64: dts: qcom: sdm845: fix USB SS wakeup + - arm64: dts: qcom: sm8150: fix USB SS wakeup + - arm64: dts: qcom: sc8180x: fix USB DP/DM HS PHY interrupts + - arm64: dts: qcom: sc8180x: fix USB SS wakeup + - media: i2c: st-mipid02: correct format propagation + - media: mtk-jpeg: Fix timeout schedule error in mtk_jpegdec_worker. + - riscv: mm: Fixup compat mode boot failure + - arm64: errata: Add Cortex-A510 speculative unprivileged load workaround + - [Config] update config for ARM64_ERRATUM_3117295 + - arm64/sme: Always exit sme_alloc() early with existing storage + - arm64: entry: fix ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD + - efi: disable mirror feature during crashkernel + - kexec: do syscore_shutdown() in kernel_kexec + - selftests: mm: hugepage-vmemmap fails on 64K page size systems + - serial: Do not hold the port lock when setting rx-during-tx GPIO + - dt-bindings: net: snps,dwmac: Tx coe unsupported + - bpf: move explored_state() closer to the beginning of verifier.c + - bpf: extract same_callsites() as utility function + - bpf: exact states comparison for iterator convergence checks + - selftests/bpf: tests with delayed read/precision makrs in loop body + - bpf: correct loop detection for iterators convergence + - selftests/bpf: test if state loops are detected in a tricky case + - bpf: print full verifier states on infinite loop detection + - selftests/bpf: track tcp payload offset as scalar in xdp_synproxy + - selftests/bpf: track string payload offset as scalar in strobemeta + - bpf: extract __check_reg_arg() utility function + - bpf: extract setup_func_entry() utility function + - bpf: verify callbacks as if they are called unknown number of times + - selftests/bpf: tests for iterating callbacks + - bpf: widening for callback iterators + - bpf: keep track of max number of bpf_loop callback iterations + - cifs: fix lock ordering while disabling multichannel + - cifs: fix a pending undercount of srv_count + - cifs: after disabling multichannel, mark tcon for reconnect + - selftests: bonding: Increase timeout to 1200s + - bnxt_en: Prevent kernel warning when running offline self test + - selftest: Don't reuse port for SO_INCOMING_CPU test. + - selftests: fill in some missing configs for net + - net/sched: flower: Fix chain template offload + - net/mlx5e: Fix operation precedence bug in port timestamping napi_poll + context + - net/mlx5e: Fix peer flow lists handling + - net/mlx5: Bridge, Enable mcast in smfs steering mode + - net/mlx5: Bridge, fix multicast packets sent to uplink + - net/mlx5e: Ignore IPsec replay window values on sender side + - selftests: net: fix rps_default_mask with >32 CPUs + - bpf: Propagate modified uaddrlen from cgroup sockaddr programs + - bpf: Add bpf_sock_addr_set_sun_path() to allow writing unix sockaddr from + bpf + - ice: work on pre-XDP prog frag count + - i40e: handle multi-buffer packets that are shrunk by xdp prog + - ice: remove redundant xdp_rxq_info registration + - ice: update xdp_rxq_info::frag_size for ZC enabled Rx queue + - i40e: set xdp_rxq_info::frag_size + - selftests: bonding: do not test arp/ns target with mode balance-alb/tlb + - tsnep: Remove FCS for XDP data path + - tsnep: Fix XDP_RING_NEED_WAKEUP for empty fill ring + - btrfs: scrub: avoid use-after-free when chunk length is not 64K aligned + - nfsd: fix RELEASE_LOCKOWNER + - Revert "drivers/firmware: Move sysfb_init() from device_initcall to + subsys_initcall_sync" + - drm/amdgpu: Fix the null pointer when load rlc firmware + - drm: Fix TODO list mentioning non-KMS drivers + - drm: Disable the cursor plane on atomic contexts with virtualized drivers + - drm/virtio: Disable damage clipping if FB changed since last page-flip + - drm: Allow drivers to indicate the damage helpers to ignore damage clips + - drm/amd/display: fix bandwidth validation failure on DCN 2.1 + - drm/amdgpu: correct the cu count for gfx v11 + - drm/amd/display: Align the returned error code with legacy DP + - drm/amd/display: Fix late derefrence 'dsc' check in + 'link_set_dsc_pps_packet()' + - drm/amd/display: Fix uninitialized variable usage in core_link_ 'read_dpcd() + & write_dpcd()' functions + - net/bpf: Avoid unused "sin_addr_len" warning when CONFIG_CGROUP_BPF is not + set + - thermal: core: Store trip pointer in struct thermal_instance + - thermal: gov_power_allocator: avoid inability to reset a cdev + - mm: migrate: record the mlocked page status to remove unnecessary lru drain + - mm: migrate: fix getting incorrect page mapping during page migration + - drm/i915/lnl: Remove watchdog timers for PSR + - drm/i915/psr: Only allow PSR in LPSP mode on HSW non-ULT + - drm/panel-edp: Add AUO B116XTN02, BOE NT116WHM-N21,836X2, NV116WHM-N49 V8.0 + - drm/panel-edp: drm/panel-edp: Fix AUO B116XTN02 name + - drm/amdgpu/gfx10: set UNORD_DISPATCH in compute MQDs + - drm/amdgpu/gfx11: set UNORD_DISPATCH in compute MQDs + - drm/panel: samsung-s6d7aa0: drop DRM_BUS_FLAG_DE_HIGH for lsl080al02 + - memblock: fix crash when reserved memory is not added to memory + - firmware: arm_scmi: Use xa_insert() when saving raw queues + - spi: intel-pci: Remove Meteor Lake-S SoC PCI ID from the list + - cpufreq/amd-pstate: Fix setting scaling max/min freq values + - spi: spi-cadence: Reverse the order of interleaved write and read operations + - cifs: fix stray unlock in cifs_chan_skip_or_disable + - drm: bridge: samsung-dsim: Don't use FORCE_STOP_STATE + - genirq: Initialize resend_node hlist for all interrupt descriptors + - clocksource: Skip watchdog check for large watchdog intervals + - thermal: trip: Drop lockdep assertion from thermal_zone_trip_id() + - platform/x86: intel-uncore-freq: Fix types in sysfs callbacks + - Upstream stable to v6.1.76, v6.6.15 + * CVE-2024-26582 + - net: tls: fix use-after-free with partial reads and async decrypt + - net: tls: fix returned read length with async decrypt + * CVE-2024-26584 + - net: tls: handle backlogging of crypto requests + * CVE-2024-26585 + - tls: fix race between tx work scheduling and socket close + * CVE-2024-26583 + - tls: extract context alloc/initialization out of tls_set_sw_offload + - net: tls: factor out tls_*crypt_async_wait() + - tls: fix race between async notify and socket close + * CVE-2023-52600 + - jfs: fix uaf in jfs_evict_inode + * Fix headphone mic detection issue on ALC897 (LP: #2056418) + - ALSA: hda/realtek - Fix headset Mic no show at resume back for Lenovo ALC897 + platform + * CVE-2024-26581 + - netfilter: nft_set_rbtree: skip end interval element from gc + * The screen brightness is unable to adjust on BOE panel DPN#R6FD8 + (LP: #2057430) + - drm/amd/display: Re-add aux intercept disable delay generically for 2+ + LTTPRs + - drm/amd/display: Clear dpcd_sink_ext_caps if not set + - drm/amd/display: Add monitor patch for specific eDP + - drm/amd/display: Add monitor patch for specific eDP + * Dynamically determine acpi_handle_list size (LP: #2049733) + - ACPI: utils: Dynamically determine acpi_handle_list size + - ACPI: utils: Fix error path in acpi_evaluate_reference() + - ACPI: utils: Fix white space in struct acpi_handle_list definition + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) + - x86/lib: Fix overflow when counting digits + - x86/mce/inject: Clear test status value + - EDAC/thunderx: Fix possible out-of-bounds string access + - powerpc: add crtsavres.o to always-y instead of extra-y + - powerpc/44x: select I2C for CURRITUCK + - powerpc/pseries/memhp: Fix access beyond end of drmem array + - selftests/powerpc: Fix error handling in FPU/VMX preemption tests + - powerpc/powernv: Add a null pointer check to scom_debug_init_one() + - powerpc/powernv: Add a null pointer check in opal_event_init() + - powerpc/powernv: Add a null pointer check in opal_powercap_init() + - powerpc/imc-pmu: Add a null pointer check in update_events_in_group() + - spi: spi-zynqmp-gqspi: fix driver kconfig dependencies + - mtd: rawnand: Increment IFC_TIMEOUT_MSECS for nand controller response + - ACPI: video: check for error while searching for backlight device parent + - ACPI: LPIT: Avoid u32 multiplication overflow + - platform/x86/intel/vsec: Fix xa_alloc memory leak + - cpufreq: scmi: process the result of devm_of_clk_add_hw_provider() + - calipso: fix memory leak in netlbl_calipso_add_pass() + - efivarfs: force RO when remounting if SetVariable is not supported + - spi: sh-msiof: Enforce fixed DTDL for R-Car H3 + - ACPI: LPSS: Fix the fractional clock divider flags + - ACPI: extlog: Clear Extended Error Log status when RAS_CEC handled the error + - kunit: debugfs: Fix unchecked dereference in debugfs_print_results() + - mtd: Fix gluebi NULL pointer dereference caused by ftl notifier + - selinux: Fix error priority for bind with AF_UNSPEC on PF_INET6 socket + - crypto: virtio - Handle dataq logic with tasklet + - crypto: sa2ul - Return crypto_aead_setkey to transfer the error + - crypto: ccp - fix memleak in ccp_init_dm_workarea + - crypto: af_alg - Disallow multiple in-flight AIO requests + - crypto: safexcel - Add error handling for dma_map_sg() calls + - crypto: sahara - remove FLAGS_NEW_KEY logic + - crypto: sahara - fix cbc selftest failure + - crypto: sahara - fix ahash selftest failure + - crypto: sahara - fix processing requests with cryptlen < sg->length + - crypto: sahara - fix error handling in sahara_hw_descriptor_create() + - crypto: hisilicon/qm - save capability registers in qm init process + - crypto: hisilicon/zip - add zip comp high perf mode configuration + - crypto: hisilicon/qm - add a function to set qm algs + - crypto: hisilicon/hpre - save capability registers in probe process + - crypto: hisilicon/sec2 - save capability registers in probe process + - crypto: hisilicon/zip - save capability registers in probe process + - pstore: ram_core: fix possible overflow in persistent_ram_init_ecc() + - erofs: fix memory leak on short-lived bounced pages + - fs: indicate request originates from old mount API + - gfs2: Fix kernel NULL pointer dereference in gfs2_rgrp_dump + - crypto: virtio - Wait for tasklet to complete on device remove + - crypto: sahara - avoid skcipher fallback code duplication + - crypto: sahara - handle zero-length aes requests + - crypto: sahara - fix ahash reqsize + - crypto: sahara - fix wait_for_completion_timeout() error handling + - crypto: sahara - improve error handling in sahara_sha_process() + - crypto: sahara - fix processing hash requests with req->nbytes < sg->length + - crypto: sahara - do not resize req->src when doing hash operations + - crypto: scomp - fix req->dst buffer overflow + - csky: fix arch_jump_label_transform_static override + - blocklayoutdriver: Fix reference leak of pnfs_device_node + - NFSv4.1/pnfs: Ensure we handle the error NFS4ERR_RETURNCONFLICT + - SUNRPC: fix _xprt_switch_find_current_entry logic + - pNFS: Fix the pnfs block driver's calculation of layoutget size + - wifi: plfxlc: check for allocation failure in plfxlc_usb_wreq_async() + - wifi: rtw88: fix RX filter in FIF_ALLMULTI flag + - bpf, lpm: Fix check prefixlen before walking trie + - bpf: Add crosstask check to __bpf_get_stack + - wifi: ath11k: Defer on rproc_get failure + - wifi: libertas: stop selecting wext + - ARM: dts: qcom: apq8064: correct XOADC register address + - net/ncsi: Fix netlink major/minor version numbers + - firmware: ti_sci: Fix an off-by-one in ti_sci_debugfs_create() + - wifi: rtlwifi: rtl8821ae: phy: fix an undefined bitwise shift behavior + - arm64: dts: ti: k3-am62a-main: Fix GPIO pin count in DT nodes + - arm64: dts: ti: k3-am65-main: Fix DSS irq trigger type + - selftests/bpf: Fix erroneous bitmask operation + - md: synchronize flush io with array reconfiguration + - bpf: enforce precision of R0 on callback return + - ARM: dts: qcom: sdx65: correct SPMI node name + - arm64: dts: qcom: sc7180: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sc7280: Mark some nodes as 'reserved' + - arm64: dts: qcom: sc7280: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sdm845: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm8150: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm8250: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sc8280xp: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm6350: Make watchdog bark interrupt edge triggered + - bpf: add percpu stats for bpf_map elements insertions/deletions + - bpf: Add map and need_defer parameters to .map_fd_put_ptr() + - bpf: Defer the free of inner map when necessary + - selftests/net: specify the interface when do arping + - bpf: fix check for attempt to corrupt spilled pointer + - scsi: fnic: Return error if vmalloc() failed + - arm64: dts: qcom: qrb5165-rb5: correct LED panic indicator + - arm64: dts: qcom: sdm845-db845c: correct LED panic indicator + - arm64: dts: qcom: sm8350: Fix DMA0 address + - arm64: dts: qcom: sc7280: Fix up GPU SIDs + - arm64: dts: qcom: sc7280: Mark Adreno SMMU as DMA coherent + - arm64: dts: qcom: sc7280: fix usb_2 wakeup interrupt types + - wifi: mt76: mt7921s: fix workqueue problem causes STA association fail + - bpf: Fix verification of indirect var-off stack access + - arm64: dts: hisilicon: hikey970-pmic: fix regulator cells properties + - dt-bindings: media: mediatek: mdp3: correct RDMA and WROT node with generic + names + - arm64: dts: mediatek: mt8183: correct MDP3 DMA-related nodes + - wifi: mt76: mt7921: fix country count limitation for CLC + - selftests/bpf: Relax time_tai test for equal timestamps in tai_forward + - block: Set memalloc_noio to false on device_add_disk() error path + - arm64: dts: renesas: white-hawk-cpu: Fix missing serial console pin control + - arm64: dts: imx8mm: Reduce GPU to nominal speed + - scsi: hisi_sas: Replace with standard error code return value + - scsi: hisi_sas: Correct the number of global debugfs registers + - ARM: dts: stm32: don't mix SCMI and non-SCMI board compatibles + - selftests/net: fix grep checking for fib_nexthop_multiprefix + - ipmr: support IP_PKTINFO on cache report IGMP msg + - virtio/vsock: fix logic which reduces credit update messages + - dma-mapping: clear dev->dma_mem to NULL after freeing it + - soc: qcom: llcc: Fix dis_cap_alloc and retain_on_pc configuration + - arm64: dts: qcom: sm8150-hdk: fix SS USB regulators + - block: add check of 'minors' and 'first_minor' in device_add_disk() + - arm64: dts: qcom: sc7280: Mark SDHCI hosts as cache-coherent + - arm64: dts: qcom: ipq6018: fix clock rates for GCC_USB0_MOCK_UTMI_CLK + - wifi: rtlwifi: add calculate_bit_shift() + - wifi: rtlwifi: rtl8188ee: phy: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192c: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192cu: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ce: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192de: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ee: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192se: using calculate_bit_shift() + - wifi: iwlwifi: mvm: set siso/mimo chains to 1 in FW SMPS request + - wifi: iwlwifi: mvm: send TX path flush in rfkill + - netfilter: nf_tables: mark newset as dead on transaction abort + - Bluetooth: Fix bogus check for re-auth no supported with non-ssp + - Bluetooth: btmtkuart: fix recv_buf() return value + - null_blk: don't cap max_hw_sectors to BLK_DEF_MAX_SECTORS + - bpf: sockmap, fix proto update hook to avoid dup calls + - sctp: support MSG_ERRQUEUE flag in recvmsg() + - sctp: fix busy polling + - net/sched: act_ct: fix skb leak and crash on ooo frags + - mlxbf_gige: Fix intermittent no ip issue + - mlxbf_gige: Enable the GigE port in mlxbf_gige_open + - ip6_tunnel: fix NEXTHDR_FRAGMENT handling in ip6_tnl_parse_tlv_enc_lim() + - ARM: davinci: always select CONFIG_CPU_ARM926T + - Revert "drm/tidss: Annotate dma-fence critical section in commit path" + - Revert "drm/omapdrm: Annotate dma-fence critical section in commit path" + - drm/panfrost: Really power off GPU cores in panfrost_gpu_power_off() + - RDMA/usnic: Silence uninitialized symbol smatch warnings + - RDMA/hns: Fix inappropriate err code for unsupported operations + - drm/panel-elida-kd35t133: hold panel in reset for unprepare + - drm/nouveau/fence:: fix warning directly dereferencing a rcu pointer + - drm/bridge: tpd12s015: Drop buggy __exit annotation for remove function + - drm/tilcdc: Fix irq free on unload + - media: pvrusb2: fix use after free on context disconnection + - media: mtk-jpeg: Remove cancel worker in mtk_jpeg_remove to avoid the crash + of multi-core JPEG devices + - media: verisilicon: Hook the (TRY_)DECODER_CMD stateless ioctls + - media: rkvdec: Hook the (TRY_)DECODER_CMD stateless ioctls + - drm/bridge: Fix typo in post_disable() description + - f2fs: fix to avoid dirent corruption + - drm/radeon/r600_cs: Fix possible int overflows in r600_cs_check_reg() + - drm/radeon/r100: Fix integer overflow issues in r100_cs_track_check() + - drm/radeon: check return value of radeon_ring_lock() + - drm/tidss: Move reset to the end of dispc_init() + - drm/tidss: Return error value from from softreset + - drm/tidss: Check for K2G in in dispc_softreset() + - drm/tidss: Fix dss reset + - ASoC: cs35l33: Fix GPIO name and drop legacy include + - ASoC: cs35l34: Fix GPIO name and drop legacy include + - drm/msm/mdp4: flush vblank event on disable + - drm/msm/dsi: Use pm_runtime_resume_and_get to prevent refcnt leaks + - drm/drv: propagate errors from drm_modeset_register_all() + - ASoC: Intel: glk_rt5682_max98357a: fix board id mismatch + - drm/panfrost: Ignore core_mask for poweroff and disable PWRTRANS irq + - drm/radeon: check the alloc_workqueue return value in radeon_crtc_init() + - drm/radeon/dpm: fix a memleak in sumo_parse_power_table + - drm/radeon/trinity_dpm: fix a memleak in trinity_parse_power_table + - drm/bridge: cdns-mhdp8546: Fix use of uninitialized variable + - drm/bridge: tc358767: Fix return value on error case + - media: cx231xx: fix a memleak in cx231xx_init_isoc + - RDMA/hns: Fix memory leak in free_mr_init() + - clk: qcom: gpucc-sm8150: Update the gpu_cc_pll1 config + - media: imx-mipi-csis: Fix clock handling in remove() + - media: dt-bindings: media: rkisp1: Fix the port description for the parallel + interface + - media: rkisp1: Fix media device memory leak + - drm/panel: st7701: Fix AVCL calculation + - f2fs: fix to wait on block writeback for post_read case + - f2fs: fix to check compress file in f2fs_move_file_range() + - f2fs: fix to update iostat correctly in f2fs_filemap_fault() + - media: dvbdev: drop refcount on error path in dvb_device_open() + - media: dvb-frontends: m88ds3103: Fix a memory leak in an error handling path + of m88ds3103_probe() + - clk: renesas: rzg2l-cpg: Reuse code in rzg2l_cpg_reset() + - clk: renesas: rzg2l: Check reset monitor registers + - drm/msm/dpu: Set input_sel bit for INTF + - drm/msm/dpu: Drop enable and frame_count parameters from dpu_hw_setup_misr() + - drm/mediatek: Return error if MDP RDMA failed to enable the clock + - drm/mediatek: Fix underrun in VDO1 when switches off the layer + - drm/amdgpu/debugfs: fix error code when smc register accessors are NULL + - drm/amd/pm: fix a double-free in si_dpm_init + - drivers/amd/pm: fix a use-after-free in kv_parse_power_table + - gpu/drm/radeon: fix two memleaks in radeon_vm_init + - drm/amd/pm: fix a double-free in amdgpu_parse_extended_power_table + - f2fs: fix to check return value of f2fs_recover_xattr_data + - dt-bindings: clock: Update the videocc resets for sm8150 + - clk: qcom: videocc-sm8150: Update the videocc resets + - clk: qcom: videocc-sm8150: Add missing PLL config property + - drivers: clk: zynqmp: calculate closest mux rate + - drivers: clk: zynqmp: update divider round rate logic + - watchdog: set cdev owner before adding + - watchdog/hpwdt: Only claim UNKNOWN NMI if from iLO + - watchdog: bcm2835_wdt: Fix WDIOC_SETTIMEOUT handling + - watchdog: rti_wdt: Drop runtime pm reference count when watchdog is unused + - clk: si5341: fix an error code problem in si5341_output_clk_set_rate + - drm/mediatek: dp: Add phy_mtk_dp module as pre-dependency + - clk: fixed-rate: fix clk_hw_register_fixed_rate_with_accuracy_parent_hw + - pwm: stm32: Use hweight32 in stm32_pwm_detect_channels + - pwm: stm32: Fix enable count for clk in .probe() + - ASoC: rt5645: Drop double EF20 entry from dmi_platform_data[] + - ALSA: scarlett2: Add missing error check to scarlett2_config_save() + - ALSA: scarlett2: Add missing error check to scarlett2_usb_set_config() + - ALSA: scarlett2: Allow passing any output to line_out_remap() + - ALSA: scarlett2: Add missing error checks to *_ctl_get() + - ALSA: scarlett2: Add clamp() in scarlett2_mixer_ctl_put() + - mmc: sdhci_am654: Fix TI SoC dependencies + - [Config] updateconfigs for CONFIG_MMC_SDHCI_AM654 + - mmc: sdhci_omap: Fix TI SoC dependencies + - [Config] update config for MMC_SDHCI_OMAP changes + - IB/iser: Prevent invalidating wrong MR + - drm/amdkfd: Confirm list is non-empty before utilizing list_first_entry in + kfd_topology.c + - drm/amd/pm/smu7: fix a memleak in smu7_hwmgr_backend_init + - kselftest/alsa - mixer-test: fix the number of parameters to + ksft_exit_fail_msg() + - kselftest/alsa - mixer-test: Fix the print format specifier warning + - ksmbd: validate the zero field of packet header + - of: Fix double free in of_parse_phandle_with_args_map + - fbdev: imxfb: fix left margin setting + - of: unittest: Fix of_count_phandle_with_args() expected value message + - selftests/bpf: Add assert for user stacks in test_task_stack + - keys, dns: Fix size check of V1 server-list header + - binder: fix async space check for 0-sized buffers + - binder: fix unused alloc->free_async_space + - mips/smp: Call rcutree_report_cpu_starting() earlier + - Input: atkbd - use ab83 as id when skipping the getid command + - binder: fix race between mmput() and do_exit() + - clocksource/drivers/timer-ti-dm: Fix make W=n kerneldoc warnings + - powerpc/64s: Increase default stack size to 32KB + - tick-sched: Fix idle and iowait sleeptime accounting vs CPU hotplug + - usb: phy: mxs: remove CONFIG_USB_OTG condition for mxs_phy_is_otg_host() + - usb: dwc: ep0: Update request status in dwc3_ep0_stall_restart + - Revert "usb: dwc3: Soft reset phy on probe for host" + - Revert "usb: dwc3: don't reset device side if dwc3 was configured as host- + only" + - usb: chipidea: wait controller resume finished for wakeup irq + - usb: cdns3: fix uvc failure work since sg support enabled + - usb: cdns3: fix iso transfer error when mult is not zero + - usb: cdns3: Fix uvc fail when DMA cross 4k boundery since sg enabled + - usb: typec: class: fix typec_altmode_put_partner to put plugs + - usb: mon: Fix atomicity violation in mon_bin_vma_fault + - serial: core: fix sanitizing check for RTS settings + - serial: core: make sure RS485 cannot be enabled when it is not supported + - serial: 8250_bcm2835aux: Restore clock error handling + - serial: core, imx: do not set RS485 enabled if it is not supported + - serial: imx: Ensure that imx_uart_rs485_config() is called with enabled + clock + - serial: 8250_exar: Set missing rs485_supported flag + - serial: omap: do not override settings for RS485 support + - ALSA: oxygen: Fix right channel of capture volume mixer + - ALSA: hda/relatek: Enable Mute LED on HP Laptop 15s-fq2xxx + - ALSA: hda/realtek: Enable mute/micmute LEDs and limit mic boost on HP ZBook + - ksmbd: validate mech token in session setup + - ksmbd: fix UAF issue in ksmbd_tcp_new_connection() + - ksmbd: only v2 leases handle the directory + - io_uring/rw: ensure io->bytes_done is always initialized + - fbdev: flush deferred work in fb_deferred_io_fsync() + - fbdev: flush deferred IO before closing + - scsi: ufs: core: Simplify power management during async scan + - scsi: target: core: add missing file_{start,end}_write() + - drm/amd: Enable PCIe PME from D3 + - block: add check that partition length needs to be aligned with block size + - block: Fix iterating over an empty bio with bio_for_each_folio_all + - pwm: jz4740: Don't use dev_err_probe() in .request() + - md/raid1: Use blk_opf_t for read and write operations + - rootfs: Fix support for rootfstype= when root= is given + - Bluetooth: Fix atomicity violation in {min,max}_key_size_set + - LoongArch: Fix and simplify fcsr initialization on execve() + - iommu/arm-smmu-qcom: Add missing GMU entry to match table + - iommu/dma: Trace bounce buffer usage when mapping buffers + - wifi: mt76: fix broken precal loading from MTD for mt7915 + - wifi: rtlwifi: Remove bogus and dangerous ASPM disable/enable code + - wifi: rtlwifi: Convert LNKCTL change to PCIe cap RMW accessors + - wifi: mwifiex: configure BSSID consistently when starting AP + - Revert "net: rtnetlink: Enslave device before bringing it up" + - cxl/port: Fix decoder initialization when nr_targets > interleave_ways + - PCI/P2PDMA: Remove reference to pci_p2pdma_map_sg() + - PCI: dwc: endpoint: Fix dw_pcie_ep_raise_msix_irq() alignment support + - PCI: mediatek: Clear interrupt status before dispatching handler + - x86/kvm: Do not try to disable kvmclock if it was not enabled + - KVM: arm64: vgic-v4: Restore pending state on host userspace write + - KVM: arm64: vgic-its: Avoid potential UAF in LPI translation cache + - iio: adc: ad7091r: Pass iio_dev to event handler + - HID: wacom: Correct behavior when processing some confidence == false + touches + - serial: sc16is7xx: add check for unsupported SPI modes during probe + - serial: sc16is7xx: set safe default SPI clock frequency + - ARM: 9330/1: davinci: also select PINCTRL + - mfd: syscon: Fix null pointer dereference in of_syscon_register() + - leds: aw2013: Select missing dependency REGMAP_I2C + - mfd: intel-lpss: Fix the fractional clock divider flags + - mips: dmi: Fix early remap on MIPS32 + - mips: Fix incorrect max_low_pfn adjustment + - riscv: Check if the code to patch lies in the exit section + - riscv: Fix module_alloc() that did not reset the linear mapping permissions + - riscv: Fix set_memory_XX() and set_direct_map_XX() by splitting huge linear + mappings + - riscv: Fix set_direct_map_default_noflush() to reset _PAGE_EXEC + - riscv: Fixed wrong register in XIP_FIXUP_FLASH_OFFSET macro + - MIPS: Alchemy: Fix an out-of-bound access in db1200_dev_setup() + - MIPS: Alchemy: Fix an out-of-bound access in db1550_dev_setup() + - power: supply: cw2015: correct time_to_empty units in sysfs + - power: supply: bq256xx: fix some problem in bq256xx_hw_init + - serial: 8250: omap: Don't skip resource freeing if + pm_runtime_resume_and_get() failed + - libapi: Add missing linux/types.h header to get the __u64 type on io.h + - base/node.c: initialize the accessor list before registering + - acpi: property: Let args be NULL in __acpi_node_get_property_reference + - software node: Let args be NULL in software_node_get_reference_args + - serial: imx: fix tx statemachine deadlock + - selftests/sgx: Fix uninitialized pointer dereference in error path + - selftests/sgx: Fix uninitialized pointer dereferences in encl_get_entry + - selftests/sgx: Include memory clobber for inline asm in test enclave + - selftests/sgx: Skip non X86_64 platform + - iio: adc: ad9467: fix reset gpio handling + - iio: adc: ad9467: don't ignore error codes + - iio: adc: ad9467: fix scale setting + - perf header: Fix one memory leakage in perf_event__fprintf_event_update() + - perf hisi-ptt: Fix one memory leakage in hisi_ptt_process_auxtrace_event() + - perf genelf: Set ELF program header addresses properly + - tty: change tty_write_lock()'s ndelay parameter to bool + - tty: early return from send_break() on TTY_DRIVER_HARDWARE_BREAK + - tty: don't check for signal_pending() in send_break() + - tty: use 'if' in send_break() instead of 'goto' + - usb: cdc-acm: return correct error code on unsupported break + - spmi: mtk-pmif: Serialize PMIF status check and command submission + - vdpa: Fix an error handling path in eni_vdpa_probe() + - nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length + - nvmet-tcp: fix a crash in nvmet_req_complete() + - perf env: Avoid recursively taking env->bpf_progs.lock + - cxl/region: fix x9 interleave typo + - apparmor: avoid crash when parsed profile name is empty + - usb: xhci-mtk: fix a short packet issue of gen1 isoc-in transfer + - serial: imx: Correct clock error message in function probe() + - nvmet: re-fix tracing strncpy() warning + - nvme: trace: avoid memcpy overflow warning + - nvmet-tcp: Fix the H2C expected PDU len calculation + - PCI: keystone: Fix race condition when initializing PHYs + - PCI: mediatek-gen3: Fix translation window size calculation + - ASoC: mediatek: sof-common: Add NULL check for normal_link string + - s390/pci: fix max size calculation in zpci_memcpy_toio() + - net: ethernet: ti: am65-cpsw: Fix max mtu to fit ethernet frames + - amt: do not use overwrapped cb area + - net: phy: micrel: populate .soft_reset for KSZ9131 + - mptcp: mptcp_parse_option() fix for MPTCPOPT_MP_JOIN + - mptcp: strict validation before using mp_opt->hmac + - mptcp: use OPTION_MPTCP_MPJ_SYNACK in subflow_finish_connect() + - mptcp: use OPTION_MPTCP_MPJ_SYN in subflow_check_req() + - mptcp: refine opt_mp_capable determination + - block: ensure we hold a queue reference when using queue limits + - udp: annotate data-races around up->pending + - net: ravb: Fix dma_addr_t truncation in error case + - dt-bindings: gpio: xilinx: Fix node address in gpio + - drm/amdkfd: fixes for HMM mem allocation + - net: stmmac: ethtool: Fixed calltrace caused by unbalanced disable_irq_wake + calls + - net: dsa: vsc73xx: Add null pointer check to vsc73xx_gpio_probe + - LoongArch: BPF: Prevent out-of-bounds memory access + - mptcp: relax check on MPC passive fallback + - netfilter: nf_tables: reject invalid set policy + - netfilter: nft_limit: do not ignore unsupported flags + - netfilter: nfnetlink_log: use proper helper for fetching physinif + - netfilter: nf_queue: remove excess nf_bridge variable + - netfilter: propagate net to nf_bridge_get_physindev + - netfilter: bridge: replace physindev with physinif in nf_bridge_info + - netfilter: nf_tables: do not allow mismatch field size and set key length + - netfilter: nf_tables: skip dead set elements in netlink dump + - netfilter: nf_tables: reject NFT_SET_CONCAT with not field length + description + - ipvs: avoid stat macros calls from preemptible context + - kdb: Fix a potential buffer overflow in kdb_local() + - ethtool: netlink: Add missing ethnl_ops_begin/complete + - loop: fix the the direct I/O support check when used on top of block devices + - mlxsw: spectrum_acl_erp: Fix error flow of pool allocation failure + - selftests: mlxsw: qos_pfc: Adjust the test to support 8 lanes + - ipv6: mcast: fix data-race in ipv6_mc_down / mld_ifc_work + - i2c: s3c24xx: fix read transfers in polling mode + - i2c: s3c24xx: fix transferring more than one message in polling mode + - riscv: Fix wrong usage of lm_alias() when splitting a huge linear mapping + - arm64: dts: armada-3720-turris-mox: set irq type for RTC + - x86: Fix CPUIDLE_FLAG_IRQ_ENABLE leaking timer reprogram + - drivers/perf: hisi: Fix some event id for HiSilicon UC pmu + - KVM: PPC: Book3S HV: Use accessors for VCPU registers + - KVM: PPC: Book3S HV: Introduce low level MSR accessor + - KVM: PPC: Book3S HV: Handle pending exceptions on guest entry with MSR_EE + - powerpc/rtas: Avoid warning on invalid token argument to sys_rtas() + - perf/x86/intel/uncore: Fix NULL pointer dereference issue in + upi_fill_topology() + - efivarfs: Free s_fs_info on unmount + - thermal: core: Fix NULL pointer dereference in zone registration error path + - cpuidle: haltpoll: Do not enable interrupts when entering idle + - crypto: rsa - add a check for allocation failure + - crypto: jh7110 - Correct deferred probe return + - NFS: Use parent's objective cred in nfs_access_login_time() + - asm-generic: Fix 32 bit __generic_cmpxchg_local + - arm64: dts: qcom: qrb4210-rb2: don't force usb peripheral mode + - arm64: dts: qcom: sc8280xp-x13s: Use the correct DP PHY compatible + - arm64: dts: qcom: sc8280xp-x13s: add missing camera LED pin config + - scsi: bfa: Use the proper data type for BLIST flags + - arm64: dts: ti: iot2050: Re-add aliases + - wifi: rtw88: sdio: Honor the host max_req_size in the RX path + - ARM: dts: qcom: sdx65: correct PCIe EP phy-names + - dt-bindings: arm: qcom: Fix html link + - arm64: dts: qcom: sc8180x-primus: Fix HALL_INT polarity + - arm64: dts: qcom: sm8450: correct TX Soundwire clock + - arm64: dts: qcom: sm8550: correct TX Soundwire clock + - arm64: dts: qcom: sa8775p: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm6125: add interrupts to DWC3 USB controller + - arm64: dts: qcom: sa8775p: fix USB wakeup interrupt types + - arm64: dts: qcom: sm8550: fix USB wakeup interrupt types + - wifi: mt76: mt7915: fallback to non-wed mode if platform_get_resource fails + in mt7915_mmio_wed_init() + - wifi: mt76: mt7996: fix the size of struct bss_rate_tlv + - wifi: mt76: mt7996: fix rate usage of inband discovery frames + - bpf: Guard stack limits against 32bit overflow + - bpf: Fix accesses to uninit stack slots + - arm64: dts: mediatek: mt8195: revise VDOSYS RDMA node name + - arm64: dts: mediatek: mt8186: Fix alias prefix for ovl_2l0 + - arm64: dts: mediatek: mt8186: fix address warning for ADSP mailboxes + - wifi: iwlwifi: don't support triggered EHT CQI feedback + - arm64: dts: xilinx: Apply overlays to base dtbs + - scsi: ufs: qcom: Fix the return value of ufs_qcom_ice_program_key() + - scsi: ufs: qcom: Fix the return value when platform_get_resource_byname() + fails + - scsi: hisi_sas: Check before using pointer variables + - bpf: Fix a race condition between btf_put() and map_free() + - virtio/vsock: send credit update during setting SO_RCVLOWAT + - bpf: Limit the number of uprobes when attaching program to multiple uprobes + - bpf: Limit the number of kprobes when attaching program to multiple kprobes + - arm64: dts: qcom: acer-aspire1: Correct audio codec definition + - arm64: dts: qcom: sm6375: fix USB wakeup interrupt types + - arm64: dts: qcom: sm6375: Hook up MPM + - arm64: dts: qcom: sm8150: make dispcc cast minimal vote on MMCX + - soc: qcom: llcc: Fix LLCC_TRP_ATTR2_CFGn offset + - arm64: dts: qcom: sm8550: Separate out X3 idle state + - arm64: dts: qcom: sm8550: Update idle state time requirements + - arm64: dts: qcom: sc8180x: Mark PCIe hosts cache-coherent + - arm64: dts: qcom: sc8180x: switch PCIe QMP PHY to new style of bindings + - arm64: dts: qcom: sc8180x: Fix up PCIe nodes + - wifi: iwlwifi: fix out of bound copy_from_user + - wifi: iwlwifi: assign phy_ctxt before eSR activation + - netfilter: nf_tables: validate chain type update if available + - Bluetooth: btnxpuart: fix recv_buf() return value + - arm64: dts: rockchip: Fix led pinctrl of lubancat 1 + - wifi: cfg80211: correct comment about MLD ID + - wifi: cfg80211: parse all ML elements in an ML probe response + - blk-cgroup: fix rcu lockdep warning in blkg_lookup() + - rxrpc: Fix skbuff cleanup of call's recvmsg_queue and rx_oos_queue + - drm/dp_mst: Fix fractional DSC bpp handling + - drm/panel: nv3051d: Hold panel in reset for unprepare + - media: visl: Hook the (TRY_)DECODER_CMD stateless ioctls + - media: amphion: Fix VPU core alias name + - drm/imx/lcdc: Fix double-free of driver data + - drm/msm/dpu: Add missing safe_lut_tbl in sc8180x catalog + - ASoC: Intel: sof_sdw_rt_sdca_jack_common: ctx->headset_codec_dev = NULL + - ASoC: SOF: topology: Use partial match for disconnecting DAI link and DAI + widget + - drm/msm/dpu: correct clk bit for WB2 block + - clk: sp7021: fix return value check in sp7021_clk_probe() + - clk: rs9: Fix DIF OEn bit placement on 9FGV0241 + - ASoC: tas2781: add support for FW version 0x0503 + - clk: qcom: gcc-sm8550: Add the missing RETAIN_FF_ENABLE GDSC flag + - clk: qcom: gcc-sm8550: Mark the PCIe GDSCs votable + - clk: qcom: gcc-sm8550: use collapse-voting for PCIe GDSCs + - clk: qcom: gcc-sm8550: Mark RCGs shared where applicable + - clk: qcom: dispcc-sm8550: Update disp PLL settings + - drm/amdkfd: Fix type of 'dbg_flags' in 'struct kfd_process' + - gpiolib: make gpio_device_get() and gpio_device_put() public + - gpiolib: provide gpio_device_find() + - gpio: sysfs: drop the mention of gpiochip_find() from sysfs code + - drm/amd/display: avoid stringop-overflow warnings for + dp_decide_lane_settings() + - kselftest/alsa - conf: Stringify the printed errno in sysfs_get() + - class: fix use-after-free in class_register() + - kernfs: convert kernfs_idr_lock to an irq safe raw spinlock + - usb: dwc3: gadget: Handle EP0 request dequeuing properly + - usb: dwc3: gadget: Queue PM runtime idle on disconnect event + - Revert "usb: typec: class: fix typec_altmode_put_partner to put plugs" + - dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: fix path to header + - ceph: select FS_ENCRYPTION_ALGS if FS_ENCRYPTION + - io_uring: don't check iopoll if request completes + - io_uring: ensure local task_work is run on wait timeout + - block: Remove special-casing of compound pages + - wifi: mwifiex: add extra delay for firmware ready + - wifi: mwifiex: fix uninitialized firmware_stat + - Revert "nSVM: Check for reserved encodings of TLB_CONTROL in nested VMCB" + - x86/pci: Reserve ECAM if BIOS didn't include it in PNP0C02 _CRS + - KVM: x86/pmu: Move PMU reset logic to common x86 code + - KVM: x86/pmu: Reset the PMU, i.e. stop counters, before refreshing + - mfd: rk8xx: fixup devices registration with PLATFORM_DEVID_AUTO + - leds: aw200xx: Fix write to DIM parameter + - mfd: tps6594: Add null pointer check to tps6594_device_init() + - srcu: Use try-lock lockdep annotation for NMI-safe access. + - um: virt-pci: fix platform map offset + - PCI: Avoid potential out-of-bounds read in pci_dev_for_each_resource() + - iommu: Map reserved memory as cacheable if device is coherent + - perf test: Remove atomics from test_loop to avoid test failures + - perf header: Fix segfault on build_mem_topology() error path + - perf test record user-regs: Fix mask for vg register + - perf vendor events arm64 AmpereOne: Rename BPU_FLUSH_MEM_FAULT to + GPC_FLUSH_MEM_FAULT + - perf mem: Fix error on hybrid related to availability of mem event in a PMU + - perf stat: Exit perf stat if parse groups fails + - iio: adc: ad9467: add mutex to struct ad9467_state + - perf unwind-libdw: Handle JIT-generated DSOs properly + - perf unwind-libunwind: Fix base address for .eh_frame + - bus: mhi: ep: Do not allocate event ring element on stack + - bus: mhi: ep: Use slab allocator where applicable + - usb: gadget: webcam: Make g_webcam loadable again + - iommu: Don't reserve 0-length IOVA region + - power: supply: Fix null pointer dereference in smb2_probe + - apparmor: Fix ref count leak in task_kill + - perf stat: Fix hard coded LL miss units + - apparmor: fix possible memory leak in unpack_trans_table + - serial: apbuart: fix console prompt on qemu + - perf db-export: Fix missing reference count get in call_path_from_sample() + - cxl/port: Fix missing target list lock + - spi: coldfire-qspi: Remove an erroneous clk_disable_unprepare() from the + remove function + - hisi_acc_vfio_pci: Update migration data pointer correctly on saving/resume + - rxrpc: Fix use of Don't Fragment flag + - octeontx2-af: CN10KB: Fix FIFO length calculation for RPM2 + - net: micrel: Fix PTP frame parsing for lan8841 + - ALSA: hda: Properly setup HDMI stream + - net: add more sanity check in virtio_net_hdr_to_skb() + - net: netdev_queue: netdev_txq_completed_mb(): fix wake condition + - bpf: iter_udp: Retry with a larger batch size without going back to the + previous bucket + - bpf: Avoid iter->offset making backward progress in bpf_iter_udp + - gpio: mlxbf3: add an error code check in mlxbf3_gpio_probe + - ASoC: SOF: ipc4-loader: remove the CPC check warnings + - selftests: bonding: Change script interpreter + - io_uring: adjust defer tw counting + - arm64/ptrace: Don't flush ZA/ZT storage when writing ZA via ptrace + - mlxsw: spectrum_acl_tcam: Fix NULL pointer dereference in error path + - mlxsw: spectrum_acl_tcam: Fix stack corruption + - mlxsw: spectrum_router: Register netdevice notifier before nexthop + - Upstream stable to v6.1.75, v6.6.14 + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26583 + - net: tls, fix WARNIING in __sk_msg_free + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26589 + - bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26591 + - bpf: Fix re-attachment branch in bpf_tracing_prog_attach + + -- Roxana Nicolescu Tue, 23 Apr 2024 10:24:50 +0200 + +linux-lowlatency-hwe-6.5 (6.5.0-28.29.1~22.04.1) jammy; urgency=medium + + * jammy/linux-lowlatency-hwe-6.5: 6.5.0-28.29.1~22.04.1 -proposed tracker + (LP: #2059692) + + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + + [ Ubuntu: 6.5.0-28.29.1 ] + + * mantic/linux-lowlatency: 6.5.0-28.29.1 -proposed tracker (LP: #2059693) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * mantic/linux: 6.5.0-28.29 -proposed tracker (LP: #2059706) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * Remove getabis scripts (LP: #2059143) + - [Packaging] Remove getabis + * CVE-2023-52600 + - jfs: fix uaf in jfs_evict_inode + * Mantic update: upstream stable patchset 2024-03-27 (LP: #2059284) // + CVE-2023-52603 + - UBSAN: array-index-out-of-bounds in dtSplitRoot + * CVE-2024-26581 + - netfilter: nft_set_rbtree: skip end interval element from gc + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26589 + - bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26591 + - bpf: Fix re-attachment branch in bpf_tracing_prog_attach + * iwlwifi disconnect and crash - intel wifi7 (LP: #2058808) + - wifi: iwlwifi: pcie: fix RB status reading + + -- Roxana Nicolescu Thu, 04 Apr 2024 18:04:20 +0200 + linux-lowlatency-hwe-6.5 (6.5.0-27.28.1~22.04.1) jammy; urgency=medium * jammy/linux-lowlatency-hwe-6.5: 6.5.0-27.28.1~22.04.1 -proposed tracker reverted: --- linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/etc/getabis +++ linux-lowlatency-hwe-6.5-6.5.0.orig/debian.lowlatency-hwe-6.5/etc/getabis @@ -1,15 +0,0 @@ -repo_list=( - "http://archive.ubuntu.com/ubuntu/pool/main/l/linux-lowlatency-hwe-6.5" - "http://ports.ubuntu.com/ubuntu-ports/pool/main/l/linux-lowlatency-hwe-6.5" - "http://archive.ubuntu.com/ubuntu/pool/universe/l/linux-lowlatency-hwe-6.5" - "http://ports.ubuntu.com/ubuntu-ports/pool/universe/l/linux-lowlatency-hwe-6.5" - "http://ppa.launchpad.net/canonical-kernel-team/ppa/ubuntu/pool/main/l/linux-lowlatency-hwe-6.5" - "http://ppa.launchpad.net/canonical-kernel-team/ppa2/ubuntu/pool/main/l/linux-lowlatency-hwe-6.5" - "http://ppa.launchpad.net/canonical-kernel-team/unstable/ubuntu/pool/main/l/linux-lowlatency-hwe-6.5" - "http://ppa.launchpad.net/canonical-kernel-team/bootstrap/ubuntu/pool/main/l/linux-lowlatency-hwe-6.5" -) - -package_prefixes linux-buildinfo - -getall amd64 lowlatency -getall arm64 lowlatency lowlatency-64k diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/reconstruct linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/reconstruct --- linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/reconstruct +++ linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/reconstruct @@ -19,10 +19,8 @@ chmod +x 'debian/scripts/misc/annotations' chmod +x 'debian/scripts/misc/arch-has-odm-enabled.sh' chmod +x 'debian/scripts/misc/find-missing-sauce.sh' -chmod +x 'debian/scripts/misc/fips-checks' chmod +x 'debian/scripts/misc/fw-to-ihex.sh' chmod +x 'debian/scripts/misc/gen-auto-reconstruct' -chmod +x 'debian/scripts/misc/getabis' chmod +x 'debian/scripts/misc/git-ubuntu-log' chmod +x 'debian/scripts/misc/insert-changes' chmod +x 'debian/scripts/misc/insert-mainline-changes' @@ -52,6 +50,13 @@ chmod +x 'tools/testing/selftests/netfilter/xt_string.sh' # Remove any files deleted from the orig. rm -f 'Documentation/networking/device_drivers/ethernet/mellanox/mlx5/devlink.rst' +rm -f 'Documentation/translations/zh_TW/sparse.txt' +rm -f 'arch/arm/boot/dts/qcom/qcom-pm8226.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pm8841.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pm8941.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pma8084.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pmx55.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pmx65.dtsi' rm -f 'arch/parisc/include/asm/mckinley.h' rm -f 'drivers/media/pci/intel/ipu3/cio2-bridge.c' rm -f 'drivers/media/pci/intel/ipu3/cio2-bridge.h' diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/scripts/helpers/local-mangle linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/scripts/helpers/local-mangle --- linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/scripts/helpers/local-mangle +++ linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/scripts/helpers/local-mangle @@ -8,11 +8,6 @@ echo -e "flavours\t= lowlatency" >> ${DEBIAN}/rules.d/amd64.mk echo -e "flavours\t= lowlatency lowlatency-64k" >> ${DEBIAN}/rules.d/arm64.mk -# We only care about lowlatency/lowlatency-64k abis -sed -i /getall/d ${DEBIAN}/etc/getabis -echo "getall amd64 lowlatency" >> ${DEBIAN}/etc/getabis -echo "getall arm64 lowlatency lowlatency-64k" >> ${DEBIAN}/etc/getabis - # Override options in rules.d/hooks.mk (normally master does not have this # file but it got added for generic annotations enforcement. cat <>${DEBIAN}/rules.d/hooks.mk diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/tracking-bug linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/tracking-bug --- linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/tracking-bug +++ linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency-hwe-6.5/tracking-bug @@ -1 +1 @@ -2055570 2024.03.04-1 +2059429 2024.04.01-1 diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/changelog linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/changelog --- linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/changelog +++ linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/changelog @@ -1,3 +1,1328 @@ +linux-lowlatency (6.5.0-34.34.1) mantic; urgency=medium + + * mantic/linux-lowlatency: 6.5.0-34.34.1 -proposed tracker (LP: #2059430) + + [ Ubuntu: 6.5.0-34.34 ] + + * mantic/linux: 6.5.0-34.34 -proposed tracker (LP: #2061443) + * CVE-2024-2201 + - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file + - x86/syscall: Don't force use of indirect calls for system calls + - x86/bhi: Add support for clearing branch history at syscall entry + - x86/bhi: Define SPEC_CTRL_BHI_DIS_S + - x86/bhi: Enumerate Branch History Injection (BHI) bug + - x86/bhi: Add BHI mitigation knob + - x86/bhi: Mitigate KVM by default + - KVM: x86: Add BHI_NO + - [Config] Set CONFIG_BHI to enabled (auto) + + [ Ubuntu: 6.5.0-33.33 ] + + * mantic/linux: 6.5.0-33.33 -proposed tracker (LP: #2060448) + * [Mantic] Compile broken on armhf (cc1 out of memory) (LP: #2060446) + - Revert "minmax: relax check to allow comparison between unsigned arguments + and signed constants" + - Revert "minmax: allow comparisons of 'int' against 'unsigned char/short'" + - Revert "minmax: allow min()/max()/clamp() if the arguments have the same + signedness." + - Revert "minmax: add umin(a, b) and umax(a, b)" + + [ Ubuntu: 6.5.0-32.32 ] + + * mantic/linux: 6.5.0-32.32 -proposed tracker (LP: #2059443) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * Drop fips-checks script from trees (LP: #2055083) + - [Packaging] Remove fips-checks script + * alsa/realtek: adjust max output valume for headphone on 2 LG machines + (LP: #2058573) + - ALSA: hda/realtek: fix the hp playback volume issue for LG machines + * Remove getabis scripts (LP: #2059143) + - [Packaging] Remove getabis + * Mantic update: upstream stable patchset 2024-03-27 (LP: #2059284) + - asm-generic: make sparse happy with odd-sized put_unaligned_*() + - powerpc/mm: Fix null-pointer dereference in pgtable_cache_add + - arm64: irq: set the correct node for VMAP stack + - drivers/perf: pmuv3: don't expose SW_INCR event in sysfs + - powerpc: Fix build error due to is_valid_bugaddr() + - powerpc/mm: Fix build failures due to arch_reserved_kernel_pages() + - powerpc/64s: Fix CONFIG_NUMA=n build due to create_section_mapping() + - x86/boot: Ignore NMIs during very early boot + - powerpc: pmd_move_must_withdraw() is only needed for + CONFIG_TRANSPARENT_HUGEPAGE + - powerpc/lib: Validate size for vector operations + - x86/mce: Mark fatal MCE's page as poison to avoid panic in the kdump kernel + - perf/core: Fix narrow startup race when creating the perf nr_addr_filters + sysfs file + - debugobjects: Stop accessing objects after releasing hash bucket lock + - regulator: core: Only increment use_count when enable_count changes + - audit: Send netlink ACK before setting connection in auditd_set + - ACPI: video: Add quirk for the Colorful X15 AT 23 Laptop + - PNP: ACPI: fix fortify warning + - ACPI: extlog: fix NULL pointer dereference check + - ACPI: NUMA: Fix the logic of getting the fake_pxm value + - PM / devfreq: Synchronize devfreq_monitor_[start/stop] + - ACPI: APEI: set memory failure flags as MF_ACTION_REQUIRED on synchronous + events + - FS:JFS:UBSAN:array-index-out-of-bounds in dbAdjTree + - jfs: fix slab-out-of-bounds Read in dtSearch + - jfs: fix array-index-out-of-bounds in dbAdjTree + - pstore/ram: Fix crash when setting number of cpus to an odd number + - crypto: octeontx2 - Fix cptvf driver cleanup + - erofs: fix ztailpacking for subpage compressed blocks + - crypto: stm32/crc32 - fix parsing list of devices + - afs: fix the usage of read_seqbegin_or_lock() in afs_lookup_volume_rcu() + - afs: fix the usage of read_seqbegin_or_lock() in afs_find_server*() + - rxrpc_find_service_conn_rcu: fix the usage of read_seqbegin_or_lock() + - jfs: fix array-index-out-of-bounds in diNewExt + - arch: consolidate arch_irq_work_raise prototypes + - s390/vfio-ap: fix sysfs status attribute for AP queue devices + - s390/ptrace: handle setting of fpc register correctly + - KVM: s390: fix setting of fpc register + - SUNRPC: Fix a suspicious RCU usage warning + - ecryptfs: Reject casefold directory inodes + - ext4: fix inconsistent between segment fstrim and full fstrim + - ext4: unify the type of flexbg_size to unsigned int + - ext4: remove unnecessary check from alloc_flex_gd() + - ext4: avoid online resizing failures due to oversized flex bg + - wifi: rt2x00: restart beacon queue when hardware reset + - selftests/bpf: satisfy compiler by having explicit return in btf test + - selftests/bpf: Fix pyperf180 compilation failure with clang18 + - wifi: rt2x00: correct wrong BBP register in RxDCOC calibration + - selftests/bpf: Fix issues in setup_classid_environment() + - soc: xilinx: Fix for call trace due to the usage of smp_processor_id() + - soc: xilinx: fix unhandled SGI warning message + - scsi: lpfc: Fix possible file string name overflow when updating firmware + - PCI: Add no PM reset quirk for NVIDIA Spectrum devices + - bonding: return -ENOMEM instead of BUG in alb_upper_dev_walk + - net: usb: ax88179_178a: avoid two consecutive device resets + - scsi: arcmsr: Support new PCI device IDs 1883 and 1886 + - ARM: dts: imx7d: Fix coresight funnel ports + - ARM: dts: imx7s: Fix lcdif compatible + - ARM: dts: imx7s: Fix nand-controller #size-cells + - wifi: ath9k: Fix potential array-index-out-of-bounds read in + ath9k_htc_txstatus() + - wifi: ath11k: fix race due to setting ATH11K_FLAG_EXT_IRQ_ENABLED too early + - bpf: Check rcu_read_lock_trace_held() before calling bpf map helpers + - scsi: libfc: Don't schedule abort twice + - scsi: libfc: Fix up timeout error in fc_fcp_rec_error() + - bpf: Set uattr->batch.count as zero before batched update or deletion + - wifi: wfx: fix possible NULL pointer dereference in wfx_set_mfp_ap() + - ARM: dts: rockchip: fix rk3036 hdmi ports node + - ARM: dts: imx25/27-eukrea: Fix RTC node name + - ARM: dts: imx: Use flash@0,0 pattern + - ARM: dts: imx27: Fix sram node + - ARM: dts: imx1: Fix sram node + - net: phy: at803x: fix passing the wrong reference for config_intr + - ionic: pass opcode to devcmd_wait + - ionic: bypass firmware cmds when stuck in reset + - block/rnbd-srv: Check for unlikely string overflow + - ARM: dts: imx25: Fix the iim compatible string + - ARM: dts: imx25/27: Pass timing0 + - ARM: dts: imx27-apf27dev: Fix LED name + - ARM: dts: imx23-sansa: Use preferred i2c-gpios properties + - ARM: dts: imx23/28: Fix the DMA controller node name + - scsi: hisi_sas: Set .phy_attached before notifing phyup event + HISI_PHYE_PHY_UP_PM + - ice: fix ICE_AQ_VSI_Q_OPT_RSS_* register values + - net: atlantic: eliminate double free in error handling logic + - net: dsa: mv88e6xxx: Fix mv88e6352_serdes_get_stats error path + - block: prevent an integer overflow in bvec_try_merge_hw_page + - md: Whenassemble the array, consult the superblock of the freshest device + - arm64: dts: qcom: msm8996: Fix 'in-ports' is a required property + - arm64: dts: qcom: msm8998: Fix 'out-ports' is a required property + - ice: fix pre-shifted bit usage + - arm64: dts: amlogic: fix format for s4 uart node + - wifi: rtl8xxxu: Add additional USB IDs for RTL8192EU devices + - libbpf: Fix NULL pointer dereference in bpf_object__collect_prog_relos + - wifi: rtlwifi: rtl8723{be,ae}: using calculate_bit_shift() + - wifi: cfg80211: free beacon_ies when overridden from hidden BSS + - Bluetooth: qca: Set both WIDEBAND_SPEECH and LE_STATES quirks for QCA2066 + - Bluetooth: hci_sync: fix BR/EDR wakeup bug + - Bluetooth: L2CAP: Fix possible multiple reject send + - net/smc: disable SEID on non-s390 archs where virtual ISM may be used + - bridge: cfm: fix enum typo in br_cc_ccm_tx_parse + - i40e: Fix VF disable behavior to block all traffic + - octeontx2-af: Fix max NPC MCAM entry check while validating ref_entry + - net: dsa: qca8k: put MDIO bus OF node on qca8k_mdio_register() failure + - f2fs: fix to check return value of f2fs_reserve_new_block() + - ALSA: hda: Refer to correct stream index at loops + - ASoC: doc: Fix undefined SND_SOC_DAPM_NOPM argument + - fast_dput(): handle underflows gracefully + - RDMA/IPoIB: Fix error code return in ipoib_mcast_join + - drm/panel-edp: Add override_edid_mode quirk for generic edp + - drm/bridge: anx7625: Fix Set HPD irq detect window to 2ms + - drm/amd/display: Fix tiled display misalignment + - f2fs: fix write pointers on zoned device after roll forward + - drm/drm_file: fix use of uninitialized variable + - drm/framebuffer: Fix use of uninitialized variable + - drm/mipi-dsi: Fix detach call without attach + - media: stk1160: Fixed high volume of stk1160_dbg messages + - media: rockchip: rga: fix swizzling for RGB formats + - PCI: add INTEL_HDA_ARL to pci_ids.h + - ALSA: hda: Intel: add HDA_ARL PCI ID support + - media: rkisp1: Fix IRQ handler return values + - media: rkisp1: Store IRQ lines + - media: rkisp1: Fix IRQ disable race issue + - f2fs: fix to tag gcing flag on page during block migration + - drm/exynos: Call drm_atomic_helper_shutdown() at shutdown/unbind time + - IB/ipoib: Fix mcast list locking + - media: amphion: remove mutext lock in condition of wait_event + - media: ddbridge: fix an error code problem in ddb_probe + - media: i2c: imx335: Fix hblank min/max values + - drm/amd/display: For prefetch mode > 0, extend prefetch if possible + - drm/msm/dpu: Ratelimit framedone timeout msgs + - drm/msm/dpu: fix writeback programming for YUV cases + - drm/amdgpu: fix ftrace event amdgpu_bo_move always move on same heap + - clk: hi3620: Fix memory leak in hi3620_mmc_clk_init() + - clk: mmp: pxa168: Fix memory leak in pxa168_clk_init() + - watchdog: it87_wdt: Keep WDTCTRL bit 3 unmodified for IT8784/IT8786 + - drm/amd/display: make flip_timestamp_in_us a 64-bit variable + - clk: imx: clk-imx8qxp: fix LVDS bypass, pixel and phy clocks + - drm/amdgpu: Fix ecc irq enable/disable unpaired + - drm/amdgpu: Let KFD sync with VM fences + - drm/amdgpu: Fix '*fw' from request_firmware() not released in + 'amdgpu_ucode_request()' + - drm/amdgpu: Drop 'fence' check in 'to_amdgpu_amdkfd_fence()' + - drm/amdkfd: Fix iterator used outside loop in 'kfd_add_peer_prop()' + - ALSA: hda/conexant: Fix headset auto detect fail in cx8070 and SN6140 + - leds: trigger: panic: Don't register panic notifier if creating the trigger + failed + - um: Fix naming clash between UML and scheduler + - um: Don't use vfprintf() for os_info() + - um: net: Fix return type of uml_net_start_xmit() + - um: time-travel: fix time corruption + - i3c: master: cdns: Update maximum prescaler value for i2c clock + - xen/gntdev: Fix the abuse of underlying struct page in DMA-buf import + - mfd: ti_am335x_tscadc: Fix TI SoC dependencies + - [Config] updateconfigs for MFD_TI_AM335X_TSCADC + - mailbox: arm_mhuv2: Fix a bug for mhuv2_sender_interrupt + - PCI: Only override AMD USB controller if required + - PCI: switchtec: Fix stdev_release() crash after surprise hot remove + - perf cs-etm: Bump minimum OpenCSD version to ensure a bugfix is present + - usb: hub: Replace hardcoded quirk value with BIT() macro + - usb: hub: Add quirk to decrease IN-ep poll interval for Microchip USB491x + hub + - selftests/sgx: Fix linker script asserts + - tty: allow TIOCSLCKTRMIOS with CAP_CHECKPOINT_RESTORE + - fs/kernfs/dir: obey S_ISGID + - spmi: mediatek: Fix UAF on device remove + - PCI: Fix 64GT/s effective data rate calculation + - PCI/AER: Decode Requester ID when no error info found + - 9p: Fix initialisation of netfs_inode for 9p + - misc: lis3lv02d_i2c: Add missing setting of the reg_ctrl callback + - libsubcmd: Fix memory leak in uniq() + - drm/amdkfd: Fix lock dependency warning + - drm/amdkfd: Fix lock dependency warning with srcu + - virtio_net: Fix "‘%d’ directive writing between 1 and 11 bytes into a region + of size 10" warnings + - blk-mq: fix IO hang from sbitmap wakeup race + - ceph: reinitialize mds feature bit even when session in open + - ceph: fix deadlock or deadcode of misusing dget() + - ceph: fix invalid pointer access if get_quota_realm return ERR_PTR + - drm/amd/powerplay: Fix kzalloc parameter 'ATOM_Tonga_PPM_Table' in + 'get_platform_power_management_table()' + - drm/amdgpu: Fix with right return code '-EIO' in + 'amdgpu_gmc_vram_checking()' + - drm/amdgpu: Release 'adev->pm.fw' before return in + 'amdgpu_device_need_post()' + - drm/amdkfd: Fix 'node' NULL check in 'svm_range_get_range_boundaries()' + - perf: Fix the nr_addr_filters fix + - wifi: cfg80211: fix RCU dereference in __cfg80211_bss_update + - drm: using mul_u32_u32() requires linux/math64.h + - scsi: isci: Fix an error code problem in isci_io_request_build() + - regulator: ti-abb: don't use devm_platform_ioremap_resource_byname for + shared interrupt register + - scsi: core: Move scsi_host_busy() out of host lock for waking up EH handler + - HID: hidraw: fix a problem of memory leak in hidraw_release() + - selftests: net: give more time for GRO aggregation + - ip6_tunnel: make sure to pull inner header in __ip6_tnl_rcv() + - ipmr: fix kernel panic when forwarding mcast packets + - net: lan966x: Fix port configuration when using SGMII interface + - tcp: add sanity checks to rx zerocopy + - ixgbe: Refactor returning internal error codes + - ixgbe: Refactor overtemp event handling + - ixgbe: Fix an error handling path in ixgbe_read_iosf_sb_reg_x550() + - net: dsa: qca8k: fix illegal usage of GPIO + - ipv6: Ensure natural alignment of const ipv6 loopback and router addresses + - llc: call sock_orphan() at release time + - bridge: mcast: fix disabled snooping after long uptime + - selftests: net: add missing config for GENEVE + - netfilter: conntrack: correct window scaling with retransmitted SYN + - netfilter: nf_tables: restrict tunnel object to NFPROTO_NETDEV + - netfilter: nf_log: replace BUG_ON by WARN_ON_ONCE when putting logger + - netfilter: nft_ct: sanitize layer 3 and 4 protocol number in custom + expectations + - net: ipv4: fix a memleak in ip_setup_cork + - af_unix: fix lockdep positive in sk_diag_dump_icons() + - SAUCE: Sync apparmor copy of af_unix.c + - selftests: net: fix available tunnels detection + - net: sysfs: Fix /sys/class/net/ path + - selftests: team: Add missing config options + - selftests: bonding: Check initial state + - arm64: irq: set the correct node for shadow call stack + - mm, kmsan: fix infinite recursion due to RCU critical section + - Revert "drm/amd/display: Disable PSR-SU on Parade 0803 TCON again" + - drm/msm/dsi: Enable runtime PM + - LoongArch/smp: Call rcutree_report_cpu_starting() at tlb_init() + - gve: Fix use-after-free vulnerability + - bonding: remove print in bond_verify_device_path + - ASoC: codecs: lpass-wsa-macro: fix compander volume hack + - ASoC: codecs: wsa883x: fix PA volume control + - drm/amdgpu: Fix missing error code in 'gmc_v6/7/8/9_0_hw_init()' + - Documentation/sphinx: fix Python string escapes + - kunit: tool: fix parsing of test attributes + - thermal: core: Fix thermal zone suspend-resume synchronization + - hwrng: starfive - Fix dev_err_probe return error + - crypto: p10-aes-gcm - Avoid -Wstringop-overflow warnings + - erofs: fix up compacted indexes for block size < 4096 + - crypto: starfive - Fix dev_err_probe return error + - s390/boot: always align vmalloc area on segment boundary + - ext4: treat end of range as exclusive in ext4_zero_range() + - wifi: rtw89: fix timeout calculation in rtw89_roc_end() + - ARM: dts: qcom: strip prefix from PMIC files + - ARM: dts: qcom: mdm9615: fix PMIC node labels + - ARM: dts: qcom: msm8660: fix PMIC node labels + - ARM: dts: samsung: exynos4: fix camera unit addresses/ranges + - ARM: dts: samsung: s5pv210: fix camera unit addresses/ranges + - net: phy: micrel: fix ts_info value in case of no phc + - bpf: Prevent inlining of bpf_fentry_test7() + - bpf: Fix a few selftest failures due to llvm18 change + - wifi: rtw89: fix misbehavior of TX beacon in concurrent mode + - bpf: Set need_defer as false when clearing fd array during map free + - wifi: ath12k: fix and enable AP mode for WCN7850 + - minmax: add umin(a, b) and umax(a, b) + - minmax: allow min()/max()/clamp() if the arguments have the same signedness. + - minmax: allow comparisons of 'int' against 'unsigned char/short' + - minmax: relax check to allow comparison between unsigned arguments and + signed constants + - net: mvmdio: Avoid excessive sleeps in polled mode + - arm64: dts: qcom: sm8550: fix soundwire controllers node name + - arm64: dts: qcom: sm8450: fix soundwire controllers node name + - arm64: dts: qcom: sm8350: Fix remoteproc interrupt type + - wifi: mt76: connac: fix EHT phy mode check + - wifi: mt76: mt7996: add PCI IDs for mt7992 + - wifi: ath12k: fix the issue that the multicast/broadcast indicator is not + read correctly for WCN7850 + - arm64: zynqmp: Move fixed clock to / for kv260 + - arm64: zynqmp: Fix clock node name in kv260 cards + - selftests/bpf: fix compiler warnings in RELEASE=1 mode + - scsi: lpfc: Reinitialize an NPIV's VMID data structures after FDISC + - scsi: lpfc: Move determination of vmid_flag after VMID reinitialization + completes + - arm64: dts: qcom: Fix coresight warnings in in-ports and out-ports + - wifi: rtw89: coex: Fix wrong Wi-Fi role info and FDDT parameter members + - Bluetooth: ISO: Avoid creating child socket if PA sync is terminating + - arm64: dts: sprd: Add clock reference for pll2 on UMS512 + - arm64: dts: sprd: Change UMS512 idle-state nodename to match bindings + - net: kcm: fix direct access to bv_len + - reiserfs: Avoid touching renamed directory if parent does not change + - drm/amd/display: Fix MST PBN/X.Y value calculations + - drm/drm_file: fix use of uninitialized variable + - drm/msm/dp: Add DisplayPort controller for SM8650 + - media: uvcvideo: Fix power line control for a Chicony camera + - media: uvcvideo: Fix power line control for SunplusIT camera + - media: rkisp1: resizer: Stop manual allocation of v4l2_subdev_state + - hwmon: (hp-wmi-sensors) Fix failure to load on EliteDesk 800 G6 + - drm/amd/display: Force p-state disallow if leaving no plane config + - drm/amdkfd: fix mes set shader debugger process management + - drm/msm/dpu: enable writeback on SM8350 + - drm/msm/dpu: enable writeback on SM8450 + - watchdog: starfive: add lock annotations to fix context imbalances + - accel/habanalabs: add support for Gaudi2C device + - drm/amd/display: Only clear symclk otg flag for HDMI + - drm/amd/display: Fix minor issues in BW Allocation Phase2 + - drm/amdgpu: apply the RV2 system aperture fix to RN/CZN as well + - pinctrl: baytrail: Fix types of config value in byt_pin_config_set() + - riscv: Make XIP bootable again + - extcon: fix possible name leak in extcon_dev_register() + - usb: xhci-plat: fix usb disconnect issue after s4 + - i2c: rk3x: Adjust mask/value offset for i2c2 on rv1126 + - drm/amdkfd: only flush mes process context if mes support is there + - riscv: Fix build error on rv32 + XIP + - selftests: net: remove dependency on ebpf tests + - selftests: net: explicitly wait for listener ready + - gve: Fix skb truesize underestimation + - net: phy: phy_device: Call into the PHY driver to set LED offload + - net: phy: mediatek-ge-soc: support PHY LEDs + - net: phy: mediatek-ge-soc: sync driver with MediaTek SDK + - selftests: net: add missing config for big tcp tests + - selftests: net: add missing required classifier + - net: dsa: mt7530: fix 10M/100M speed on MT7988 switch + - e1000e: correct maximum frequency adjustment values + - selftests: net: Add missing matchall classifier + - devlink: Fix referring to hw_addr attribute during state validation + - pds_core: Cancel AQ work on teardown + - pds_core: Use struct pdsc for the pdsc_adminq_isr private data + - pds_core: implement pci reset handlers + - pds_core: Prevent race issues involving the adminq + - pds_core: Clear BARs on reset + - pds_core: Rework teardown/setup flow to be more common + - selftests: net: add missing config for nftables-backed iptables + - selftests: net: add missing config for pmtu.sh tests + - selftests: net: don't access /dev/stdout in pmtu.sh + - octeontx2-pf: Remove xdp queues on program detach + - selftests: net: add missing config for NF_TARGET_TTL + - selftests: net: enable some more knobs + - selftests/bpf: Remove flaky test_btf_id test + - ASoC: qcom: sc8280xp: limit speaker volumes + - ASoC: codecs: wcd938x: fix headphones volume controls + - pds_core: Prevent health thread from running during reset/remove + - Upstream stable to v6.1.77, v6.6.16 + * Mantic update: upstream stable patchset 2024-03-27 (LP: #2059284) // + CVE-2023-52603 + - UBSAN: array-index-out-of-bounds in dtSplitRoot + * iwlwifi disconnect and crash - intel wifi7 (LP: #2058808) + - wifi: iwlwifi: pcie: fix RB status reading + * Mantic update: upstream stable patchset 2024-03-26 (LP: #2059068) + - iio: adc: ad7091r: Set alert bit in config register + - iio: adc: ad7091r: Allow users to configure device events + - ext4: allow for the last group to be marked as trimmed + - arm64: properly install vmlinuz.efi + - OPP: Pass rounded rate to _set_opp() + - btrfs: sysfs: validate scrub_speed_max value + - crypto: api - Disallow identical driver names + - PM: hibernate: Enforce ordering during image compression/decompression + - hwrng: core - Fix page fault dead lock on mmap-ed hwrng + - crypto: s390/aes - Fix buffer overread in CTR mode + - s390/vfio-ap: unpin pages on gisc registration failure + - PM / devfreq: Fix buffer overflow in trans_stat_show + - media: imx355: Enable runtime PM before registering async sub-device + - rpmsg: virtio: Free driver_override when rpmsg_remove() + - media: ov9734: Enable runtime PM before registering async sub-device + - s390/vfio-ap: always filter entire AP matrix + - s390/vfio-ap: loop over the shadow APCB when filtering guest's AP + configuration + - s390/vfio-ap: let on_scan_complete() callback filter matrix and update + guest's APCB + - mips: Fix max_mapnr being uninitialized on early stages + - bus: mhi: host: Add alignment check for event ring read pointer + - bus: mhi: host: Drop chan lock before queuing buffers + - bus: mhi: host: Add spinlock to protect WP access when queueing TREs + - parisc/firmware: Fix F-extend for PDC addresses + - parisc/power: Fix power soft-off button emulation on qemu + - async: Split async_schedule_node_domain() + - async: Introduce async_schedule_dev_nocall() + - iio: adc: ad7091r: Enable internal vref if external vref is not supplied + - dmaengine: fix NULL pointer in channel unregistration function + - scsi: ufs: core: Remove the ufshcd_hba_exit() call from ufshcd_async_scan() + - arm64: dts: qcom: sc7180: fix USB wakeup interrupt types + - arm64: dts: qcom: sdm845: fix USB wakeup interrupt types + - arm64: dts: qcom: sm8150: fix USB wakeup interrupt types + - arm64: dts: qcom: sc7280: fix usb_1 wakeup interrupt types + - arm64: dts: qcom: sdm845: fix USB DP/DM HS PHY interrupts + - arm64: dts: qcom: sm8150: fix USB DP/DM HS PHY interrupts + - lsm: new security_file_ioctl_compat() hook + - docs: kernel_abi.py: fix command injection + - scripts/get_abi: fix source path leak + - media: videobuf2-dma-sg: fix vmap callback + - mmc: core: Use mrq.sbc in close-ended ffu + - mmc: mmc_spi: remove custom DMA mapped buffers + - media: mtk-jpeg: Fix use after free bug due to error path handling in + mtk_jpeg_dec_device_run + - arm64: Rename ARM64_WORKAROUND_2966298 + - rtc: cmos: Use ACPI alarm for non-Intel x86 systems too + - rtc: Adjust failure return code for cmos_set_alarm() + - rtc: mc146818-lib: Adjust failure return code for mc146818_get_time() + - rtc: Add support for configuring the UIP timeout for RTC reads + - rtc: Extend timeout for waiting for UIP to clear to 1s + - nouveau/vmm: don't set addr on the fail path to avoid warning + - ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path + - mm/rmap: fix misplaced parenthesis of a likely() + - mm/sparsemem: fix race in accessing memory_section->usage + - rename(): fix the locking of subdirectories + - serial: sc16is7xx: improve regmap debugfs by using one regmap per port + - serial: sc16is7xx: remove wasteful static buffer in sc16is7xx_regmap_name() + - serial: sc16is7xx: remove global regmap from struct sc16is7xx_port + - serial: sc16is7xx: remove unused line structure member + - serial: sc16is7xx: change EFR lock to operate on each channels + - serial: sc16is7xx: convert from _raw_ to _noinc_ regmap functions for FIFO + - serial: sc16is7xx: fix invalid sc16is7xx_lines bitfield in case of probe + error + - serial: sc16is7xx: remove obsolete loop in sc16is7xx_port_irq() + - serial: sc16is7xx: improve do/while loop in sc16is7xx_irq() + - LoongArch/smp: Call rcutree_report_cpu_starting() earlier + - mm: page_alloc: unreserve highatomic page blocks before oom + - ksmbd: set v2 lease version on lease upgrade + - ksmbd: fix potential circular locking issue in smb2_set_ea() + - ksmbd: don't increment epoch if current state and request state are same + - ksmbd: send lease break notification on FILE_RENAME_INFORMATION + - ksmbd: Add missing set_freezable() for freezable kthread + - Revert "drm/amd: Enable PCIe PME from D3" + - wifi: mac80211: fix potential sta-link leak + - net/smc: fix illegal rmb_desc access in SMC-D connection dump + - tcp: make sure init the accept_queue's spinlocks once + - bnxt_en: Wait for FLR to complete during probe + - vlan: skip nested type that is not IFLA_VLAN_QOS_MAPPING + - llc: make llc_ui_sendmsg() more robust against bonding changes + - llc: Drop support for ETH_P_TR_802_2. + - udp: fix busy polling + - net: fix removing a namespace with conflicting altnames + - tun: fix missing dropped counter in tun_xdp_act + - tun: add missing rx stats accounting in tun_xdp_act + - net: micrel: Fix PTP frame parsing for lan8814 + - net/rds: Fix UBSAN: array-index-out-of-bounds in rds_cmsg_recv + - netfs, fscache: Prevent Oops in fscache_put_cache() + - tracing: Ensure visibility when inserting an element into tracing_map + - afs: Hide silly-rename files from userspace + - tcp: Add memory barrier to tcp_push() + - netlink: fix potential sleeping issue in mqueue_flush_file + - ipv6: init the accept_queue's spinlocks in inet6_create + - net/mlx5: DR, Use the right GVMI number for drop action + - net/mlx5: DR, Can't go to uplink vport on RX rule + - net/mlx5: Use mlx5 device constant for selecting CQ period mode for ASO + - net/mlx5e: Allow software parsing when IPsec crypto is enabled + - net/mlx5e: fix a double-free in arfs_create_groups + - net/mlx5e: fix a potential double-free in fs_any_create_groups + - rcu: Defer RCU kthreads wakeup when CPU is dying + - netfilter: nft_limit: reject configurations that cause integer overflow + - netfilter: nf_tables: restrict anonymous set and map names to 16 bytes + - netfilter: nf_tables: validate NFPROTO_* family + - net: stmmac: Wait a bit for the reset to take effect + - net: mvpp2: clear BM pool before initialization + - selftests: netdevsim: fix the udp_tunnel_nic test + - fjes: fix memleaks in fjes_hw_setup + - net: fec: fix the unhandled context fault from smmu + - nbd: always initialize struct msghdr completely + - btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of subvolume + being deleted + - btrfs: ref-verify: free ref cache before clearing mount opt + - btrfs: tree-checker: fix inline ref size in error messages + - btrfs: don't warn if discard range is not aligned to sector + - btrfs: defrag: reject unknown flags of btrfs_ioctl_defrag_range_args + - btrfs: don't abort filesystem when attempting to snapshot deleted subvolume + - rbd: don't move requests to the running list on errors + - exec: Fix error handling in begin_new_exec() + - wifi: iwlwifi: fix a memory corruption + - hv_netvsc: Calculate correct ring size when PAGE_SIZE is not 4 Kbytes + - netfilter: nft_chain_filter: handle NETDEV_UNREGISTER for inet/ingress + basechain + - platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe + - ksmbd: fix global oob in ksmbd_nl_policy + - firmware: arm_scmi: Check mailbox/SMT channel for consistency + - xfs: read only mounts with fsopen mount API are busted + - gpiolib: acpi: Ignore touchpad wakeup on GPD G1619-04 + - cpufreq: intel_pstate: Refine computation of P-state for given frequency + - drm: Don't unref the same fb many times by mistake due to deadlock handling + - drm/bridge: nxp-ptn3460: fix i2c_master_send() error checking + - drm/tidss: Fix atomic_flush check + - drm/bridge: nxp-ptn3460: simplify some error checking + - drm/amd/display: Port DENTIST hang and TDR fixes to OTG disable W/A + - drm/amdgpu/pm: Fix the power source flag error + - erofs: fix lz4 inplace decompression + - media: ov13b10: Enable runtime PM before registering async sub-device + - PM: sleep: Fix possible deadlocks in core system-wide PM code + - thermal: intel: hfi: Refactor enabling code into helper functions + - thermal: intel: hfi: Disable an HFI instance when all its CPUs go offline + - thermal: intel: hfi: Add syscore callbacks for system-wide PM + - fs/pipe: move check to pipe_has_watch_queue() + - pipe: wakeup wr_wait after setting max_usage + - ARM: dts: qcom: sdx55: fix USB wakeup interrupt types + - ARM: dts: samsung: exynos4210-i9100: Unconditionally enable LDO12 + - ARM: dts: qcom: sdx55: fix pdc '#interrupt-cells' + - ARM: dts: qcom: sdx55: fix USB DP/DM HS PHY interrupts + - ARM: dts: qcom: sdx55: fix USB SS wakeup + - dlm: use kernel_connect() and kernel_bind() + - serial: core: Provide port lock wrappers + - serial: sc16is7xx: Use port lock wrappers + - serial: sc16is7xx: fix unconditional activation of THRI interrupt + - btrfs: zoned: factor out prepare_allocation_zoned() + - btrfs: zoned: optimize hint byte for zoned allocator + - drm/panel-edp: drm/panel-edp: Fix AUO B116XAK01 name and timing + - Revert "powerpc/64s: Increase default stack size to 32KB" + - drm/bridge: parade-ps8640: Wait for HPD when doing an AUX transfer + - drm: panel-simple: add missing bus flags for Tianma tm070jvhg[30/33] + - drm/bridge: sii902x: Fix probing race issue + - drm/bridge: sii902x: Fix audio codec unregistration + - drm/bridge: parade-ps8640: Ensure bridge is suspended in .post_disable() + - drm/bridge: parade-ps8640: Make sure we drop the AUX mutex in the error case + - drm/exynos: fix accidental on-stack copy of exynos_drm_plane + - drm/exynos: gsc: minor fix for loop iteration in gsc_runtime_resume + - gpio: eic-sprd: Clear interrupt after set the interrupt type + - drm/bridge: anx7625: Ensure bridge is suspended in disable() + - spi: bcm-qspi: fix SFDP BFPT read by usig mspi read + - spi: fix finalize message on error return + - MIPS: lantiq: register smp_ops on non-smp platforms + - cxl/region:Fix overflow issue in alloc_hpa() + - mips: Call lose_fpu(0) before initializing fcr31 in mips_set_personality_nan + - tick/sched: Preserve number of idle sleeps across CPU hotplug events + - x86/entry/ia32: Ensure s32 is sign extended to s64 + - serial: core: fix kernel-doc for uart_port_unlock_irqrestore() + - docs: sparse: move TW sparse.txt to TW dev-tools + - docs: sparse: add sparse.rst to toctree + - serial: core: Simplify uart_get_rs485_mode() + - serial: core: set missing supported flag for RX during TX GPIO + - soundwire: bus: introduce controller_id + - soundwire: fix initializing sysfs for same devices on different buses + - net: stmmac: Tx coe sw fallback + - net: stmmac: Prevent DSA tags from breaking COE + - dmaengine: idxd: Move dma_free_coherent() out of spinlocked context + - riscv: Fix an off-by-one in get_early_cmdline() + - scsi: core: Kick the requeue list after inserting when flushing + - sh: ecovec24: Rename missed backlight field from fbdev to dev + - smb: client: fix parsing of SMB3.1.1 POSIX create context + - cifs: do not pass cifs_sb when trying to add channels + - cifs: handle cases where a channel is closed + - cifs: reconnect work should have reference on server struct + - cifs: handle when server starts supporting multichannel + - cifs: handle when server stops supporting multichannel + - cifs: reconnect worker should take reference on server struct + unconditionally + - cifs: handle servers that still advertise multichannel after disabling + - cifs: update iface_last_update on each query-and-update + - powerpc/ps3_defconfig: Disable PPC64_BIG_ENDIAN_ELF_ABI_V2 + - crypto: lib/mpi - Fix unexpected pointer access in mpi_ec_init + - mtd: maps: vmu-flash: Fix the (mtd core) switch to ref counters + - mtd: rawnand: Prevent crossing LUN boundaries during sequential reads + - mtd: rawnand: Fix core interference with sequential reads + - mtd: rawnand: Prevent sequential reads with on-die ECC engines + - mtd: rawnand: Clarify conditions to enable continuous reads + - soc: qcom: pmic_glink_altmode: fix port sanity check + - media: ov01a10: Enable runtime PM before registering async sub-device + - soc: fsl: cpm1: tsa: Fix __iomem addresses declaration + - soc: fsl: cpm1: qmc: Fix __iomem addresses declaration + - soc: fsl: cpm1: qmc: Fix rx channel reset + - s390/vfio-ap: reset queues filtered from the guest's AP config + - s390/vfio-ap: reset queues associated with adapter for queue unbound from + driver + - s390/vfio-ap: do not reset queue removed from host config + - ARM: dts: imx6q-apalis: add can power-up delay on ixora board + - arm64: dts: qcom: sc8280xp-crd: fix eDP phy compatible + - arm64: dts: sprd: fix the cpu node for UMS512 + - arm64: dts: rockchip: configure eth pad driver strength for orangepi r1 plus + lts + - arm64: dts: rockchip: Fix rk3588 USB power-domain clocks + - arm64: dts: qcom: msm8916: Make blsp_dma controlled-remotely + - arm64: dts: qcom: msm8939: Make blsp_dma controlled-remotely + - arm64: dts: qcom: sdm670: fix USB wakeup interrupt types + - arm64: dts: qcom: sc8180x: fix USB wakeup interrupt types + - arm64: dts: qcom: Add missing vio-supply for AW2013 + - arm64: dts: qcom: sdm845: fix USB SS wakeup + - arm64: dts: qcom: sm8150: fix USB SS wakeup + - arm64: dts: qcom: sc8180x: fix USB DP/DM HS PHY interrupts + - arm64: dts: qcom: sc8180x: fix USB SS wakeup + - media: i2c: st-mipid02: correct format propagation + - media: mtk-jpeg: Fix timeout schedule error in mtk_jpegdec_worker. + - riscv: mm: Fixup compat mode boot failure + - arm64: errata: Add Cortex-A510 speculative unprivileged load workaround + - [Config] update config for ARM64_ERRATUM_3117295 + - arm64/sme: Always exit sme_alloc() early with existing storage + - arm64: entry: fix ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD + - efi: disable mirror feature during crashkernel + - kexec: do syscore_shutdown() in kernel_kexec + - selftests: mm: hugepage-vmemmap fails on 64K page size systems + - serial: Do not hold the port lock when setting rx-during-tx GPIO + - dt-bindings: net: snps,dwmac: Tx coe unsupported + - bpf: move explored_state() closer to the beginning of verifier.c + - bpf: extract same_callsites() as utility function + - bpf: exact states comparison for iterator convergence checks + - selftests/bpf: tests with delayed read/precision makrs in loop body + - bpf: correct loop detection for iterators convergence + - selftests/bpf: test if state loops are detected in a tricky case + - bpf: print full verifier states on infinite loop detection + - selftests/bpf: track tcp payload offset as scalar in xdp_synproxy + - selftests/bpf: track string payload offset as scalar in strobemeta + - bpf: extract __check_reg_arg() utility function + - bpf: extract setup_func_entry() utility function + - bpf: verify callbacks as if they are called unknown number of times + - selftests/bpf: tests for iterating callbacks + - bpf: widening for callback iterators + - bpf: keep track of max number of bpf_loop callback iterations + - cifs: fix lock ordering while disabling multichannel + - cifs: fix a pending undercount of srv_count + - cifs: after disabling multichannel, mark tcon for reconnect + - selftests: bonding: Increase timeout to 1200s + - bnxt_en: Prevent kernel warning when running offline self test + - selftest: Don't reuse port for SO_INCOMING_CPU test. + - selftests: fill in some missing configs for net + - net/sched: flower: Fix chain template offload + - net/mlx5e: Fix operation precedence bug in port timestamping napi_poll + context + - net/mlx5e: Fix peer flow lists handling + - net/mlx5: Bridge, Enable mcast in smfs steering mode + - net/mlx5: Bridge, fix multicast packets sent to uplink + - net/mlx5e: Ignore IPsec replay window values on sender side + - selftests: net: fix rps_default_mask with >32 CPUs + - bpf: Propagate modified uaddrlen from cgroup sockaddr programs + - bpf: Add bpf_sock_addr_set_sun_path() to allow writing unix sockaddr from + bpf + - ice: work on pre-XDP prog frag count + - i40e: handle multi-buffer packets that are shrunk by xdp prog + - ice: remove redundant xdp_rxq_info registration + - ice: update xdp_rxq_info::frag_size for ZC enabled Rx queue + - i40e: set xdp_rxq_info::frag_size + - selftests: bonding: do not test arp/ns target with mode balance-alb/tlb + - tsnep: Remove FCS for XDP data path + - tsnep: Fix XDP_RING_NEED_WAKEUP for empty fill ring + - btrfs: scrub: avoid use-after-free when chunk length is not 64K aligned + - nfsd: fix RELEASE_LOCKOWNER + - Revert "drivers/firmware: Move sysfb_init() from device_initcall to + subsys_initcall_sync" + - drm/amdgpu: Fix the null pointer when load rlc firmware + - drm: Fix TODO list mentioning non-KMS drivers + - drm: Disable the cursor plane on atomic contexts with virtualized drivers + - drm/virtio: Disable damage clipping if FB changed since last page-flip + - drm: Allow drivers to indicate the damage helpers to ignore damage clips + - drm/amd/display: fix bandwidth validation failure on DCN 2.1 + - drm/amdgpu: correct the cu count for gfx v11 + - drm/amd/display: Align the returned error code with legacy DP + - drm/amd/display: Fix late derefrence 'dsc' check in + 'link_set_dsc_pps_packet()' + - drm/amd/display: Fix uninitialized variable usage in core_link_ 'read_dpcd() + & write_dpcd()' functions + - net/bpf: Avoid unused "sin_addr_len" warning when CONFIG_CGROUP_BPF is not + set + - thermal: core: Store trip pointer in struct thermal_instance + - thermal: gov_power_allocator: avoid inability to reset a cdev + - mm: migrate: record the mlocked page status to remove unnecessary lru drain + - mm: migrate: fix getting incorrect page mapping during page migration + - drm/i915/lnl: Remove watchdog timers for PSR + - drm/i915/psr: Only allow PSR in LPSP mode on HSW non-ULT + - drm/panel-edp: Add AUO B116XTN02, BOE NT116WHM-N21,836X2, NV116WHM-N49 V8.0 + - drm/panel-edp: drm/panel-edp: Fix AUO B116XTN02 name + - drm/amdgpu/gfx10: set UNORD_DISPATCH in compute MQDs + - drm/amdgpu/gfx11: set UNORD_DISPATCH in compute MQDs + - drm/panel: samsung-s6d7aa0: drop DRM_BUS_FLAG_DE_HIGH for lsl080al02 + - memblock: fix crash when reserved memory is not added to memory + - firmware: arm_scmi: Use xa_insert() when saving raw queues + - spi: intel-pci: Remove Meteor Lake-S SoC PCI ID from the list + - cpufreq/amd-pstate: Fix setting scaling max/min freq values + - spi: spi-cadence: Reverse the order of interleaved write and read operations + - cifs: fix stray unlock in cifs_chan_skip_or_disable + - drm: bridge: samsung-dsim: Don't use FORCE_STOP_STATE + - genirq: Initialize resend_node hlist for all interrupt descriptors + - clocksource: Skip watchdog check for large watchdog intervals + - thermal: trip: Drop lockdep assertion from thermal_zone_trip_id() + - platform/x86: intel-uncore-freq: Fix types in sysfs callbacks + - Upstream stable to v6.1.76, v6.6.15 + * CVE-2024-26582 + - net: tls: fix use-after-free with partial reads and async decrypt + - net: tls: fix returned read length with async decrypt + * CVE-2024-26584 + - net: tls: handle backlogging of crypto requests + * CVE-2024-26585 + - tls: fix race between tx work scheduling and socket close + * CVE-2024-26583 + - tls: extract context alloc/initialization out of tls_set_sw_offload + - net: tls: factor out tls_*crypt_async_wait() + - tls: fix race between async notify and socket close + * CVE-2023-52600 + - jfs: fix uaf in jfs_evict_inode + * Fix headphone mic detection issue on ALC897 (LP: #2056418) + - ALSA: hda/realtek - Fix headset Mic no show at resume back for Lenovo ALC897 + platform + * CVE-2024-26581 + - netfilter: nft_set_rbtree: skip end interval element from gc + * The screen brightness is unable to adjust on BOE panel DPN#R6FD8 + (LP: #2057430) + - drm/amd/display: Re-add aux intercept disable delay generically for 2+ + LTTPRs + - drm/amd/display: Clear dpcd_sink_ext_caps if not set + - drm/amd/display: Add monitor patch for specific eDP + - drm/amd/display: Add monitor patch for specific eDP + * Dynamically determine acpi_handle_list size (LP: #2049733) + - ACPI: utils: Dynamically determine acpi_handle_list size + - ACPI: utils: Fix error path in acpi_evaluate_reference() + - ACPI: utils: Fix white space in struct acpi_handle_list definition + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) + - x86/lib: Fix overflow when counting digits + - x86/mce/inject: Clear test status value + - EDAC/thunderx: Fix possible out-of-bounds string access + - powerpc: add crtsavres.o to always-y instead of extra-y + - powerpc/44x: select I2C for CURRITUCK + - powerpc/pseries/memhp: Fix access beyond end of drmem array + - selftests/powerpc: Fix error handling in FPU/VMX preemption tests + - powerpc/powernv: Add a null pointer check to scom_debug_init_one() + - powerpc/powernv: Add a null pointer check in opal_event_init() + - powerpc/powernv: Add a null pointer check in opal_powercap_init() + - powerpc/imc-pmu: Add a null pointer check in update_events_in_group() + - spi: spi-zynqmp-gqspi: fix driver kconfig dependencies + - mtd: rawnand: Increment IFC_TIMEOUT_MSECS for nand controller response + - ACPI: video: check for error while searching for backlight device parent + - ACPI: LPIT: Avoid u32 multiplication overflow + - platform/x86/intel/vsec: Fix xa_alloc memory leak + - cpufreq: scmi: process the result of devm_of_clk_add_hw_provider() + - calipso: fix memory leak in netlbl_calipso_add_pass() + - efivarfs: force RO when remounting if SetVariable is not supported + - spi: sh-msiof: Enforce fixed DTDL for R-Car H3 + - ACPI: LPSS: Fix the fractional clock divider flags + - ACPI: extlog: Clear Extended Error Log status when RAS_CEC handled the error + - kunit: debugfs: Fix unchecked dereference in debugfs_print_results() + - mtd: Fix gluebi NULL pointer dereference caused by ftl notifier + - selinux: Fix error priority for bind with AF_UNSPEC on PF_INET6 socket + - crypto: virtio - Handle dataq logic with tasklet + - crypto: sa2ul - Return crypto_aead_setkey to transfer the error + - crypto: ccp - fix memleak in ccp_init_dm_workarea + - crypto: af_alg - Disallow multiple in-flight AIO requests + - crypto: safexcel - Add error handling for dma_map_sg() calls + - crypto: sahara - remove FLAGS_NEW_KEY logic + - crypto: sahara - fix cbc selftest failure + - crypto: sahara - fix ahash selftest failure + - crypto: sahara - fix processing requests with cryptlen < sg->length + - crypto: sahara - fix error handling in sahara_hw_descriptor_create() + - crypto: hisilicon/qm - save capability registers in qm init process + - crypto: hisilicon/zip - add zip comp high perf mode configuration + - crypto: hisilicon/qm - add a function to set qm algs + - crypto: hisilicon/hpre - save capability registers in probe process + - crypto: hisilicon/sec2 - save capability registers in probe process + - crypto: hisilicon/zip - save capability registers in probe process + - pstore: ram_core: fix possible overflow in persistent_ram_init_ecc() + - erofs: fix memory leak on short-lived bounced pages + - fs: indicate request originates from old mount API + - gfs2: Fix kernel NULL pointer dereference in gfs2_rgrp_dump + - crypto: virtio - Wait for tasklet to complete on device remove + - crypto: sahara - avoid skcipher fallback code duplication + - crypto: sahara - handle zero-length aes requests + - crypto: sahara - fix ahash reqsize + - crypto: sahara - fix wait_for_completion_timeout() error handling + - crypto: sahara - improve error handling in sahara_sha_process() + - crypto: sahara - fix processing hash requests with req->nbytes < sg->length + - crypto: sahara - do not resize req->src when doing hash operations + - crypto: scomp - fix req->dst buffer overflow + - csky: fix arch_jump_label_transform_static override + - blocklayoutdriver: Fix reference leak of pnfs_device_node + - NFSv4.1/pnfs: Ensure we handle the error NFS4ERR_RETURNCONFLICT + - SUNRPC: fix _xprt_switch_find_current_entry logic + - pNFS: Fix the pnfs block driver's calculation of layoutget size + - wifi: plfxlc: check for allocation failure in plfxlc_usb_wreq_async() + - wifi: rtw88: fix RX filter in FIF_ALLMULTI flag + - bpf, lpm: Fix check prefixlen before walking trie + - bpf: Add crosstask check to __bpf_get_stack + - wifi: ath11k: Defer on rproc_get failure + - wifi: libertas: stop selecting wext + - ARM: dts: qcom: apq8064: correct XOADC register address + - net/ncsi: Fix netlink major/minor version numbers + - firmware: ti_sci: Fix an off-by-one in ti_sci_debugfs_create() + - wifi: rtlwifi: rtl8821ae: phy: fix an undefined bitwise shift behavior + - arm64: dts: ti: k3-am62a-main: Fix GPIO pin count in DT nodes + - arm64: dts: ti: k3-am65-main: Fix DSS irq trigger type + - selftests/bpf: Fix erroneous bitmask operation + - md: synchronize flush io with array reconfiguration + - bpf: enforce precision of R0 on callback return + - ARM: dts: qcom: sdx65: correct SPMI node name + - arm64: dts: qcom: sc7180: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sc7280: Mark some nodes as 'reserved' + - arm64: dts: qcom: sc7280: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sdm845: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm8150: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm8250: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sc8280xp: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm6350: Make watchdog bark interrupt edge triggered + - bpf: add percpu stats for bpf_map elements insertions/deletions + - bpf: Add map and need_defer parameters to .map_fd_put_ptr() + - bpf: Defer the free of inner map when necessary + - selftests/net: specify the interface when do arping + - bpf: fix check for attempt to corrupt spilled pointer + - scsi: fnic: Return error if vmalloc() failed + - arm64: dts: qcom: qrb5165-rb5: correct LED panic indicator + - arm64: dts: qcom: sdm845-db845c: correct LED panic indicator + - arm64: dts: qcom: sm8350: Fix DMA0 address + - arm64: dts: qcom: sc7280: Fix up GPU SIDs + - arm64: dts: qcom: sc7280: Mark Adreno SMMU as DMA coherent + - arm64: dts: qcom: sc7280: fix usb_2 wakeup interrupt types + - wifi: mt76: mt7921s: fix workqueue problem causes STA association fail + - bpf: Fix verification of indirect var-off stack access + - arm64: dts: hisilicon: hikey970-pmic: fix regulator cells properties + - dt-bindings: media: mediatek: mdp3: correct RDMA and WROT node with generic + names + - arm64: dts: mediatek: mt8183: correct MDP3 DMA-related nodes + - wifi: mt76: mt7921: fix country count limitation for CLC + - selftests/bpf: Relax time_tai test for equal timestamps in tai_forward + - block: Set memalloc_noio to false on device_add_disk() error path + - arm64: dts: renesas: white-hawk-cpu: Fix missing serial console pin control + - arm64: dts: imx8mm: Reduce GPU to nominal speed + - scsi: hisi_sas: Replace with standard error code return value + - scsi: hisi_sas: Correct the number of global debugfs registers + - ARM: dts: stm32: don't mix SCMI and non-SCMI board compatibles + - selftests/net: fix grep checking for fib_nexthop_multiprefix + - ipmr: support IP_PKTINFO on cache report IGMP msg + - virtio/vsock: fix logic which reduces credit update messages + - dma-mapping: clear dev->dma_mem to NULL after freeing it + - soc: qcom: llcc: Fix dis_cap_alloc and retain_on_pc configuration + - arm64: dts: qcom: sm8150-hdk: fix SS USB regulators + - block: add check of 'minors' and 'first_minor' in device_add_disk() + - arm64: dts: qcom: sc7280: Mark SDHCI hosts as cache-coherent + - arm64: dts: qcom: ipq6018: fix clock rates for GCC_USB0_MOCK_UTMI_CLK + - wifi: rtlwifi: add calculate_bit_shift() + - wifi: rtlwifi: rtl8188ee: phy: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192c: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192cu: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ce: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192de: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ee: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192se: using calculate_bit_shift() + - wifi: iwlwifi: mvm: set siso/mimo chains to 1 in FW SMPS request + - wifi: iwlwifi: mvm: send TX path flush in rfkill + - netfilter: nf_tables: mark newset as dead on transaction abort + - Bluetooth: Fix bogus check for re-auth no supported with non-ssp + - Bluetooth: btmtkuart: fix recv_buf() return value + - null_blk: don't cap max_hw_sectors to BLK_DEF_MAX_SECTORS + - bpf: sockmap, fix proto update hook to avoid dup calls + - sctp: support MSG_ERRQUEUE flag in recvmsg() + - sctp: fix busy polling + - net/sched: act_ct: fix skb leak and crash on ooo frags + - mlxbf_gige: Fix intermittent no ip issue + - mlxbf_gige: Enable the GigE port in mlxbf_gige_open + - ip6_tunnel: fix NEXTHDR_FRAGMENT handling in ip6_tnl_parse_tlv_enc_lim() + - ARM: davinci: always select CONFIG_CPU_ARM926T + - Revert "drm/tidss: Annotate dma-fence critical section in commit path" + - Revert "drm/omapdrm: Annotate dma-fence critical section in commit path" + - drm/panfrost: Really power off GPU cores in panfrost_gpu_power_off() + - RDMA/usnic: Silence uninitialized symbol smatch warnings + - RDMA/hns: Fix inappropriate err code for unsupported operations + - drm/panel-elida-kd35t133: hold panel in reset for unprepare + - drm/nouveau/fence:: fix warning directly dereferencing a rcu pointer + - drm/bridge: tpd12s015: Drop buggy __exit annotation for remove function + - drm/tilcdc: Fix irq free on unload + - media: pvrusb2: fix use after free on context disconnection + - media: mtk-jpeg: Remove cancel worker in mtk_jpeg_remove to avoid the crash + of multi-core JPEG devices + - media: verisilicon: Hook the (TRY_)DECODER_CMD stateless ioctls + - media: rkvdec: Hook the (TRY_)DECODER_CMD stateless ioctls + - drm/bridge: Fix typo in post_disable() description + - f2fs: fix to avoid dirent corruption + - drm/radeon/r600_cs: Fix possible int overflows in r600_cs_check_reg() + - drm/radeon/r100: Fix integer overflow issues in r100_cs_track_check() + - drm/radeon: check return value of radeon_ring_lock() + - drm/tidss: Move reset to the end of dispc_init() + - drm/tidss: Return error value from from softreset + - drm/tidss: Check for K2G in in dispc_softreset() + - drm/tidss: Fix dss reset + - ASoC: cs35l33: Fix GPIO name and drop legacy include + - ASoC: cs35l34: Fix GPIO name and drop legacy include + - drm/msm/mdp4: flush vblank event on disable + - drm/msm/dsi: Use pm_runtime_resume_and_get to prevent refcnt leaks + - drm/drv: propagate errors from drm_modeset_register_all() + - ASoC: Intel: glk_rt5682_max98357a: fix board id mismatch + - drm/panfrost: Ignore core_mask for poweroff and disable PWRTRANS irq + - drm/radeon: check the alloc_workqueue return value in radeon_crtc_init() + - drm/radeon/dpm: fix a memleak in sumo_parse_power_table + - drm/radeon/trinity_dpm: fix a memleak in trinity_parse_power_table + - drm/bridge: cdns-mhdp8546: Fix use of uninitialized variable + - drm/bridge: tc358767: Fix return value on error case + - media: cx231xx: fix a memleak in cx231xx_init_isoc + - RDMA/hns: Fix memory leak in free_mr_init() + - clk: qcom: gpucc-sm8150: Update the gpu_cc_pll1 config + - media: imx-mipi-csis: Fix clock handling in remove() + - media: dt-bindings: media: rkisp1: Fix the port description for the parallel + interface + - media: rkisp1: Fix media device memory leak + - drm/panel: st7701: Fix AVCL calculation + - f2fs: fix to wait on block writeback for post_read case + - f2fs: fix to check compress file in f2fs_move_file_range() + - f2fs: fix to update iostat correctly in f2fs_filemap_fault() + - media: dvbdev: drop refcount on error path in dvb_device_open() + - media: dvb-frontends: m88ds3103: Fix a memory leak in an error handling path + of m88ds3103_probe() + - clk: renesas: rzg2l-cpg: Reuse code in rzg2l_cpg_reset() + - clk: renesas: rzg2l: Check reset monitor registers + - drm/msm/dpu: Set input_sel bit for INTF + - drm/msm/dpu: Drop enable and frame_count parameters from dpu_hw_setup_misr() + - drm/mediatek: Return error if MDP RDMA failed to enable the clock + - drm/mediatek: Fix underrun in VDO1 when switches off the layer + - drm/amdgpu/debugfs: fix error code when smc register accessors are NULL + - drm/amd/pm: fix a double-free in si_dpm_init + - drivers/amd/pm: fix a use-after-free in kv_parse_power_table + - gpu/drm/radeon: fix two memleaks in radeon_vm_init + - drm/amd/pm: fix a double-free in amdgpu_parse_extended_power_table + - f2fs: fix to check return value of f2fs_recover_xattr_data + - dt-bindings: clock: Update the videocc resets for sm8150 + - clk: qcom: videocc-sm8150: Update the videocc resets + - clk: qcom: videocc-sm8150: Add missing PLL config property + - drivers: clk: zynqmp: calculate closest mux rate + - drivers: clk: zynqmp: update divider round rate logic + - watchdog: set cdev owner before adding + - watchdog/hpwdt: Only claim UNKNOWN NMI if from iLO + - watchdog: bcm2835_wdt: Fix WDIOC_SETTIMEOUT handling + - watchdog: rti_wdt: Drop runtime pm reference count when watchdog is unused + - clk: si5341: fix an error code problem in si5341_output_clk_set_rate + - drm/mediatek: dp: Add phy_mtk_dp module as pre-dependency + - clk: fixed-rate: fix clk_hw_register_fixed_rate_with_accuracy_parent_hw + - pwm: stm32: Use hweight32 in stm32_pwm_detect_channels + - pwm: stm32: Fix enable count for clk in .probe() + - ASoC: rt5645: Drop double EF20 entry from dmi_platform_data[] + - ALSA: scarlett2: Add missing error check to scarlett2_config_save() + - ALSA: scarlett2: Add missing error check to scarlett2_usb_set_config() + - ALSA: scarlett2: Allow passing any output to line_out_remap() + - ALSA: scarlett2: Add missing error checks to *_ctl_get() + - ALSA: scarlett2: Add clamp() in scarlett2_mixer_ctl_put() + - mmc: sdhci_am654: Fix TI SoC dependencies + - [Config] updateconfigs for CONFIG_MMC_SDHCI_AM654 + - mmc: sdhci_omap: Fix TI SoC dependencies + - [Config] update config for MMC_SDHCI_OMAP changes + - IB/iser: Prevent invalidating wrong MR + - drm/amdkfd: Confirm list is non-empty before utilizing list_first_entry in + kfd_topology.c + - drm/amd/pm/smu7: fix a memleak in smu7_hwmgr_backend_init + - kselftest/alsa - mixer-test: fix the number of parameters to + ksft_exit_fail_msg() + - kselftest/alsa - mixer-test: Fix the print format specifier warning + - ksmbd: validate the zero field of packet header + - of: Fix double free in of_parse_phandle_with_args_map + - fbdev: imxfb: fix left margin setting + - of: unittest: Fix of_count_phandle_with_args() expected value message + - selftests/bpf: Add assert for user stacks in test_task_stack + - keys, dns: Fix size check of V1 server-list header + - binder: fix async space check for 0-sized buffers + - binder: fix unused alloc->free_async_space + - mips/smp: Call rcutree_report_cpu_starting() earlier + - Input: atkbd - use ab83 as id when skipping the getid command + - binder: fix race between mmput() and do_exit() + - clocksource/drivers/timer-ti-dm: Fix make W=n kerneldoc warnings + - powerpc/64s: Increase default stack size to 32KB + - tick-sched: Fix idle and iowait sleeptime accounting vs CPU hotplug + - usb: phy: mxs: remove CONFIG_USB_OTG condition for mxs_phy_is_otg_host() + - usb: dwc: ep0: Update request status in dwc3_ep0_stall_restart + - Revert "usb: dwc3: Soft reset phy on probe for host" + - Revert "usb: dwc3: don't reset device side if dwc3 was configured as host- + only" + - usb: chipidea: wait controller resume finished for wakeup irq + - usb: cdns3: fix uvc failure work since sg support enabled + - usb: cdns3: fix iso transfer error when mult is not zero + - usb: cdns3: Fix uvc fail when DMA cross 4k boundery since sg enabled + - usb: typec: class: fix typec_altmode_put_partner to put plugs + - usb: mon: Fix atomicity violation in mon_bin_vma_fault + - serial: core: fix sanitizing check for RTS settings + - serial: core: make sure RS485 cannot be enabled when it is not supported + - serial: 8250_bcm2835aux: Restore clock error handling + - serial: core, imx: do not set RS485 enabled if it is not supported + - serial: imx: Ensure that imx_uart_rs485_config() is called with enabled + clock + - serial: 8250_exar: Set missing rs485_supported flag + - serial: omap: do not override settings for RS485 support + - ALSA: oxygen: Fix right channel of capture volume mixer + - ALSA: hda/relatek: Enable Mute LED on HP Laptop 15s-fq2xxx + - ALSA: hda/realtek: Enable mute/micmute LEDs and limit mic boost on HP ZBook + - ksmbd: validate mech token in session setup + - ksmbd: fix UAF issue in ksmbd_tcp_new_connection() + - ksmbd: only v2 leases handle the directory + - io_uring/rw: ensure io->bytes_done is always initialized + - fbdev: flush deferred work in fb_deferred_io_fsync() + - fbdev: flush deferred IO before closing + - scsi: ufs: core: Simplify power management during async scan + - scsi: target: core: add missing file_{start,end}_write() + - drm/amd: Enable PCIe PME from D3 + - block: add check that partition length needs to be aligned with block size + - block: Fix iterating over an empty bio with bio_for_each_folio_all + - pwm: jz4740: Don't use dev_err_probe() in .request() + - md/raid1: Use blk_opf_t for read and write operations + - rootfs: Fix support for rootfstype= when root= is given + - Bluetooth: Fix atomicity violation in {min,max}_key_size_set + - LoongArch: Fix and simplify fcsr initialization on execve() + - iommu/arm-smmu-qcom: Add missing GMU entry to match table + - iommu/dma: Trace bounce buffer usage when mapping buffers + - wifi: mt76: fix broken precal loading from MTD for mt7915 + - wifi: rtlwifi: Remove bogus and dangerous ASPM disable/enable code + - wifi: rtlwifi: Convert LNKCTL change to PCIe cap RMW accessors + - wifi: mwifiex: configure BSSID consistently when starting AP + - Revert "net: rtnetlink: Enslave device before bringing it up" + - cxl/port: Fix decoder initialization when nr_targets > interleave_ways + - PCI/P2PDMA: Remove reference to pci_p2pdma_map_sg() + - PCI: dwc: endpoint: Fix dw_pcie_ep_raise_msix_irq() alignment support + - PCI: mediatek: Clear interrupt status before dispatching handler + - x86/kvm: Do not try to disable kvmclock if it was not enabled + - KVM: arm64: vgic-v4: Restore pending state on host userspace write + - KVM: arm64: vgic-its: Avoid potential UAF in LPI translation cache + - iio: adc: ad7091r: Pass iio_dev to event handler + - HID: wacom: Correct behavior when processing some confidence == false + touches + - serial: sc16is7xx: add check for unsupported SPI modes during probe + - serial: sc16is7xx: set safe default SPI clock frequency + - ARM: 9330/1: davinci: also select PINCTRL + - mfd: syscon: Fix null pointer dereference in of_syscon_register() + - leds: aw2013: Select missing dependency REGMAP_I2C + - mfd: intel-lpss: Fix the fractional clock divider flags + - mips: dmi: Fix early remap on MIPS32 + - mips: Fix incorrect max_low_pfn adjustment + - riscv: Check if the code to patch lies in the exit section + - riscv: Fix module_alloc() that did not reset the linear mapping permissions + - riscv: Fix set_memory_XX() and set_direct_map_XX() by splitting huge linear + mappings + - riscv: Fix set_direct_map_default_noflush() to reset _PAGE_EXEC + - riscv: Fixed wrong register in XIP_FIXUP_FLASH_OFFSET macro + - MIPS: Alchemy: Fix an out-of-bound access in db1200_dev_setup() + - MIPS: Alchemy: Fix an out-of-bound access in db1550_dev_setup() + - power: supply: cw2015: correct time_to_empty units in sysfs + - power: supply: bq256xx: fix some problem in bq256xx_hw_init + - serial: 8250: omap: Don't skip resource freeing if + pm_runtime_resume_and_get() failed + - libapi: Add missing linux/types.h header to get the __u64 type on io.h + - base/node.c: initialize the accessor list before registering + - acpi: property: Let args be NULL in __acpi_node_get_property_reference + - software node: Let args be NULL in software_node_get_reference_args + - serial: imx: fix tx statemachine deadlock + - selftests/sgx: Fix uninitialized pointer dereference in error path + - selftests/sgx: Fix uninitialized pointer dereferences in encl_get_entry + - selftests/sgx: Include memory clobber for inline asm in test enclave + - selftests/sgx: Skip non X86_64 platform + - iio: adc: ad9467: fix reset gpio handling + - iio: adc: ad9467: don't ignore error codes + - iio: adc: ad9467: fix scale setting + - perf header: Fix one memory leakage in perf_event__fprintf_event_update() + - perf hisi-ptt: Fix one memory leakage in hisi_ptt_process_auxtrace_event() + - perf genelf: Set ELF program header addresses properly + - tty: change tty_write_lock()'s ndelay parameter to bool + - tty: early return from send_break() on TTY_DRIVER_HARDWARE_BREAK + - tty: don't check for signal_pending() in send_break() + - tty: use 'if' in send_break() instead of 'goto' + - usb: cdc-acm: return correct error code on unsupported break + - spmi: mtk-pmif: Serialize PMIF status check and command submission + - vdpa: Fix an error handling path in eni_vdpa_probe() + - nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length + - nvmet-tcp: fix a crash in nvmet_req_complete() + - perf env: Avoid recursively taking env->bpf_progs.lock + - cxl/region: fix x9 interleave typo + - apparmor: avoid crash when parsed profile name is empty + - usb: xhci-mtk: fix a short packet issue of gen1 isoc-in transfer + - serial: imx: Correct clock error message in function probe() + - nvmet: re-fix tracing strncpy() warning + - nvme: trace: avoid memcpy overflow warning + - nvmet-tcp: Fix the H2C expected PDU len calculation + - PCI: keystone: Fix race condition when initializing PHYs + - PCI: mediatek-gen3: Fix translation window size calculation + - ASoC: mediatek: sof-common: Add NULL check for normal_link string + - s390/pci: fix max size calculation in zpci_memcpy_toio() + - net: ethernet: ti: am65-cpsw: Fix max mtu to fit ethernet frames + - amt: do not use overwrapped cb area + - net: phy: micrel: populate .soft_reset for KSZ9131 + - mptcp: mptcp_parse_option() fix for MPTCPOPT_MP_JOIN + - mptcp: strict validation before using mp_opt->hmac + - mptcp: use OPTION_MPTCP_MPJ_SYNACK in subflow_finish_connect() + - mptcp: use OPTION_MPTCP_MPJ_SYN in subflow_check_req() + - mptcp: refine opt_mp_capable determination + - block: ensure we hold a queue reference when using queue limits + - udp: annotate data-races around up->pending + - net: ravb: Fix dma_addr_t truncation in error case + - dt-bindings: gpio: xilinx: Fix node address in gpio + - drm/amdkfd: fixes for HMM mem allocation + - net: stmmac: ethtool: Fixed calltrace caused by unbalanced disable_irq_wake + calls + - net: dsa: vsc73xx: Add null pointer check to vsc73xx_gpio_probe + - LoongArch: BPF: Prevent out-of-bounds memory access + - mptcp: relax check on MPC passive fallback + - netfilter: nf_tables: reject invalid set policy + - netfilter: nft_limit: do not ignore unsupported flags + - netfilter: nfnetlink_log: use proper helper for fetching physinif + - netfilter: nf_queue: remove excess nf_bridge variable + - netfilter: propagate net to nf_bridge_get_physindev + - netfilter: bridge: replace physindev with physinif in nf_bridge_info + - netfilter: nf_tables: do not allow mismatch field size and set key length + - netfilter: nf_tables: skip dead set elements in netlink dump + - netfilter: nf_tables: reject NFT_SET_CONCAT with not field length + description + - ipvs: avoid stat macros calls from preemptible context + - kdb: Fix a potential buffer overflow in kdb_local() + - ethtool: netlink: Add missing ethnl_ops_begin/complete + - loop: fix the the direct I/O support check when used on top of block devices + - mlxsw: spectrum_acl_erp: Fix error flow of pool allocation failure + - selftests: mlxsw: qos_pfc: Adjust the test to support 8 lanes + - ipv6: mcast: fix data-race in ipv6_mc_down / mld_ifc_work + - i2c: s3c24xx: fix read transfers in polling mode + - i2c: s3c24xx: fix transferring more than one message in polling mode + - riscv: Fix wrong usage of lm_alias() when splitting a huge linear mapping + - arm64: dts: armada-3720-turris-mox: set irq type for RTC + - x86: Fix CPUIDLE_FLAG_IRQ_ENABLE leaking timer reprogram + - drivers/perf: hisi: Fix some event id for HiSilicon UC pmu + - KVM: PPC: Book3S HV: Use accessors for VCPU registers + - KVM: PPC: Book3S HV: Introduce low level MSR accessor + - KVM: PPC: Book3S HV: Handle pending exceptions on guest entry with MSR_EE + - powerpc/rtas: Avoid warning on invalid token argument to sys_rtas() + - perf/x86/intel/uncore: Fix NULL pointer dereference issue in + upi_fill_topology() + - efivarfs: Free s_fs_info on unmount + - thermal: core: Fix NULL pointer dereference in zone registration error path + - cpuidle: haltpoll: Do not enable interrupts when entering idle + - crypto: rsa - add a check for allocation failure + - crypto: jh7110 - Correct deferred probe return + - NFS: Use parent's objective cred in nfs_access_login_time() + - asm-generic: Fix 32 bit __generic_cmpxchg_local + - arm64: dts: qcom: qrb4210-rb2: don't force usb peripheral mode + - arm64: dts: qcom: sc8280xp-x13s: Use the correct DP PHY compatible + - arm64: dts: qcom: sc8280xp-x13s: add missing camera LED pin config + - scsi: bfa: Use the proper data type for BLIST flags + - arm64: dts: ti: iot2050: Re-add aliases + - wifi: rtw88: sdio: Honor the host max_req_size in the RX path + - ARM: dts: qcom: sdx65: correct PCIe EP phy-names + - dt-bindings: arm: qcom: Fix html link + - arm64: dts: qcom: sc8180x-primus: Fix HALL_INT polarity + - arm64: dts: qcom: sm8450: correct TX Soundwire clock + - arm64: dts: qcom: sm8550: correct TX Soundwire clock + - arm64: dts: qcom: sa8775p: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm6125: add interrupts to DWC3 USB controller + - arm64: dts: qcom: sa8775p: fix USB wakeup interrupt types + - arm64: dts: qcom: sm8550: fix USB wakeup interrupt types + - wifi: mt76: mt7915: fallback to non-wed mode if platform_get_resource fails + in mt7915_mmio_wed_init() + - wifi: mt76: mt7996: fix the size of struct bss_rate_tlv + - wifi: mt76: mt7996: fix rate usage of inband discovery frames + - bpf: Guard stack limits against 32bit overflow + - bpf: Fix accesses to uninit stack slots + - arm64: dts: mediatek: mt8195: revise VDOSYS RDMA node name + - arm64: dts: mediatek: mt8186: Fix alias prefix for ovl_2l0 + - arm64: dts: mediatek: mt8186: fix address warning for ADSP mailboxes + - wifi: iwlwifi: don't support triggered EHT CQI feedback + - arm64: dts: xilinx: Apply overlays to base dtbs + - scsi: ufs: qcom: Fix the return value of ufs_qcom_ice_program_key() + - scsi: ufs: qcom: Fix the return value when platform_get_resource_byname() + fails + - scsi: hisi_sas: Check before using pointer variables + - bpf: Fix a race condition between btf_put() and map_free() + - virtio/vsock: send credit update during setting SO_RCVLOWAT + - bpf: Limit the number of uprobes when attaching program to multiple uprobes + - bpf: Limit the number of kprobes when attaching program to multiple kprobes + - arm64: dts: qcom: acer-aspire1: Correct audio codec definition + - arm64: dts: qcom: sm6375: fix USB wakeup interrupt types + - arm64: dts: qcom: sm6375: Hook up MPM + - arm64: dts: qcom: sm8150: make dispcc cast minimal vote on MMCX + - soc: qcom: llcc: Fix LLCC_TRP_ATTR2_CFGn offset + - arm64: dts: qcom: sm8550: Separate out X3 idle state + - arm64: dts: qcom: sm8550: Update idle state time requirements + - arm64: dts: qcom: sc8180x: Mark PCIe hosts cache-coherent + - arm64: dts: qcom: sc8180x: switch PCIe QMP PHY to new style of bindings + - arm64: dts: qcom: sc8180x: Fix up PCIe nodes + - wifi: iwlwifi: fix out of bound copy_from_user + - wifi: iwlwifi: assign phy_ctxt before eSR activation + - netfilter: nf_tables: validate chain type update if available + - Bluetooth: btnxpuart: fix recv_buf() return value + - arm64: dts: rockchip: Fix led pinctrl of lubancat 1 + - wifi: cfg80211: correct comment about MLD ID + - wifi: cfg80211: parse all ML elements in an ML probe response + - blk-cgroup: fix rcu lockdep warning in blkg_lookup() + - rxrpc: Fix skbuff cleanup of call's recvmsg_queue and rx_oos_queue + - drm/dp_mst: Fix fractional DSC bpp handling + - drm/panel: nv3051d: Hold panel in reset for unprepare + - media: visl: Hook the (TRY_)DECODER_CMD stateless ioctls + - media: amphion: Fix VPU core alias name + - drm/imx/lcdc: Fix double-free of driver data + - drm/msm/dpu: Add missing safe_lut_tbl in sc8180x catalog + - ASoC: Intel: sof_sdw_rt_sdca_jack_common: ctx->headset_codec_dev = NULL + - ASoC: SOF: topology: Use partial match for disconnecting DAI link and DAI + widget + - drm/msm/dpu: correct clk bit for WB2 block + - clk: sp7021: fix return value check in sp7021_clk_probe() + - clk: rs9: Fix DIF OEn bit placement on 9FGV0241 + - ASoC: tas2781: add support for FW version 0x0503 + - clk: qcom: gcc-sm8550: Add the missing RETAIN_FF_ENABLE GDSC flag + - clk: qcom: gcc-sm8550: Mark the PCIe GDSCs votable + - clk: qcom: gcc-sm8550: use collapse-voting for PCIe GDSCs + - clk: qcom: gcc-sm8550: Mark RCGs shared where applicable + - clk: qcom: dispcc-sm8550: Update disp PLL settings + - drm/amdkfd: Fix type of 'dbg_flags' in 'struct kfd_process' + - gpiolib: make gpio_device_get() and gpio_device_put() public + - gpiolib: provide gpio_device_find() + - gpio: sysfs: drop the mention of gpiochip_find() from sysfs code + - drm/amd/display: avoid stringop-overflow warnings for + dp_decide_lane_settings() + - kselftest/alsa - conf: Stringify the printed errno in sysfs_get() + - class: fix use-after-free in class_register() + - kernfs: convert kernfs_idr_lock to an irq safe raw spinlock + - usb: dwc3: gadget: Handle EP0 request dequeuing properly + - usb: dwc3: gadget: Queue PM runtime idle on disconnect event + - Revert "usb: typec: class: fix typec_altmode_put_partner to put plugs" + - dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: fix path to header + - ceph: select FS_ENCRYPTION_ALGS if FS_ENCRYPTION + - io_uring: don't check iopoll if request completes + - io_uring: ensure local task_work is run on wait timeout + - block: Remove special-casing of compound pages + - wifi: mwifiex: add extra delay for firmware ready + - wifi: mwifiex: fix uninitialized firmware_stat + - Revert "nSVM: Check for reserved encodings of TLB_CONTROL in nested VMCB" + - x86/pci: Reserve ECAM if BIOS didn't include it in PNP0C02 _CRS + - KVM: x86/pmu: Move PMU reset logic to common x86 code + - KVM: x86/pmu: Reset the PMU, i.e. stop counters, before refreshing + - mfd: rk8xx: fixup devices registration with PLATFORM_DEVID_AUTO + - leds: aw200xx: Fix write to DIM parameter + - mfd: tps6594: Add null pointer check to tps6594_device_init() + - srcu: Use try-lock lockdep annotation for NMI-safe access. + - um: virt-pci: fix platform map offset + - PCI: Avoid potential out-of-bounds read in pci_dev_for_each_resource() + - iommu: Map reserved memory as cacheable if device is coherent + - perf test: Remove atomics from test_loop to avoid test failures + - perf header: Fix segfault on build_mem_topology() error path + - perf test record user-regs: Fix mask for vg register + - perf vendor events arm64 AmpereOne: Rename BPU_FLUSH_MEM_FAULT to + GPC_FLUSH_MEM_FAULT + - perf mem: Fix error on hybrid related to availability of mem event in a PMU + - perf stat: Exit perf stat if parse groups fails + - iio: adc: ad9467: add mutex to struct ad9467_state + - perf unwind-libdw: Handle JIT-generated DSOs properly + - perf unwind-libunwind: Fix base address for .eh_frame + - bus: mhi: ep: Do not allocate event ring element on stack + - bus: mhi: ep: Use slab allocator where applicable + - usb: gadget: webcam: Make g_webcam loadable again + - iommu: Don't reserve 0-length IOVA region + - power: supply: Fix null pointer dereference in smb2_probe + - apparmor: Fix ref count leak in task_kill + - perf stat: Fix hard coded LL miss units + - apparmor: fix possible memory leak in unpack_trans_table + - serial: apbuart: fix console prompt on qemu + - perf db-export: Fix missing reference count get in call_path_from_sample() + - cxl/port: Fix missing target list lock + - spi: coldfire-qspi: Remove an erroneous clk_disable_unprepare() from the + remove function + - hisi_acc_vfio_pci: Update migration data pointer correctly on saving/resume + - rxrpc: Fix use of Don't Fragment flag + - octeontx2-af: CN10KB: Fix FIFO length calculation for RPM2 + - net: micrel: Fix PTP frame parsing for lan8841 + - ALSA: hda: Properly setup HDMI stream + - net: add more sanity check in virtio_net_hdr_to_skb() + - net: netdev_queue: netdev_txq_completed_mb(): fix wake condition + - bpf: iter_udp: Retry with a larger batch size without going back to the + previous bucket + - bpf: Avoid iter->offset making backward progress in bpf_iter_udp + - gpio: mlxbf3: add an error code check in mlxbf3_gpio_probe + - ASoC: SOF: ipc4-loader: remove the CPC check warnings + - selftests: bonding: Change script interpreter + - io_uring: adjust defer tw counting + - arm64/ptrace: Don't flush ZA/ZT storage when writing ZA via ptrace + - mlxsw: spectrum_acl_tcam: Fix NULL pointer dereference in error path + - mlxsw: spectrum_acl_tcam: Fix stack corruption + - mlxsw: spectrum_router: Register netdevice notifier before nexthop + - Upstream stable to v6.1.75, v6.6.14 + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26583 + - net: tls, fix WARNIING in __sk_msg_free + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26589 + - bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26591 + - bpf: Fix re-attachment branch in bpf_tracing_prog_attach + + -- Roxana Nicolescu Fri, 19 Apr 2024 14:54:04 +0200 + +linux-lowlatency (6.5.0-28.29.1) mantic; urgency=medium + + * mantic/linux-lowlatency: 6.5.0-28.29.1 -proposed tracker (LP: #2059693) + + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + + [ Ubuntu: 6.5.0-28.29 ] + + * mantic/linux: 6.5.0-28.29 -proposed tracker (LP: #2059706) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * Remove getabis scripts (LP: #2059143) + - [Packaging] Remove getabis + * CVE-2023-52600 + - jfs: fix uaf in jfs_evict_inode + * Mantic update: upstream stable patchset 2024-03-27 (LP: #2059284) // + CVE-2023-52603 + - UBSAN: array-index-out-of-bounds in dtSplitRoot + * CVE-2024-26581 + - netfilter: nft_set_rbtree: skip end interval element from gc + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26589 + - bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26591 + - bpf: Fix re-attachment branch in bpf_tracing_prog_attach + * iwlwifi disconnect and crash - intel wifi7 (LP: #2058808) + - wifi: iwlwifi: pcie: fix RB status reading + + -- Roxana Nicolescu Thu, 04 Apr 2024 14:59:41 +0200 + linux-lowlatency (6.5.0-27.28.1) mantic; urgency=medium * mantic/linux-lowlatency: 6.5.0-27.28.1 -proposed tracker (LP: #2055571) reverted: --- linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/etc/getabis +++ linux-lowlatency-hwe-6.5-6.5.0.orig/debian.lowlatency/etc/getabis @@ -1,15 +0,0 @@ -repo_list=( - "http://archive.ubuntu.com/ubuntu/pool/main/l/linux-lowlatency" - "http://ports.ubuntu.com/ubuntu-ports/pool/main/l/linux-lowlatency" - "http://archive.ubuntu.com/ubuntu/pool/universe/l/linux-lowlatency" - "http://ports.ubuntu.com/ubuntu-ports/pool/universe/l/linux-lowlatency" - "http://ppa.launchpad.net/canonical-kernel-team/ppa/ubuntu/pool/main/l/linux-lowlatency" - "http://ppa.launchpad.net/canonical-kernel-team/ppa2/ubuntu/pool/main/l/linux-lowlatency" - "http://ppa.launchpad.net/canonical-kernel-team/unstable/ubuntu/pool/main/l/linux-lowlatency" - "http://ppa.launchpad.net/canonical-kernel-team/bootstrap/ubuntu/pool/main/l/linux-lowlatency" -) - -package_prefixes linux-buildinfo - -getall amd64 lowlatency -getall arm64 lowlatency lowlatency-64k diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/reconstruct linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/reconstruct --- linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/reconstruct +++ linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/reconstruct @@ -17,10 +17,8 @@ chmod +x 'debian/scripts/misc/annotations' chmod +x 'debian/scripts/misc/arch-has-odm-enabled.sh' chmod +x 'debian/scripts/misc/find-missing-sauce.sh' -chmod +x 'debian/scripts/misc/fips-checks' chmod +x 'debian/scripts/misc/fw-to-ihex.sh' chmod +x 'debian/scripts/misc/gen-auto-reconstruct' -chmod +x 'debian/scripts/misc/getabis' chmod +x 'debian/scripts/misc/git-ubuntu-log' chmod +x 'debian/scripts/misc/insert-changes' chmod +x 'debian/scripts/misc/insert-mainline-changes' @@ -50,6 +48,13 @@ chmod +x 'tools/testing/selftests/netfilter/xt_string.sh' # Remove any files deleted from the orig. rm -f 'Documentation/networking/device_drivers/ethernet/mellanox/mlx5/devlink.rst' +rm -f 'Documentation/translations/zh_TW/sparse.txt' +rm -f 'arch/arm/boot/dts/qcom/qcom-pm8226.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pm8841.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pm8941.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pma8084.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pmx55.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pmx65.dtsi' rm -f 'arch/parisc/include/asm/mckinley.h' rm -f 'drivers/media/pci/intel/ipu3/cio2-bridge.c' rm -f 'drivers/media/pci/intel/ipu3/cio2-bridge.h' diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/scripts/helpers/local-mangle linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/scripts/helpers/local-mangle --- linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/scripts/helpers/local-mangle +++ linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/scripts/helpers/local-mangle @@ -8,11 +8,6 @@ echo -e "flavours\t= lowlatency" >> ${DEBIAN}/rules.d/amd64.mk echo -e "flavours\t= lowlatency lowlatency-64k" >> ${DEBIAN}/rules.d/arm64.mk -# We only care about lowlatency/lowlatency-64k abis -sed -i /getall/d ${DEBIAN}/etc/getabis -echo "getall amd64 lowlatency" >> ${DEBIAN}/etc/getabis -echo "getall arm64 lowlatency lowlatency-64k" >> ${DEBIAN}/etc/getabis - # Override options in rules.d/hooks.mk (normally master does not have this # file but it got added for generic annotations enforcement. cat <>${DEBIAN}/rules.d/hooks.mk diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/tracking-bug linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/tracking-bug --- linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/tracking-bug +++ linux-lowlatency-hwe-6.5-6.5.0/debian.lowlatency/tracking-bug @@ -1 +1 @@ -2055571 2024.03.04-1 +2059430 2024.04.01-1 diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.master/changelog linux-lowlatency-hwe-6.5-6.5.0/debian.master/changelog --- linux-lowlatency-hwe-6.5-6.5.0/debian.master/changelog +++ linux-lowlatency-hwe-6.5-6.5.0/debian.master/changelog @@ -1,3 +1,1319 @@ +linux (6.5.0-34.34) mantic; urgency=medium + + * mantic/linux: 6.5.0-34.34 -proposed tracker (LP: #2061443) + + * CVE-2024-2201 + - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file + - x86/syscall: Don't force use of indirect calls for system calls + - x86/bhi: Add support for clearing branch history at syscall entry + - x86/bhi: Define SPEC_CTRL_BHI_DIS_S + - x86/bhi: Enumerate Branch History Injection (BHI) bug + - x86/bhi: Add BHI mitigation knob + - x86/bhi: Mitigate KVM by default + - KVM: x86: Add BHI_NO + - [Config] Set CONFIG_BHI to enabled (auto) + + -- Stefan Bader Mon, 15 Apr 2024 15:09:54 +0200 + +linux (6.5.0-33.33) mantic; urgency=medium + + * mantic/linux: 6.5.0-33.33 -proposed tracker (LP: #2060448) + + * [Mantic] Compile broken on armhf (cc1 out of memory) (LP: #2060446) + - Revert "minmax: relax check to allow comparison between unsigned arguments + and signed constants" + - Revert "minmax: allow comparisons of 'int' against 'unsigned char/short'" + - Revert "minmax: allow min()/max()/clamp() if the arguments have the same + signedness." + - Revert "minmax: add umin(a, b) and umax(a, b)" + + -- Stefan Bader Mon, 08 Apr 2024 11:39:11 +0200 + +linux (6.5.0-32.32) mantic; urgency=medium + + * mantic/linux: 6.5.0-32.32 -proposed tracker (LP: #2059443) + + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + + * Drop fips-checks script from trees (LP: #2055083) + - [Packaging] Remove fips-checks script + + * alsa/realtek: adjust max output valume for headphone on 2 LG machines + (LP: #2058573) + - ALSA: hda/realtek: fix the hp playback volume issue for LG machines + + * Remove getabis scripts (LP: #2059143) + - [Packaging] Remove getabis + + * Mantic update: upstream stable patchset 2024-03-27 (LP: #2059284) + - asm-generic: make sparse happy with odd-sized put_unaligned_*() + - powerpc/mm: Fix null-pointer dereference in pgtable_cache_add + - arm64: irq: set the correct node for VMAP stack + - drivers/perf: pmuv3: don't expose SW_INCR event in sysfs + - powerpc: Fix build error due to is_valid_bugaddr() + - powerpc/mm: Fix build failures due to arch_reserved_kernel_pages() + - powerpc/64s: Fix CONFIG_NUMA=n build due to create_section_mapping() + - x86/boot: Ignore NMIs during very early boot + - powerpc: pmd_move_must_withdraw() is only needed for + CONFIG_TRANSPARENT_HUGEPAGE + - powerpc/lib: Validate size for vector operations + - x86/mce: Mark fatal MCE's page as poison to avoid panic in the kdump kernel + - perf/core: Fix narrow startup race when creating the perf nr_addr_filters + sysfs file + - debugobjects: Stop accessing objects after releasing hash bucket lock + - regulator: core: Only increment use_count when enable_count changes + - audit: Send netlink ACK before setting connection in auditd_set + - ACPI: video: Add quirk for the Colorful X15 AT 23 Laptop + - PNP: ACPI: fix fortify warning + - ACPI: extlog: fix NULL pointer dereference check + - ACPI: NUMA: Fix the logic of getting the fake_pxm value + - PM / devfreq: Synchronize devfreq_monitor_[start/stop] + - ACPI: APEI: set memory failure flags as MF_ACTION_REQUIRED on synchronous + events + - FS:JFS:UBSAN:array-index-out-of-bounds in dbAdjTree + - jfs: fix slab-out-of-bounds Read in dtSearch + - jfs: fix array-index-out-of-bounds in dbAdjTree + - pstore/ram: Fix crash when setting number of cpus to an odd number + - crypto: octeontx2 - Fix cptvf driver cleanup + - erofs: fix ztailpacking for subpage compressed blocks + - crypto: stm32/crc32 - fix parsing list of devices + - afs: fix the usage of read_seqbegin_or_lock() in afs_lookup_volume_rcu() + - afs: fix the usage of read_seqbegin_or_lock() in afs_find_server*() + - rxrpc_find_service_conn_rcu: fix the usage of read_seqbegin_or_lock() + - jfs: fix array-index-out-of-bounds in diNewExt + - arch: consolidate arch_irq_work_raise prototypes + - s390/vfio-ap: fix sysfs status attribute for AP queue devices + - s390/ptrace: handle setting of fpc register correctly + - KVM: s390: fix setting of fpc register + - SUNRPC: Fix a suspicious RCU usage warning + - ecryptfs: Reject casefold directory inodes + - ext4: fix inconsistent between segment fstrim and full fstrim + - ext4: unify the type of flexbg_size to unsigned int + - ext4: remove unnecessary check from alloc_flex_gd() + - ext4: avoid online resizing failures due to oversized flex bg + - wifi: rt2x00: restart beacon queue when hardware reset + - selftests/bpf: satisfy compiler by having explicit return in btf test + - selftests/bpf: Fix pyperf180 compilation failure with clang18 + - wifi: rt2x00: correct wrong BBP register in RxDCOC calibration + - selftests/bpf: Fix issues in setup_classid_environment() + - soc: xilinx: Fix for call trace due to the usage of smp_processor_id() + - soc: xilinx: fix unhandled SGI warning message + - scsi: lpfc: Fix possible file string name overflow when updating firmware + - PCI: Add no PM reset quirk for NVIDIA Spectrum devices + - bonding: return -ENOMEM instead of BUG in alb_upper_dev_walk + - net: usb: ax88179_178a: avoid two consecutive device resets + - scsi: arcmsr: Support new PCI device IDs 1883 and 1886 + - ARM: dts: imx7d: Fix coresight funnel ports + - ARM: dts: imx7s: Fix lcdif compatible + - ARM: dts: imx7s: Fix nand-controller #size-cells + - wifi: ath9k: Fix potential array-index-out-of-bounds read in + ath9k_htc_txstatus() + - wifi: ath11k: fix race due to setting ATH11K_FLAG_EXT_IRQ_ENABLED too early + - bpf: Check rcu_read_lock_trace_held() before calling bpf map helpers + - scsi: libfc: Don't schedule abort twice + - scsi: libfc: Fix up timeout error in fc_fcp_rec_error() + - bpf: Set uattr->batch.count as zero before batched update or deletion + - wifi: wfx: fix possible NULL pointer dereference in wfx_set_mfp_ap() + - ARM: dts: rockchip: fix rk3036 hdmi ports node + - ARM: dts: imx25/27-eukrea: Fix RTC node name + - ARM: dts: imx: Use flash@0,0 pattern + - ARM: dts: imx27: Fix sram node + - ARM: dts: imx1: Fix sram node + - net: phy: at803x: fix passing the wrong reference for config_intr + - ionic: pass opcode to devcmd_wait + - ionic: bypass firmware cmds when stuck in reset + - block/rnbd-srv: Check for unlikely string overflow + - ARM: dts: imx25: Fix the iim compatible string + - ARM: dts: imx25/27: Pass timing0 + - ARM: dts: imx27-apf27dev: Fix LED name + - ARM: dts: imx23-sansa: Use preferred i2c-gpios properties + - ARM: dts: imx23/28: Fix the DMA controller node name + - scsi: hisi_sas: Set .phy_attached before notifing phyup event + HISI_PHYE_PHY_UP_PM + - ice: fix ICE_AQ_VSI_Q_OPT_RSS_* register values + - net: atlantic: eliminate double free in error handling logic + - net: dsa: mv88e6xxx: Fix mv88e6352_serdes_get_stats error path + - block: prevent an integer overflow in bvec_try_merge_hw_page + - md: Whenassemble the array, consult the superblock of the freshest device + - arm64: dts: qcom: msm8996: Fix 'in-ports' is a required property + - arm64: dts: qcom: msm8998: Fix 'out-ports' is a required property + - ice: fix pre-shifted bit usage + - arm64: dts: amlogic: fix format for s4 uart node + - wifi: rtl8xxxu: Add additional USB IDs for RTL8192EU devices + - libbpf: Fix NULL pointer dereference in bpf_object__collect_prog_relos + - wifi: rtlwifi: rtl8723{be,ae}: using calculate_bit_shift() + - wifi: cfg80211: free beacon_ies when overridden from hidden BSS + - Bluetooth: qca: Set both WIDEBAND_SPEECH and LE_STATES quirks for QCA2066 + - Bluetooth: hci_sync: fix BR/EDR wakeup bug + - Bluetooth: L2CAP: Fix possible multiple reject send + - net/smc: disable SEID on non-s390 archs where virtual ISM may be used + - bridge: cfm: fix enum typo in br_cc_ccm_tx_parse + - i40e: Fix VF disable behavior to block all traffic + - octeontx2-af: Fix max NPC MCAM entry check while validating ref_entry + - net: dsa: qca8k: put MDIO bus OF node on qca8k_mdio_register() failure + - f2fs: fix to check return value of f2fs_reserve_new_block() + - ALSA: hda: Refer to correct stream index at loops + - ASoC: doc: Fix undefined SND_SOC_DAPM_NOPM argument + - fast_dput(): handle underflows gracefully + - RDMA/IPoIB: Fix error code return in ipoib_mcast_join + - drm/panel-edp: Add override_edid_mode quirk for generic edp + - drm/bridge: anx7625: Fix Set HPD irq detect window to 2ms + - drm/amd/display: Fix tiled display misalignment + - f2fs: fix write pointers on zoned device after roll forward + - drm/drm_file: fix use of uninitialized variable + - drm/framebuffer: Fix use of uninitialized variable + - drm/mipi-dsi: Fix detach call without attach + - media: stk1160: Fixed high volume of stk1160_dbg messages + - media: rockchip: rga: fix swizzling for RGB formats + - PCI: add INTEL_HDA_ARL to pci_ids.h + - ALSA: hda: Intel: add HDA_ARL PCI ID support + - media: rkisp1: Fix IRQ handler return values + - media: rkisp1: Store IRQ lines + - media: rkisp1: Fix IRQ disable race issue + - f2fs: fix to tag gcing flag on page during block migration + - drm/exynos: Call drm_atomic_helper_shutdown() at shutdown/unbind time + - IB/ipoib: Fix mcast list locking + - media: amphion: remove mutext lock in condition of wait_event + - media: ddbridge: fix an error code problem in ddb_probe + - media: i2c: imx335: Fix hblank min/max values + - drm/amd/display: For prefetch mode > 0, extend prefetch if possible + - drm/msm/dpu: Ratelimit framedone timeout msgs + - drm/msm/dpu: fix writeback programming for YUV cases + - drm/amdgpu: fix ftrace event amdgpu_bo_move always move on same heap + - clk: hi3620: Fix memory leak in hi3620_mmc_clk_init() + - clk: mmp: pxa168: Fix memory leak in pxa168_clk_init() + - watchdog: it87_wdt: Keep WDTCTRL bit 3 unmodified for IT8784/IT8786 + - drm/amd/display: make flip_timestamp_in_us a 64-bit variable + - clk: imx: clk-imx8qxp: fix LVDS bypass, pixel and phy clocks + - drm/amdgpu: Fix ecc irq enable/disable unpaired + - drm/amdgpu: Let KFD sync with VM fences + - drm/amdgpu: Fix '*fw' from request_firmware() not released in + 'amdgpu_ucode_request()' + - drm/amdgpu: Drop 'fence' check in 'to_amdgpu_amdkfd_fence()' + - drm/amdkfd: Fix iterator used outside loop in 'kfd_add_peer_prop()' + - ALSA: hda/conexant: Fix headset auto detect fail in cx8070 and SN6140 + - leds: trigger: panic: Don't register panic notifier if creating the trigger + failed + - um: Fix naming clash between UML and scheduler + - um: Don't use vfprintf() for os_info() + - um: net: Fix return type of uml_net_start_xmit() + - um: time-travel: fix time corruption + - i3c: master: cdns: Update maximum prescaler value for i2c clock + - xen/gntdev: Fix the abuse of underlying struct page in DMA-buf import + - mfd: ti_am335x_tscadc: Fix TI SoC dependencies + - [Config] updateconfigs for MFD_TI_AM335X_TSCADC + - mailbox: arm_mhuv2: Fix a bug for mhuv2_sender_interrupt + - PCI: Only override AMD USB controller if required + - PCI: switchtec: Fix stdev_release() crash after surprise hot remove + - perf cs-etm: Bump minimum OpenCSD version to ensure a bugfix is present + - usb: hub: Replace hardcoded quirk value with BIT() macro + - usb: hub: Add quirk to decrease IN-ep poll interval for Microchip USB491x + hub + - selftests/sgx: Fix linker script asserts + - tty: allow TIOCSLCKTRMIOS with CAP_CHECKPOINT_RESTORE + - fs/kernfs/dir: obey S_ISGID + - spmi: mediatek: Fix UAF on device remove + - PCI: Fix 64GT/s effective data rate calculation + - PCI/AER: Decode Requester ID when no error info found + - 9p: Fix initialisation of netfs_inode for 9p + - misc: lis3lv02d_i2c: Add missing setting of the reg_ctrl callback + - libsubcmd: Fix memory leak in uniq() + - drm/amdkfd: Fix lock dependency warning + - drm/amdkfd: Fix lock dependency warning with srcu + - virtio_net: Fix "‘%d’ directive writing between 1 and 11 bytes into a region + of size 10" warnings + - blk-mq: fix IO hang from sbitmap wakeup race + - ceph: reinitialize mds feature bit even when session in open + - ceph: fix deadlock or deadcode of misusing dget() + - ceph: fix invalid pointer access if get_quota_realm return ERR_PTR + - drm/amd/powerplay: Fix kzalloc parameter 'ATOM_Tonga_PPM_Table' in + 'get_platform_power_management_table()' + - drm/amdgpu: Fix with right return code '-EIO' in + 'amdgpu_gmc_vram_checking()' + - drm/amdgpu: Release 'adev->pm.fw' before return in + 'amdgpu_device_need_post()' + - drm/amdkfd: Fix 'node' NULL check in 'svm_range_get_range_boundaries()' + - perf: Fix the nr_addr_filters fix + - wifi: cfg80211: fix RCU dereference in __cfg80211_bss_update + - drm: using mul_u32_u32() requires linux/math64.h + - scsi: isci: Fix an error code problem in isci_io_request_build() + - regulator: ti-abb: don't use devm_platform_ioremap_resource_byname for + shared interrupt register + - scsi: core: Move scsi_host_busy() out of host lock for waking up EH handler + - HID: hidraw: fix a problem of memory leak in hidraw_release() + - selftests: net: give more time for GRO aggregation + - ip6_tunnel: make sure to pull inner header in __ip6_tnl_rcv() + - ipmr: fix kernel panic when forwarding mcast packets + - net: lan966x: Fix port configuration when using SGMII interface + - tcp: add sanity checks to rx zerocopy + - ixgbe: Refactor returning internal error codes + - ixgbe: Refactor overtemp event handling + - ixgbe: Fix an error handling path in ixgbe_read_iosf_sb_reg_x550() + - net: dsa: qca8k: fix illegal usage of GPIO + - ipv6: Ensure natural alignment of const ipv6 loopback and router addresses + - llc: call sock_orphan() at release time + - bridge: mcast: fix disabled snooping after long uptime + - selftests: net: add missing config for GENEVE + - netfilter: conntrack: correct window scaling with retransmitted SYN + - netfilter: nf_tables: restrict tunnel object to NFPROTO_NETDEV + - netfilter: nf_log: replace BUG_ON by WARN_ON_ONCE when putting logger + - netfilter: nft_ct: sanitize layer 3 and 4 protocol number in custom + expectations + - net: ipv4: fix a memleak in ip_setup_cork + - af_unix: fix lockdep positive in sk_diag_dump_icons() + - SAUCE: Sync apparmor copy of af_unix.c + - selftests: net: fix available tunnels detection + - net: sysfs: Fix /sys/class/net/ path + - selftests: team: Add missing config options + - selftests: bonding: Check initial state + - arm64: irq: set the correct node for shadow call stack + - mm, kmsan: fix infinite recursion due to RCU critical section + - Revert "drm/amd/display: Disable PSR-SU on Parade 0803 TCON again" + - drm/msm/dsi: Enable runtime PM + - LoongArch/smp: Call rcutree_report_cpu_starting() at tlb_init() + - gve: Fix use-after-free vulnerability + - bonding: remove print in bond_verify_device_path + - ASoC: codecs: lpass-wsa-macro: fix compander volume hack + - ASoC: codecs: wsa883x: fix PA volume control + - drm/amdgpu: Fix missing error code in 'gmc_v6/7/8/9_0_hw_init()' + - Documentation/sphinx: fix Python string escapes + - kunit: tool: fix parsing of test attributes + - thermal: core: Fix thermal zone suspend-resume synchronization + - hwrng: starfive - Fix dev_err_probe return error + - crypto: p10-aes-gcm - Avoid -Wstringop-overflow warnings + - erofs: fix up compacted indexes for block size < 4096 + - crypto: starfive - Fix dev_err_probe return error + - s390/boot: always align vmalloc area on segment boundary + - ext4: treat end of range as exclusive in ext4_zero_range() + - wifi: rtw89: fix timeout calculation in rtw89_roc_end() + - ARM: dts: qcom: strip prefix from PMIC files + - ARM: dts: qcom: mdm9615: fix PMIC node labels + - ARM: dts: qcom: msm8660: fix PMIC node labels + - ARM: dts: samsung: exynos4: fix camera unit addresses/ranges + - ARM: dts: samsung: s5pv210: fix camera unit addresses/ranges + - net: phy: micrel: fix ts_info value in case of no phc + - bpf: Prevent inlining of bpf_fentry_test7() + - bpf: Fix a few selftest failures due to llvm18 change + - wifi: rtw89: fix misbehavior of TX beacon in concurrent mode + - bpf: Set need_defer as false when clearing fd array during map free + - wifi: ath12k: fix and enable AP mode for WCN7850 + - minmax: add umin(a, b) and umax(a, b) + - minmax: allow min()/max()/clamp() if the arguments have the same signedness. + - minmax: allow comparisons of 'int' against 'unsigned char/short' + - minmax: relax check to allow comparison between unsigned arguments and + signed constants + - net: mvmdio: Avoid excessive sleeps in polled mode + - arm64: dts: qcom: sm8550: fix soundwire controllers node name + - arm64: dts: qcom: sm8450: fix soundwire controllers node name + - arm64: dts: qcom: sm8350: Fix remoteproc interrupt type + - wifi: mt76: connac: fix EHT phy mode check + - wifi: mt76: mt7996: add PCI IDs for mt7992 + - wifi: ath12k: fix the issue that the multicast/broadcast indicator is not + read correctly for WCN7850 + - arm64: zynqmp: Move fixed clock to / for kv260 + - arm64: zynqmp: Fix clock node name in kv260 cards + - selftests/bpf: fix compiler warnings in RELEASE=1 mode + - scsi: lpfc: Reinitialize an NPIV's VMID data structures after FDISC + - scsi: lpfc: Move determination of vmid_flag after VMID reinitialization + completes + - arm64: dts: qcom: Fix coresight warnings in in-ports and out-ports + - wifi: rtw89: coex: Fix wrong Wi-Fi role info and FDDT parameter members + - Bluetooth: ISO: Avoid creating child socket if PA sync is terminating + - arm64: dts: sprd: Add clock reference for pll2 on UMS512 + - arm64: dts: sprd: Change UMS512 idle-state nodename to match bindings + - net: kcm: fix direct access to bv_len + - reiserfs: Avoid touching renamed directory if parent does not change + - drm/amd/display: Fix MST PBN/X.Y value calculations + - drm/drm_file: fix use of uninitialized variable + - drm/msm/dp: Add DisplayPort controller for SM8650 + - media: uvcvideo: Fix power line control for a Chicony camera + - media: uvcvideo: Fix power line control for SunplusIT camera + - media: rkisp1: resizer: Stop manual allocation of v4l2_subdev_state + - hwmon: (hp-wmi-sensors) Fix failure to load on EliteDesk 800 G6 + - drm/amd/display: Force p-state disallow if leaving no plane config + - drm/amdkfd: fix mes set shader debugger process management + - drm/msm/dpu: enable writeback on SM8350 + - drm/msm/dpu: enable writeback on SM8450 + - watchdog: starfive: add lock annotations to fix context imbalances + - accel/habanalabs: add support for Gaudi2C device + - drm/amd/display: Only clear symclk otg flag for HDMI + - drm/amd/display: Fix minor issues in BW Allocation Phase2 + - drm/amdgpu: apply the RV2 system aperture fix to RN/CZN as well + - pinctrl: baytrail: Fix types of config value in byt_pin_config_set() + - riscv: Make XIP bootable again + - extcon: fix possible name leak in extcon_dev_register() + - usb: xhci-plat: fix usb disconnect issue after s4 + - i2c: rk3x: Adjust mask/value offset for i2c2 on rv1126 + - drm/amdkfd: only flush mes process context if mes support is there + - riscv: Fix build error on rv32 + XIP + - selftests: net: remove dependency on ebpf tests + - selftests: net: explicitly wait for listener ready + - gve: Fix skb truesize underestimation + - net: phy: phy_device: Call into the PHY driver to set LED offload + - net: phy: mediatek-ge-soc: support PHY LEDs + - net: phy: mediatek-ge-soc: sync driver with MediaTek SDK + - selftests: net: add missing config for big tcp tests + - selftests: net: add missing required classifier + - net: dsa: mt7530: fix 10M/100M speed on MT7988 switch + - e1000e: correct maximum frequency adjustment values + - selftests: net: Add missing matchall classifier + - devlink: Fix referring to hw_addr attribute during state validation + - pds_core: Cancel AQ work on teardown + - pds_core: Use struct pdsc for the pdsc_adminq_isr private data + - pds_core: implement pci reset handlers + - pds_core: Prevent race issues involving the adminq + - pds_core: Clear BARs on reset + - pds_core: Rework teardown/setup flow to be more common + - selftests: net: add missing config for nftables-backed iptables + - selftests: net: add missing config for pmtu.sh tests + - selftests: net: don't access /dev/stdout in pmtu.sh + - octeontx2-pf: Remove xdp queues on program detach + - selftests: net: add missing config for NF_TARGET_TTL + - selftests: net: enable some more knobs + - selftests/bpf: Remove flaky test_btf_id test + - ASoC: qcom: sc8280xp: limit speaker volumes + - ASoC: codecs: wcd938x: fix headphones volume controls + - pds_core: Prevent health thread from running during reset/remove + - Upstream stable to v6.1.77, v6.6.16 + + * Mantic update: upstream stable patchset 2024-03-27 (LP: #2059284) // + CVE-2023-52603 + - UBSAN: array-index-out-of-bounds in dtSplitRoot + + * iwlwifi disconnect and crash - intel wifi7 (LP: #2058808) + - wifi: iwlwifi: pcie: fix RB status reading + + * Mantic update: upstream stable patchset 2024-03-26 (LP: #2059068) + - iio: adc: ad7091r: Set alert bit in config register + - iio: adc: ad7091r: Allow users to configure device events + - ext4: allow for the last group to be marked as trimmed + - arm64: properly install vmlinuz.efi + - OPP: Pass rounded rate to _set_opp() + - btrfs: sysfs: validate scrub_speed_max value + - crypto: api - Disallow identical driver names + - PM: hibernate: Enforce ordering during image compression/decompression + - hwrng: core - Fix page fault dead lock on mmap-ed hwrng + - crypto: s390/aes - Fix buffer overread in CTR mode + - s390/vfio-ap: unpin pages on gisc registration failure + - PM / devfreq: Fix buffer overflow in trans_stat_show + - media: imx355: Enable runtime PM before registering async sub-device + - rpmsg: virtio: Free driver_override when rpmsg_remove() + - media: ov9734: Enable runtime PM before registering async sub-device + - s390/vfio-ap: always filter entire AP matrix + - s390/vfio-ap: loop over the shadow APCB when filtering guest's AP + configuration + - s390/vfio-ap: let on_scan_complete() callback filter matrix and update + guest's APCB + - mips: Fix max_mapnr being uninitialized on early stages + - bus: mhi: host: Add alignment check for event ring read pointer + - bus: mhi: host: Drop chan lock before queuing buffers + - bus: mhi: host: Add spinlock to protect WP access when queueing TREs + - parisc/firmware: Fix F-extend for PDC addresses + - parisc/power: Fix power soft-off button emulation on qemu + - async: Split async_schedule_node_domain() + - async: Introduce async_schedule_dev_nocall() + - iio: adc: ad7091r: Enable internal vref if external vref is not supplied + - dmaengine: fix NULL pointer in channel unregistration function + - scsi: ufs: core: Remove the ufshcd_hba_exit() call from ufshcd_async_scan() + - arm64: dts: qcom: sc7180: fix USB wakeup interrupt types + - arm64: dts: qcom: sdm845: fix USB wakeup interrupt types + - arm64: dts: qcom: sm8150: fix USB wakeup interrupt types + - arm64: dts: qcom: sc7280: fix usb_1 wakeup interrupt types + - arm64: dts: qcom: sdm845: fix USB DP/DM HS PHY interrupts + - arm64: dts: qcom: sm8150: fix USB DP/DM HS PHY interrupts + - lsm: new security_file_ioctl_compat() hook + - docs: kernel_abi.py: fix command injection + - scripts/get_abi: fix source path leak + - media: videobuf2-dma-sg: fix vmap callback + - mmc: core: Use mrq.sbc in close-ended ffu + - mmc: mmc_spi: remove custom DMA mapped buffers + - media: mtk-jpeg: Fix use after free bug due to error path handling in + mtk_jpeg_dec_device_run + - arm64: Rename ARM64_WORKAROUND_2966298 + - rtc: cmos: Use ACPI alarm for non-Intel x86 systems too + - rtc: Adjust failure return code for cmos_set_alarm() + - rtc: mc146818-lib: Adjust failure return code for mc146818_get_time() + - rtc: Add support for configuring the UIP timeout for RTC reads + - rtc: Extend timeout for waiting for UIP to clear to 1s + - nouveau/vmm: don't set addr on the fail path to avoid warning + - ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path + - mm/rmap: fix misplaced parenthesis of a likely() + - mm/sparsemem: fix race in accessing memory_section->usage + - rename(): fix the locking of subdirectories + - serial: sc16is7xx: improve regmap debugfs by using one regmap per port + - serial: sc16is7xx: remove wasteful static buffer in sc16is7xx_regmap_name() + - serial: sc16is7xx: remove global regmap from struct sc16is7xx_port + - serial: sc16is7xx: remove unused line structure member + - serial: sc16is7xx: change EFR lock to operate on each channels + - serial: sc16is7xx: convert from _raw_ to _noinc_ regmap functions for FIFO + - serial: sc16is7xx: fix invalid sc16is7xx_lines bitfield in case of probe + error + - serial: sc16is7xx: remove obsolete loop in sc16is7xx_port_irq() + - serial: sc16is7xx: improve do/while loop in sc16is7xx_irq() + - LoongArch/smp: Call rcutree_report_cpu_starting() earlier + - mm: page_alloc: unreserve highatomic page blocks before oom + - ksmbd: set v2 lease version on lease upgrade + - ksmbd: fix potential circular locking issue in smb2_set_ea() + - ksmbd: don't increment epoch if current state and request state are same + - ksmbd: send lease break notification on FILE_RENAME_INFORMATION + - ksmbd: Add missing set_freezable() for freezable kthread + - Revert "drm/amd: Enable PCIe PME from D3" + - wifi: mac80211: fix potential sta-link leak + - net/smc: fix illegal rmb_desc access in SMC-D connection dump + - tcp: make sure init the accept_queue's spinlocks once + - bnxt_en: Wait for FLR to complete during probe + - vlan: skip nested type that is not IFLA_VLAN_QOS_MAPPING + - llc: make llc_ui_sendmsg() more robust against bonding changes + - llc: Drop support for ETH_P_TR_802_2. + - udp: fix busy polling + - net: fix removing a namespace with conflicting altnames + - tun: fix missing dropped counter in tun_xdp_act + - tun: add missing rx stats accounting in tun_xdp_act + - net: micrel: Fix PTP frame parsing for lan8814 + - net/rds: Fix UBSAN: array-index-out-of-bounds in rds_cmsg_recv + - netfs, fscache: Prevent Oops in fscache_put_cache() + - tracing: Ensure visibility when inserting an element into tracing_map + - afs: Hide silly-rename files from userspace + - tcp: Add memory barrier to tcp_push() + - netlink: fix potential sleeping issue in mqueue_flush_file + - ipv6: init the accept_queue's spinlocks in inet6_create + - net/mlx5: DR, Use the right GVMI number for drop action + - net/mlx5: DR, Can't go to uplink vport on RX rule + - net/mlx5: Use mlx5 device constant for selecting CQ period mode for ASO + - net/mlx5e: Allow software parsing when IPsec crypto is enabled + - net/mlx5e: fix a double-free in arfs_create_groups + - net/mlx5e: fix a potential double-free in fs_any_create_groups + - rcu: Defer RCU kthreads wakeup when CPU is dying + - netfilter: nft_limit: reject configurations that cause integer overflow + - netfilter: nf_tables: restrict anonymous set and map names to 16 bytes + - netfilter: nf_tables: validate NFPROTO_* family + - net: stmmac: Wait a bit for the reset to take effect + - net: mvpp2: clear BM pool before initialization + - selftests: netdevsim: fix the udp_tunnel_nic test + - fjes: fix memleaks in fjes_hw_setup + - net: fec: fix the unhandled context fault from smmu + - nbd: always initialize struct msghdr completely + - btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of subvolume + being deleted + - btrfs: ref-verify: free ref cache before clearing mount opt + - btrfs: tree-checker: fix inline ref size in error messages + - btrfs: don't warn if discard range is not aligned to sector + - btrfs: defrag: reject unknown flags of btrfs_ioctl_defrag_range_args + - btrfs: don't abort filesystem when attempting to snapshot deleted subvolume + - rbd: don't move requests to the running list on errors + - exec: Fix error handling in begin_new_exec() + - wifi: iwlwifi: fix a memory corruption + - hv_netvsc: Calculate correct ring size when PAGE_SIZE is not 4 Kbytes + - netfilter: nft_chain_filter: handle NETDEV_UNREGISTER for inet/ingress + basechain + - platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe + - ksmbd: fix global oob in ksmbd_nl_policy + - firmware: arm_scmi: Check mailbox/SMT channel for consistency + - xfs: read only mounts with fsopen mount API are busted + - gpiolib: acpi: Ignore touchpad wakeup on GPD G1619-04 + - cpufreq: intel_pstate: Refine computation of P-state for given frequency + - drm: Don't unref the same fb many times by mistake due to deadlock handling + - drm/bridge: nxp-ptn3460: fix i2c_master_send() error checking + - drm/tidss: Fix atomic_flush check + - drm/bridge: nxp-ptn3460: simplify some error checking + - drm/amd/display: Port DENTIST hang and TDR fixes to OTG disable W/A + - drm/amdgpu/pm: Fix the power source flag error + - erofs: fix lz4 inplace decompression + - media: ov13b10: Enable runtime PM before registering async sub-device + - PM: sleep: Fix possible deadlocks in core system-wide PM code + - thermal: intel: hfi: Refactor enabling code into helper functions + - thermal: intel: hfi: Disable an HFI instance when all its CPUs go offline + - thermal: intel: hfi: Add syscore callbacks for system-wide PM + - fs/pipe: move check to pipe_has_watch_queue() + - pipe: wakeup wr_wait after setting max_usage + - ARM: dts: qcom: sdx55: fix USB wakeup interrupt types + - ARM: dts: samsung: exynos4210-i9100: Unconditionally enable LDO12 + - ARM: dts: qcom: sdx55: fix pdc '#interrupt-cells' + - ARM: dts: qcom: sdx55: fix USB DP/DM HS PHY interrupts + - ARM: dts: qcom: sdx55: fix USB SS wakeup + - dlm: use kernel_connect() and kernel_bind() + - serial: core: Provide port lock wrappers + - serial: sc16is7xx: Use port lock wrappers + - serial: sc16is7xx: fix unconditional activation of THRI interrupt + - btrfs: zoned: factor out prepare_allocation_zoned() + - btrfs: zoned: optimize hint byte for zoned allocator + - drm/panel-edp: drm/panel-edp: Fix AUO B116XAK01 name and timing + - Revert "powerpc/64s: Increase default stack size to 32KB" + - drm/bridge: parade-ps8640: Wait for HPD when doing an AUX transfer + - drm: panel-simple: add missing bus flags for Tianma tm070jvhg[30/33] + - drm/bridge: sii902x: Fix probing race issue + - drm/bridge: sii902x: Fix audio codec unregistration + - drm/bridge: parade-ps8640: Ensure bridge is suspended in .post_disable() + - drm/bridge: parade-ps8640: Make sure we drop the AUX mutex in the error case + - drm/exynos: fix accidental on-stack copy of exynos_drm_plane + - drm/exynos: gsc: minor fix for loop iteration in gsc_runtime_resume + - gpio: eic-sprd: Clear interrupt after set the interrupt type + - drm/bridge: anx7625: Ensure bridge is suspended in disable() + - spi: bcm-qspi: fix SFDP BFPT read by usig mspi read + - spi: fix finalize message on error return + - MIPS: lantiq: register smp_ops on non-smp platforms + - cxl/region:Fix overflow issue in alloc_hpa() + - mips: Call lose_fpu(0) before initializing fcr31 in mips_set_personality_nan + - tick/sched: Preserve number of idle sleeps across CPU hotplug events + - x86/entry/ia32: Ensure s32 is sign extended to s64 + - serial: core: fix kernel-doc for uart_port_unlock_irqrestore() + - docs: sparse: move TW sparse.txt to TW dev-tools + - docs: sparse: add sparse.rst to toctree + - serial: core: Simplify uart_get_rs485_mode() + - serial: core: set missing supported flag for RX during TX GPIO + - soundwire: bus: introduce controller_id + - soundwire: fix initializing sysfs for same devices on different buses + - net: stmmac: Tx coe sw fallback + - net: stmmac: Prevent DSA tags from breaking COE + - dmaengine: idxd: Move dma_free_coherent() out of spinlocked context + - riscv: Fix an off-by-one in get_early_cmdline() + - scsi: core: Kick the requeue list after inserting when flushing + - sh: ecovec24: Rename missed backlight field from fbdev to dev + - smb: client: fix parsing of SMB3.1.1 POSIX create context + - cifs: do not pass cifs_sb when trying to add channels + - cifs: handle cases where a channel is closed + - cifs: reconnect work should have reference on server struct + - cifs: handle when server starts supporting multichannel + - cifs: handle when server stops supporting multichannel + - cifs: reconnect worker should take reference on server struct + unconditionally + - cifs: handle servers that still advertise multichannel after disabling + - cifs: update iface_last_update on each query-and-update + - powerpc/ps3_defconfig: Disable PPC64_BIG_ENDIAN_ELF_ABI_V2 + - crypto: lib/mpi - Fix unexpected pointer access in mpi_ec_init + - mtd: maps: vmu-flash: Fix the (mtd core) switch to ref counters + - mtd: rawnand: Prevent crossing LUN boundaries during sequential reads + - mtd: rawnand: Fix core interference with sequential reads + - mtd: rawnand: Prevent sequential reads with on-die ECC engines + - mtd: rawnand: Clarify conditions to enable continuous reads + - soc: qcom: pmic_glink_altmode: fix port sanity check + - media: ov01a10: Enable runtime PM before registering async sub-device + - soc: fsl: cpm1: tsa: Fix __iomem addresses declaration + - soc: fsl: cpm1: qmc: Fix __iomem addresses declaration + - soc: fsl: cpm1: qmc: Fix rx channel reset + - s390/vfio-ap: reset queues filtered from the guest's AP config + - s390/vfio-ap: reset queues associated with adapter for queue unbound from + driver + - s390/vfio-ap: do not reset queue removed from host config + - ARM: dts: imx6q-apalis: add can power-up delay on ixora board + - arm64: dts: qcom: sc8280xp-crd: fix eDP phy compatible + - arm64: dts: sprd: fix the cpu node for UMS512 + - arm64: dts: rockchip: configure eth pad driver strength for orangepi r1 plus + lts + - arm64: dts: rockchip: Fix rk3588 USB power-domain clocks + - arm64: dts: qcom: msm8916: Make blsp_dma controlled-remotely + - arm64: dts: qcom: msm8939: Make blsp_dma controlled-remotely + - arm64: dts: qcom: sdm670: fix USB wakeup interrupt types + - arm64: dts: qcom: sc8180x: fix USB wakeup interrupt types + - arm64: dts: qcom: Add missing vio-supply for AW2013 + - arm64: dts: qcom: sdm845: fix USB SS wakeup + - arm64: dts: qcom: sm8150: fix USB SS wakeup + - arm64: dts: qcom: sc8180x: fix USB DP/DM HS PHY interrupts + - arm64: dts: qcom: sc8180x: fix USB SS wakeup + - media: i2c: st-mipid02: correct format propagation + - media: mtk-jpeg: Fix timeout schedule error in mtk_jpegdec_worker. + - riscv: mm: Fixup compat mode boot failure + - arm64: errata: Add Cortex-A510 speculative unprivileged load workaround + - [Config] update config for ARM64_ERRATUM_3117295 + - arm64/sme: Always exit sme_alloc() early with existing storage + - arm64: entry: fix ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD + - efi: disable mirror feature during crashkernel + - kexec: do syscore_shutdown() in kernel_kexec + - selftests: mm: hugepage-vmemmap fails on 64K page size systems + - serial: Do not hold the port lock when setting rx-during-tx GPIO + - dt-bindings: net: snps,dwmac: Tx coe unsupported + - bpf: move explored_state() closer to the beginning of verifier.c + - bpf: extract same_callsites() as utility function + - bpf: exact states comparison for iterator convergence checks + - selftests/bpf: tests with delayed read/precision makrs in loop body + - bpf: correct loop detection for iterators convergence + - selftests/bpf: test if state loops are detected in a tricky case + - bpf: print full verifier states on infinite loop detection + - selftests/bpf: track tcp payload offset as scalar in xdp_synproxy + - selftests/bpf: track string payload offset as scalar in strobemeta + - bpf: extract __check_reg_arg() utility function + - bpf: extract setup_func_entry() utility function + - bpf: verify callbacks as if they are called unknown number of times + - selftests/bpf: tests for iterating callbacks + - bpf: widening for callback iterators + - bpf: keep track of max number of bpf_loop callback iterations + - cifs: fix lock ordering while disabling multichannel + - cifs: fix a pending undercount of srv_count + - cifs: after disabling multichannel, mark tcon for reconnect + - selftests: bonding: Increase timeout to 1200s + - bnxt_en: Prevent kernel warning when running offline self test + - selftest: Don't reuse port for SO_INCOMING_CPU test. + - selftests: fill in some missing configs for net + - net/sched: flower: Fix chain template offload + - net/mlx5e: Fix operation precedence bug in port timestamping napi_poll + context + - net/mlx5e: Fix peer flow lists handling + - net/mlx5: Bridge, Enable mcast in smfs steering mode + - net/mlx5: Bridge, fix multicast packets sent to uplink + - net/mlx5e: Ignore IPsec replay window values on sender side + - selftests: net: fix rps_default_mask with >32 CPUs + - bpf: Propagate modified uaddrlen from cgroup sockaddr programs + - bpf: Add bpf_sock_addr_set_sun_path() to allow writing unix sockaddr from + bpf + - ice: work on pre-XDP prog frag count + - i40e: handle multi-buffer packets that are shrunk by xdp prog + - ice: remove redundant xdp_rxq_info registration + - ice: update xdp_rxq_info::frag_size for ZC enabled Rx queue + - i40e: set xdp_rxq_info::frag_size + - selftests: bonding: do not test arp/ns target with mode balance-alb/tlb + - tsnep: Remove FCS for XDP data path + - tsnep: Fix XDP_RING_NEED_WAKEUP for empty fill ring + - btrfs: scrub: avoid use-after-free when chunk length is not 64K aligned + - nfsd: fix RELEASE_LOCKOWNER + - Revert "drivers/firmware: Move sysfb_init() from device_initcall to + subsys_initcall_sync" + - drm/amdgpu: Fix the null pointer when load rlc firmware + - drm: Fix TODO list mentioning non-KMS drivers + - drm: Disable the cursor plane on atomic contexts with virtualized drivers + - drm/virtio: Disable damage clipping if FB changed since last page-flip + - drm: Allow drivers to indicate the damage helpers to ignore damage clips + - drm/amd/display: fix bandwidth validation failure on DCN 2.1 + - drm/amdgpu: correct the cu count for gfx v11 + - drm/amd/display: Align the returned error code with legacy DP + - drm/amd/display: Fix late derefrence 'dsc' check in + 'link_set_dsc_pps_packet()' + - drm/amd/display: Fix uninitialized variable usage in core_link_ 'read_dpcd() + & write_dpcd()' functions + - net/bpf: Avoid unused "sin_addr_len" warning when CONFIG_CGROUP_BPF is not + set + - thermal: core: Store trip pointer in struct thermal_instance + - thermal: gov_power_allocator: avoid inability to reset a cdev + - mm: migrate: record the mlocked page status to remove unnecessary lru drain + - mm: migrate: fix getting incorrect page mapping during page migration + - drm/i915/lnl: Remove watchdog timers for PSR + - drm/i915/psr: Only allow PSR in LPSP mode on HSW non-ULT + - drm/panel-edp: Add AUO B116XTN02, BOE NT116WHM-N21,836X2, NV116WHM-N49 V8.0 + - drm/panel-edp: drm/panel-edp: Fix AUO B116XTN02 name + - drm/amdgpu/gfx10: set UNORD_DISPATCH in compute MQDs + - drm/amdgpu/gfx11: set UNORD_DISPATCH in compute MQDs + - drm/panel: samsung-s6d7aa0: drop DRM_BUS_FLAG_DE_HIGH for lsl080al02 + - memblock: fix crash when reserved memory is not added to memory + - firmware: arm_scmi: Use xa_insert() when saving raw queues + - spi: intel-pci: Remove Meteor Lake-S SoC PCI ID from the list + - cpufreq/amd-pstate: Fix setting scaling max/min freq values + - spi: spi-cadence: Reverse the order of interleaved write and read operations + - cifs: fix stray unlock in cifs_chan_skip_or_disable + - drm: bridge: samsung-dsim: Don't use FORCE_STOP_STATE + - genirq: Initialize resend_node hlist for all interrupt descriptors + - clocksource: Skip watchdog check for large watchdog intervals + - thermal: trip: Drop lockdep assertion from thermal_zone_trip_id() + - platform/x86: intel-uncore-freq: Fix types in sysfs callbacks + - Upstream stable to v6.1.76, v6.6.15 + + * CVE-2024-26582 + - net: tls: fix use-after-free with partial reads and async decrypt + - net: tls: fix returned read length with async decrypt + + * CVE-2024-26584 + - net: tls: handle backlogging of crypto requests + + * CVE-2024-26585 + - tls: fix race between tx work scheduling and socket close + + * CVE-2024-26583 + - tls: extract context alloc/initialization out of tls_set_sw_offload + - net: tls: factor out tls_*crypt_async_wait() + - tls: fix race between async notify and socket close + + * CVE-2023-52600 + - jfs: fix uaf in jfs_evict_inode + + * Fix headphone mic detection issue on ALC897 (LP: #2056418) + - ALSA: hda/realtek - Fix headset Mic no show at resume back for Lenovo ALC897 + platform + + * CVE-2024-26581 + - netfilter: nft_set_rbtree: skip end interval element from gc + + * The screen brightness is unable to adjust on BOE panel DPN#R6FD8 + (LP: #2057430) + - drm/amd/display: Re-add aux intercept disable delay generically for 2+ + LTTPRs + - drm/amd/display: Clear dpcd_sink_ext_caps if not set + - drm/amd/display: Add monitor patch for specific eDP + - drm/amd/display: Add monitor patch for specific eDP + + * Dynamically determine acpi_handle_list size (LP: #2049733) + - ACPI: utils: Dynamically determine acpi_handle_list size + - ACPI: utils: Fix error path in acpi_evaluate_reference() + - ACPI: utils: Fix white space in struct acpi_handle_list definition + + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) + - x86/lib: Fix overflow when counting digits + - x86/mce/inject: Clear test status value + - EDAC/thunderx: Fix possible out-of-bounds string access + - powerpc: add crtsavres.o to always-y instead of extra-y + - powerpc/44x: select I2C for CURRITUCK + - powerpc/pseries/memhp: Fix access beyond end of drmem array + - selftests/powerpc: Fix error handling in FPU/VMX preemption tests + - powerpc/powernv: Add a null pointer check to scom_debug_init_one() + - powerpc/powernv: Add a null pointer check in opal_event_init() + - powerpc/powernv: Add a null pointer check in opal_powercap_init() + - powerpc/imc-pmu: Add a null pointer check in update_events_in_group() + - spi: spi-zynqmp-gqspi: fix driver kconfig dependencies + - mtd: rawnand: Increment IFC_TIMEOUT_MSECS for nand controller response + - ACPI: video: check for error while searching for backlight device parent + - ACPI: LPIT: Avoid u32 multiplication overflow + - platform/x86/intel/vsec: Fix xa_alloc memory leak + - cpufreq: scmi: process the result of devm_of_clk_add_hw_provider() + - calipso: fix memory leak in netlbl_calipso_add_pass() + - efivarfs: force RO when remounting if SetVariable is not supported + - spi: sh-msiof: Enforce fixed DTDL for R-Car H3 + - ACPI: LPSS: Fix the fractional clock divider flags + - ACPI: extlog: Clear Extended Error Log status when RAS_CEC handled the error + - kunit: debugfs: Fix unchecked dereference in debugfs_print_results() + - mtd: Fix gluebi NULL pointer dereference caused by ftl notifier + - selinux: Fix error priority for bind with AF_UNSPEC on PF_INET6 socket + - crypto: virtio - Handle dataq logic with tasklet + - crypto: sa2ul - Return crypto_aead_setkey to transfer the error + - crypto: ccp - fix memleak in ccp_init_dm_workarea + - crypto: af_alg - Disallow multiple in-flight AIO requests + - crypto: safexcel - Add error handling for dma_map_sg() calls + - crypto: sahara - remove FLAGS_NEW_KEY logic + - crypto: sahara - fix cbc selftest failure + - crypto: sahara - fix ahash selftest failure + - crypto: sahara - fix processing requests with cryptlen < sg->length + - crypto: sahara - fix error handling in sahara_hw_descriptor_create() + - crypto: hisilicon/qm - save capability registers in qm init process + - crypto: hisilicon/zip - add zip comp high perf mode configuration + - crypto: hisilicon/qm - add a function to set qm algs + - crypto: hisilicon/hpre - save capability registers in probe process + - crypto: hisilicon/sec2 - save capability registers in probe process + - crypto: hisilicon/zip - save capability registers in probe process + - pstore: ram_core: fix possible overflow in persistent_ram_init_ecc() + - erofs: fix memory leak on short-lived bounced pages + - fs: indicate request originates from old mount API + - gfs2: Fix kernel NULL pointer dereference in gfs2_rgrp_dump + - crypto: virtio - Wait for tasklet to complete on device remove + - crypto: sahara - avoid skcipher fallback code duplication + - crypto: sahara - handle zero-length aes requests + - crypto: sahara - fix ahash reqsize + - crypto: sahara - fix wait_for_completion_timeout() error handling + - crypto: sahara - improve error handling in sahara_sha_process() + - crypto: sahara - fix processing hash requests with req->nbytes < sg->length + - crypto: sahara - do not resize req->src when doing hash operations + - crypto: scomp - fix req->dst buffer overflow + - csky: fix arch_jump_label_transform_static override + - blocklayoutdriver: Fix reference leak of pnfs_device_node + - NFSv4.1/pnfs: Ensure we handle the error NFS4ERR_RETURNCONFLICT + - SUNRPC: fix _xprt_switch_find_current_entry logic + - pNFS: Fix the pnfs block driver's calculation of layoutget size + - wifi: plfxlc: check for allocation failure in plfxlc_usb_wreq_async() + - wifi: rtw88: fix RX filter in FIF_ALLMULTI flag + - bpf, lpm: Fix check prefixlen before walking trie + - bpf: Add crosstask check to __bpf_get_stack + - wifi: ath11k: Defer on rproc_get failure + - wifi: libertas: stop selecting wext + - ARM: dts: qcom: apq8064: correct XOADC register address + - net/ncsi: Fix netlink major/minor version numbers + - firmware: ti_sci: Fix an off-by-one in ti_sci_debugfs_create() + - wifi: rtlwifi: rtl8821ae: phy: fix an undefined bitwise shift behavior + - arm64: dts: ti: k3-am62a-main: Fix GPIO pin count in DT nodes + - arm64: dts: ti: k3-am65-main: Fix DSS irq trigger type + - selftests/bpf: Fix erroneous bitmask operation + - md: synchronize flush io with array reconfiguration + - bpf: enforce precision of R0 on callback return + - ARM: dts: qcom: sdx65: correct SPMI node name + - arm64: dts: qcom: sc7180: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sc7280: Mark some nodes as 'reserved' + - arm64: dts: qcom: sc7280: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sdm845: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm8150: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm8250: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sc8280xp: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm6350: Make watchdog bark interrupt edge triggered + - bpf: add percpu stats for bpf_map elements insertions/deletions + - bpf: Add map and need_defer parameters to .map_fd_put_ptr() + - bpf: Defer the free of inner map when necessary + - selftests/net: specify the interface when do arping + - bpf: fix check for attempt to corrupt spilled pointer + - scsi: fnic: Return error if vmalloc() failed + - arm64: dts: qcom: qrb5165-rb5: correct LED panic indicator + - arm64: dts: qcom: sdm845-db845c: correct LED panic indicator + - arm64: dts: qcom: sm8350: Fix DMA0 address + - arm64: dts: qcom: sc7280: Fix up GPU SIDs + - arm64: dts: qcom: sc7280: Mark Adreno SMMU as DMA coherent + - arm64: dts: qcom: sc7280: fix usb_2 wakeup interrupt types + - wifi: mt76: mt7921s: fix workqueue problem causes STA association fail + - bpf: Fix verification of indirect var-off stack access + - arm64: dts: hisilicon: hikey970-pmic: fix regulator cells properties + - dt-bindings: media: mediatek: mdp3: correct RDMA and WROT node with generic + names + - arm64: dts: mediatek: mt8183: correct MDP3 DMA-related nodes + - wifi: mt76: mt7921: fix country count limitation for CLC + - selftests/bpf: Relax time_tai test for equal timestamps in tai_forward + - block: Set memalloc_noio to false on device_add_disk() error path + - arm64: dts: renesas: white-hawk-cpu: Fix missing serial console pin control + - arm64: dts: imx8mm: Reduce GPU to nominal speed + - scsi: hisi_sas: Replace with standard error code return value + - scsi: hisi_sas: Correct the number of global debugfs registers + - ARM: dts: stm32: don't mix SCMI and non-SCMI board compatibles + - selftests/net: fix grep checking for fib_nexthop_multiprefix + - ipmr: support IP_PKTINFO on cache report IGMP msg + - virtio/vsock: fix logic which reduces credit update messages + - dma-mapping: clear dev->dma_mem to NULL after freeing it + - soc: qcom: llcc: Fix dis_cap_alloc and retain_on_pc configuration + - arm64: dts: qcom: sm8150-hdk: fix SS USB regulators + - block: add check of 'minors' and 'first_minor' in device_add_disk() + - arm64: dts: qcom: sc7280: Mark SDHCI hosts as cache-coherent + - arm64: dts: qcom: ipq6018: fix clock rates for GCC_USB0_MOCK_UTMI_CLK + - wifi: rtlwifi: add calculate_bit_shift() + - wifi: rtlwifi: rtl8188ee: phy: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192c: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192cu: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ce: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192de: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ee: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192se: using calculate_bit_shift() + - wifi: iwlwifi: mvm: set siso/mimo chains to 1 in FW SMPS request + - wifi: iwlwifi: mvm: send TX path flush in rfkill + - netfilter: nf_tables: mark newset as dead on transaction abort + - Bluetooth: Fix bogus check for re-auth no supported with non-ssp + - Bluetooth: btmtkuart: fix recv_buf() return value + - null_blk: don't cap max_hw_sectors to BLK_DEF_MAX_SECTORS + - bpf: sockmap, fix proto update hook to avoid dup calls + - sctp: support MSG_ERRQUEUE flag in recvmsg() + - sctp: fix busy polling + - net/sched: act_ct: fix skb leak and crash on ooo frags + - mlxbf_gige: Fix intermittent no ip issue + - mlxbf_gige: Enable the GigE port in mlxbf_gige_open + - ip6_tunnel: fix NEXTHDR_FRAGMENT handling in ip6_tnl_parse_tlv_enc_lim() + - ARM: davinci: always select CONFIG_CPU_ARM926T + - Revert "drm/tidss: Annotate dma-fence critical section in commit path" + - Revert "drm/omapdrm: Annotate dma-fence critical section in commit path" + - drm/panfrost: Really power off GPU cores in panfrost_gpu_power_off() + - RDMA/usnic: Silence uninitialized symbol smatch warnings + - RDMA/hns: Fix inappropriate err code for unsupported operations + - drm/panel-elida-kd35t133: hold panel in reset for unprepare + - drm/nouveau/fence:: fix warning directly dereferencing a rcu pointer + - drm/bridge: tpd12s015: Drop buggy __exit annotation for remove function + - drm/tilcdc: Fix irq free on unload + - media: pvrusb2: fix use after free on context disconnection + - media: mtk-jpeg: Remove cancel worker in mtk_jpeg_remove to avoid the crash + of multi-core JPEG devices + - media: verisilicon: Hook the (TRY_)DECODER_CMD stateless ioctls + - media: rkvdec: Hook the (TRY_)DECODER_CMD stateless ioctls + - drm/bridge: Fix typo in post_disable() description + - f2fs: fix to avoid dirent corruption + - drm/radeon/r600_cs: Fix possible int overflows in r600_cs_check_reg() + - drm/radeon/r100: Fix integer overflow issues in r100_cs_track_check() + - drm/radeon: check return value of radeon_ring_lock() + - drm/tidss: Move reset to the end of dispc_init() + - drm/tidss: Return error value from from softreset + - drm/tidss: Check for K2G in in dispc_softreset() + - drm/tidss: Fix dss reset + - ASoC: cs35l33: Fix GPIO name and drop legacy include + - ASoC: cs35l34: Fix GPIO name and drop legacy include + - drm/msm/mdp4: flush vblank event on disable + - drm/msm/dsi: Use pm_runtime_resume_and_get to prevent refcnt leaks + - drm/drv: propagate errors from drm_modeset_register_all() + - ASoC: Intel: glk_rt5682_max98357a: fix board id mismatch + - drm/panfrost: Ignore core_mask for poweroff and disable PWRTRANS irq + - drm/radeon: check the alloc_workqueue return value in radeon_crtc_init() + - drm/radeon/dpm: fix a memleak in sumo_parse_power_table + - drm/radeon/trinity_dpm: fix a memleak in trinity_parse_power_table + - drm/bridge: cdns-mhdp8546: Fix use of uninitialized variable + - drm/bridge: tc358767: Fix return value on error case + - media: cx231xx: fix a memleak in cx231xx_init_isoc + - RDMA/hns: Fix memory leak in free_mr_init() + - clk: qcom: gpucc-sm8150: Update the gpu_cc_pll1 config + - media: imx-mipi-csis: Fix clock handling in remove() + - media: dt-bindings: media: rkisp1: Fix the port description for the parallel + interface + - media: rkisp1: Fix media device memory leak + - drm/panel: st7701: Fix AVCL calculation + - f2fs: fix to wait on block writeback for post_read case + - f2fs: fix to check compress file in f2fs_move_file_range() + - f2fs: fix to update iostat correctly in f2fs_filemap_fault() + - media: dvbdev: drop refcount on error path in dvb_device_open() + - media: dvb-frontends: m88ds3103: Fix a memory leak in an error handling path + of m88ds3103_probe() + - clk: renesas: rzg2l-cpg: Reuse code in rzg2l_cpg_reset() + - clk: renesas: rzg2l: Check reset monitor registers + - drm/msm/dpu: Set input_sel bit for INTF + - drm/msm/dpu: Drop enable and frame_count parameters from dpu_hw_setup_misr() + - drm/mediatek: Return error if MDP RDMA failed to enable the clock + - drm/mediatek: Fix underrun in VDO1 when switches off the layer + - drm/amdgpu/debugfs: fix error code when smc register accessors are NULL + - drm/amd/pm: fix a double-free in si_dpm_init + - drivers/amd/pm: fix a use-after-free in kv_parse_power_table + - gpu/drm/radeon: fix two memleaks in radeon_vm_init + - drm/amd/pm: fix a double-free in amdgpu_parse_extended_power_table + - f2fs: fix to check return value of f2fs_recover_xattr_data + - dt-bindings: clock: Update the videocc resets for sm8150 + - clk: qcom: videocc-sm8150: Update the videocc resets + - clk: qcom: videocc-sm8150: Add missing PLL config property + - drivers: clk: zynqmp: calculate closest mux rate + - drivers: clk: zynqmp: update divider round rate logic + - watchdog: set cdev owner before adding + - watchdog/hpwdt: Only claim UNKNOWN NMI if from iLO + - watchdog: bcm2835_wdt: Fix WDIOC_SETTIMEOUT handling + - watchdog: rti_wdt: Drop runtime pm reference count when watchdog is unused + - clk: si5341: fix an error code problem in si5341_output_clk_set_rate + - drm/mediatek: dp: Add phy_mtk_dp module as pre-dependency + - clk: fixed-rate: fix clk_hw_register_fixed_rate_with_accuracy_parent_hw + - pwm: stm32: Use hweight32 in stm32_pwm_detect_channels + - pwm: stm32: Fix enable count for clk in .probe() + - ASoC: rt5645: Drop double EF20 entry from dmi_platform_data[] + - ALSA: scarlett2: Add missing error check to scarlett2_config_save() + - ALSA: scarlett2: Add missing error check to scarlett2_usb_set_config() + - ALSA: scarlett2: Allow passing any output to line_out_remap() + - ALSA: scarlett2: Add missing error checks to *_ctl_get() + - ALSA: scarlett2: Add clamp() in scarlett2_mixer_ctl_put() + - mmc: sdhci_am654: Fix TI SoC dependencies + - [Config] updateconfigs for CONFIG_MMC_SDHCI_AM654 + - mmc: sdhci_omap: Fix TI SoC dependencies + - [Config] update config for MMC_SDHCI_OMAP changes + - IB/iser: Prevent invalidating wrong MR + - drm/amdkfd: Confirm list is non-empty before utilizing list_first_entry in + kfd_topology.c + - drm/amd/pm/smu7: fix a memleak in smu7_hwmgr_backend_init + - kselftest/alsa - mixer-test: fix the number of parameters to + ksft_exit_fail_msg() + - kselftest/alsa - mixer-test: Fix the print format specifier warning + - ksmbd: validate the zero field of packet header + - of: Fix double free in of_parse_phandle_with_args_map + - fbdev: imxfb: fix left margin setting + - of: unittest: Fix of_count_phandle_with_args() expected value message + - selftests/bpf: Add assert for user stacks in test_task_stack + - keys, dns: Fix size check of V1 server-list header + - binder: fix async space check for 0-sized buffers + - binder: fix unused alloc->free_async_space + - mips/smp: Call rcutree_report_cpu_starting() earlier + - Input: atkbd - use ab83 as id when skipping the getid command + - binder: fix race between mmput() and do_exit() + - clocksource/drivers/timer-ti-dm: Fix make W=n kerneldoc warnings + - powerpc/64s: Increase default stack size to 32KB + - tick-sched: Fix idle and iowait sleeptime accounting vs CPU hotplug + - usb: phy: mxs: remove CONFIG_USB_OTG condition for mxs_phy_is_otg_host() + - usb: dwc: ep0: Update request status in dwc3_ep0_stall_restart + - Revert "usb: dwc3: Soft reset phy on probe for host" + - Revert "usb: dwc3: don't reset device side if dwc3 was configured as host- + only" + - usb: chipidea: wait controller resume finished for wakeup irq + - usb: cdns3: fix uvc failure work since sg support enabled + - usb: cdns3: fix iso transfer error when mult is not zero + - usb: cdns3: Fix uvc fail when DMA cross 4k boundery since sg enabled + - usb: typec: class: fix typec_altmode_put_partner to put plugs + - usb: mon: Fix atomicity violation in mon_bin_vma_fault + - serial: core: fix sanitizing check for RTS settings + - serial: core: make sure RS485 cannot be enabled when it is not supported + - serial: 8250_bcm2835aux: Restore clock error handling + - serial: core, imx: do not set RS485 enabled if it is not supported + - serial: imx: Ensure that imx_uart_rs485_config() is called with enabled + clock + - serial: 8250_exar: Set missing rs485_supported flag + - serial: omap: do not override settings for RS485 support + - ALSA: oxygen: Fix right channel of capture volume mixer + - ALSA: hda/relatek: Enable Mute LED on HP Laptop 15s-fq2xxx + - ALSA: hda/realtek: Enable mute/micmute LEDs and limit mic boost on HP ZBook + - ksmbd: validate mech token in session setup + - ksmbd: fix UAF issue in ksmbd_tcp_new_connection() + - ksmbd: only v2 leases handle the directory + - io_uring/rw: ensure io->bytes_done is always initialized + - fbdev: flush deferred work in fb_deferred_io_fsync() + - fbdev: flush deferred IO before closing + - scsi: ufs: core: Simplify power management during async scan + - scsi: target: core: add missing file_{start,end}_write() + - drm/amd: Enable PCIe PME from D3 + - block: add check that partition length needs to be aligned with block size + - block: Fix iterating over an empty bio with bio_for_each_folio_all + - pwm: jz4740: Don't use dev_err_probe() in .request() + - md/raid1: Use blk_opf_t for read and write operations + - rootfs: Fix support for rootfstype= when root= is given + - Bluetooth: Fix atomicity violation in {min,max}_key_size_set + - LoongArch: Fix and simplify fcsr initialization on execve() + - iommu/arm-smmu-qcom: Add missing GMU entry to match table + - iommu/dma: Trace bounce buffer usage when mapping buffers + - wifi: mt76: fix broken precal loading from MTD for mt7915 + - wifi: rtlwifi: Remove bogus and dangerous ASPM disable/enable code + - wifi: rtlwifi: Convert LNKCTL change to PCIe cap RMW accessors + - wifi: mwifiex: configure BSSID consistently when starting AP + - Revert "net: rtnetlink: Enslave device before bringing it up" + - cxl/port: Fix decoder initialization when nr_targets > interleave_ways + - PCI/P2PDMA: Remove reference to pci_p2pdma_map_sg() + - PCI: dwc: endpoint: Fix dw_pcie_ep_raise_msix_irq() alignment support + - PCI: mediatek: Clear interrupt status before dispatching handler + - x86/kvm: Do not try to disable kvmclock if it was not enabled + - KVM: arm64: vgic-v4: Restore pending state on host userspace write + - KVM: arm64: vgic-its: Avoid potential UAF in LPI translation cache + - iio: adc: ad7091r: Pass iio_dev to event handler + - HID: wacom: Correct behavior when processing some confidence == false + touches + - serial: sc16is7xx: add check for unsupported SPI modes during probe + - serial: sc16is7xx: set safe default SPI clock frequency + - ARM: 9330/1: davinci: also select PINCTRL + - mfd: syscon: Fix null pointer dereference in of_syscon_register() + - leds: aw2013: Select missing dependency REGMAP_I2C + - mfd: intel-lpss: Fix the fractional clock divider flags + - mips: dmi: Fix early remap on MIPS32 + - mips: Fix incorrect max_low_pfn adjustment + - riscv: Check if the code to patch lies in the exit section + - riscv: Fix module_alloc() that did not reset the linear mapping permissions + - riscv: Fix set_memory_XX() and set_direct_map_XX() by splitting huge linear + mappings + - riscv: Fix set_direct_map_default_noflush() to reset _PAGE_EXEC + - riscv: Fixed wrong register in XIP_FIXUP_FLASH_OFFSET macro + - MIPS: Alchemy: Fix an out-of-bound access in db1200_dev_setup() + - MIPS: Alchemy: Fix an out-of-bound access in db1550_dev_setup() + - power: supply: cw2015: correct time_to_empty units in sysfs + - power: supply: bq256xx: fix some problem in bq256xx_hw_init + - serial: 8250: omap: Don't skip resource freeing if + pm_runtime_resume_and_get() failed + - libapi: Add missing linux/types.h header to get the __u64 type on io.h + - base/node.c: initialize the accessor list before registering + - acpi: property: Let args be NULL in __acpi_node_get_property_reference + - software node: Let args be NULL in software_node_get_reference_args + - serial: imx: fix tx statemachine deadlock + - selftests/sgx: Fix uninitialized pointer dereference in error path + - selftests/sgx: Fix uninitialized pointer dereferences in encl_get_entry + - selftests/sgx: Include memory clobber for inline asm in test enclave + - selftests/sgx: Skip non X86_64 platform + - iio: adc: ad9467: fix reset gpio handling + - iio: adc: ad9467: don't ignore error codes + - iio: adc: ad9467: fix scale setting + - perf header: Fix one memory leakage in perf_event__fprintf_event_update() + - perf hisi-ptt: Fix one memory leakage in hisi_ptt_process_auxtrace_event() + - perf genelf: Set ELF program header addresses properly + - tty: change tty_write_lock()'s ndelay parameter to bool + - tty: early return from send_break() on TTY_DRIVER_HARDWARE_BREAK + - tty: don't check for signal_pending() in send_break() + - tty: use 'if' in send_break() instead of 'goto' + - usb: cdc-acm: return correct error code on unsupported break + - spmi: mtk-pmif: Serialize PMIF status check and command submission + - vdpa: Fix an error handling path in eni_vdpa_probe() + - nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length + - nvmet-tcp: fix a crash in nvmet_req_complete() + - perf env: Avoid recursively taking env->bpf_progs.lock + - cxl/region: fix x9 interleave typo + - apparmor: avoid crash when parsed profile name is empty + - usb: xhci-mtk: fix a short packet issue of gen1 isoc-in transfer + - serial: imx: Correct clock error message in function probe() + - nvmet: re-fix tracing strncpy() warning + - nvme: trace: avoid memcpy overflow warning + - nvmet-tcp: Fix the H2C expected PDU len calculation + - PCI: keystone: Fix race condition when initializing PHYs + - PCI: mediatek-gen3: Fix translation window size calculation + - ASoC: mediatek: sof-common: Add NULL check for normal_link string + - s390/pci: fix max size calculation in zpci_memcpy_toio() + - net: ethernet: ti: am65-cpsw: Fix max mtu to fit ethernet frames + - amt: do not use overwrapped cb area + - net: phy: micrel: populate .soft_reset for KSZ9131 + - mptcp: mptcp_parse_option() fix for MPTCPOPT_MP_JOIN + - mptcp: strict validation before using mp_opt->hmac + - mptcp: use OPTION_MPTCP_MPJ_SYNACK in subflow_finish_connect() + - mptcp: use OPTION_MPTCP_MPJ_SYN in subflow_check_req() + - mptcp: refine opt_mp_capable determination + - block: ensure we hold a queue reference when using queue limits + - udp: annotate data-races around up->pending + - net: ravb: Fix dma_addr_t truncation in error case + - dt-bindings: gpio: xilinx: Fix node address in gpio + - drm/amdkfd: fixes for HMM mem allocation + - net: stmmac: ethtool: Fixed calltrace caused by unbalanced disable_irq_wake + calls + - net: dsa: vsc73xx: Add null pointer check to vsc73xx_gpio_probe + - LoongArch: BPF: Prevent out-of-bounds memory access + - mptcp: relax check on MPC passive fallback + - netfilter: nf_tables: reject invalid set policy + - netfilter: nft_limit: do not ignore unsupported flags + - netfilter: nfnetlink_log: use proper helper for fetching physinif + - netfilter: nf_queue: remove excess nf_bridge variable + - netfilter: propagate net to nf_bridge_get_physindev + - netfilter: bridge: replace physindev with physinif in nf_bridge_info + - netfilter: nf_tables: do not allow mismatch field size and set key length + - netfilter: nf_tables: skip dead set elements in netlink dump + - netfilter: nf_tables: reject NFT_SET_CONCAT with not field length + description + - ipvs: avoid stat macros calls from preemptible context + - kdb: Fix a potential buffer overflow in kdb_local() + - ethtool: netlink: Add missing ethnl_ops_begin/complete + - loop: fix the the direct I/O support check when used on top of block devices + - mlxsw: spectrum_acl_erp: Fix error flow of pool allocation failure + - selftests: mlxsw: qos_pfc: Adjust the test to support 8 lanes + - ipv6: mcast: fix data-race in ipv6_mc_down / mld_ifc_work + - i2c: s3c24xx: fix read transfers in polling mode + - i2c: s3c24xx: fix transferring more than one message in polling mode + - riscv: Fix wrong usage of lm_alias() when splitting a huge linear mapping + - arm64: dts: armada-3720-turris-mox: set irq type for RTC + - x86: Fix CPUIDLE_FLAG_IRQ_ENABLE leaking timer reprogram + - drivers/perf: hisi: Fix some event id for HiSilicon UC pmu + - KVM: PPC: Book3S HV: Use accessors for VCPU registers + - KVM: PPC: Book3S HV: Introduce low level MSR accessor + - KVM: PPC: Book3S HV: Handle pending exceptions on guest entry with MSR_EE + - powerpc/rtas: Avoid warning on invalid token argument to sys_rtas() + - perf/x86/intel/uncore: Fix NULL pointer dereference issue in + upi_fill_topology() + - efivarfs: Free s_fs_info on unmount + - thermal: core: Fix NULL pointer dereference in zone registration error path + - cpuidle: haltpoll: Do not enable interrupts when entering idle + - crypto: rsa - add a check for allocation failure + - crypto: jh7110 - Correct deferred probe return + - NFS: Use parent's objective cred in nfs_access_login_time() + - asm-generic: Fix 32 bit __generic_cmpxchg_local + - arm64: dts: qcom: qrb4210-rb2: don't force usb peripheral mode + - arm64: dts: qcom: sc8280xp-x13s: Use the correct DP PHY compatible + - arm64: dts: qcom: sc8280xp-x13s: add missing camera LED pin config + - scsi: bfa: Use the proper data type for BLIST flags + - arm64: dts: ti: iot2050: Re-add aliases + - wifi: rtw88: sdio: Honor the host max_req_size in the RX path + - ARM: dts: qcom: sdx65: correct PCIe EP phy-names + - dt-bindings: arm: qcom: Fix html link + - arm64: dts: qcom: sc8180x-primus: Fix HALL_INT polarity + - arm64: dts: qcom: sm8450: correct TX Soundwire clock + - arm64: dts: qcom: sm8550: correct TX Soundwire clock + - arm64: dts: qcom: sa8775p: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm6125: add interrupts to DWC3 USB controller + - arm64: dts: qcom: sa8775p: fix USB wakeup interrupt types + - arm64: dts: qcom: sm8550: fix USB wakeup interrupt types + - wifi: mt76: mt7915: fallback to non-wed mode if platform_get_resource fails + in mt7915_mmio_wed_init() + - wifi: mt76: mt7996: fix the size of struct bss_rate_tlv + - wifi: mt76: mt7996: fix rate usage of inband discovery frames + - bpf: Guard stack limits against 32bit overflow + - bpf: Fix accesses to uninit stack slots + - arm64: dts: mediatek: mt8195: revise VDOSYS RDMA node name + - arm64: dts: mediatek: mt8186: Fix alias prefix for ovl_2l0 + - arm64: dts: mediatek: mt8186: fix address warning for ADSP mailboxes + - wifi: iwlwifi: don't support triggered EHT CQI feedback + - arm64: dts: xilinx: Apply overlays to base dtbs + - scsi: ufs: qcom: Fix the return value of ufs_qcom_ice_program_key() + - scsi: ufs: qcom: Fix the return value when platform_get_resource_byname() + fails + - scsi: hisi_sas: Check before using pointer variables + - bpf: Fix a race condition between btf_put() and map_free() + - virtio/vsock: send credit update during setting SO_RCVLOWAT + - bpf: Limit the number of uprobes when attaching program to multiple uprobes + - bpf: Limit the number of kprobes when attaching program to multiple kprobes + - arm64: dts: qcom: acer-aspire1: Correct audio codec definition + - arm64: dts: qcom: sm6375: fix USB wakeup interrupt types + - arm64: dts: qcom: sm6375: Hook up MPM + - arm64: dts: qcom: sm8150: make dispcc cast minimal vote on MMCX + - soc: qcom: llcc: Fix LLCC_TRP_ATTR2_CFGn offset + - arm64: dts: qcom: sm8550: Separate out X3 idle state + - arm64: dts: qcom: sm8550: Update idle state time requirements + - arm64: dts: qcom: sc8180x: Mark PCIe hosts cache-coherent + - arm64: dts: qcom: sc8180x: switch PCIe QMP PHY to new style of bindings + - arm64: dts: qcom: sc8180x: Fix up PCIe nodes + - wifi: iwlwifi: fix out of bound copy_from_user + - wifi: iwlwifi: assign phy_ctxt before eSR activation + - netfilter: nf_tables: validate chain type update if available + - Bluetooth: btnxpuart: fix recv_buf() return value + - arm64: dts: rockchip: Fix led pinctrl of lubancat 1 + - wifi: cfg80211: correct comment about MLD ID + - wifi: cfg80211: parse all ML elements in an ML probe response + - blk-cgroup: fix rcu lockdep warning in blkg_lookup() + - rxrpc: Fix skbuff cleanup of call's recvmsg_queue and rx_oos_queue + - drm/dp_mst: Fix fractional DSC bpp handling + - drm/panel: nv3051d: Hold panel in reset for unprepare + - media: visl: Hook the (TRY_)DECODER_CMD stateless ioctls + - media: amphion: Fix VPU core alias name + - drm/imx/lcdc: Fix double-free of driver data + - drm/msm/dpu: Add missing safe_lut_tbl in sc8180x catalog + - ASoC: Intel: sof_sdw_rt_sdca_jack_common: ctx->headset_codec_dev = NULL + - ASoC: SOF: topology: Use partial match for disconnecting DAI link and DAI + widget + - drm/msm/dpu: correct clk bit for WB2 block + - clk: sp7021: fix return value check in sp7021_clk_probe() + - clk: rs9: Fix DIF OEn bit placement on 9FGV0241 + - ASoC: tas2781: add support for FW version 0x0503 + - clk: qcom: gcc-sm8550: Add the missing RETAIN_FF_ENABLE GDSC flag + - clk: qcom: gcc-sm8550: Mark the PCIe GDSCs votable + - clk: qcom: gcc-sm8550: use collapse-voting for PCIe GDSCs + - clk: qcom: gcc-sm8550: Mark RCGs shared where applicable + - clk: qcom: dispcc-sm8550: Update disp PLL settings + - drm/amdkfd: Fix type of 'dbg_flags' in 'struct kfd_process' + - gpiolib: make gpio_device_get() and gpio_device_put() public + - gpiolib: provide gpio_device_find() + - gpio: sysfs: drop the mention of gpiochip_find() from sysfs code + - drm/amd/display: avoid stringop-overflow warnings for + dp_decide_lane_settings() + - kselftest/alsa - conf: Stringify the printed errno in sysfs_get() + - class: fix use-after-free in class_register() + - kernfs: convert kernfs_idr_lock to an irq safe raw spinlock + - usb: dwc3: gadget: Handle EP0 request dequeuing properly + - usb: dwc3: gadget: Queue PM runtime idle on disconnect event + - Revert "usb: typec: class: fix typec_altmode_put_partner to put plugs" + - dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: fix path to header + - ceph: select FS_ENCRYPTION_ALGS if FS_ENCRYPTION + - io_uring: don't check iopoll if request completes + - io_uring: ensure local task_work is run on wait timeout + - block: Remove special-casing of compound pages + - wifi: mwifiex: add extra delay for firmware ready + - wifi: mwifiex: fix uninitialized firmware_stat + - Revert "nSVM: Check for reserved encodings of TLB_CONTROL in nested VMCB" + - x86/pci: Reserve ECAM if BIOS didn't include it in PNP0C02 _CRS + - KVM: x86/pmu: Move PMU reset logic to common x86 code + - KVM: x86/pmu: Reset the PMU, i.e. stop counters, before refreshing + - mfd: rk8xx: fixup devices registration with PLATFORM_DEVID_AUTO + - leds: aw200xx: Fix write to DIM parameter + - mfd: tps6594: Add null pointer check to tps6594_device_init() + - srcu: Use try-lock lockdep annotation for NMI-safe access. + - um: virt-pci: fix platform map offset + - PCI: Avoid potential out-of-bounds read in pci_dev_for_each_resource() + - iommu: Map reserved memory as cacheable if device is coherent + - perf test: Remove atomics from test_loop to avoid test failures + - perf header: Fix segfault on build_mem_topology() error path + - perf test record user-regs: Fix mask for vg register + - perf vendor events arm64 AmpereOne: Rename BPU_FLUSH_MEM_FAULT to + GPC_FLUSH_MEM_FAULT + - perf mem: Fix error on hybrid related to availability of mem event in a PMU + - perf stat: Exit perf stat if parse groups fails + - iio: adc: ad9467: add mutex to struct ad9467_state + - perf unwind-libdw: Handle JIT-generated DSOs properly + - perf unwind-libunwind: Fix base address for .eh_frame + - bus: mhi: ep: Do not allocate event ring element on stack + - bus: mhi: ep: Use slab allocator where applicable + - usb: gadget: webcam: Make g_webcam loadable again + - iommu: Don't reserve 0-length IOVA region + - power: supply: Fix null pointer dereference in smb2_probe + - apparmor: Fix ref count leak in task_kill + - perf stat: Fix hard coded LL miss units + - apparmor: fix possible memory leak in unpack_trans_table + - serial: apbuart: fix console prompt on qemu + - perf db-export: Fix missing reference count get in call_path_from_sample() + - cxl/port: Fix missing target list lock + - spi: coldfire-qspi: Remove an erroneous clk_disable_unprepare() from the + remove function + - hisi_acc_vfio_pci: Update migration data pointer correctly on saving/resume + - rxrpc: Fix use of Don't Fragment flag + - octeontx2-af: CN10KB: Fix FIFO length calculation for RPM2 + - net: micrel: Fix PTP frame parsing for lan8841 + - ALSA: hda: Properly setup HDMI stream + - net: add more sanity check in virtio_net_hdr_to_skb() + - net: netdev_queue: netdev_txq_completed_mb(): fix wake condition + - bpf: iter_udp: Retry with a larger batch size without going back to the + previous bucket + - bpf: Avoid iter->offset making backward progress in bpf_iter_udp + - gpio: mlxbf3: add an error code check in mlxbf3_gpio_probe + - ASoC: SOF: ipc4-loader: remove the CPC check warnings + - selftests: bonding: Change script interpreter + - io_uring: adjust defer tw counting + - arm64/ptrace: Don't flush ZA/ZT storage when writing ZA via ptrace + - mlxsw: spectrum_acl_tcam: Fix NULL pointer dereference in error path + - mlxsw: spectrum_acl_tcam: Fix stack corruption + - mlxsw: spectrum_router: Register netdevice notifier before nexthop + - Upstream stable to v6.1.75, v6.6.14 + + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26583 + - net: tls, fix WARNIING in __sk_msg_free + + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26589 + - bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS + + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26591 + - bpf: Fix re-attachment branch in bpf_tracing_prog_attach + + -- Roxana Nicolescu Thu, 28 Mar 2024 15:20:29 +0100 + linux (6.5.0-27.28) mantic; urgency=medium * mantic/linux: 6.5.0-27.28 -proposed tracker (LP: #2055584) diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.master/config/annotations linux-lowlatency-hwe-6.5-6.5.0/debian.master/config/annotations --- linux-lowlatency-hwe-6.5-6.5.0/debian.master/config/annotations +++ linux-lowlatency-hwe-6.5-6.5.0/debian.master/config/annotations @@ -1550,6 +1550,7 @@ CONFIG_ARM64_ERRATUM_2645198 policy<{'arm64': 'y'}> CONFIG_ARM64_ERRATUM_2658417 policy<{'arm64': 'y'}> CONFIG_ARM64_ERRATUM_2966298 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_3117295 policy<{'arm64': 'y'}> CONFIG_ARM64_ERRATUM_819472 policy<{'arm64': 'y'}> CONFIG_ARM64_ERRATUM_824069 policy<{'arm64': 'y'}> CONFIG_ARM64_ERRATUM_826319 policy<{'arm64': 'y'}> @@ -1584,6 +1585,7 @@ CONFIG_ARM64_WORKAROUND_CLEAN_CACHE policy<{'arm64': 'y'}> CONFIG_ARM64_WORKAROUND_REPEAT_TLBI policy<{'arm64': 'y'}> CONFIG_ARM64_WORKAROUND_SPECULATIVE_AT policy<{'arm64': 'y'}> +CONFIG_ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD policy<{'arm64': 'y'}> CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE policy<{'arm64': 'y'}> CONFIG_ARMADA375_USBCLUSTER_PHY policy<{'armhf': 'y'}> CONFIG_ARMADA_370_CLK policy<{'armhf': 'y'}> @@ -7751,7 +7753,7 @@ CONFIG_MFD_SY7636A policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}> CONFIG_MFD_SYSCON policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}> CONFIG_MFD_TC3589X policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}> -CONFIG_MFD_TI_AM335X_TSCADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}> +CONFIG_MFD_TI_AM335X_TSCADC policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-', 's390x': '-'}> CONFIG_MFD_TI_LMU policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}> CONFIG_MFD_TI_LP873X policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}> CONFIG_MFD_TI_LP87565 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> @@ -7929,12 +7931,12 @@ CONFIG_MMC_REALTEK_USB policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_MMC_RICOH_MMC policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}> CONFIG_MMC_SDHCI_ACPI policy<{'amd64': 'm', 'arm64': 'm', 'riscv64': 'm'}> -CONFIG_MMC_SDHCI_AM654 policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> +CONFIG_MMC_SDHCI_AM654 policy<{'arm64': 'm', 'armhf': '-', 'ppc64el': '-', 'riscv64': '-'}> CONFIG_MMC_SDHCI_BIG_ENDIAN_32BIT_BYTE_SWAPPER policy<{'ppc64el': 'y'}> CONFIG_MMC_SDHCI_CADENCE policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_MMC_SDHCI_DOVE policy<{'armhf': 'm'}> CONFIG_MMC_SDHCI_ESDHC_IMX policy<{'arm64': 'm', 'armhf': 'y'}> -CONFIG_MMC_SDHCI_EXTERNAL_DMA policy<{'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}> +CONFIG_MMC_SDHCI_EXTERNAL_DMA policy<{'arm64': '-', 'armhf': 'y', 'ppc64el': '-', 'riscv64': '-'}> CONFIG_MMC_SDHCI_F_SDH30 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_MMC_SDHCI_IO_ACCESSORS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}> CONFIG_MMC_SDHCI_MILBEAUT policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> @@ -7946,7 +7948,7 @@ CONFIG_MMC_SDHCI_OF_ESDHC policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm'}> CONFIG_MMC_SDHCI_OF_HLWD policy<{'ppc64el': 'm'}> CONFIG_MMC_SDHCI_OF_SPARX5 policy<{'arm64': 'm'}> -CONFIG_MMC_SDHCI_OMAP policy<{'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> +CONFIG_MMC_SDHCI_OMAP policy<{'arm64': '-', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-'}> CONFIG_MMC_SDHCI_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_MMC_SDHCI_PXAV3 policy<{'arm64': 'm', 'armhf': 'm'}> CONFIG_MMC_SDHCI_S3C policy<{'armhf': 'n'}> @@ -12916,6 +12918,9 @@ CONFIG_SPEAKUP_SYNTH_SOFT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_SPEAKUP_SYNTH_SPKOUT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_SPEAKUP_SYNTH_TXPRT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> +CONFIG_SPECTRE_BHI_AUTO policy<{'amd64': 'y'}> +CONFIG_SPECTRE_BHI_OFF policy<{'amd64': 'n'}> +CONFIG_SPECTRE_BHI_ON policy<{'amd64': 'n'}> CONFIG_SPECULATION_MITIGATIONS policy<{'amd64': 'y'}> CONFIG_SPI policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'n'}> CONFIG_SPI_ALTERA policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}> @@ -13499,7 +13504,7 @@ CONFIG_TI_ADS7950 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_TI_ADS8344 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_TI_ADS8688 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> -CONFIG_TI_AM335X_ADC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> +CONFIG_TI_AM335X_ADC policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-'}> CONFIG_TI_AM65_CPSW_TAS policy<{'arm64': 'y'}> CONFIG_TI_CPPI41 policy<{'armhf': 'm'}> CONFIG_TI_CPSW policy<{'armhf': 'y'}> @@ -13538,7 +13543,7 @@ CONFIG_TI_SCI_INTR_IRQCHIP policy<{'arm64': 'y'}> CONFIG_TI_SCI_PM_DOMAINS policy<{'arm64': 'm'}> CONFIG_TI_SCI_PROTOCOL policy<{'arm64': 'y'}> -CONFIG_TI_SOC_THERMAL policy<{'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n'}> +CONFIG_TI_SOC_THERMAL policy<{'arm64': '-', 'armhf': 'n', 'ppc64el': '-', 'riscv64': '-'}> CONFIG_TI_ST policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}> CONFIG_TI_SYSC policy<{'armhf': 'y'}> CONFIG_TI_SYSCON_CLK policy<{'arm64': 'y'}> @@ -13644,7 +13649,7 @@ CONFIG_TOUCHSCREEN_SUR40 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_TOUCHSCREEN_SURFACE3_SPI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}> CONFIG_TOUCHSCREEN_SX8654 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}> -CONFIG_TOUCHSCREEN_TI_AM335X_TSC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> +CONFIG_TOUCHSCREEN_TI_AM335X_TSC policy<{'amd64': '-', 'arm64': 'm', 'armhf': 'm', 'ppc64el': '-', 'riscv64': '-'}> CONFIG_TOUCHSCREEN_TOUCHIT213 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}> CONFIG_TOUCHSCREEN_TOUCHRIGHT policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}> CONFIG_TOUCHSCREEN_TOUCHWIN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}> reverted: --- linux-lowlatency-hwe-6.5-6.5.0/debian.master/etc/getabis +++ linux-lowlatency-hwe-6.5-6.5.0.orig/debian.master/etc/getabis @@ -1,19 +0,0 @@ -repo_list=( - "http://archive.ubuntu.com/ubuntu/pool/main/l/linux" - "http://ports.ubuntu.com/ubuntu-ports/pool/main/l/linux" - "http://archive.ubuntu.com/ubuntu/pool/universe/l/linux" - "http://ports.ubuntu.com/ubuntu-ports/pool/universe/l/linux" - "http://ppa.launchpad.net/canonical-kernel-team/ppa/ubuntu/pool/main/l/linux" - "http://ppa.launchpad.net/canonical-kernel-team/unstable/ubuntu/pool/main/l/linux" - "http://ppa.launchpad.net/canonical-kernel-team/bootstrap/ubuntu/pool/main/l/linux" - "http://ppa.launchpad.net/canonical-kernel-team/unstable/ubuntu/pool/main/l/linux-unstable" - "http://ppa.launchpad.net/canonical-kernel-team/bootstrap/ubuntu/pool/main/l/linux-unstable" -) - -package_prefixes linux-buildinfo - -getall armhf generic -getall amd64 generic -getall arm64 generic generic-64k -getall ppc64el generic -getall s390x generic diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.master/reconstruct linux-lowlatency-hwe-6.5-6.5.0/debian.master/reconstruct --- linux-lowlatency-hwe-6.5-6.5.0/debian.master/reconstruct +++ linux-lowlatency-hwe-6.5-6.5.0/debian.master/reconstruct @@ -15,10 +15,8 @@ chmod +x 'debian/scripts/misc/annotations' chmod +x 'debian/scripts/misc/arch-has-odm-enabled.sh' chmod +x 'debian/scripts/misc/find-missing-sauce.sh' -chmod +x 'debian/scripts/misc/fips-checks' chmod +x 'debian/scripts/misc/fw-to-ihex.sh' chmod +x 'debian/scripts/misc/gen-auto-reconstruct' -chmod +x 'debian/scripts/misc/getabis' chmod +x 'debian/scripts/misc/git-ubuntu-log' chmod +x 'debian/scripts/misc/insert-changes' chmod +x 'debian/scripts/misc/insert-mainline-changes' @@ -48,6 +46,13 @@ chmod +x 'tools/testing/selftests/netfilter/xt_string.sh' # Remove any files deleted from the orig. rm -f 'Documentation/networking/device_drivers/ethernet/mellanox/mlx5/devlink.rst' +rm -f 'Documentation/translations/zh_TW/sparse.txt' +rm -f 'arch/arm/boot/dts/qcom/qcom-pm8226.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pm8841.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pm8941.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pma8084.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pmx55.dtsi' +rm -f 'arch/arm/boot/dts/qcom/qcom-pmx65.dtsi' rm -f 'arch/parisc/include/asm/mckinley.h' rm -f 'drivers/media/pci/intel/ipu3/cio2-bridge.c' rm -f 'drivers/media/pci/intel/ipu3/cio2-bridge.h' diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.master/tracking-bug linux-lowlatency-hwe-6.5-6.5.0/debian.master/tracking-bug --- linux-lowlatency-hwe-6.5-6.5.0/debian.master/tracking-bug +++ linux-lowlatency-hwe-6.5-6.5.0/debian.master/tracking-bug @@ -1 +1 @@ -2055584 2024.03.04-1 +2061443 2024.04.01-3 diff -u linux-lowlatency-hwe-6.5-6.5.0/debian.master/upstream-stable linux-lowlatency-hwe-6.5-6.5.0/debian.master/upstream-stable --- linux-lowlatency-hwe-6.5-6.5.0/debian.master/upstream-stable +++ linux-lowlatency-hwe-6.5-6.5.0/debian.master/upstream-stable @@ -3,3 +3,3 @@ - linux-6.1.y = v6.1.74 + linux-6.1.y = v6.1.77 linux-6.5.y = v6.5.13 - linux-6.6.y = v6.6.13 + linux-6.6.y = v6.6.16 diff -u linux-lowlatency-hwe-6.5-6.5.0/debian/changelog linux-lowlatency-hwe-6.5-6.5.0/debian/changelog --- linux-lowlatency-hwe-6.5-6.5.0/debian/changelog +++ linux-lowlatency-hwe-6.5-6.5.0/debian/changelog @@ -1,3 +1,1328 @@ +linux-lowlatency-hwe-6.5 (6.5.0-34.34.1~22.04.1) jammy; urgency=medium + + * jammy/linux-lowlatency-hwe-6.5: 6.5.0-34.34.1~22.04.1 -proposed tracker + (LP: #2059429) + + [ Ubuntu: 6.5.0-34.34.1 ] + + * mantic/linux-lowlatency: 6.5.0-34.34.1 -proposed tracker (LP: #2059430) + * mantic/linux: 6.5.0-34.34 -proposed tracker (LP: #2061443) + * CVE-2024-2201 + - x86/bugs: Change commas to semicolons in 'spectre_v2' sysfs file + - x86/syscall: Don't force use of indirect calls for system calls + - x86/bhi: Add support for clearing branch history at syscall entry + - x86/bhi: Define SPEC_CTRL_BHI_DIS_S + - x86/bhi: Enumerate Branch History Injection (BHI) bug + - x86/bhi: Add BHI mitigation knob + - x86/bhi: Mitigate KVM by default + - KVM: x86: Add BHI_NO + - [Config] Set CONFIG_BHI to enabled (auto) + * mantic/linux: 6.5.0-33.33 -proposed tracker (LP: #2060448) + * [Mantic] Compile broken on armhf (cc1 out of memory) (LP: #2060446) + - Revert "minmax: relax check to allow comparison between unsigned arguments + and signed constants" + - Revert "minmax: allow comparisons of 'int' against 'unsigned char/short'" + - Revert "minmax: allow min()/max()/clamp() if the arguments have the same + signedness." + - Revert "minmax: add umin(a, b) and umax(a, b)" + * mantic/linux: 6.5.0-32.32 -proposed tracker (LP: #2059443) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * Drop fips-checks script from trees (LP: #2055083) + - [Packaging] Remove fips-checks script + * alsa/realtek: adjust max output valume for headphone on 2 LG machines + (LP: #2058573) + - ALSA: hda/realtek: fix the hp playback volume issue for LG machines + * Remove getabis scripts (LP: #2059143) + - [Packaging] Remove getabis + * Mantic update: upstream stable patchset 2024-03-27 (LP: #2059284) + - asm-generic: make sparse happy with odd-sized put_unaligned_*() + - powerpc/mm: Fix null-pointer dereference in pgtable_cache_add + - arm64: irq: set the correct node for VMAP stack + - drivers/perf: pmuv3: don't expose SW_INCR event in sysfs + - powerpc: Fix build error due to is_valid_bugaddr() + - powerpc/mm: Fix build failures due to arch_reserved_kernel_pages() + - powerpc/64s: Fix CONFIG_NUMA=n build due to create_section_mapping() + - x86/boot: Ignore NMIs during very early boot + - powerpc: pmd_move_must_withdraw() is only needed for + CONFIG_TRANSPARENT_HUGEPAGE + - powerpc/lib: Validate size for vector operations + - x86/mce: Mark fatal MCE's page as poison to avoid panic in the kdump kernel + - perf/core: Fix narrow startup race when creating the perf nr_addr_filters + sysfs file + - debugobjects: Stop accessing objects after releasing hash bucket lock + - regulator: core: Only increment use_count when enable_count changes + - audit: Send netlink ACK before setting connection in auditd_set + - ACPI: video: Add quirk for the Colorful X15 AT 23 Laptop + - PNP: ACPI: fix fortify warning + - ACPI: extlog: fix NULL pointer dereference check + - ACPI: NUMA: Fix the logic of getting the fake_pxm value + - PM / devfreq: Synchronize devfreq_monitor_[start/stop] + - ACPI: APEI: set memory failure flags as MF_ACTION_REQUIRED on synchronous + events + - FS:JFS:UBSAN:array-index-out-of-bounds in dbAdjTree + - jfs: fix slab-out-of-bounds Read in dtSearch + - jfs: fix array-index-out-of-bounds in dbAdjTree + - pstore/ram: Fix crash when setting number of cpus to an odd number + - crypto: octeontx2 - Fix cptvf driver cleanup + - erofs: fix ztailpacking for subpage compressed blocks + - crypto: stm32/crc32 - fix parsing list of devices + - afs: fix the usage of read_seqbegin_or_lock() in afs_lookup_volume_rcu() + - afs: fix the usage of read_seqbegin_or_lock() in afs_find_server*() + - rxrpc_find_service_conn_rcu: fix the usage of read_seqbegin_or_lock() + - jfs: fix array-index-out-of-bounds in diNewExt + - arch: consolidate arch_irq_work_raise prototypes + - s390/vfio-ap: fix sysfs status attribute for AP queue devices + - s390/ptrace: handle setting of fpc register correctly + - KVM: s390: fix setting of fpc register + - SUNRPC: Fix a suspicious RCU usage warning + - ecryptfs: Reject casefold directory inodes + - ext4: fix inconsistent between segment fstrim and full fstrim + - ext4: unify the type of flexbg_size to unsigned int + - ext4: remove unnecessary check from alloc_flex_gd() + - ext4: avoid online resizing failures due to oversized flex bg + - wifi: rt2x00: restart beacon queue when hardware reset + - selftests/bpf: satisfy compiler by having explicit return in btf test + - selftests/bpf: Fix pyperf180 compilation failure with clang18 + - wifi: rt2x00: correct wrong BBP register in RxDCOC calibration + - selftests/bpf: Fix issues in setup_classid_environment() + - soc: xilinx: Fix for call trace due to the usage of smp_processor_id() + - soc: xilinx: fix unhandled SGI warning message + - scsi: lpfc: Fix possible file string name overflow when updating firmware + - PCI: Add no PM reset quirk for NVIDIA Spectrum devices + - bonding: return -ENOMEM instead of BUG in alb_upper_dev_walk + - net: usb: ax88179_178a: avoid two consecutive device resets + - scsi: arcmsr: Support new PCI device IDs 1883 and 1886 + - ARM: dts: imx7d: Fix coresight funnel ports + - ARM: dts: imx7s: Fix lcdif compatible + - ARM: dts: imx7s: Fix nand-controller #size-cells + - wifi: ath9k: Fix potential array-index-out-of-bounds read in + ath9k_htc_txstatus() + - wifi: ath11k: fix race due to setting ATH11K_FLAG_EXT_IRQ_ENABLED too early + - bpf: Check rcu_read_lock_trace_held() before calling bpf map helpers + - scsi: libfc: Don't schedule abort twice + - scsi: libfc: Fix up timeout error in fc_fcp_rec_error() + - bpf: Set uattr->batch.count as zero before batched update or deletion + - wifi: wfx: fix possible NULL pointer dereference in wfx_set_mfp_ap() + - ARM: dts: rockchip: fix rk3036 hdmi ports node + - ARM: dts: imx25/27-eukrea: Fix RTC node name + - ARM: dts: imx: Use flash@0,0 pattern + - ARM: dts: imx27: Fix sram node + - ARM: dts: imx1: Fix sram node + - net: phy: at803x: fix passing the wrong reference for config_intr + - ionic: pass opcode to devcmd_wait + - ionic: bypass firmware cmds when stuck in reset + - block/rnbd-srv: Check for unlikely string overflow + - ARM: dts: imx25: Fix the iim compatible string + - ARM: dts: imx25/27: Pass timing0 + - ARM: dts: imx27-apf27dev: Fix LED name + - ARM: dts: imx23-sansa: Use preferred i2c-gpios properties + - ARM: dts: imx23/28: Fix the DMA controller node name + - scsi: hisi_sas: Set .phy_attached before notifing phyup event + HISI_PHYE_PHY_UP_PM + - ice: fix ICE_AQ_VSI_Q_OPT_RSS_* register values + - net: atlantic: eliminate double free in error handling logic + - net: dsa: mv88e6xxx: Fix mv88e6352_serdes_get_stats error path + - block: prevent an integer overflow in bvec_try_merge_hw_page + - md: Whenassemble the array, consult the superblock of the freshest device + - arm64: dts: qcom: msm8996: Fix 'in-ports' is a required property + - arm64: dts: qcom: msm8998: Fix 'out-ports' is a required property + - ice: fix pre-shifted bit usage + - arm64: dts: amlogic: fix format for s4 uart node + - wifi: rtl8xxxu: Add additional USB IDs for RTL8192EU devices + - libbpf: Fix NULL pointer dereference in bpf_object__collect_prog_relos + - wifi: rtlwifi: rtl8723{be,ae}: using calculate_bit_shift() + - wifi: cfg80211: free beacon_ies when overridden from hidden BSS + - Bluetooth: qca: Set both WIDEBAND_SPEECH and LE_STATES quirks for QCA2066 + - Bluetooth: hci_sync: fix BR/EDR wakeup bug + - Bluetooth: L2CAP: Fix possible multiple reject send + - net/smc: disable SEID on non-s390 archs where virtual ISM may be used + - bridge: cfm: fix enum typo in br_cc_ccm_tx_parse + - i40e: Fix VF disable behavior to block all traffic + - octeontx2-af: Fix max NPC MCAM entry check while validating ref_entry + - net: dsa: qca8k: put MDIO bus OF node on qca8k_mdio_register() failure + - f2fs: fix to check return value of f2fs_reserve_new_block() + - ALSA: hda: Refer to correct stream index at loops + - ASoC: doc: Fix undefined SND_SOC_DAPM_NOPM argument + - fast_dput(): handle underflows gracefully + - RDMA/IPoIB: Fix error code return in ipoib_mcast_join + - drm/panel-edp: Add override_edid_mode quirk for generic edp + - drm/bridge: anx7625: Fix Set HPD irq detect window to 2ms + - drm/amd/display: Fix tiled display misalignment + - f2fs: fix write pointers on zoned device after roll forward + - drm/drm_file: fix use of uninitialized variable + - drm/framebuffer: Fix use of uninitialized variable + - drm/mipi-dsi: Fix detach call without attach + - media: stk1160: Fixed high volume of stk1160_dbg messages + - media: rockchip: rga: fix swizzling for RGB formats + - PCI: add INTEL_HDA_ARL to pci_ids.h + - ALSA: hda: Intel: add HDA_ARL PCI ID support + - media: rkisp1: Fix IRQ handler return values + - media: rkisp1: Store IRQ lines + - media: rkisp1: Fix IRQ disable race issue + - f2fs: fix to tag gcing flag on page during block migration + - drm/exynos: Call drm_atomic_helper_shutdown() at shutdown/unbind time + - IB/ipoib: Fix mcast list locking + - media: amphion: remove mutext lock in condition of wait_event + - media: ddbridge: fix an error code problem in ddb_probe + - media: i2c: imx335: Fix hblank min/max values + - drm/amd/display: For prefetch mode > 0, extend prefetch if possible + - drm/msm/dpu: Ratelimit framedone timeout msgs + - drm/msm/dpu: fix writeback programming for YUV cases + - drm/amdgpu: fix ftrace event amdgpu_bo_move always move on same heap + - clk: hi3620: Fix memory leak in hi3620_mmc_clk_init() + - clk: mmp: pxa168: Fix memory leak in pxa168_clk_init() + - watchdog: it87_wdt: Keep WDTCTRL bit 3 unmodified for IT8784/IT8786 + - drm/amd/display: make flip_timestamp_in_us a 64-bit variable + - clk: imx: clk-imx8qxp: fix LVDS bypass, pixel and phy clocks + - drm/amdgpu: Fix ecc irq enable/disable unpaired + - drm/amdgpu: Let KFD sync with VM fences + - drm/amdgpu: Fix '*fw' from request_firmware() not released in + 'amdgpu_ucode_request()' + - drm/amdgpu: Drop 'fence' check in 'to_amdgpu_amdkfd_fence()' + - drm/amdkfd: Fix iterator used outside loop in 'kfd_add_peer_prop()' + - ALSA: hda/conexant: Fix headset auto detect fail in cx8070 and SN6140 + - leds: trigger: panic: Don't register panic notifier if creating the trigger + failed + - um: Fix naming clash between UML and scheduler + - um: Don't use vfprintf() for os_info() + - um: net: Fix return type of uml_net_start_xmit() + - um: time-travel: fix time corruption + - i3c: master: cdns: Update maximum prescaler value for i2c clock + - xen/gntdev: Fix the abuse of underlying struct page in DMA-buf import + - mfd: ti_am335x_tscadc: Fix TI SoC dependencies + - [Config] updateconfigs for MFD_TI_AM335X_TSCADC + - mailbox: arm_mhuv2: Fix a bug for mhuv2_sender_interrupt + - PCI: Only override AMD USB controller if required + - PCI: switchtec: Fix stdev_release() crash after surprise hot remove + - perf cs-etm: Bump minimum OpenCSD version to ensure a bugfix is present + - usb: hub: Replace hardcoded quirk value with BIT() macro + - usb: hub: Add quirk to decrease IN-ep poll interval for Microchip USB491x + hub + - selftests/sgx: Fix linker script asserts + - tty: allow TIOCSLCKTRMIOS with CAP_CHECKPOINT_RESTORE + - fs/kernfs/dir: obey S_ISGID + - spmi: mediatek: Fix UAF on device remove + - PCI: Fix 64GT/s effective data rate calculation + - PCI/AER: Decode Requester ID when no error info found + - 9p: Fix initialisation of netfs_inode for 9p + - misc: lis3lv02d_i2c: Add missing setting of the reg_ctrl callback + - libsubcmd: Fix memory leak in uniq() + - drm/amdkfd: Fix lock dependency warning + - drm/amdkfd: Fix lock dependency warning with srcu + - virtio_net: Fix "‘%d’ directive writing between 1 and 11 bytes into a region + of size 10" warnings + - blk-mq: fix IO hang from sbitmap wakeup race + - ceph: reinitialize mds feature bit even when session in open + - ceph: fix deadlock or deadcode of misusing dget() + - ceph: fix invalid pointer access if get_quota_realm return ERR_PTR + - drm/amd/powerplay: Fix kzalloc parameter 'ATOM_Tonga_PPM_Table' in + 'get_platform_power_management_table()' + - drm/amdgpu: Fix with right return code '-EIO' in + 'amdgpu_gmc_vram_checking()' + - drm/amdgpu: Release 'adev->pm.fw' before return in + 'amdgpu_device_need_post()' + - drm/amdkfd: Fix 'node' NULL check in 'svm_range_get_range_boundaries()' + - perf: Fix the nr_addr_filters fix + - wifi: cfg80211: fix RCU dereference in __cfg80211_bss_update + - drm: using mul_u32_u32() requires linux/math64.h + - scsi: isci: Fix an error code problem in isci_io_request_build() + - regulator: ti-abb: don't use devm_platform_ioremap_resource_byname for + shared interrupt register + - scsi: core: Move scsi_host_busy() out of host lock for waking up EH handler + - HID: hidraw: fix a problem of memory leak in hidraw_release() + - selftests: net: give more time for GRO aggregation + - ip6_tunnel: make sure to pull inner header in __ip6_tnl_rcv() + - ipmr: fix kernel panic when forwarding mcast packets + - net: lan966x: Fix port configuration when using SGMII interface + - tcp: add sanity checks to rx zerocopy + - ixgbe: Refactor returning internal error codes + - ixgbe: Refactor overtemp event handling + - ixgbe: Fix an error handling path in ixgbe_read_iosf_sb_reg_x550() + - net: dsa: qca8k: fix illegal usage of GPIO + - ipv6: Ensure natural alignment of const ipv6 loopback and router addresses + - llc: call sock_orphan() at release time + - bridge: mcast: fix disabled snooping after long uptime + - selftests: net: add missing config for GENEVE + - netfilter: conntrack: correct window scaling with retransmitted SYN + - netfilter: nf_tables: restrict tunnel object to NFPROTO_NETDEV + - netfilter: nf_log: replace BUG_ON by WARN_ON_ONCE when putting logger + - netfilter: nft_ct: sanitize layer 3 and 4 protocol number in custom + expectations + - net: ipv4: fix a memleak in ip_setup_cork + - af_unix: fix lockdep positive in sk_diag_dump_icons() + - SAUCE: Sync apparmor copy of af_unix.c + - selftests: net: fix available tunnels detection + - net: sysfs: Fix /sys/class/net/ path + - selftests: team: Add missing config options + - selftests: bonding: Check initial state + - arm64: irq: set the correct node for shadow call stack + - mm, kmsan: fix infinite recursion due to RCU critical section + - Revert "drm/amd/display: Disable PSR-SU on Parade 0803 TCON again" + - drm/msm/dsi: Enable runtime PM + - LoongArch/smp: Call rcutree_report_cpu_starting() at tlb_init() + - gve: Fix use-after-free vulnerability + - bonding: remove print in bond_verify_device_path + - ASoC: codecs: lpass-wsa-macro: fix compander volume hack + - ASoC: codecs: wsa883x: fix PA volume control + - drm/amdgpu: Fix missing error code in 'gmc_v6/7/8/9_0_hw_init()' + - Documentation/sphinx: fix Python string escapes + - kunit: tool: fix parsing of test attributes + - thermal: core: Fix thermal zone suspend-resume synchronization + - hwrng: starfive - Fix dev_err_probe return error + - crypto: p10-aes-gcm - Avoid -Wstringop-overflow warnings + - erofs: fix up compacted indexes for block size < 4096 + - crypto: starfive - Fix dev_err_probe return error + - s390/boot: always align vmalloc area on segment boundary + - ext4: treat end of range as exclusive in ext4_zero_range() + - wifi: rtw89: fix timeout calculation in rtw89_roc_end() + - ARM: dts: qcom: strip prefix from PMIC files + - ARM: dts: qcom: mdm9615: fix PMIC node labels + - ARM: dts: qcom: msm8660: fix PMIC node labels + - ARM: dts: samsung: exynos4: fix camera unit addresses/ranges + - ARM: dts: samsung: s5pv210: fix camera unit addresses/ranges + - net: phy: micrel: fix ts_info value in case of no phc + - bpf: Prevent inlining of bpf_fentry_test7() + - bpf: Fix a few selftest failures due to llvm18 change + - wifi: rtw89: fix misbehavior of TX beacon in concurrent mode + - bpf: Set need_defer as false when clearing fd array during map free + - wifi: ath12k: fix and enable AP mode for WCN7850 + - minmax: add umin(a, b) and umax(a, b) + - minmax: allow min()/max()/clamp() if the arguments have the same signedness. + - minmax: allow comparisons of 'int' against 'unsigned char/short' + - minmax: relax check to allow comparison between unsigned arguments and + signed constants + - net: mvmdio: Avoid excessive sleeps in polled mode + - arm64: dts: qcom: sm8550: fix soundwire controllers node name + - arm64: dts: qcom: sm8450: fix soundwire controllers node name + - arm64: dts: qcom: sm8350: Fix remoteproc interrupt type + - wifi: mt76: connac: fix EHT phy mode check + - wifi: mt76: mt7996: add PCI IDs for mt7992 + - wifi: ath12k: fix the issue that the multicast/broadcast indicator is not + read correctly for WCN7850 + - arm64: zynqmp: Move fixed clock to / for kv260 + - arm64: zynqmp: Fix clock node name in kv260 cards + - selftests/bpf: fix compiler warnings in RELEASE=1 mode + - scsi: lpfc: Reinitialize an NPIV's VMID data structures after FDISC + - scsi: lpfc: Move determination of vmid_flag after VMID reinitialization + completes + - arm64: dts: qcom: Fix coresight warnings in in-ports and out-ports + - wifi: rtw89: coex: Fix wrong Wi-Fi role info and FDDT parameter members + - Bluetooth: ISO: Avoid creating child socket if PA sync is terminating + - arm64: dts: sprd: Add clock reference for pll2 on UMS512 + - arm64: dts: sprd: Change UMS512 idle-state nodename to match bindings + - net: kcm: fix direct access to bv_len + - reiserfs: Avoid touching renamed directory if parent does not change + - drm/amd/display: Fix MST PBN/X.Y value calculations + - drm/drm_file: fix use of uninitialized variable + - drm/msm/dp: Add DisplayPort controller for SM8650 + - media: uvcvideo: Fix power line control for a Chicony camera + - media: uvcvideo: Fix power line control for SunplusIT camera + - media: rkisp1: resizer: Stop manual allocation of v4l2_subdev_state + - hwmon: (hp-wmi-sensors) Fix failure to load on EliteDesk 800 G6 + - drm/amd/display: Force p-state disallow if leaving no plane config + - drm/amdkfd: fix mes set shader debugger process management + - drm/msm/dpu: enable writeback on SM8350 + - drm/msm/dpu: enable writeback on SM8450 + - watchdog: starfive: add lock annotations to fix context imbalances + - accel/habanalabs: add support for Gaudi2C device + - drm/amd/display: Only clear symclk otg flag for HDMI + - drm/amd/display: Fix minor issues in BW Allocation Phase2 + - drm/amdgpu: apply the RV2 system aperture fix to RN/CZN as well + - pinctrl: baytrail: Fix types of config value in byt_pin_config_set() + - riscv: Make XIP bootable again + - extcon: fix possible name leak in extcon_dev_register() + - usb: xhci-plat: fix usb disconnect issue after s4 + - i2c: rk3x: Adjust mask/value offset for i2c2 on rv1126 + - drm/amdkfd: only flush mes process context if mes support is there + - riscv: Fix build error on rv32 + XIP + - selftests: net: remove dependency on ebpf tests + - selftests: net: explicitly wait for listener ready + - gve: Fix skb truesize underestimation + - net: phy: phy_device: Call into the PHY driver to set LED offload + - net: phy: mediatek-ge-soc: support PHY LEDs + - net: phy: mediatek-ge-soc: sync driver with MediaTek SDK + - selftests: net: add missing config for big tcp tests + - selftests: net: add missing required classifier + - net: dsa: mt7530: fix 10M/100M speed on MT7988 switch + - e1000e: correct maximum frequency adjustment values + - selftests: net: Add missing matchall classifier + - devlink: Fix referring to hw_addr attribute during state validation + - pds_core: Cancel AQ work on teardown + - pds_core: Use struct pdsc for the pdsc_adminq_isr private data + - pds_core: implement pci reset handlers + - pds_core: Prevent race issues involving the adminq + - pds_core: Clear BARs on reset + - pds_core: Rework teardown/setup flow to be more common + - selftests: net: add missing config for nftables-backed iptables + - selftests: net: add missing config for pmtu.sh tests + - selftests: net: don't access /dev/stdout in pmtu.sh + - octeontx2-pf: Remove xdp queues on program detach + - selftests: net: add missing config for NF_TARGET_TTL + - selftests: net: enable some more knobs + - selftests/bpf: Remove flaky test_btf_id test + - ASoC: qcom: sc8280xp: limit speaker volumes + - ASoC: codecs: wcd938x: fix headphones volume controls + - pds_core: Prevent health thread from running during reset/remove + - Upstream stable to v6.1.77, v6.6.16 + * Mantic update: upstream stable patchset 2024-03-27 (LP: #2059284) // + CVE-2023-52603 + - UBSAN: array-index-out-of-bounds in dtSplitRoot + * iwlwifi disconnect and crash - intel wifi7 (LP: #2058808) + - wifi: iwlwifi: pcie: fix RB status reading + * Mantic update: upstream stable patchset 2024-03-26 (LP: #2059068) + - iio: adc: ad7091r: Set alert bit in config register + - iio: adc: ad7091r: Allow users to configure device events + - ext4: allow for the last group to be marked as trimmed + - arm64: properly install vmlinuz.efi + - OPP: Pass rounded rate to _set_opp() + - btrfs: sysfs: validate scrub_speed_max value + - crypto: api - Disallow identical driver names + - PM: hibernate: Enforce ordering during image compression/decompression + - hwrng: core - Fix page fault dead lock on mmap-ed hwrng + - crypto: s390/aes - Fix buffer overread in CTR mode + - s390/vfio-ap: unpin pages on gisc registration failure + - PM / devfreq: Fix buffer overflow in trans_stat_show + - media: imx355: Enable runtime PM before registering async sub-device + - rpmsg: virtio: Free driver_override when rpmsg_remove() + - media: ov9734: Enable runtime PM before registering async sub-device + - s390/vfio-ap: always filter entire AP matrix + - s390/vfio-ap: loop over the shadow APCB when filtering guest's AP + configuration + - s390/vfio-ap: let on_scan_complete() callback filter matrix and update + guest's APCB + - mips: Fix max_mapnr being uninitialized on early stages + - bus: mhi: host: Add alignment check for event ring read pointer + - bus: mhi: host: Drop chan lock before queuing buffers + - bus: mhi: host: Add spinlock to protect WP access when queueing TREs + - parisc/firmware: Fix F-extend for PDC addresses + - parisc/power: Fix power soft-off button emulation on qemu + - async: Split async_schedule_node_domain() + - async: Introduce async_schedule_dev_nocall() + - iio: adc: ad7091r: Enable internal vref if external vref is not supplied + - dmaengine: fix NULL pointer in channel unregistration function + - scsi: ufs: core: Remove the ufshcd_hba_exit() call from ufshcd_async_scan() + - arm64: dts: qcom: sc7180: fix USB wakeup interrupt types + - arm64: dts: qcom: sdm845: fix USB wakeup interrupt types + - arm64: dts: qcom: sm8150: fix USB wakeup interrupt types + - arm64: dts: qcom: sc7280: fix usb_1 wakeup interrupt types + - arm64: dts: qcom: sdm845: fix USB DP/DM HS PHY interrupts + - arm64: dts: qcom: sm8150: fix USB DP/DM HS PHY interrupts + - lsm: new security_file_ioctl_compat() hook + - docs: kernel_abi.py: fix command injection + - scripts/get_abi: fix source path leak + - media: videobuf2-dma-sg: fix vmap callback + - mmc: core: Use mrq.sbc in close-ended ffu + - mmc: mmc_spi: remove custom DMA mapped buffers + - media: mtk-jpeg: Fix use after free bug due to error path handling in + mtk_jpeg_dec_device_run + - arm64: Rename ARM64_WORKAROUND_2966298 + - rtc: cmos: Use ACPI alarm for non-Intel x86 systems too + - rtc: Adjust failure return code for cmos_set_alarm() + - rtc: mc146818-lib: Adjust failure return code for mc146818_get_time() + - rtc: Add support for configuring the UIP timeout for RTC reads + - rtc: Extend timeout for waiting for UIP to clear to 1s + - nouveau/vmm: don't set addr on the fail path to avoid warning + - ubifs: ubifs_symlink: Fix memleak of inode->i_link in error path + - mm/rmap: fix misplaced parenthesis of a likely() + - mm/sparsemem: fix race in accessing memory_section->usage + - rename(): fix the locking of subdirectories + - serial: sc16is7xx: improve regmap debugfs by using one regmap per port + - serial: sc16is7xx: remove wasteful static buffer in sc16is7xx_regmap_name() + - serial: sc16is7xx: remove global regmap from struct sc16is7xx_port + - serial: sc16is7xx: remove unused line structure member + - serial: sc16is7xx: change EFR lock to operate on each channels + - serial: sc16is7xx: convert from _raw_ to _noinc_ regmap functions for FIFO + - serial: sc16is7xx: fix invalid sc16is7xx_lines bitfield in case of probe + error + - serial: sc16is7xx: remove obsolete loop in sc16is7xx_port_irq() + - serial: sc16is7xx: improve do/while loop in sc16is7xx_irq() + - LoongArch/smp: Call rcutree_report_cpu_starting() earlier + - mm: page_alloc: unreserve highatomic page blocks before oom + - ksmbd: set v2 lease version on lease upgrade + - ksmbd: fix potential circular locking issue in smb2_set_ea() + - ksmbd: don't increment epoch if current state and request state are same + - ksmbd: send lease break notification on FILE_RENAME_INFORMATION + - ksmbd: Add missing set_freezable() for freezable kthread + - Revert "drm/amd: Enable PCIe PME from D3" + - wifi: mac80211: fix potential sta-link leak + - net/smc: fix illegal rmb_desc access in SMC-D connection dump + - tcp: make sure init the accept_queue's spinlocks once + - bnxt_en: Wait for FLR to complete during probe + - vlan: skip nested type that is not IFLA_VLAN_QOS_MAPPING + - llc: make llc_ui_sendmsg() more robust against bonding changes + - llc: Drop support for ETH_P_TR_802_2. + - udp: fix busy polling + - net: fix removing a namespace with conflicting altnames + - tun: fix missing dropped counter in tun_xdp_act + - tun: add missing rx stats accounting in tun_xdp_act + - net: micrel: Fix PTP frame parsing for lan8814 + - net/rds: Fix UBSAN: array-index-out-of-bounds in rds_cmsg_recv + - netfs, fscache: Prevent Oops in fscache_put_cache() + - tracing: Ensure visibility when inserting an element into tracing_map + - afs: Hide silly-rename files from userspace + - tcp: Add memory barrier to tcp_push() + - netlink: fix potential sleeping issue in mqueue_flush_file + - ipv6: init the accept_queue's spinlocks in inet6_create + - net/mlx5: DR, Use the right GVMI number for drop action + - net/mlx5: DR, Can't go to uplink vport on RX rule + - net/mlx5: Use mlx5 device constant for selecting CQ period mode for ASO + - net/mlx5e: Allow software parsing when IPsec crypto is enabled + - net/mlx5e: fix a double-free in arfs_create_groups + - net/mlx5e: fix a potential double-free in fs_any_create_groups + - rcu: Defer RCU kthreads wakeup when CPU is dying + - netfilter: nft_limit: reject configurations that cause integer overflow + - netfilter: nf_tables: restrict anonymous set and map names to 16 bytes + - netfilter: nf_tables: validate NFPROTO_* family + - net: stmmac: Wait a bit for the reset to take effect + - net: mvpp2: clear BM pool before initialization + - selftests: netdevsim: fix the udp_tunnel_nic test + - fjes: fix memleaks in fjes_hw_setup + - net: fec: fix the unhandled context fault from smmu + - nbd: always initialize struct msghdr completely + - btrfs: avoid copying BTRFS_ROOT_SUBVOL_DEAD flag to snapshot of subvolume + being deleted + - btrfs: ref-verify: free ref cache before clearing mount opt + - btrfs: tree-checker: fix inline ref size in error messages + - btrfs: don't warn if discard range is not aligned to sector + - btrfs: defrag: reject unknown flags of btrfs_ioctl_defrag_range_args + - btrfs: don't abort filesystem when attempting to snapshot deleted subvolume + - rbd: don't move requests to the running list on errors + - exec: Fix error handling in begin_new_exec() + - wifi: iwlwifi: fix a memory corruption + - hv_netvsc: Calculate correct ring size when PAGE_SIZE is not 4 Kbytes + - netfilter: nft_chain_filter: handle NETDEV_UNREGISTER for inet/ingress + basechain + - platform/x86: p2sb: Allow p2sb_bar() calls during PCI device probe + - ksmbd: fix global oob in ksmbd_nl_policy + - firmware: arm_scmi: Check mailbox/SMT channel for consistency + - xfs: read only mounts with fsopen mount API are busted + - gpiolib: acpi: Ignore touchpad wakeup on GPD G1619-04 + - cpufreq: intel_pstate: Refine computation of P-state for given frequency + - drm: Don't unref the same fb many times by mistake due to deadlock handling + - drm/bridge: nxp-ptn3460: fix i2c_master_send() error checking + - drm/tidss: Fix atomic_flush check + - drm/bridge: nxp-ptn3460: simplify some error checking + - drm/amd/display: Port DENTIST hang and TDR fixes to OTG disable W/A + - drm/amdgpu/pm: Fix the power source flag error + - erofs: fix lz4 inplace decompression + - media: ov13b10: Enable runtime PM before registering async sub-device + - PM: sleep: Fix possible deadlocks in core system-wide PM code + - thermal: intel: hfi: Refactor enabling code into helper functions + - thermal: intel: hfi: Disable an HFI instance when all its CPUs go offline + - thermal: intel: hfi: Add syscore callbacks for system-wide PM + - fs/pipe: move check to pipe_has_watch_queue() + - pipe: wakeup wr_wait after setting max_usage + - ARM: dts: qcom: sdx55: fix USB wakeup interrupt types + - ARM: dts: samsung: exynos4210-i9100: Unconditionally enable LDO12 + - ARM: dts: qcom: sdx55: fix pdc '#interrupt-cells' + - ARM: dts: qcom: sdx55: fix USB DP/DM HS PHY interrupts + - ARM: dts: qcom: sdx55: fix USB SS wakeup + - dlm: use kernel_connect() and kernel_bind() + - serial: core: Provide port lock wrappers + - serial: sc16is7xx: Use port lock wrappers + - serial: sc16is7xx: fix unconditional activation of THRI interrupt + - btrfs: zoned: factor out prepare_allocation_zoned() + - btrfs: zoned: optimize hint byte for zoned allocator + - drm/panel-edp: drm/panel-edp: Fix AUO B116XAK01 name and timing + - Revert "powerpc/64s: Increase default stack size to 32KB" + - drm/bridge: parade-ps8640: Wait for HPD when doing an AUX transfer + - drm: panel-simple: add missing bus flags for Tianma tm070jvhg[30/33] + - drm/bridge: sii902x: Fix probing race issue + - drm/bridge: sii902x: Fix audio codec unregistration + - drm/bridge: parade-ps8640: Ensure bridge is suspended in .post_disable() + - drm/bridge: parade-ps8640: Make sure we drop the AUX mutex in the error case + - drm/exynos: fix accidental on-stack copy of exynos_drm_plane + - drm/exynos: gsc: minor fix for loop iteration in gsc_runtime_resume + - gpio: eic-sprd: Clear interrupt after set the interrupt type + - drm/bridge: anx7625: Ensure bridge is suspended in disable() + - spi: bcm-qspi: fix SFDP BFPT read by usig mspi read + - spi: fix finalize message on error return + - MIPS: lantiq: register smp_ops on non-smp platforms + - cxl/region:Fix overflow issue in alloc_hpa() + - mips: Call lose_fpu(0) before initializing fcr31 in mips_set_personality_nan + - tick/sched: Preserve number of idle sleeps across CPU hotplug events + - x86/entry/ia32: Ensure s32 is sign extended to s64 + - serial: core: fix kernel-doc for uart_port_unlock_irqrestore() + - docs: sparse: move TW sparse.txt to TW dev-tools + - docs: sparse: add sparse.rst to toctree + - serial: core: Simplify uart_get_rs485_mode() + - serial: core: set missing supported flag for RX during TX GPIO + - soundwire: bus: introduce controller_id + - soundwire: fix initializing sysfs for same devices on different buses + - net: stmmac: Tx coe sw fallback + - net: stmmac: Prevent DSA tags from breaking COE + - dmaengine: idxd: Move dma_free_coherent() out of spinlocked context + - riscv: Fix an off-by-one in get_early_cmdline() + - scsi: core: Kick the requeue list after inserting when flushing + - sh: ecovec24: Rename missed backlight field from fbdev to dev + - smb: client: fix parsing of SMB3.1.1 POSIX create context + - cifs: do not pass cifs_sb when trying to add channels + - cifs: handle cases where a channel is closed + - cifs: reconnect work should have reference on server struct + - cifs: handle when server starts supporting multichannel + - cifs: handle when server stops supporting multichannel + - cifs: reconnect worker should take reference on server struct + unconditionally + - cifs: handle servers that still advertise multichannel after disabling + - cifs: update iface_last_update on each query-and-update + - powerpc/ps3_defconfig: Disable PPC64_BIG_ENDIAN_ELF_ABI_V2 + - crypto: lib/mpi - Fix unexpected pointer access in mpi_ec_init + - mtd: maps: vmu-flash: Fix the (mtd core) switch to ref counters + - mtd: rawnand: Prevent crossing LUN boundaries during sequential reads + - mtd: rawnand: Fix core interference with sequential reads + - mtd: rawnand: Prevent sequential reads with on-die ECC engines + - mtd: rawnand: Clarify conditions to enable continuous reads + - soc: qcom: pmic_glink_altmode: fix port sanity check + - media: ov01a10: Enable runtime PM before registering async sub-device + - soc: fsl: cpm1: tsa: Fix __iomem addresses declaration + - soc: fsl: cpm1: qmc: Fix __iomem addresses declaration + - soc: fsl: cpm1: qmc: Fix rx channel reset + - s390/vfio-ap: reset queues filtered from the guest's AP config + - s390/vfio-ap: reset queues associated with adapter for queue unbound from + driver + - s390/vfio-ap: do not reset queue removed from host config + - ARM: dts: imx6q-apalis: add can power-up delay on ixora board + - arm64: dts: qcom: sc8280xp-crd: fix eDP phy compatible + - arm64: dts: sprd: fix the cpu node for UMS512 + - arm64: dts: rockchip: configure eth pad driver strength for orangepi r1 plus + lts + - arm64: dts: rockchip: Fix rk3588 USB power-domain clocks + - arm64: dts: qcom: msm8916: Make blsp_dma controlled-remotely + - arm64: dts: qcom: msm8939: Make blsp_dma controlled-remotely + - arm64: dts: qcom: sdm670: fix USB wakeup interrupt types + - arm64: dts: qcom: sc8180x: fix USB wakeup interrupt types + - arm64: dts: qcom: Add missing vio-supply for AW2013 + - arm64: dts: qcom: sdm845: fix USB SS wakeup + - arm64: dts: qcom: sm8150: fix USB SS wakeup + - arm64: dts: qcom: sc8180x: fix USB DP/DM HS PHY interrupts + - arm64: dts: qcom: sc8180x: fix USB SS wakeup + - media: i2c: st-mipid02: correct format propagation + - media: mtk-jpeg: Fix timeout schedule error in mtk_jpegdec_worker. + - riscv: mm: Fixup compat mode boot failure + - arm64: errata: Add Cortex-A510 speculative unprivileged load workaround + - [Config] update config for ARM64_ERRATUM_3117295 + - arm64/sme: Always exit sme_alloc() early with existing storage + - arm64: entry: fix ARM64_WORKAROUND_SPECULATIVE_UNPRIV_LOAD + - efi: disable mirror feature during crashkernel + - kexec: do syscore_shutdown() in kernel_kexec + - selftests: mm: hugepage-vmemmap fails on 64K page size systems + - serial: Do not hold the port lock when setting rx-during-tx GPIO + - dt-bindings: net: snps,dwmac: Tx coe unsupported + - bpf: move explored_state() closer to the beginning of verifier.c + - bpf: extract same_callsites() as utility function + - bpf: exact states comparison for iterator convergence checks + - selftests/bpf: tests with delayed read/precision makrs in loop body + - bpf: correct loop detection for iterators convergence + - selftests/bpf: test if state loops are detected in a tricky case + - bpf: print full verifier states on infinite loop detection + - selftests/bpf: track tcp payload offset as scalar in xdp_synproxy + - selftests/bpf: track string payload offset as scalar in strobemeta + - bpf: extract __check_reg_arg() utility function + - bpf: extract setup_func_entry() utility function + - bpf: verify callbacks as if they are called unknown number of times + - selftests/bpf: tests for iterating callbacks + - bpf: widening for callback iterators + - bpf: keep track of max number of bpf_loop callback iterations + - cifs: fix lock ordering while disabling multichannel + - cifs: fix a pending undercount of srv_count + - cifs: after disabling multichannel, mark tcon for reconnect + - selftests: bonding: Increase timeout to 1200s + - bnxt_en: Prevent kernel warning when running offline self test + - selftest: Don't reuse port for SO_INCOMING_CPU test. + - selftests: fill in some missing configs for net + - net/sched: flower: Fix chain template offload + - net/mlx5e: Fix operation precedence bug in port timestamping napi_poll + context + - net/mlx5e: Fix peer flow lists handling + - net/mlx5: Bridge, Enable mcast in smfs steering mode + - net/mlx5: Bridge, fix multicast packets sent to uplink + - net/mlx5e: Ignore IPsec replay window values on sender side + - selftests: net: fix rps_default_mask with >32 CPUs + - bpf: Propagate modified uaddrlen from cgroup sockaddr programs + - bpf: Add bpf_sock_addr_set_sun_path() to allow writing unix sockaddr from + bpf + - ice: work on pre-XDP prog frag count + - i40e: handle multi-buffer packets that are shrunk by xdp prog + - ice: remove redundant xdp_rxq_info registration + - ice: update xdp_rxq_info::frag_size for ZC enabled Rx queue + - i40e: set xdp_rxq_info::frag_size + - selftests: bonding: do not test arp/ns target with mode balance-alb/tlb + - tsnep: Remove FCS for XDP data path + - tsnep: Fix XDP_RING_NEED_WAKEUP for empty fill ring + - btrfs: scrub: avoid use-after-free when chunk length is not 64K aligned + - nfsd: fix RELEASE_LOCKOWNER + - Revert "drivers/firmware: Move sysfb_init() from device_initcall to + subsys_initcall_sync" + - drm/amdgpu: Fix the null pointer when load rlc firmware + - drm: Fix TODO list mentioning non-KMS drivers + - drm: Disable the cursor plane on atomic contexts with virtualized drivers + - drm/virtio: Disable damage clipping if FB changed since last page-flip + - drm: Allow drivers to indicate the damage helpers to ignore damage clips + - drm/amd/display: fix bandwidth validation failure on DCN 2.1 + - drm/amdgpu: correct the cu count for gfx v11 + - drm/amd/display: Align the returned error code with legacy DP + - drm/amd/display: Fix late derefrence 'dsc' check in + 'link_set_dsc_pps_packet()' + - drm/amd/display: Fix uninitialized variable usage in core_link_ 'read_dpcd() + & write_dpcd()' functions + - net/bpf: Avoid unused "sin_addr_len" warning when CONFIG_CGROUP_BPF is not + set + - thermal: core: Store trip pointer in struct thermal_instance + - thermal: gov_power_allocator: avoid inability to reset a cdev + - mm: migrate: record the mlocked page status to remove unnecessary lru drain + - mm: migrate: fix getting incorrect page mapping during page migration + - drm/i915/lnl: Remove watchdog timers for PSR + - drm/i915/psr: Only allow PSR in LPSP mode on HSW non-ULT + - drm/panel-edp: Add AUO B116XTN02, BOE NT116WHM-N21,836X2, NV116WHM-N49 V8.0 + - drm/panel-edp: drm/panel-edp: Fix AUO B116XTN02 name + - drm/amdgpu/gfx10: set UNORD_DISPATCH in compute MQDs + - drm/amdgpu/gfx11: set UNORD_DISPATCH in compute MQDs + - drm/panel: samsung-s6d7aa0: drop DRM_BUS_FLAG_DE_HIGH for lsl080al02 + - memblock: fix crash when reserved memory is not added to memory + - firmware: arm_scmi: Use xa_insert() when saving raw queues + - spi: intel-pci: Remove Meteor Lake-S SoC PCI ID from the list + - cpufreq/amd-pstate: Fix setting scaling max/min freq values + - spi: spi-cadence: Reverse the order of interleaved write and read operations + - cifs: fix stray unlock in cifs_chan_skip_or_disable + - drm: bridge: samsung-dsim: Don't use FORCE_STOP_STATE + - genirq: Initialize resend_node hlist for all interrupt descriptors + - clocksource: Skip watchdog check for large watchdog intervals + - thermal: trip: Drop lockdep assertion from thermal_zone_trip_id() + - platform/x86: intel-uncore-freq: Fix types in sysfs callbacks + - Upstream stable to v6.1.76, v6.6.15 + * CVE-2024-26582 + - net: tls: fix use-after-free with partial reads and async decrypt + - net: tls: fix returned read length with async decrypt + * CVE-2024-26584 + - net: tls: handle backlogging of crypto requests + * CVE-2024-26585 + - tls: fix race between tx work scheduling and socket close + * CVE-2024-26583 + - tls: extract context alloc/initialization out of tls_set_sw_offload + - net: tls: factor out tls_*crypt_async_wait() + - tls: fix race between async notify and socket close + * CVE-2023-52600 + - jfs: fix uaf in jfs_evict_inode + * Fix headphone mic detection issue on ALC897 (LP: #2056418) + - ALSA: hda/realtek - Fix headset Mic no show at resume back for Lenovo ALC897 + platform + * CVE-2024-26581 + - netfilter: nft_set_rbtree: skip end interval element from gc + * The screen brightness is unable to adjust on BOE panel DPN#R6FD8 + (LP: #2057430) + - drm/amd/display: Re-add aux intercept disable delay generically for 2+ + LTTPRs + - drm/amd/display: Clear dpcd_sink_ext_caps if not set + - drm/amd/display: Add monitor patch for specific eDP + - drm/amd/display: Add monitor patch for specific eDP + * Dynamically determine acpi_handle_list size (LP: #2049733) + - ACPI: utils: Dynamically determine acpi_handle_list size + - ACPI: utils: Fix error path in acpi_evaluate_reference() + - ACPI: utils: Fix white space in struct acpi_handle_list definition + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) + - x86/lib: Fix overflow when counting digits + - x86/mce/inject: Clear test status value + - EDAC/thunderx: Fix possible out-of-bounds string access + - powerpc: add crtsavres.o to always-y instead of extra-y + - powerpc/44x: select I2C for CURRITUCK + - powerpc/pseries/memhp: Fix access beyond end of drmem array + - selftests/powerpc: Fix error handling in FPU/VMX preemption tests + - powerpc/powernv: Add a null pointer check to scom_debug_init_one() + - powerpc/powernv: Add a null pointer check in opal_event_init() + - powerpc/powernv: Add a null pointer check in opal_powercap_init() + - powerpc/imc-pmu: Add a null pointer check in update_events_in_group() + - spi: spi-zynqmp-gqspi: fix driver kconfig dependencies + - mtd: rawnand: Increment IFC_TIMEOUT_MSECS for nand controller response + - ACPI: video: check for error while searching for backlight device parent + - ACPI: LPIT: Avoid u32 multiplication overflow + - platform/x86/intel/vsec: Fix xa_alloc memory leak + - cpufreq: scmi: process the result of devm_of_clk_add_hw_provider() + - calipso: fix memory leak in netlbl_calipso_add_pass() + - efivarfs: force RO when remounting if SetVariable is not supported + - spi: sh-msiof: Enforce fixed DTDL for R-Car H3 + - ACPI: LPSS: Fix the fractional clock divider flags + - ACPI: extlog: Clear Extended Error Log status when RAS_CEC handled the error + - kunit: debugfs: Fix unchecked dereference in debugfs_print_results() + - mtd: Fix gluebi NULL pointer dereference caused by ftl notifier + - selinux: Fix error priority for bind with AF_UNSPEC on PF_INET6 socket + - crypto: virtio - Handle dataq logic with tasklet + - crypto: sa2ul - Return crypto_aead_setkey to transfer the error + - crypto: ccp - fix memleak in ccp_init_dm_workarea + - crypto: af_alg - Disallow multiple in-flight AIO requests + - crypto: safexcel - Add error handling for dma_map_sg() calls + - crypto: sahara - remove FLAGS_NEW_KEY logic + - crypto: sahara - fix cbc selftest failure + - crypto: sahara - fix ahash selftest failure + - crypto: sahara - fix processing requests with cryptlen < sg->length + - crypto: sahara - fix error handling in sahara_hw_descriptor_create() + - crypto: hisilicon/qm - save capability registers in qm init process + - crypto: hisilicon/zip - add zip comp high perf mode configuration + - crypto: hisilicon/qm - add a function to set qm algs + - crypto: hisilicon/hpre - save capability registers in probe process + - crypto: hisilicon/sec2 - save capability registers in probe process + - crypto: hisilicon/zip - save capability registers in probe process + - pstore: ram_core: fix possible overflow in persistent_ram_init_ecc() + - erofs: fix memory leak on short-lived bounced pages + - fs: indicate request originates from old mount API + - gfs2: Fix kernel NULL pointer dereference in gfs2_rgrp_dump + - crypto: virtio - Wait for tasklet to complete on device remove + - crypto: sahara - avoid skcipher fallback code duplication + - crypto: sahara - handle zero-length aes requests + - crypto: sahara - fix ahash reqsize + - crypto: sahara - fix wait_for_completion_timeout() error handling + - crypto: sahara - improve error handling in sahara_sha_process() + - crypto: sahara - fix processing hash requests with req->nbytes < sg->length + - crypto: sahara - do not resize req->src when doing hash operations + - crypto: scomp - fix req->dst buffer overflow + - csky: fix arch_jump_label_transform_static override + - blocklayoutdriver: Fix reference leak of pnfs_device_node + - NFSv4.1/pnfs: Ensure we handle the error NFS4ERR_RETURNCONFLICT + - SUNRPC: fix _xprt_switch_find_current_entry logic + - pNFS: Fix the pnfs block driver's calculation of layoutget size + - wifi: plfxlc: check for allocation failure in plfxlc_usb_wreq_async() + - wifi: rtw88: fix RX filter in FIF_ALLMULTI flag + - bpf, lpm: Fix check prefixlen before walking trie + - bpf: Add crosstask check to __bpf_get_stack + - wifi: ath11k: Defer on rproc_get failure + - wifi: libertas: stop selecting wext + - ARM: dts: qcom: apq8064: correct XOADC register address + - net/ncsi: Fix netlink major/minor version numbers + - firmware: ti_sci: Fix an off-by-one in ti_sci_debugfs_create() + - wifi: rtlwifi: rtl8821ae: phy: fix an undefined bitwise shift behavior + - arm64: dts: ti: k3-am62a-main: Fix GPIO pin count in DT nodes + - arm64: dts: ti: k3-am65-main: Fix DSS irq trigger type + - selftests/bpf: Fix erroneous bitmask operation + - md: synchronize flush io with array reconfiguration + - bpf: enforce precision of R0 on callback return + - ARM: dts: qcom: sdx65: correct SPMI node name + - arm64: dts: qcom: sc7180: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sc7280: Mark some nodes as 'reserved' + - arm64: dts: qcom: sc7280: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sdm845: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm8150: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm8250: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sc8280xp: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm6350: Make watchdog bark interrupt edge triggered + - bpf: add percpu stats for bpf_map elements insertions/deletions + - bpf: Add map and need_defer parameters to .map_fd_put_ptr() + - bpf: Defer the free of inner map when necessary + - selftests/net: specify the interface when do arping + - bpf: fix check for attempt to corrupt spilled pointer + - scsi: fnic: Return error if vmalloc() failed + - arm64: dts: qcom: qrb5165-rb5: correct LED panic indicator + - arm64: dts: qcom: sdm845-db845c: correct LED panic indicator + - arm64: dts: qcom: sm8350: Fix DMA0 address + - arm64: dts: qcom: sc7280: Fix up GPU SIDs + - arm64: dts: qcom: sc7280: Mark Adreno SMMU as DMA coherent + - arm64: dts: qcom: sc7280: fix usb_2 wakeup interrupt types + - wifi: mt76: mt7921s: fix workqueue problem causes STA association fail + - bpf: Fix verification of indirect var-off stack access + - arm64: dts: hisilicon: hikey970-pmic: fix regulator cells properties + - dt-bindings: media: mediatek: mdp3: correct RDMA and WROT node with generic + names + - arm64: dts: mediatek: mt8183: correct MDP3 DMA-related nodes + - wifi: mt76: mt7921: fix country count limitation for CLC + - selftests/bpf: Relax time_tai test for equal timestamps in tai_forward + - block: Set memalloc_noio to false on device_add_disk() error path + - arm64: dts: renesas: white-hawk-cpu: Fix missing serial console pin control + - arm64: dts: imx8mm: Reduce GPU to nominal speed + - scsi: hisi_sas: Replace with standard error code return value + - scsi: hisi_sas: Correct the number of global debugfs registers + - ARM: dts: stm32: don't mix SCMI and non-SCMI board compatibles + - selftests/net: fix grep checking for fib_nexthop_multiprefix + - ipmr: support IP_PKTINFO on cache report IGMP msg + - virtio/vsock: fix logic which reduces credit update messages + - dma-mapping: clear dev->dma_mem to NULL after freeing it + - soc: qcom: llcc: Fix dis_cap_alloc and retain_on_pc configuration + - arm64: dts: qcom: sm8150-hdk: fix SS USB regulators + - block: add check of 'minors' and 'first_minor' in device_add_disk() + - arm64: dts: qcom: sc7280: Mark SDHCI hosts as cache-coherent + - arm64: dts: qcom: ipq6018: fix clock rates for GCC_USB0_MOCK_UTMI_CLK + - wifi: rtlwifi: add calculate_bit_shift() + - wifi: rtlwifi: rtl8188ee: phy: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192c: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192cu: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ce: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192de: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192ee: using calculate_bit_shift() + - wifi: rtlwifi: rtl8192se: using calculate_bit_shift() + - wifi: iwlwifi: mvm: set siso/mimo chains to 1 in FW SMPS request + - wifi: iwlwifi: mvm: send TX path flush in rfkill + - netfilter: nf_tables: mark newset as dead on transaction abort + - Bluetooth: Fix bogus check for re-auth no supported with non-ssp + - Bluetooth: btmtkuart: fix recv_buf() return value + - null_blk: don't cap max_hw_sectors to BLK_DEF_MAX_SECTORS + - bpf: sockmap, fix proto update hook to avoid dup calls + - sctp: support MSG_ERRQUEUE flag in recvmsg() + - sctp: fix busy polling + - net/sched: act_ct: fix skb leak and crash on ooo frags + - mlxbf_gige: Fix intermittent no ip issue + - mlxbf_gige: Enable the GigE port in mlxbf_gige_open + - ip6_tunnel: fix NEXTHDR_FRAGMENT handling in ip6_tnl_parse_tlv_enc_lim() + - ARM: davinci: always select CONFIG_CPU_ARM926T + - Revert "drm/tidss: Annotate dma-fence critical section in commit path" + - Revert "drm/omapdrm: Annotate dma-fence critical section in commit path" + - drm/panfrost: Really power off GPU cores in panfrost_gpu_power_off() + - RDMA/usnic: Silence uninitialized symbol smatch warnings + - RDMA/hns: Fix inappropriate err code for unsupported operations + - drm/panel-elida-kd35t133: hold panel in reset for unprepare + - drm/nouveau/fence:: fix warning directly dereferencing a rcu pointer + - drm/bridge: tpd12s015: Drop buggy __exit annotation for remove function + - drm/tilcdc: Fix irq free on unload + - media: pvrusb2: fix use after free on context disconnection + - media: mtk-jpeg: Remove cancel worker in mtk_jpeg_remove to avoid the crash + of multi-core JPEG devices + - media: verisilicon: Hook the (TRY_)DECODER_CMD stateless ioctls + - media: rkvdec: Hook the (TRY_)DECODER_CMD stateless ioctls + - drm/bridge: Fix typo in post_disable() description + - f2fs: fix to avoid dirent corruption + - drm/radeon/r600_cs: Fix possible int overflows in r600_cs_check_reg() + - drm/radeon/r100: Fix integer overflow issues in r100_cs_track_check() + - drm/radeon: check return value of radeon_ring_lock() + - drm/tidss: Move reset to the end of dispc_init() + - drm/tidss: Return error value from from softreset + - drm/tidss: Check for K2G in in dispc_softreset() + - drm/tidss: Fix dss reset + - ASoC: cs35l33: Fix GPIO name and drop legacy include + - ASoC: cs35l34: Fix GPIO name and drop legacy include + - drm/msm/mdp4: flush vblank event on disable + - drm/msm/dsi: Use pm_runtime_resume_and_get to prevent refcnt leaks + - drm/drv: propagate errors from drm_modeset_register_all() + - ASoC: Intel: glk_rt5682_max98357a: fix board id mismatch + - drm/panfrost: Ignore core_mask for poweroff and disable PWRTRANS irq + - drm/radeon: check the alloc_workqueue return value in radeon_crtc_init() + - drm/radeon/dpm: fix a memleak in sumo_parse_power_table + - drm/radeon/trinity_dpm: fix a memleak in trinity_parse_power_table + - drm/bridge: cdns-mhdp8546: Fix use of uninitialized variable + - drm/bridge: tc358767: Fix return value on error case + - media: cx231xx: fix a memleak in cx231xx_init_isoc + - RDMA/hns: Fix memory leak in free_mr_init() + - clk: qcom: gpucc-sm8150: Update the gpu_cc_pll1 config + - media: imx-mipi-csis: Fix clock handling in remove() + - media: dt-bindings: media: rkisp1: Fix the port description for the parallel + interface + - media: rkisp1: Fix media device memory leak + - drm/panel: st7701: Fix AVCL calculation + - f2fs: fix to wait on block writeback for post_read case + - f2fs: fix to check compress file in f2fs_move_file_range() + - f2fs: fix to update iostat correctly in f2fs_filemap_fault() + - media: dvbdev: drop refcount on error path in dvb_device_open() + - media: dvb-frontends: m88ds3103: Fix a memory leak in an error handling path + of m88ds3103_probe() + - clk: renesas: rzg2l-cpg: Reuse code in rzg2l_cpg_reset() + - clk: renesas: rzg2l: Check reset monitor registers + - drm/msm/dpu: Set input_sel bit for INTF + - drm/msm/dpu: Drop enable and frame_count parameters from dpu_hw_setup_misr() + - drm/mediatek: Return error if MDP RDMA failed to enable the clock + - drm/mediatek: Fix underrun in VDO1 when switches off the layer + - drm/amdgpu/debugfs: fix error code when smc register accessors are NULL + - drm/amd/pm: fix a double-free in si_dpm_init + - drivers/amd/pm: fix a use-after-free in kv_parse_power_table + - gpu/drm/radeon: fix two memleaks in radeon_vm_init + - drm/amd/pm: fix a double-free in amdgpu_parse_extended_power_table + - f2fs: fix to check return value of f2fs_recover_xattr_data + - dt-bindings: clock: Update the videocc resets for sm8150 + - clk: qcom: videocc-sm8150: Update the videocc resets + - clk: qcom: videocc-sm8150: Add missing PLL config property + - drivers: clk: zynqmp: calculate closest mux rate + - drivers: clk: zynqmp: update divider round rate logic + - watchdog: set cdev owner before adding + - watchdog/hpwdt: Only claim UNKNOWN NMI if from iLO + - watchdog: bcm2835_wdt: Fix WDIOC_SETTIMEOUT handling + - watchdog: rti_wdt: Drop runtime pm reference count when watchdog is unused + - clk: si5341: fix an error code problem in si5341_output_clk_set_rate + - drm/mediatek: dp: Add phy_mtk_dp module as pre-dependency + - clk: fixed-rate: fix clk_hw_register_fixed_rate_with_accuracy_parent_hw + - pwm: stm32: Use hweight32 in stm32_pwm_detect_channels + - pwm: stm32: Fix enable count for clk in .probe() + - ASoC: rt5645: Drop double EF20 entry from dmi_platform_data[] + - ALSA: scarlett2: Add missing error check to scarlett2_config_save() + - ALSA: scarlett2: Add missing error check to scarlett2_usb_set_config() + - ALSA: scarlett2: Allow passing any output to line_out_remap() + - ALSA: scarlett2: Add missing error checks to *_ctl_get() + - ALSA: scarlett2: Add clamp() in scarlett2_mixer_ctl_put() + - mmc: sdhci_am654: Fix TI SoC dependencies + - [Config] updateconfigs for CONFIG_MMC_SDHCI_AM654 + - mmc: sdhci_omap: Fix TI SoC dependencies + - [Config] update config for MMC_SDHCI_OMAP changes + - IB/iser: Prevent invalidating wrong MR + - drm/amdkfd: Confirm list is non-empty before utilizing list_first_entry in + kfd_topology.c + - drm/amd/pm/smu7: fix a memleak in smu7_hwmgr_backend_init + - kselftest/alsa - mixer-test: fix the number of parameters to + ksft_exit_fail_msg() + - kselftest/alsa - mixer-test: Fix the print format specifier warning + - ksmbd: validate the zero field of packet header + - of: Fix double free in of_parse_phandle_with_args_map + - fbdev: imxfb: fix left margin setting + - of: unittest: Fix of_count_phandle_with_args() expected value message + - selftests/bpf: Add assert for user stacks in test_task_stack + - keys, dns: Fix size check of V1 server-list header + - binder: fix async space check for 0-sized buffers + - binder: fix unused alloc->free_async_space + - mips/smp: Call rcutree_report_cpu_starting() earlier + - Input: atkbd - use ab83 as id when skipping the getid command + - binder: fix race between mmput() and do_exit() + - clocksource/drivers/timer-ti-dm: Fix make W=n kerneldoc warnings + - powerpc/64s: Increase default stack size to 32KB + - tick-sched: Fix idle and iowait sleeptime accounting vs CPU hotplug + - usb: phy: mxs: remove CONFIG_USB_OTG condition for mxs_phy_is_otg_host() + - usb: dwc: ep0: Update request status in dwc3_ep0_stall_restart + - Revert "usb: dwc3: Soft reset phy on probe for host" + - Revert "usb: dwc3: don't reset device side if dwc3 was configured as host- + only" + - usb: chipidea: wait controller resume finished for wakeup irq + - usb: cdns3: fix uvc failure work since sg support enabled + - usb: cdns3: fix iso transfer error when mult is not zero + - usb: cdns3: Fix uvc fail when DMA cross 4k boundery since sg enabled + - usb: typec: class: fix typec_altmode_put_partner to put plugs + - usb: mon: Fix atomicity violation in mon_bin_vma_fault + - serial: core: fix sanitizing check for RTS settings + - serial: core: make sure RS485 cannot be enabled when it is not supported + - serial: 8250_bcm2835aux: Restore clock error handling + - serial: core, imx: do not set RS485 enabled if it is not supported + - serial: imx: Ensure that imx_uart_rs485_config() is called with enabled + clock + - serial: 8250_exar: Set missing rs485_supported flag + - serial: omap: do not override settings for RS485 support + - ALSA: oxygen: Fix right channel of capture volume mixer + - ALSA: hda/relatek: Enable Mute LED on HP Laptop 15s-fq2xxx + - ALSA: hda/realtek: Enable mute/micmute LEDs and limit mic boost on HP ZBook + - ksmbd: validate mech token in session setup + - ksmbd: fix UAF issue in ksmbd_tcp_new_connection() + - ksmbd: only v2 leases handle the directory + - io_uring/rw: ensure io->bytes_done is always initialized + - fbdev: flush deferred work in fb_deferred_io_fsync() + - fbdev: flush deferred IO before closing + - scsi: ufs: core: Simplify power management during async scan + - scsi: target: core: add missing file_{start,end}_write() + - drm/amd: Enable PCIe PME from D3 + - block: add check that partition length needs to be aligned with block size + - block: Fix iterating over an empty bio with bio_for_each_folio_all + - pwm: jz4740: Don't use dev_err_probe() in .request() + - md/raid1: Use blk_opf_t for read and write operations + - rootfs: Fix support for rootfstype= when root= is given + - Bluetooth: Fix atomicity violation in {min,max}_key_size_set + - LoongArch: Fix and simplify fcsr initialization on execve() + - iommu/arm-smmu-qcom: Add missing GMU entry to match table + - iommu/dma: Trace bounce buffer usage when mapping buffers + - wifi: mt76: fix broken precal loading from MTD for mt7915 + - wifi: rtlwifi: Remove bogus and dangerous ASPM disable/enable code + - wifi: rtlwifi: Convert LNKCTL change to PCIe cap RMW accessors + - wifi: mwifiex: configure BSSID consistently when starting AP + - Revert "net: rtnetlink: Enslave device before bringing it up" + - cxl/port: Fix decoder initialization when nr_targets > interleave_ways + - PCI/P2PDMA: Remove reference to pci_p2pdma_map_sg() + - PCI: dwc: endpoint: Fix dw_pcie_ep_raise_msix_irq() alignment support + - PCI: mediatek: Clear interrupt status before dispatching handler + - x86/kvm: Do not try to disable kvmclock if it was not enabled + - KVM: arm64: vgic-v4: Restore pending state on host userspace write + - KVM: arm64: vgic-its: Avoid potential UAF in LPI translation cache + - iio: adc: ad7091r: Pass iio_dev to event handler + - HID: wacom: Correct behavior when processing some confidence == false + touches + - serial: sc16is7xx: add check for unsupported SPI modes during probe + - serial: sc16is7xx: set safe default SPI clock frequency + - ARM: 9330/1: davinci: also select PINCTRL + - mfd: syscon: Fix null pointer dereference in of_syscon_register() + - leds: aw2013: Select missing dependency REGMAP_I2C + - mfd: intel-lpss: Fix the fractional clock divider flags + - mips: dmi: Fix early remap on MIPS32 + - mips: Fix incorrect max_low_pfn adjustment + - riscv: Check if the code to patch lies in the exit section + - riscv: Fix module_alloc() that did not reset the linear mapping permissions + - riscv: Fix set_memory_XX() and set_direct_map_XX() by splitting huge linear + mappings + - riscv: Fix set_direct_map_default_noflush() to reset _PAGE_EXEC + - riscv: Fixed wrong register in XIP_FIXUP_FLASH_OFFSET macro + - MIPS: Alchemy: Fix an out-of-bound access in db1200_dev_setup() + - MIPS: Alchemy: Fix an out-of-bound access in db1550_dev_setup() + - power: supply: cw2015: correct time_to_empty units in sysfs + - power: supply: bq256xx: fix some problem in bq256xx_hw_init + - serial: 8250: omap: Don't skip resource freeing if + pm_runtime_resume_and_get() failed + - libapi: Add missing linux/types.h header to get the __u64 type on io.h + - base/node.c: initialize the accessor list before registering + - acpi: property: Let args be NULL in __acpi_node_get_property_reference + - software node: Let args be NULL in software_node_get_reference_args + - serial: imx: fix tx statemachine deadlock + - selftests/sgx: Fix uninitialized pointer dereference in error path + - selftests/sgx: Fix uninitialized pointer dereferences in encl_get_entry + - selftests/sgx: Include memory clobber for inline asm in test enclave + - selftests/sgx: Skip non X86_64 platform + - iio: adc: ad9467: fix reset gpio handling + - iio: adc: ad9467: don't ignore error codes + - iio: adc: ad9467: fix scale setting + - perf header: Fix one memory leakage in perf_event__fprintf_event_update() + - perf hisi-ptt: Fix one memory leakage in hisi_ptt_process_auxtrace_event() + - perf genelf: Set ELF program header addresses properly + - tty: change tty_write_lock()'s ndelay parameter to bool + - tty: early return from send_break() on TTY_DRIVER_HARDWARE_BREAK + - tty: don't check for signal_pending() in send_break() + - tty: use 'if' in send_break() instead of 'goto' + - usb: cdc-acm: return correct error code on unsupported break + - spmi: mtk-pmif: Serialize PMIF status check and command submission + - vdpa: Fix an error handling path in eni_vdpa_probe() + - nvmet-tcp: Fix a kernel panic when host sends an invalid H2C PDU length + - nvmet-tcp: fix a crash in nvmet_req_complete() + - perf env: Avoid recursively taking env->bpf_progs.lock + - cxl/region: fix x9 interleave typo + - apparmor: avoid crash when parsed profile name is empty + - usb: xhci-mtk: fix a short packet issue of gen1 isoc-in transfer + - serial: imx: Correct clock error message in function probe() + - nvmet: re-fix tracing strncpy() warning + - nvme: trace: avoid memcpy overflow warning + - nvmet-tcp: Fix the H2C expected PDU len calculation + - PCI: keystone: Fix race condition when initializing PHYs + - PCI: mediatek-gen3: Fix translation window size calculation + - ASoC: mediatek: sof-common: Add NULL check for normal_link string + - s390/pci: fix max size calculation in zpci_memcpy_toio() + - net: ethernet: ti: am65-cpsw: Fix max mtu to fit ethernet frames + - amt: do not use overwrapped cb area + - net: phy: micrel: populate .soft_reset for KSZ9131 + - mptcp: mptcp_parse_option() fix for MPTCPOPT_MP_JOIN + - mptcp: strict validation before using mp_opt->hmac + - mptcp: use OPTION_MPTCP_MPJ_SYNACK in subflow_finish_connect() + - mptcp: use OPTION_MPTCP_MPJ_SYN in subflow_check_req() + - mptcp: refine opt_mp_capable determination + - block: ensure we hold a queue reference when using queue limits + - udp: annotate data-races around up->pending + - net: ravb: Fix dma_addr_t truncation in error case + - dt-bindings: gpio: xilinx: Fix node address in gpio + - drm/amdkfd: fixes for HMM mem allocation + - net: stmmac: ethtool: Fixed calltrace caused by unbalanced disable_irq_wake + calls + - net: dsa: vsc73xx: Add null pointer check to vsc73xx_gpio_probe + - LoongArch: BPF: Prevent out-of-bounds memory access + - mptcp: relax check on MPC passive fallback + - netfilter: nf_tables: reject invalid set policy + - netfilter: nft_limit: do not ignore unsupported flags + - netfilter: nfnetlink_log: use proper helper for fetching physinif + - netfilter: nf_queue: remove excess nf_bridge variable + - netfilter: propagate net to nf_bridge_get_physindev + - netfilter: bridge: replace physindev with physinif in nf_bridge_info + - netfilter: nf_tables: do not allow mismatch field size and set key length + - netfilter: nf_tables: skip dead set elements in netlink dump + - netfilter: nf_tables: reject NFT_SET_CONCAT with not field length + description + - ipvs: avoid stat macros calls from preemptible context + - kdb: Fix a potential buffer overflow in kdb_local() + - ethtool: netlink: Add missing ethnl_ops_begin/complete + - loop: fix the the direct I/O support check when used on top of block devices + - mlxsw: spectrum_acl_erp: Fix error flow of pool allocation failure + - selftests: mlxsw: qos_pfc: Adjust the test to support 8 lanes + - ipv6: mcast: fix data-race in ipv6_mc_down / mld_ifc_work + - i2c: s3c24xx: fix read transfers in polling mode + - i2c: s3c24xx: fix transferring more than one message in polling mode + - riscv: Fix wrong usage of lm_alias() when splitting a huge linear mapping + - arm64: dts: armada-3720-turris-mox: set irq type for RTC + - x86: Fix CPUIDLE_FLAG_IRQ_ENABLE leaking timer reprogram + - drivers/perf: hisi: Fix some event id for HiSilicon UC pmu + - KVM: PPC: Book3S HV: Use accessors for VCPU registers + - KVM: PPC: Book3S HV: Introduce low level MSR accessor + - KVM: PPC: Book3S HV: Handle pending exceptions on guest entry with MSR_EE + - powerpc/rtas: Avoid warning on invalid token argument to sys_rtas() + - perf/x86/intel/uncore: Fix NULL pointer dereference issue in + upi_fill_topology() + - efivarfs: Free s_fs_info on unmount + - thermal: core: Fix NULL pointer dereference in zone registration error path + - cpuidle: haltpoll: Do not enable interrupts when entering idle + - crypto: rsa - add a check for allocation failure + - crypto: jh7110 - Correct deferred probe return + - NFS: Use parent's objective cred in nfs_access_login_time() + - asm-generic: Fix 32 bit __generic_cmpxchg_local + - arm64: dts: qcom: qrb4210-rb2: don't force usb peripheral mode + - arm64: dts: qcom: sc8280xp-x13s: Use the correct DP PHY compatible + - arm64: dts: qcom: sc8280xp-x13s: add missing camera LED pin config + - scsi: bfa: Use the proper data type for BLIST flags + - arm64: dts: ti: iot2050: Re-add aliases + - wifi: rtw88: sdio: Honor the host max_req_size in the RX path + - ARM: dts: qcom: sdx65: correct PCIe EP phy-names + - dt-bindings: arm: qcom: Fix html link + - arm64: dts: qcom: sc8180x-primus: Fix HALL_INT polarity + - arm64: dts: qcom: sm8450: correct TX Soundwire clock + - arm64: dts: qcom: sm8550: correct TX Soundwire clock + - arm64: dts: qcom: sa8775p: Make watchdog bark interrupt edge triggered + - arm64: dts: qcom: sm6125: add interrupts to DWC3 USB controller + - arm64: dts: qcom: sa8775p: fix USB wakeup interrupt types + - arm64: dts: qcom: sm8550: fix USB wakeup interrupt types + - wifi: mt76: mt7915: fallback to non-wed mode if platform_get_resource fails + in mt7915_mmio_wed_init() + - wifi: mt76: mt7996: fix the size of struct bss_rate_tlv + - wifi: mt76: mt7996: fix rate usage of inband discovery frames + - bpf: Guard stack limits against 32bit overflow + - bpf: Fix accesses to uninit stack slots + - arm64: dts: mediatek: mt8195: revise VDOSYS RDMA node name + - arm64: dts: mediatek: mt8186: Fix alias prefix for ovl_2l0 + - arm64: dts: mediatek: mt8186: fix address warning for ADSP mailboxes + - wifi: iwlwifi: don't support triggered EHT CQI feedback + - arm64: dts: xilinx: Apply overlays to base dtbs + - scsi: ufs: qcom: Fix the return value of ufs_qcom_ice_program_key() + - scsi: ufs: qcom: Fix the return value when platform_get_resource_byname() + fails + - scsi: hisi_sas: Check before using pointer variables + - bpf: Fix a race condition between btf_put() and map_free() + - virtio/vsock: send credit update during setting SO_RCVLOWAT + - bpf: Limit the number of uprobes when attaching program to multiple uprobes + - bpf: Limit the number of kprobes when attaching program to multiple kprobes + - arm64: dts: qcom: acer-aspire1: Correct audio codec definition + - arm64: dts: qcom: sm6375: fix USB wakeup interrupt types + - arm64: dts: qcom: sm6375: Hook up MPM + - arm64: dts: qcom: sm8150: make dispcc cast minimal vote on MMCX + - soc: qcom: llcc: Fix LLCC_TRP_ATTR2_CFGn offset + - arm64: dts: qcom: sm8550: Separate out X3 idle state + - arm64: dts: qcom: sm8550: Update idle state time requirements + - arm64: dts: qcom: sc8180x: Mark PCIe hosts cache-coherent + - arm64: dts: qcom: sc8180x: switch PCIe QMP PHY to new style of bindings + - arm64: dts: qcom: sc8180x: Fix up PCIe nodes + - wifi: iwlwifi: fix out of bound copy_from_user + - wifi: iwlwifi: assign phy_ctxt before eSR activation + - netfilter: nf_tables: validate chain type update if available + - Bluetooth: btnxpuart: fix recv_buf() return value + - arm64: dts: rockchip: Fix led pinctrl of lubancat 1 + - wifi: cfg80211: correct comment about MLD ID + - wifi: cfg80211: parse all ML elements in an ML probe response + - blk-cgroup: fix rcu lockdep warning in blkg_lookup() + - rxrpc: Fix skbuff cleanup of call's recvmsg_queue and rx_oos_queue + - drm/dp_mst: Fix fractional DSC bpp handling + - drm/panel: nv3051d: Hold panel in reset for unprepare + - media: visl: Hook the (TRY_)DECODER_CMD stateless ioctls + - media: amphion: Fix VPU core alias name + - drm/imx/lcdc: Fix double-free of driver data + - drm/msm/dpu: Add missing safe_lut_tbl in sc8180x catalog + - ASoC: Intel: sof_sdw_rt_sdca_jack_common: ctx->headset_codec_dev = NULL + - ASoC: SOF: topology: Use partial match for disconnecting DAI link and DAI + widget + - drm/msm/dpu: correct clk bit for WB2 block + - clk: sp7021: fix return value check in sp7021_clk_probe() + - clk: rs9: Fix DIF OEn bit placement on 9FGV0241 + - ASoC: tas2781: add support for FW version 0x0503 + - clk: qcom: gcc-sm8550: Add the missing RETAIN_FF_ENABLE GDSC flag + - clk: qcom: gcc-sm8550: Mark the PCIe GDSCs votable + - clk: qcom: gcc-sm8550: use collapse-voting for PCIe GDSCs + - clk: qcom: gcc-sm8550: Mark RCGs shared where applicable + - clk: qcom: dispcc-sm8550: Update disp PLL settings + - drm/amdkfd: Fix type of 'dbg_flags' in 'struct kfd_process' + - gpiolib: make gpio_device_get() and gpio_device_put() public + - gpiolib: provide gpio_device_find() + - gpio: sysfs: drop the mention of gpiochip_find() from sysfs code + - drm/amd/display: avoid stringop-overflow warnings for + dp_decide_lane_settings() + - kselftest/alsa - conf: Stringify the printed errno in sysfs_get() + - class: fix use-after-free in class_register() + - kernfs: convert kernfs_idr_lock to an irq safe raw spinlock + - usb: dwc3: gadget: Handle EP0 request dequeuing properly + - usb: dwc3: gadget: Queue PM runtime idle on disconnect event + - Revert "usb: typec: class: fix typec_altmode_put_partner to put plugs" + - dt-bindings: phy: qcom,sc8280xp-qmp-usb43dp-phy: fix path to header + - ceph: select FS_ENCRYPTION_ALGS if FS_ENCRYPTION + - io_uring: don't check iopoll if request completes + - io_uring: ensure local task_work is run on wait timeout + - block: Remove special-casing of compound pages + - wifi: mwifiex: add extra delay for firmware ready + - wifi: mwifiex: fix uninitialized firmware_stat + - Revert "nSVM: Check for reserved encodings of TLB_CONTROL in nested VMCB" + - x86/pci: Reserve ECAM if BIOS didn't include it in PNP0C02 _CRS + - KVM: x86/pmu: Move PMU reset logic to common x86 code + - KVM: x86/pmu: Reset the PMU, i.e. stop counters, before refreshing + - mfd: rk8xx: fixup devices registration with PLATFORM_DEVID_AUTO + - leds: aw200xx: Fix write to DIM parameter + - mfd: tps6594: Add null pointer check to tps6594_device_init() + - srcu: Use try-lock lockdep annotation for NMI-safe access. + - um: virt-pci: fix platform map offset + - PCI: Avoid potential out-of-bounds read in pci_dev_for_each_resource() + - iommu: Map reserved memory as cacheable if device is coherent + - perf test: Remove atomics from test_loop to avoid test failures + - perf header: Fix segfault on build_mem_topology() error path + - perf test record user-regs: Fix mask for vg register + - perf vendor events arm64 AmpereOne: Rename BPU_FLUSH_MEM_FAULT to + GPC_FLUSH_MEM_FAULT + - perf mem: Fix error on hybrid related to availability of mem event in a PMU + - perf stat: Exit perf stat if parse groups fails + - iio: adc: ad9467: add mutex to struct ad9467_state + - perf unwind-libdw: Handle JIT-generated DSOs properly + - perf unwind-libunwind: Fix base address for .eh_frame + - bus: mhi: ep: Do not allocate event ring element on stack + - bus: mhi: ep: Use slab allocator where applicable + - usb: gadget: webcam: Make g_webcam loadable again + - iommu: Don't reserve 0-length IOVA region + - power: supply: Fix null pointer dereference in smb2_probe + - apparmor: Fix ref count leak in task_kill + - perf stat: Fix hard coded LL miss units + - apparmor: fix possible memory leak in unpack_trans_table + - serial: apbuart: fix console prompt on qemu + - perf db-export: Fix missing reference count get in call_path_from_sample() + - cxl/port: Fix missing target list lock + - spi: coldfire-qspi: Remove an erroneous clk_disable_unprepare() from the + remove function + - hisi_acc_vfio_pci: Update migration data pointer correctly on saving/resume + - rxrpc: Fix use of Don't Fragment flag + - octeontx2-af: CN10KB: Fix FIFO length calculation for RPM2 + - net: micrel: Fix PTP frame parsing for lan8841 + - ALSA: hda: Properly setup HDMI stream + - net: add more sanity check in virtio_net_hdr_to_skb() + - net: netdev_queue: netdev_txq_completed_mb(): fix wake condition + - bpf: iter_udp: Retry with a larger batch size without going back to the + previous bucket + - bpf: Avoid iter->offset making backward progress in bpf_iter_udp + - gpio: mlxbf3: add an error code check in mlxbf3_gpio_probe + - ASoC: SOF: ipc4-loader: remove the CPC check warnings + - selftests: bonding: Change script interpreter + - io_uring: adjust defer tw counting + - arm64/ptrace: Don't flush ZA/ZT storage when writing ZA via ptrace + - mlxsw: spectrum_acl_tcam: Fix NULL pointer dereference in error path + - mlxsw: spectrum_acl_tcam: Fix stack corruption + - mlxsw: spectrum_router: Register netdevice notifier before nexthop + - Upstream stable to v6.1.75, v6.6.14 + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26583 + - net: tls, fix WARNIING in __sk_msg_free + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26589 + - bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26591 + - bpf: Fix re-attachment branch in bpf_tracing_prog_attach + + -- Roxana Nicolescu Tue, 23 Apr 2024 10:24:50 +0200 + +linux-lowlatency-hwe-6.5 (6.5.0-28.29.1~22.04.1) jammy; urgency=medium + + * jammy/linux-lowlatency-hwe-6.5: 6.5.0-28.29.1~22.04.1 -proposed tracker + (LP: #2059692) + + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + + [ Ubuntu: 6.5.0-28.29.1 ] + + * mantic/linux-lowlatency: 6.5.0-28.29.1 -proposed tracker (LP: #2059693) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * mantic/linux: 6.5.0-28.29 -proposed tracker (LP: #2059706) + * Packaging resync (LP: #1786013) + - [Packaging] drop getabis data + * Remove getabis scripts (LP: #2059143) + - [Packaging] Remove getabis + * CVE-2023-52600 + - jfs: fix uaf in jfs_evict_inode + * Mantic update: upstream stable patchset 2024-03-27 (LP: #2059284) // + CVE-2023-52603 + - UBSAN: array-index-out-of-bounds in dtSplitRoot + * CVE-2024-26581 + - netfilter: nft_set_rbtree: skip end interval element from gc + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26589 + - bpf: Reject variable offset alu on PTR_TO_FLOW_KEYS + * Mantic update: upstream stable patchset 2024-03-07 (LP: #2056403) // + CVE-2024-26591 + - bpf: Fix re-attachment branch in bpf_tracing_prog_attach + * iwlwifi disconnect and crash - intel wifi7 (LP: #2058808) + - wifi: iwlwifi: pcie: fix RB status reading + + -- Roxana Nicolescu Thu, 04 Apr 2024 18:04:20 +0200 + linux-lowlatency-hwe-6.5 (6.5.0-27.28.1~22.04.1) jammy; urgency=medium * jammy/linux-lowlatency-hwe-6.5: 6.5.0-27.28.1~22.04.1 -proposed tracker diff -u linux-lowlatency-hwe-6.5-6.5.0/debian/control linux-lowlatency-hwe-6.5-6.5.0/debian/control --- linux-lowlatency-hwe-6.5-6.5.0/debian/control +++ linux-lowlatency-hwe-6.5-6.5.0/debian/control @@ -67,7 +67,7 @@ XS-Testsuite: autopkgtest #XS-Testsuite-Depends: gcc-4.7 binutils -Package: linux-lowlatency-hwe-6.5-headers-6.5.0-27 +Package: linux-lowlatency-hwe-6.5-headers-6.5.0-34 Build-Profiles: Architecture: all Multi-Arch: foreign @@ -77,7 +77,7 @@ Description: Header files related to Linux kernel version 6.5.0 This package provides kernel header files for version 6.5.0, for sites that want the latest kernel headers. Please read - /usr/share/doc/linux-lowlatency-hwe-6.5-headers-6.5.0-27/debian.README.gz for details + /usr/share/doc/linux-lowlatency-hwe-6.5-headers-6.5.0-34/debian.README.gz for details Package: linux-lowlatency-hwe-6.5-tools-common Build-Profiles: @@ -92,18 +92,18 @@ version locked tools (such as perf and x86_energy_perf_policy) for version 6.5.0. -Package: linux-lowlatency-hwe-6.5-tools-6.5.0-27 +Package: linux-lowlatency-hwe-6.5-tools-6.5.0-34 Build-Profiles: Architecture: amd64 arm64 Section: devel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends}, linux-tools-common -Description: Linux kernel version specific tools for version 6.5.0-27 +Description: Linux kernel version specific tools for version 6.5.0-34 This package provides the architecture dependant parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.5.0-27 on + version 6.5.0-34 on 64 bit x86. - You probably want to install linux-tools-6.5.0-27-. + You probably want to install linux-tools-6.5.0-34-. Package: linux-lowlatency-hwe-6.5-cloud-tools-common Build-Profiles: @@ -116,17 +116,17 @@ This package provides the architecture independent parts for kernel version locked tools for cloud tools for version 6.5.0. -Package: linux-lowlatency-hwe-6.5-cloud-tools-6.5.0-27 +Package: linux-lowlatency-hwe-6.5-cloud-tools-6.5.0-34 Build-Profiles: Architecture: amd64 arm64 Section: devel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends}, linux-cloud-tools-common -Description: Linux kernel version specific cloud tools for version 6.5.0-27 +Description: Linux kernel version specific cloud tools for version 6.5.0-34 This package provides the architecture dependant parts for kernel - version locked tools for cloud tools for version 6.5.0-27 on + version locked tools for cloud tools for version 6.5.0-34 on 64 bit x86. - You probably want to install linux-cloud-tools-6.5.0-27-. + You probably want to install linux-cloud-tools-6.5.0-34-. Package: linux-lowlatency-hwe-6.5-tools-host Build-Profiles: @@ -140,17 +140,17 @@ -Package: linux-image-unsigned-6.5.0-27-lowlatency +Package: linux-image-unsigned-6.5.0-34-lowlatency Build-Profiles: Architecture: amd64 arm64 Section: kernel Priority: optional Provides: linux-image, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules, virtualbox-guest-modules [amd64], ${linux:rprovides} -Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.5.0-27-lowlatency +Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.5.0-34-lowlatency Recommends: grub-pc [amd64] | grub-efi-amd64 [amd64] | grub-efi-ia32 [amd64] | grub [amd64] | lilo [amd64] | flash-kernel [armhf arm64] | grub-efi-arm64 [arm64] | grub-efi-arm [armhf], initramfs-tools | linux-initramfs-tool Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x] -Conflicts: linux-image-6.5.0-27-lowlatency -Suggests: fdutils, linux-doc | linux-lowlatency-hwe-6.5-source-6.5.0, linux-lowlatency-hwe-6.5-tools, linux-headers-6.5.0-27-lowlatency, linux-modules-extra-6.5.0-27-lowlatency +Conflicts: linux-image-6.5.0-34-lowlatency +Suggests: fdutils, linux-doc | linux-lowlatency-hwe-6.5-source-6.5.0, linux-lowlatency-hwe-6.5-tools, linux-headers-6.5.0-34-lowlatency, linux-modules-extra-6.5.0-34-lowlatency Description: Linux kernel image for version 6.5.0 on 64 bit x86 SMP This package contains the unsigned Linux kernel image for version 6.5.0 on 64 bit x86 SMP. @@ -163,7 +163,7 @@ the linux-lowlatency meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-6.5.0-27-lowlatency +Package: linux-modules-6.5.0-34-lowlatency Build-Profiles: Architecture: amd64 arm64 Section: kernel @@ -183,12 +183,12 @@ the linux-lowlatency meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-extra-6.5.0-27-lowlatency +Package: linux-modules-extra-6.5.0-34-lowlatency Build-Profiles: Architecture: amd64 arm64 Section: kernel Priority: optional -Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.5.0-27-lowlatency, wireless-regdb +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.5.0-34-lowlatency, wireless-regdb Description: Linux kernel extra modules for version 6.5.0 on 64 bit x86 SMP This package contains the Linux kernel extra modules for version 6.5.0 on 64 bit x86 SMP. @@ -205,21 +205,21 @@ the linux-lowlatency meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-headers-6.5.0-27-lowlatency +Package: linux-headers-6.5.0-34-lowlatency Build-Profiles: Architecture: amd64 arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-headers-6.5.0-27, ${shlibs:Depends} +Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-headers-6.5.0-34, ${shlibs:Depends} Provides: linux-headers, linux-headers-3.0 Description: Linux kernel headers for version 6.5.0 on 64 bit x86 SMP This package provides kernel header files for version 6.5.0 on 64 bit x86 SMP. . This is for sites that want the latest kernel headers. Please read - /usr/share/doc/linux-headers-6.5.0-27/debian.README.gz for details. + /usr/share/doc/linux-headers-6.5.0-34/debian.README.gz for details. -Package: linux-lowlatency-hwe-6.5-lib-rust-6.5.0-27-lowlatency +Package: linux-lowlatency-hwe-6.5-lib-rust-6.5.0-34-lowlatency Build-Profiles: Architecture: amd64 Multi-Arch: foreign @@ -230,7 +230,7 @@ This package provides kernel library files for version 6.5.0, that allow to compile out-of-tree kernel modules written in Rust. -Package: linux-image-unsigned-6.5.0-27-lowlatency-dbgsym +Package: linux-image-unsigned-6.5.0-34-lowlatency-dbgsym Build-Profiles: Architecture: amd64 arm64 Section: devel @@ -247,31 +247,31 @@ is uncompressed, and unstripped. This package also includes the unstripped modules. -Package: linux-tools-6.5.0-27-lowlatency +Package: linux-tools-6.5.0-34-lowlatency Build-Profiles: Architecture: amd64 arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-tools-6.5.0-27 -Description: Linux kernel version specific tools for version 6.5.0-27 +Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-tools-6.5.0-34 +Description: Linux kernel version specific tools for version 6.5.0-34 This package provides the architecture dependant parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.5.0-27 on + version 6.5.0-34 on 64 bit x86. -Package: linux-cloud-tools-6.5.0-27-lowlatency +Package: linux-cloud-tools-6.5.0-34-lowlatency Build-Profiles: Architecture: amd64 arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-cloud-tools-6.5.0-27 -Description: Linux kernel version specific cloud tools for version 6.5.0-27 +Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-cloud-tools-6.5.0-34 +Description: Linux kernel version specific cloud tools for version 6.5.0-34 This package provides the architecture dependant parts for kernel - version locked tools for cloud for version 6.5.0-27 on + version locked tools for cloud for version 6.5.0-34 on 64 bit x86. -Package: linux-buildinfo-6.5.0-27-lowlatency +Package: linux-buildinfo-6.5.0-34-lowlatency Build-Profiles: Architecture: amd64 arm64 Section: kernel @@ -285,18 +285,18 @@ You likely do not want to install this package. -Package: linux-modules-iwlwifi-6.5.0-27-lowlatency +Package: linux-modules-iwlwifi-6.5.0-34-lowlatency Build-Profiles: Architecture: amd64 arm64 Section: kernel Priority: optional Depends: ${misc:Depends}, - linux-image-6.5.0-27-lowlatency | linux-image-unsigned-6.5.0-27-lowlatency, + linux-image-6.5.0-34-lowlatency | linux-image-unsigned-6.5.0-34-lowlatency, Built-Using: ${linux:BuiltUsing} -Description: Linux kernel iwlwifi modules for version 6.5.0-27 +Description: Linux kernel iwlwifi modules for version 6.5.0-34 This package provides the Linux kernel iwlwifi modules for version - 6.5.0-27. + 6.5.0-34. . You likely do not want to install this package directly. Instead, install the one of the linux-modules-iwlwifi-lowlatency* meta-packages, @@ -304,17 +304,17 @@ also installed. -Package: linux-image-unsigned-6.5.0-27-lowlatency-64k +Package: linux-image-unsigned-6.5.0-34-lowlatency-64k Build-Profiles: Architecture: arm64 Section: kernel Priority: optional Provides: linux-image, fuse-module, kvm-api-4, redhat-cluster-modules, ivtv-modules, ${linux:rprovides} -Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.5.0-27-lowlatency-64k +Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.5.0-34-lowlatency-64k Recommends: grub-efi-arm64 [arm64] | flash-kernel [arm64], initramfs-tools | linux-initramfs-tool Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x] -Conflicts: linux-image-6.5.0-27-lowlatency-64k -Suggests: fdutils, linux-doc | linux-lowlatency-hwe-6.5-source-6.5.0, linux-lowlatency-hwe-6.5-tools, linux-headers-6.5.0-27-lowlatency-64k, linux-modules-extra-6.5.0-27-lowlatency-64k +Conflicts: linux-image-6.5.0-34-lowlatency-64k +Suggests: fdutils, linux-doc | linux-lowlatency-hwe-6.5-source-6.5.0, linux-lowlatency-hwe-6.5-tools, linux-headers-6.5.0-34-lowlatency-64k, linux-modules-extra-6.5.0-34-lowlatency-64k Description: Linux kernel image for version 6.5.0 on 64 bit x86 SMP This package contains the unsigned Linux kernel image for version 6.5.0 on 64 bit x86 SMP. @@ -327,7 +327,7 @@ the linux-lowlatency-64k meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-6.5.0-27-lowlatency-64k +Package: linux-modules-6.5.0-34-lowlatency-64k Build-Profiles: Architecture: arm64 Section: kernel @@ -347,12 +347,12 @@ the linux-lowlatency-64k meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-extra-6.5.0-27-lowlatency-64k +Package: linux-modules-extra-6.5.0-34-lowlatency-64k Build-Profiles: Architecture: arm64 Section: kernel Priority: optional -Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.5.0-27-lowlatency-64k, wireless-regdb +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.5.0-34-lowlatency-64k, wireless-regdb Description: Linux kernel extra modules for version 6.5.0 on 64 bit x86 SMP This package contains the Linux kernel extra modules for version 6.5.0 on 64 bit x86 SMP. @@ -369,21 +369,21 @@ the linux-lowlatency-64k meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-headers-6.5.0-27-lowlatency-64k +Package: linux-headers-6.5.0-34-lowlatency-64k Build-Profiles: Architecture: arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-headers-6.5.0-27, ${shlibs:Depends} +Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-headers-6.5.0-34, ${shlibs:Depends} Provides: linux-headers, linux-headers-3.0 Description: Linux kernel headers for version 6.5.0 on 64 bit x86 SMP This package provides kernel header files for version 6.5.0 on 64 bit x86 SMP. . This is for sites that want the latest kernel headers. Please read - /usr/share/doc/linux-headers-6.5.0-27/debian.README.gz for details. + /usr/share/doc/linux-headers-6.5.0-34/debian.README.gz for details. -Package: linux-lowlatency-hwe-6.5-lib-rust-6.5.0-27-lowlatency-64k +Package: linux-lowlatency-hwe-6.5-lib-rust-6.5.0-34-lowlatency-64k Build-Profiles: Architecture: amd64 Multi-Arch: foreign @@ -394,7 +394,7 @@ This package provides kernel library files for version 6.5.0, that allow to compile out-of-tree kernel modules written in Rust. -Package: linux-image-unsigned-6.5.0-27-lowlatency-64k-dbgsym +Package: linux-image-unsigned-6.5.0-34-lowlatency-64k-dbgsym Build-Profiles: Architecture: arm64 Section: devel @@ -411,31 +411,31 @@ is uncompressed, and unstripped. This package also includes the unstripped modules. -Package: linux-tools-6.5.0-27-lowlatency-64k +Package: linux-tools-6.5.0-34-lowlatency-64k Build-Profiles: Architecture: arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-tools-6.5.0-27 -Description: Linux kernel version specific tools for version 6.5.0-27 +Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-tools-6.5.0-34 +Description: Linux kernel version specific tools for version 6.5.0-34 This package provides the architecture dependant parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.5.0-27 on + version 6.5.0-34 on 64 bit x86. -Package: linux-cloud-tools-6.5.0-27-lowlatency-64k +Package: linux-cloud-tools-6.5.0-34-lowlatency-64k Build-Profiles: Architecture: arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-cloud-tools-6.5.0-27 -Description: Linux kernel version specific cloud tools for version 6.5.0-27 +Depends: ${misc:Depends}, linux-lowlatency-hwe-6.5-cloud-tools-6.5.0-34 +Description: Linux kernel version specific cloud tools for version 6.5.0-34 This package provides the architecture dependant parts for kernel - version locked tools for cloud for version 6.5.0-27 on + version locked tools for cloud for version 6.5.0-34 on 64 bit x86. -Package: linux-buildinfo-6.5.0-27-lowlatency-64k +Package: linux-buildinfo-6.5.0-34-lowlatency-64k Build-Profiles: Architecture: arm64 Section: kernel @@ -449,18 +449,18 @@ You likely do not want to install this package. -Package: linux-modules-iwlwifi-6.5.0-27-lowlatency-64k +Package: linux-modules-iwlwifi-6.5.0-34-lowlatency-64k Build-Profiles: Architecture: arm64 Section: kernel Priority: optional Depends: ${misc:Depends}, - linux-image-6.5.0-27-lowlatency-64k | linux-image-unsigned-6.5.0-27-lowlatency-64k, + linux-image-6.5.0-34-lowlatency-64k | linux-image-unsigned-6.5.0-34-lowlatency-64k, Built-Using: ${linux:BuiltUsing} -Description: Linux kernel iwlwifi modules for version 6.5.0-27 +Description: Linux kernel iwlwifi modules for version 6.5.0-34 This package provides the Linux kernel iwlwifi modules for version - 6.5.0-27. + 6.5.0-34. . You likely do not want to install this package directly. Instead, install the one of the linux-modules-iwlwifi-lowlatency-64k* meta-packages, diff -u linux-lowlatency-hwe-6.5-6.5.0/debian/rules.d/0-common-vars.mk linux-lowlatency-hwe-6.5-6.5.0/debian/rules.d/0-common-vars.mk --- linux-lowlatency-hwe-6.5-6.5.0/debian/rules.d/0-common-vars.mk +++ linux-lowlatency-hwe-6.5-6.5.0/debian/rules.d/0-common-vars.mk @@ -195,9 +195,6 @@ # DTBs do_dtbs=false -# FIPS check -do_fips_checks=false - # ZSTD compressed kernel modules do_zstd_ko=true ifeq ($(series),jammy) diff -u linux-lowlatency-hwe-6.5-6.5.0/debian/rules.d/1-maintainer.mk linux-lowlatency-hwe-6.5-6.5.0/debian/rules.d/1-maintainer.mk --- linux-lowlatency-hwe-6.5-6.5.0/debian/rules.d/1-maintainer.mk +++ linux-lowlatency-hwe-6.5-6.5.0/debian/rules.d/1-maintainer.mk @@ -130,9 +130,6 @@ .PHONY: finalchecks finalchecks: debian/control -ifeq ($(do_fips_checks),true) - $(DROOT)/scripts/misc/fips-checks -endif $(DROOT)/scripts/checks/final-checks "$(DEBIAN)" "$(prev_fullver)" $(do_skip_checks) .PHONY: startnewrelease reverted: --- linux-lowlatency-hwe-6.5-6.5.0/debian/scripts/misc/fips-checks +++ linux-lowlatency-hwe-6.5-6.5.0.orig/debian/scripts/misc/fips-checks @@ -1,139 +0,0 @@ -#!/bin/bash -eu -export LC_ALL=C.UTF-8 - -usage() { - cat << EOF -Usage: ${P:-$(basename "$0")} [-h|--help] - -Check if there are any FIPS relevant changes since the last -release. Any change that is identified should have a justification in -the justifications file or the check will fail. - -Optional arguments: - -h, --help Show this help message and exit. - -p, --previous Version to use as the previous base version. - -c, --current Version to use as the current base version. - -EOF -} - -prev_base_version= -curr_base_version= -crypto_files=( crypto arch/x86/crypto drivers/char/random.c arch/s390/crypto arch/arm64/crypto lib/crypto/sha1.c lib/crypto/aes.c ) - -c_red='\033[0;31m' -c_green='\033[0;32m' -c_off='\033[0m' - -# Parse arguments -while [ "$#" -gt 0 ]; do - case "$1" in - -h|--help) - usage - exit 0 - ;; - -p|--previous) - shift - prev_base_version="$1" - ;; - -c|--current) - shift - curr_base_version="$1" - ;; - *) - usage - exit 1 - ;; - esac - shift -done - -DEBIAN= -# shellcheck disable=SC1091 -. debian/debian.env - -# Check if the "$DEBIAN" directory exists. -if [ ! -d "$DEBIAN" ]; then - echo "You must run this script from the top directory of this repository." - exit 1 -fi - -CONF="$DEBIAN/etc/update.conf" -if [ ! -f "$CONF" ]; then - echo "Missing file: $CONF" - exit 1 -fi -# shellcheck disable=SC1090 -. "$CONF" - -if [ "$DEBIAN_MASTER" = "" ]; then - echo "DEBIAN_MASTER should be defined either in $DEBIAN/etc/update.conf or the environment" - exit 1 -fi - -# Find the base kernel version used by the previous version -if [ -z "$prev_base_version" ]; then - offset=1 - # Loop through each entry of the current changelog, searching for an - # entry that refers to the master version used as base (ie a line - # containing "[ Ubuntu: 4.15.0-39.42 ]"): - while true; do - changes=$(dpkg-parsechangelog -l"$DEBIAN/changelog" -SChanges -c1 -o"$offset") - if ! [ "$changes" ]; then - echo "Failed to retrieve base master version from changelog file: $DEBIAN/changelog" - exit 1 - fi - prev_base_version=$(echo "$changes" | sed -n -r -e '/^\s.*\[ Ubuntu: ([~0-9.-]*) \]$/{s//\1/p;q}') - [ "$prev_base_version" ] && break - offset=$(( offset + 1 )) - done - if [ -z "${prev_base_version}" ]; then - echo "Failed to retrieve base version from previous version from changelog: $DEBIAN/changelog" - exit 1 - fi -fi - -# Find the current base kernel version -if [ -z "$curr_base_version" ]; then - curr_base_version=$(dpkg-parsechangelog -l"${DEBIAN_MASTER}/changelog" -SVersion) - if ! [ "$curr_base_version" ]; then - echo "Failed to retrieve current master version from changelog: $DEBIAN_MASTER/changelog" - exit 1 - fi -fi - -# Check base kernel tags -package=$(dpkg-parsechangelog -l"${DEBIAN_MASTER}/changelog" -SSource) -tag_prefix="Ubuntu${package#linux}-" -prev_tag="${tag_prefix}${prev_base_version}" -curr_tag="${tag_prefix}${curr_base_version}" -for tag in "$prev_tag" "$curr_tag"; do - if ! git rev-parse --verify "$tag" &> /dev/null; then - echo "Missing tag \"$tag\". Please fetch tags from base kernel." - exit 1 - fi -done - -# Check all the changes -fails=0 -justifications_file="$DEBIAN/fips.justifications" -justifications=$(grep -P '^[^#\s]' "$justifications_file" 2> /dev/null || true) -while read -r id; do - short_msg=$(git log --format=%s --max-count=1 "$id") - if echo "$justifications" | grep -q -x -F "$short_msg"; then - echo -e "${c_green}OK${c_off} | ${id::12} ${short_msg}" - continue - fi - echo -e "${c_red}FAIL${c_off} | ${id::12} ${short_msg}" - fails=$(( fails + 1 )) -done < <(git rev-list "${prev_tag}..${curr_tag}" -- "${crypto_files[@]}") - -echo -if [ "$fails" -gt 0 ]; then - echo "FIPS relevant changes were found without justification: ${fails} change(s)." - echo "Please, check the commits above and update the file \"${justifications_file}\"." - exit 1 -fi - -echo "Check completed without errors." -exit 0 reverted: --- linux-lowlatency-hwe-6.5-6.5.0/debian/scripts/misc/getabis +++ linux-lowlatency-hwe-6.5-6.5.0.orig/debian/scripts/misc/getabis @@ -1,222 +0,0 @@ -#!/bin/bash - -export LC_ALL=C.UTF-8 - -if [ "$#" = "1" ]; then - set - $(echo "$1" | sed -e 's/-/ /') -fi -if [ "$#" != "2" ]; then - echo "Usage: $0 " 1>&2 - echo "Usage: $0 " 1>&2 - exit 1 -fi - -if [ "$DEBIAN" = "" ]; then - . debian/debian.env -fi - -ver=$1 -revision=$2 -abi=${revision%%.*} - -verabi=$ver-$abi -verfull=$ver-$revision - -WGET="wget --tries=1 --timeout=10 --quiet -c" - -# Check if we use a flat (unversioned) ABI directory -if [ -f "${DEBIAN}/abi/version" ] || \ - grep -qP '^abidir\s+.*/__abi.current/' debian/rules.d/0-common-vars.mk ; then - echo "Using flat ABI directory" - flat_abi=1 - abidir=$(pwd)/${DEBIAN}/abi -else - echo "Using versioned ABI directory" - flat_abi=0 - abidir=$(pwd)/${DEBIAN}/abi/${verfull} -fi - -tmpdir="`pwd`/abi-tmp-$verfull" -origdir="`pwd`" -fwinfo=$abidir/fwinfo - -test -d $tmpdir || mkdir $tmpdir - -package_prefixes() { - : # no longer used ... -} - -getall() { - arch=$1 - shift - - mkdir -p $abidir/$arch - - for sub in $@; do - if [ -f $abidir/$arch/$sub ]; then - echo "Existing $sub($arch)..." - continue - fi - echo "Fetching $sub($arch)..." - getall_set "linux-buildinfo" "$arch" "$sub" || \ - getall_set "linux-image-unsigned linux-modules linux-modules-extra" "$arch" "$sub" || \ - getall_set "linux-image-unsigned linux-modules" "$arch" "$sub" || \ - getall_set "linux-image linux-modules linux-modules-extra" "$arch" "$sub" || \ - getall_set "linux-image linux-modules" "$arch" "$sub" || \ - getall_set "linux-image linux-image-extra" "$arch" "$sub" || \ - getall_set "linux-image" "$arch" "$sub" || \ - { echo "FAILED"; exit 1; } - done -} -getall_set() -{ - prefixes="$1" - arch="$2" - sub="$3" - ( - echo -n " set:" - filenames="" - cd $tmpdir - found=1 - for prefix in $prefixes - do - echo -n " $prefix=" - if [ "$found" = 0 ]; then - echo -n "-" - continue - fi - filename=${prefix}-${verabi}-${sub}_${verfull}_${arch}.deb - for r in "${repo_list[@]}" - do - if ! [ -f $filename ]; then - $WGET $r/$filename - rc="$?" - # If this was not successful or a valid error - # return from the server all bets are off, bail. - [ "$rc" != 0 -a "$rc" != 8 ] && return 2 - fi - if [ -f $filename ]; then - echo -n "y" - filenames="$filenames $filename" - break - fi - done - if [ ! -f "$filename" ]; then - echo -n "n" - found=0 - fi - done - echo "" - if [ "$found" = 0 ]; then - return 1 - fi - echo " extracting..." - for filename in $filenames - do - dpkg-deb --extract $filename tmp - done - # FORM 1: linux-image et al extracted here. - if [ -d tmp/boot ]; then - echo " images..." - find tmp -name "*.ko" | while read f; do - modinfo $f | grep ^firmware >> $fwinfo - done - if [ -f tmp/boot/abi-* ]; then - mv tmp/boot/abi-* $abidir/$arch/$sub - else - echo " NO ABI FILE" - fi - if [ -f tmp/boot/retpoline-* ]; then - mv tmp/boot/retpoline-* $abidir/$arch/$sub.retpoline - else - echo " NO RETPOLINE FILE" - fi - (cd tmp; find lib/modules/$verabi-$sub/kernel -name '*.ko') | \ - sed -e 's/.*\/\([^\/]*\)\.ko/\1/' | sort > \ - $abidir/$arch/$sub.modules - ( - cd tmp; - # Prevent exposing some errors when called by python scripts. SIGPIPE seems to get - # exposed when using the `find ...` form of the command. - ko=$(find lib/modules/$verabi-$sub/kernel \ - -name '*.ko' | head -1) - readelf -p .comment "$ko" | gawk ' - ($1 == "[") { - printf("%s", $3); - for (n=4; n<=NF; n++) { - printf(" %s", $n); - } - print "" - }' | sort -u >$abidir/$arch/$sub.compiler - version=`cat $abidir/$arch/$sub.compiler` - echo " $version" - ) - # FORM 2: moduleinfo packages - # cranky fix -- modinfo supported - else - echo " buildinfo..." - base="tmp/usr/lib/linux/${verabi}-${sub}" - mv "$base/abi" "$abidir/$arch/$sub" - for comp in 'modules' 'retpoline' 'compiler' - do - mv "$base/$comp" "$abidir/$arch/$sub.$comp" - done - if [ -e "${base}"/modules.builtin ] ; then - mv "${base}"/modules.builtin "${abidir}/${arch}/${sub}".modules.builtin - fi - cat "$base/fwinfo" >>"$fwinfo" - if [ -e "${base}"/fwinfo.builtin ] ; then - cat "${base}"/fwinfo.builtin >> "${fwinfo}".builtin - fi - fi - rm -rf tmp $filenames - echo " done" - ) - rc="$?" - if [ "$rc" = 2 ]; then - echo "ERROR: downloads are reporting network failures" 1>&2 - exit 1 - fi - return "$rc" -} - -# MAIN - -# Setup abi directory -rm -rf "${abidir}" -mkdir -p $abidir -echo $abi > $abidir/abiname -if [ ${flat_abi} -eq 1 ] ; then - echo "${verfull}" > "${abidir}"/version -fi - -# NOTE: The flavours are hardcoded, because they may have changed from the -# current build. - -. $DEBIAN/etc/getabis - -# Extract compiler source package version from e.g.: -# GCC: (Ubuntu/Linaro 4.8.2-19ubuntu1) 4.8.2 -compilers=`sed 's/^.*(.* \(.*\)).*$/\1/' $abidir/*/*.compiler | sort -u | wc -l` -if [ "$compilers" != 1 ]; then - echo "WARNING: inconsistent compiler versions detected:" 1>&2 - sort -u $abidir/*/*.compiler | sed 's/^/WARNING: /' 1>&2 -fi - -# Sort fwinfo files -sort < $fwinfo | uniq > fwinfo.tmp -mv fwinfo.tmp $fwinfo -if [ -e "${fwinfo}".builtin ] ; then - sort < "${fwinfo}".builtin | uniq > fwinfo.tmp - mv fwinfo.tmp "${fwinfo}".builtin -fi - -rmdir $tmpdir - -# If this is running in a git repo, add the new ABI directory, remove the old -if [ -d ".git" ]; then - git add "${abidir}" - if [ ${flat_abi} -eq 0 ] ; then - find "$DEBIAN"/abi/* -maxdepth 0 -type d | grep -v "$verfull" | while read f; do git rm -rf "$f"; done - fi -fi diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/acpi_video.c linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/acpi_video.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/acpi_video.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/acpi_video.c @@ -501,6 +501,15 @@ DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3350"), }, }, + { + .callback = video_set_report_key_events, + .driver_data = (void *)((uintptr_t)REPORT_BRIGHTNESS_KEY_EVENTS), + .ident = "COLORFUL X15 AT 23", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "COLORFUL"), + DMI_MATCH(DMI_PRODUCT_NAME, "X15 AT 23"), + }, + }, /* * Some machines change the brightness themselves when a brightness * hotkey gets pressed, despite us telling them not to. In this case @@ -1713,12 +1722,12 @@ return; count++; - acpi_get_parent(device->dev->handle, &acpi_parent); - - pdev = acpi_get_pci_dev(acpi_parent); - if (pdev) { - parent = &pdev->dev; - pci_dev_put(pdev); + if (ACPI_SUCCESS(acpi_get_parent(device->dev->handle, &acpi_parent))) { + pdev = acpi_get_pci_dev(acpi_parent); + if (pdev) { + parent = &pdev->dev; + pci_dev_put(pdev); + } } memset(&props, 0, sizeof(struct backlight_properties)); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/apei/ghes.c linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/apei/ghes.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/apei/ghes.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/apei/ghes.c @@ -102,6 +102,20 @@ } /* + * A platform may describe one error source for the handling of synchronous + * errors (e.g. MCE or SEA), or for handling asynchronous errors (e.g. SCI + * or External Interrupt). On x86, the HEST notifications are always + * asynchronous, so only SEA on ARM is delivered as a synchronous + * notification. + */ +static inline bool is_hest_sync_notify(struct ghes *ghes) +{ + u8 notify_type = ghes->generic->notify.type; + + return notify_type == ACPI_HEST_NOTIFY_SEA; +} + +/* * This driver isn't really modular, however for the time being, * continuing to use module_param is the easiest way to remain * compatible with existing boot arg use cases. @@ -489,7 +503,7 @@ } static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, - int sev) + int sev, bool sync) { int flags = -1; int sec_sev = ghes_severity(gdata->error_severity); @@ -503,7 +517,7 @@ (gdata->flags & CPER_SEC_ERROR_THRESHOLD_EXCEEDED)) flags = MF_SOFT_OFFLINE; if (sev == GHES_SEV_RECOVERABLE && sec_sev == GHES_SEV_RECOVERABLE) - flags = 0; + flags = sync ? MF_ACTION_REQUIRED : 0; if (flags != -1) return ghes_do_memory_failure(mem_err->physical_addr, flags); @@ -511,9 +525,11 @@ return false; } -static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int sev) +static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, + int sev, bool sync) { struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); + int flags = sync ? MF_ACTION_REQUIRED : 0; bool queued = false; int sec_sev, i; char *p; @@ -538,7 +554,7 @@ * and don't filter out 'corrected' error here. */ if (is_cache && has_pa) { - queued = ghes_do_memory_failure(err_info->physical_fault_addr, 0); + queued = ghes_do_memory_failure(err_info->physical_fault_addr, flags); p += err_info->length; continue; } @@ -666,6 +682,7 @@ const guid_t *fru_id = &guid_null; char *fru_text = ""; bool queued = false; + bool sync = is_hest_sync_notify(ghes); sev = ghes_severity(estatus->error_severity); apei_estatus_for_each_section(estatus, gdata) { @@ -683,13 +700,13 @@ atomic_notifier_call_chain(&ghes_report_chain, sev, mem_err); arch_apei_report_mem_error(sev, mem_err); - queued = ghes_handle_memory_failure(gdata, sev); + queued = ghes_handle_memory_failure(gdata, sev, sync); } else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { ghes_handle_aer(gdata); } else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { - queued = ghes_handle_arm_hw_error(gdata, sev); + queued = ghes_handle_arm_hw_error(gdata, sev, sync); } else { void *err = acpi_hest_get_payload(gdata); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/numa/srat.c linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/numa/srat.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/numa/srat.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/numa/srat.c @@ -183,7 +183,7 @@ int i, j; int d = slit->locality_count; for (i = 0; i < d; i++) { - for (j = 0; j < d; j++) { + for (j = 0; j < d; j++) { u8 val = slit->entry[d*i + j]; if (i == j) { if (val != LOCAL_DISTANCE) @@ -532,7 +532,7 @@ */ /* fake_pxm is the next unused PXM value after SRAT parsing */ - for (i = 0, fake_pxm = -1; i < MAX_NUMNODES - 1; i++) { + for (i = 0, fake_pxm = -1; i < MAX_NUMNODES; i++) { if (node_to_pxm_map[i] > fake_pxm) fake_pxm = node_to_pxm_map[i]; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/property.c linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/property.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/property.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/property.c @@ -851,6 +851,7 @@ * @index: Index of the reference to return * @num_args: Maximum number of arguments after each reference * @args: Location to store the returned reference with optional arguments + * (may be NULL) * * Find property with @name, verifify that it is a package containing at least * one object reference and if so, store the ACPI device object pointer to the @@ -907,6 +908,9 @@ if (!device) return -EINVAL; + if (!args) + return 0; + args->fwnode = acpi_fwnode_handle(device); args->nargs = 0; return 0; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/scan.c linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/scan.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/scan.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/scan.c @@ -2034,6 +2034,7 @@ mutex_unlock(&acpi_dep_list_lock); } + acpi_handle_list_free(&dep_devices); return count; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/thermal.c linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/thermal.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/thermal.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/thermal.c @@ -190,7 +190,7 @@ { acpi_status status; unsigned long long tmp; - struct acpi_handle_list devices; + struct acpi_handle_list devices = { 0 }; bool valid = false; int i; @@ -294,7 +294,7 @@ } } if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.valid) { - memset(&devices, 0, sizeof(struct acpi_handle_list)); + status = acpi_evaluate_reference(tz->device->handle, "_PSL", NULL, &devices); if (ACPI_FAILURE(status)) { @@ -305,12 +305,12 @@ tz->trips.passive.valid = true; } - if (memcmp(&tz->trips.passive.devices, &devices, - sizeof(struct acpi_handle_list))) { - memcpy(&tz->trips.passive.devices, &devices, - sizeof(struct acpi_handle_list)); - ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); + if (acpi_handle_list_equal(&tz->trips.passive.devices, &devices)) { + acpi_handle_list_free(&devices); + return 0; } + ACPI_THERMAL_TRIPS_EXCEPTION(flag, tz, "device"); + acpi_handle_list_replace(&tz->trips.passive.devices, &devices); } if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) { if (valid != tz->trips.passive.valid) @@ -959,6 +959,17 @@ mutex_unlock(&tz->thermal_check_lock); } +static void acpi_thermal_free_thermal_zone(struct acpi_thermal *tz) +{ + int i; + + acpi_handle_list_free(&tz->trips.passive.devices); + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) + acpi_handle_list_free(&tz->trips.active[i].devices); + + kfree(tz); +} + static int acpi_thermal_add(struct acpi_device *device) { struct acpi_thermal *tz; @@ -996,7 +1007,7 @@ goto end; free_memory: - kfree(tz); + acpi_thermal_free_thermal_zone(tz); end: return result; } @@ -1012,7 +1023,7 @@ tz = acpi_driver_data(device); acpi_thermal_unregister_thermal_zone(tz); - kfree(tz); + acpi_thermal_free_thermal_zone(tz); } #ifdef CONFIG_PM_SLEEP diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/android/binder_alloc.c linux-lowlatency-hwe-6.5-6.5.0/drivers/android/binder_alloc.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/android/binder_alloc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/android/binder_alloc.c @@ -270,7 +270,7 @@ } if (mm) { mmap_write_unlock(mm); - mmput(mm); + mmput_async(mm); } return 0; @@ -303,7 +303,7 @@ err_no_vma: if (mm) { mmap_write_unlock(mm); - mmput(mm); + mmput_async(mm); } return vma ? -ENOMEM : -ESRCH; } @@ -343,8 +343,7 @@ continue; if (!buffer->async_transaction) continue; - total_alloc_size += binder_alloc_buffer_size(alloc, buffer) - + sizeof(struct binder_buffer); + total_alloc_size += binder_alloc_buffer_size(alloc, buffer); num_buffers++; } @@ -406,17 +405,17 @@ alloc->pid, extra_buffers_size); return ERR_PTR(-EINVAL); } - if (is_async && - alloc->free_async_space < size + sizeof(struct binder_buffer)) { + + /* Pad 0-size buffers so they get assigned unique addresses */ + size = max(size, sizeof(void *)); + + if (is_async && alloc->free_async_space < size) { binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: binder_alloc_buf size %zd failed, no async space left\n", alloc->pid, size); return ERR_PTR(-ENOSPC); } - /* Pad 0-size buffers so they get assigned unique addresses */ - size = max(size, sizeof(void *)); - while (n) { buffer = rb_entry(n, struct binder_buffer, rb_node); BUG_ON(!buffer->free); @@ -518,7 +517,7 @@ buffer->pid = pid; buffer->oneway_spam_suspect = false; if (is_async) { - alloc->free_async_space -= size + sizeof(struct binder_buffer); + alloc->free_async_space -= size; binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, "%d: binder_alloc_buf size %zd async free %zd\n", alloc->pid, size, alloc->free_async_space); @@ -656,8 +655,7 @@ BUG_ON(buffer->user_data > alloc->buffer + alloc->buffer_size); if (buffer->async_transaction) { - alloc->free_async_space += buffer_size + sizeof(struct binder_buffer); - + alloc->free_async_space += buffer_size; binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, "%d: binder_free_buf size %zd async free %zd\n", alloc->pid, size, alloc->free_async_space); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/block/nbd.c linux-lowlatency-hwe-6.5-6.5.0/drivers/block/nbd.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/block/nbd.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/block/nbd.c @@ -510,7 +510,7 @@ struct iov_iter *iter, int msg_flags, int *sent) { int result; - struct msghdr msg; + struct msghdr msg = { }; unsigned int noreclaim_flag; if (unlikely(!sock)) { @@ -526,10 +526,6 @@ do { sock->sk->sk_allocation = GFP_NOIO | __GFP_MEMALLOC; sock->sk->sk_use_task_frag = false; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_control = NULL; - msg.msg_controllen = 0; msg.msg_flags = msg_flags | MSG_NOSIGNAL; if (send) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/block/null_blk/main.c linux-lowlatency-hwe-6.5-6.5.0/drivers/block/null_blk/main.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/block/null_blk/main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/block/null_blk/main.c @@ -2165,10 +2165,8 @@ blk_queue_logical_block_size(nullb->q, dev->blocksize); blk_queue_physical_block_size(nullb->q, dev->blocksize); - if (!dev->max_sectors) - dev->max_sectors = queue_max_hw_sectors(nullb->q); - dev->max_sectors = min(dev->max_sectors, BLK_DEF_MAX_SECTORS); - blk_queue_max_hw_sectors(nullb->q, dev->max_sectors); + if (dev->max_sectors) + blk_queue_max_hw_sectors(nullb->q, dev->max_sectors); if (dev->virt_boundary) blk_queue_virt_boundary(nullb->q, PAGE_SIZE - 1); @@ -2268,12 +2266,6 @@ g_bs = PAGE_SIZE; } - if (g_max_sectors > BLK_DEF_MAX_SECTORS) { - pr_warn("invalid max sectors\n"); - pr_warn("defaults max sectors to %u\n", BLK_DEF_MAX_SECTORS); - g_max_sectors = BLK_DEF_MAX_SECTORS; - } - if (g_home_node != NUMA_NO_NODE && g_home_node >= nr_online_nodes) { pr_err("invalid home_node value\n"); g_home_node = NUMA_NO_NODE; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/block/rbd.c linux-lowlatency-hwe-6.5-6.5.0/drivers/block/rbd.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/block/rbd.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/block/rbd.c @@ -3452,14 +3452,15 @@ static void rbd_lock_del_request(struct rbd_img_request *img_req) { struct rbd_device *rbd_dev = img_req->rbd_dev; - bool need_wakeup; + bool need_wakeup = false; lockdep_assert_held(&rbd_dev->lock_rwsem); spin_lock(&rbd_dev->lock_lists_lock); - rbd_assert(!list_empty(&img_req->lock_item)); - list_del_init(&img_req->lock_item); - need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING && - list_empty(&rbd_dev->running_list)); + if (!list_empty(&img_req->lock_item)) { + list_del_init(&img_req->lock_item); + need_wakeup = (rbd_dev->lock_state == RBD_LOCK_STATE_RELEASING && + list_empty(&rbd_dev->running_list)); + } spin_unlock(&rbd_dev->lock_lists_lock); if (need_wakeup) complete(&rbd_dev->releasing_wait); @@ -3842,14 +3843,19 @@ return; } - list_for_each_entry(img_req, &rbd_dev->acquiring_list, lock_item) { + while (!list_empty(&rbd_dev->acquiring_list)) { + img_req = list_first_entry(&rbd_dev->acquiring_list, + struct rbd_img_request, lock_item); mutex_lock(&img_req->state_mutex); rbd_assert(img_req->state == RBD_IMG_EXCLUSIVE_LOCK); + if (!result) + list_move_tail(&img_req->lock_item, + &rbd_dev->running_list); + else + list_del_init(&img_req->lock_item); rbd_img_schedule(img_req, result); mutex_unlock(&img_req->state_mutex); } - - list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list); } static bool locker_equal(const struct ceph_locker *lhs, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/char/hw_random/core.c linux-lowlatency-hwe-6.5-6.5.0/drivers/char/hw_random/core.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/char/hw_random/core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/char/hw_random/core.c @@ -24,10 +24,13 @@ #include #include #include +#include #include #define RNG_MODULE_NAME "hw_random" +#define RNG_BUFFER_SIZE (SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES) + static struct hwrng *current_rng; /* the current rng has been explicitly chosen by user via sysfs */ static int cur_rng_set_by_user; @@ -59,7 +62,7 @@ static size_t rng_buffer_size(void) { - return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES; + return RNG_BUFFER_SIZE; } static void add_early_randomness(struct hwrng *rng) @@ -210,6 +213,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf, size_t size, loff_t *offp) { + u8 buffer[RNG_BUFFER_SIZE]; ssize_t ret = 0; int err = 0; int bytes_read, len; @@ -237,34 +241,37 @@ if (bytes_read < 0) { err = bytes_read; goto out_unlock_reading; + } else if (bytes_read == 0 && + (filp->f_flags & O_NONBLOCK)) { + err = -EAGAIN; + goto out_unlock_reading; } + data_avail = bytes_read; } - if (!data_avail) { - if (filp->f_flags & O_NONBLOCK) { - err = -EAGAIN; - goto out_unlock_reading; - } - } else { - len = data_avail; + len = data_avail; + if (len) { if (len > size) len = size; data_avail -= len; - if (copy_to_user(buf + ret, rng_buffer + data_avail, - len)) { + memcpy(buffer, rng_buffer + data_avail, len); + } + mutex_unlock(&reading_mutex); + put_rng(rng); + + if (len) { + if (copy_to_user(buf + ret, buffer, len)) { err = -EFAULT; - goto out_unlock_reading; + goto out; } size -= len; ret += len; } - mutex_unlock(&reading_mutex); - put_rng(rng); if (need_resched()) schedule_timeout_interruptible(1); @@ -275,6 +282,7 @@ } } out: + memzero_explicit(buffer, sizeof(buffer)); return ret ? : err; out_unlock_reading: diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/imx/clk-imx8qxp.c linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/imx/clk-imx8qxp.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/imx/clk-imx8qxp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/imx/clk-imx8qxp.c @@ -67,6 +67,22 @@ "lcd_pxl_bypass_div_clk", }; +static const char *const lvds0_sels[] = { + "clk_dummy", + "clk_dummy", + "clk_dummy", + "clk_dummy", + "mipi0_lvds_bypass_clk", +}; + +static const char *const lvds1_sels[] = { + "clk_dummy", + "clk_dummy", + "clk_dummy", + "clk_dummy", + "mipi1_lvds_bypass_clk", +}; + static const char * const mipi_sels[] = { "clk_dummy", "clk_dummy", @@ -201,9 +217,9 @@ /* MIPI-LVDS SS */ imx_clk_scu("mipi0_bypass_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_BYPASS); imx_clk_scu("mipi0_pixel_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PER); - imx_clk_scu("mipi0_lvds_pixel_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2); imx_clk_scu("mipi0_lvds_bypass_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_BYPASS); - imx_clk_scu("mipi0_lvds_phy_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3); + imx_clk_scu2("mipi0_lvds_pixel_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2); + imx_clk_scu2("mipi0_lvds_phy_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3); imx_clk_scu2("mipi0_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_MST_BUS); imx_clk_scu2("mipi0_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_SLV_BUS); imx_clk_scu2("mipi0_dsi_phy_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PHY); @@ -213,9 +229,9 @@ imx_clk_scu("mipi1_bypass_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_BYPASS); imx_clk_scu("mipi1_pixel_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_PER); - imx_clk_scu("mipi1_lvds_pixel_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2); imx_clk_scu("mipi1_lvds_bypass_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_BYPASS); - imx_clk_scu("mipi1_lvds_phy_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3); + imx_clk_scu2("mipi1_lvds_pixel_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2); + imx_clk_scu2("mipi1_lvds_phy_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3); imx_clk_scu2("mipi1_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_MST_BUS); imx_clk_scu2("mipi1_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_SLV_BUS); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/qcom/dispcc-sm8550.c linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/qcom/dispcc-sm8550.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/qcom/dispcc-sm8550.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/qcom/dispcc-sm8550.c @@ -81,6 +81,10 @@ .config_ctl_val = 0x20485699, .config_ctl_hi_val = 0x00182261, .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, .user_ctl_val = 0x00000000, .user_ctl_hi_val = 0x00000005, }; @@ -108,6 +112,10 @@ .config_ctl_val = 0x20485699, .config_ctl_hi_val = 0x00182261, .config_ctl_hi1_val = 0x82aa299c, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x00000003, + .test_ctl_hi1_val = 0x00009000, + .test_ctl_hi2_val = 0x00000034, .user_ctl_val = 0x00000000, .user_ctl_hi_val = 0x00000005, }; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/renesas/rzg2l-cpg.c linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/renesas/rzg2l-cpg.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/renesas/rzg2l-cpg.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/renesas/rzg2l-cpg.c @@ -1112,41 +1112,33 @@ #define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev) -static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, - unsigned long id) -{ - struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); - const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; - u32 dis = BIT(info->resets[id].bit); - u32 we = dis << 16; - - dev_dbg(rcdev->dev, "reset id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); - - /* Reset module */ - writel(we, priv->base + CLK_RST_R(reg)); - - /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ - udelay(35); - - /* Release module from reset state */ - writel(we | dis, priv->base + CLK_RST_R(reg)); - - return 0; -} - static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev, unsigned long id) { struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); const struct rzg2l_cpg_info *info = priv->info; unsigned int reg = info->resets[id].off; - u32 value = BIT(info->resets[id].bit) << 16; + u32 mask = BIT(info->resets[id].bit); + s8 monbit = info->resets[id].monbit; + u32 value = mask << 16; dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); writel(value, priv->base + CLK_RST_R(reg)); - return 0; + + if (info->has_clk_mon_regs) { + reg = CLK_MRST_R(reg); + } else if (monbit >= 0) { + reg = CPG_RST_MON; + mask = BIT(monbit); + } else { + /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ + udelay(35); + return 0; + } + + return readl_poll_timeout_atomic(priv->base + reg, value, + value & mask, 10, 200); } static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev, @@ -1155,14 +1147,40 @@ struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); const struct rzg2l_cpg_info *info = priv->info; unsigned int reg = info->resets[id].off; - u32 dis = BIT(info->resets[id].bit); - u32 value = (dis << 16) | dis; + u32 mask = BIT(info->resets[id].bit); + s8 monbit = info->resets[id].monbit; + u32 value = (mask << 16) | mask; dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id, CLK_RST_R(reg)); writel(value, priv->base + CLK_RST_R(reg)); - return 0; + + if (info->has_clk_mon_regs) { + reg = CLK_MRST_R(reg); + } else if (monbit >= 0) { + reg = CPG_RST_MON; + mask = BIT(monbit); + } else { + /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ + udelay(35); + return 0; + } + + return readl_poll_timeout_atomic(priv->base + reg, value, + !(value & mask), 10, 200); +} + +static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev, + unsigned long id) +{ + int ret; + + ret = rzg2l_cpg_assert(rcdev, id); + if (ret) + return ret; + + return rzg2l_cpg_deassert(rcdev, id); } static int rzg2l_cpg_status(struct reset_controller_dev *rcdev, @@ -1170,18 +1188,21 @@ { struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev); const struct rzg2l_cpg_info *info = priv->info; - unsigned int reg = info->resets[id].off; - u32 bitmask = BIT(info->resets[id].bit); s8 monbit = info->resets[id].monbit; + unsigned int reg; + u32 bitmask; if (info->has_clk_mon_regs) { - return !!(readl(priv->base + CLK_MRST_R(reg)) & bitmask); + reg = CLK_MRST_R(info->resets[id].off); + bitmask = BIT(info->resets[id].bit); } else if (monbit >= 0) { - u32 monbitmask = BIT(monbit); - - return !!(readl(priv->base + CPG_RST_MON) & monbitmask); + reg = CPG_RST_MON; + bitmask = BIT(monbit); + } else { + return -ENOTSUPP; } - return -ENOTSUPP; + + return !!(readl(priv->base + reg) & bitmask); } static const struct reset_control_ops rzg2l_cpg_reset_ops = { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/clocksource/timer-ti-dm.c linux-lowlatency-hwe-6.5-6.5.0/drivers/clocksource/timer-ti-dm.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/clocksource/timer-ti-dm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clocksource/timer-ti-dm.c @@ -184,7 +184,7 @@ * dmtimer_write - write timer registers in posted and non-posted mode * @timer: timer pointer over which write operation is to perform * @reg: lowest byte holds the register offset - * @value: data to write into the register + * @val: data to write into the register * * The posted mode bit is encoded in reg. Note that in posted mode, the write * pending bit must be checked. Otherwise a write on a register which has a @@ -950,7 +950,7 @@ /** * omap_dm_timer_set_int_disable - disable timer interrupts - * @timer: pointer to timer handle + * @cookie: pointer to timer cookie * @mask: bit mask of interrupts to be disabled * * Disables the specified timer interrupts for a timer. diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/cpufreq/amd-pstate.c linux-lowlatency-hwe-6.5-6.5.0/drivers/cpufreq/amd-pstate.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/cpufreq/amd-pstate.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/cpufreq/amd-pstate.c @@ -1232,14 +1232,13 @@ max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); + WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf); + WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf); + max_perf = clamp_t(unsigned long, max_perf, cpudata->min_limit_perf, cpudata->max_limit_perf); min_perf = clamp_t(unsigned long, min_perf, cpudata->min_limit_perf, cpudata->max_limit_perf); - - WRITE_ONCE(cpudata->max_limit_perf, max_limit_perf); - WRITE_ONCE(cpudata->min_limit_perf, min_limit_perf); - value = READ_ONCE(cpudata->cppc_req_cached); if (cpudata->policy == CPUFREQ_POLICY_PERFORMANCE) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/cpufreq/intel_pstate.c linux-lowlatency-hwe-6.5-6.5.0/drivers/cpufreq/intel_pstate.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/cpufreq/intel_pstate.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/cpufreq/intel_pstate.c @@ -526,6 +526,30 @@ } #endif /* CONFIG_ACPI_CPPC_LIB */ +static int intel_pstate_freq_to_hwp_rel(struct cpudata *cpu, int freq, + unsigned int relation) +{ + if (freq == cpu->pstate.turbo_freq) + return cpu->pstate.turbo_pstate; + + if (freq == cpu->pstate.max_freq) + return cpu->pstate.max_pstate; + + switch (relation) { + case CPUFREQ_RELATION_H: + return freq / cpu->pstate.scaling; + case CPUFREQ_RELATION_C: + return DIV_ROUND_CLOSEST(freq, cpu->pstate.scaling); + } + + return DIV_ROUND_UP(freq, cpu->pstate.scaling); +} + +static int intel_pstate_freq_to_hwp(struct cpudata *cpu, int freq) +{ + return intel_pstate_freq_to_hwp_rel(cpu, freq, CPUFREQ_RELATION_L); +} + /** * intel_pstate_hybrid_hwp_adjust - Calibrate HWP performance levels. * @cpu: Target CPU. @@ -543,6 +567,7 @@ int perf_ctl_scaling = cpu->pstate.perf_ctl_scaling; int perf_ctl_turbo = pstate_funcs.get_turbo(cpu->cpu); int scaling = cpu->pstate.scaling; + int freq; pr_debug("CPU%d: perf_ctl_max_phys = %d\n", cpu->cpu, perf_ctl_max_phys); pr_debug("CPU%d: perf_ctl_turbo = %d\n", cpu->cpu, perf_ctl_turbo); @@ -556,16 +581,16 @@ cpu->pstate.max_freq = rounddown(cpu->pstate.max_pstate * scaling, perf_ctl_scaling); - cpu->pstate.max_pstate_physical = - DIV_ROUND_UP(perf_ctl_max_phys * perf_ctl_scaling, - scaling); + freq = perf_ctl_max_phys * perf_ctl_scaling; + cpu->pstate.max_pstate_physical = intel_pstate_freq_to_hwp(cpu, freq); - cpu->pstate.min_freq = cpu->pstate.min_pstate * perf_ctl_scaling; + freq = cpu->pstate.min_pstate * perf_ctl_scaling; + cpu->pstate.min_freq = freq; /* * Cast the min P-state value retrieved via pstate_funcs.get_min() to * the effective range of HWP performance levels. */ - cpu->pstate.min_pstate = DIV_ROUND_UP(cpu->pstate.min_freq, scaling); + cpu->pstate.min_pstate = intel_pstate_freq_to_hwp(cpu, freq); } static inline void update_turbo_state(void) @@ -2528,13 +2553,12 @@ * abstract values to represent performance rather than pure ratios. */ if (hwp_active && cpu->pstate.scaling != perf_ctl_scaling) { - int scaling = cpu->pstate.scaling; int freq; freq = max_policy_perf * perf_ctl_scaling; - max_policy_perf = DIV_ROUND_UP(freq, scaling); + max_policy_perf = intel_pstate_freq_to_hwp(cpu, freq); freq = min_policy_perf * perf_ctl_scaling; - min_policy_perf = DIV_ROUND_UP(freq, scaling); + min_policy_perf = intel_pstate_freq_to_hwp(cpu, freq); } pr_debug("cpu:%d min_policy_perf:%d max_policy_perf:%d\n", @@ -2908,18 +2932,7 @@ cpufreq_freq_transition_begin(policy, &freqs); - switch (relation) { - case CPUFREQ_RELATION_L: - target_pstate = DIV_ROUND_UP(freqs.new, cpu->pstate.scaling); - break; - case CPUFREQ_RELATION_H: - target_pstate = freqs.new / cpu->pstate.scaling; - break; - default: - target_pstate = DIV_ROUND_CLOSEST(freqs.new, cpu->pstate.scaling); - break; - } - + target_pstate = intel_pstate_freq_to_hwp_rel(cpu, freqs.new, relation); target_pstate = intel_cpufreq_update_pstate(policy, target_pstate, false); freqs.new = target_pstate * cpu->pstate.scaling; @@ -2937,7 +2950,7 @@ update_turbo_state(); - target_pstate = DIV_ROUND_UP(target_freq, cpu->pstate.scaling); + target_pstate = intel_pstate_freq_to_hwp(cpu, target_freq); target_pstate = intel_cpufreq_update_pstate(policy, target_pstate, true); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/hpre/hpre_main.c linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/hpre/hpre_main.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/hpre/hpre_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/hpre/hpre_main.c @@ -117,8 +117,6 @@ #define HPRE_DFX_COMMON2_LEN 0xE #define HPRE_DFX_CORE_LEN 0x43 -#define HPRE_DEV_ALG_MAX_LEN 256 - static const char hpre_name[] = "hisi_hpre"; static struct dentry *hpre_debugfs_root; static const struct pci_device_id hpre_dev_ids[] = { @@ -134,12 +132,7 @@ const char *msg; }; -struct hpre_dev_alg { - u32 alg_msk; - const char *alg; -}; - -static const struct hpre_dev_alg hpre_dev_algs[] = { +static const struct qm_dev_alg hpre_dev_algs[] = { { .alg_msk = BIT(0), .alg = "rsa\n" @@ -232,6 +225,20 @@ {HPRE_CORE10_ALG_BITMAP_CAP, 0x3170, 0, GENMASK(31, 0), 0x0, 0x10, 0x10} }; +enum hpre_pre_store_cap_idx { + HPRE_CLUSTER_NUM_CAP_IDX = 0x0, + HPRE_CORE_ENABLE_BITMAP_CAP_IDX, + HPRE_DRV_ALG_BITMAP_CAP_IDX, + HPRE_DEV_ALG_BITMAP_CAP_IDX, +}; + +static const u32 hpre_pre_store_caps[] = { + HPRE_CLUSTER_NUM_CAP, + HPRE_CORE_ENABLE_BITMAP_CAP, + HPRE_DRV_ALG_BITMAP_CAP, + HPRE_DEV_ALG_BITMAP_CAP, +}; + static const struct hpre_hw_error hpre_hw_errors[] = { { .int_msk = BIT(0), @@ -351,42 +358,13 @@ { u32 cap_val; - cap_val = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DRV_ALG_BITMAP_CAP, qm->cap_ver); + cap_val = qm->cap_tables.dev_cap_table[HPRE_DRV_ALG_BITMAP_CAP_IDX].cap_val; if (alg & cap_val) return true; return false; } -static int hpre_set_qm_algs(struct hisi_qm *qm) -{ - struct device *dev = &qm->pdev->dev; - char *algs, *ptr; - u32 alg_msk; - int i; - - if (!qm->use_sva) - return 0; - - algs = devm_kzalloc(dev, HPRE_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); - if (!algs) - return -ENOMEM; - - alg_msk = hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_DEV_ALG_BITMAP_CAP, qm->cap_ver); - - for (i = 0; i < ARRAY_SIZE(hpre_dev_algs); i++) - if (alg_msk & hpre_dev_algs[i].alg_msk) - strcat(algs, hpre_dev_algs[i].alg); - - ptr = strrchr(algs, '\n'); - if (ptr) - *ptr = '\0'; - - qm->uacce->algs = algs; - - return 0; -} - static int hpre_diff_regs_show(struct seq_file *s, void *unused) { struct hisi_qm *qm = s->private; @@ -456,16 +434,6 @@ module_param_cb(vfs_num, &vfs_num_ops, &vfs_num, 0444); MODULE_PARM_DESC(vfs_num, "Number of VFs to enable(1-63), 0(default)"); -static inline int hpre_cluster_num(struct hisi_qm *qm) -{ - return hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_CLUSTER_NUM_CAP, qm->cap_ver); -} - -static inline int hpre_cluster_core_mask(struct hisi_qm *qm) -{ - return hisi_qm_get_hw_info(qm, hpre_basic_info, HPRE_CORE_ENABLE_BITMAP_CAP, qm->cap_ver); -} - struct hisi_qp *hpre_create_qp(u8 type) { int node = cpu_to_node(smp_processor_id()); @@ -532,13 +500,15 @@ static int hpre_set_cluster(struct hisi_qm *qm) { - u32 cluster_core_mask = hpre_cluster_core_mask(qm); - u8 clusters_num = hpre_cluster_num(qm); struct device *dev = &qm->pdev->dev; unsigned long offset; + u32 cluster_core_mask; + u8 clusters_num; u32 val = 0; int ret, i; + cluster_core_mask = qm->cap_tables.dev_cap_table[HPRE_CORE_ENABLE_BITMAP_CAP_IDX].cap_val; + clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; for (i = 0; i < clusters_num; i++) { offset = i * HPRE_CLSTR_ADDR_INTRVL; @@ -733,11 +703,12 @@ static void hpre_cnt_regs_clear(struct hisi_qm *qm) { - u8 clusters_num = hpre_cluster_num(qm); unsigned long offset; + u8 clusters_num; int i; /* clear clusterX/cluster_ctrl */ + clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; for (i = 0; i < clusters_num; i++) { offset = HPRE_CLSTR_BASE + i * HPRE_CLSTR_ADDR_INTRVL; writel(0x0, qm->io_base + offset + HPRE_CLUSTER_INQURY); @@ -1024,13 +995,14 @@ static int hpre_cluster_debugfs_init(struct hisi_qm *qm) { - u8 clusters_num = hpre_cluster_num(qm); struct device *dev = &qm->pdev->dev; char buf[HPRE_DBGFS_VAL_MAX_LEN]; struct debugfs_regset32 *regset; struct dentry *tmp_d; + u8 clusters_num; int i, ret; + clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; for (i = 0; i < clusters_num; i++) { ret = snprintf(buf, HPRE_DBGFS_VAL_MAX_LEN, "cluster%d", i); if (ret >= HPRE_DBGFS_VAL_MAX_LEN) @@ -1135,8 +1107,37 @@ debugfs_remove_recursive(qm->debug.debug_root); } +static int hpre_pre_store_cap_reg(struct hisi_qm *qm) +{ + struct hisi_qm_cap_record *hpre_cap; + struct device *dev = &qm->pdev->dev; + size_t i, size; + + size = ARRAY_SIZE(hpre_pre_store_caps); + hpre_cap = devm_kzalloc(dev, sizeof(*hpre_cap) * size, GFP_KERNEL); + if (!hpre_cap) + return -ENOMEM; + + for (i = 0; i < size; i++) { + hpre_cap[i].type = hpre_pre_store_caps[i]; + hpre_cap[i].cap_val = hisi_qm_get_hw_info(qm, hpre_basic_info, + hpre_pre_store_caps[i], qm->cap_ver); + } + + if (hpre_cap[HPRE_CLUSTER_NUM_CAP_IDX].cap_val > HPRE_CLUSTERS_NUM_MAX) { + dev_err(dev, "Device cluster num %u is out of range for driver supports %d!\n", + hpre_cap[HPRE_CLUSTER_NUM_CAP_IDX].cap_val, HPRE_CLUSTERS_NUM_MAX); + return -EINVAL; + } + + qm->cap_tables.dev_cap_table = hpre_cap; + + return 0; +} + static int hpre_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) { + u64 alg_msk; int ret; if (pdev->revision == QM_HW_V1) { @@ -1167,7 +1168,16 @@ return ret; } - ret = hpre_set_qm_algs(qm); + /* Fetch and save the value of capability registers */ + ret = hpre_pre_store_cap_reg(qm); + if (ret) { + pci_err(pdev, "Failed to pre-store capability registers!\n"); + hisi_qm_uninit(qm); + return ret; + } + + alg_msk = qm->cap_tables.dev_cap_table[HPRE_DEV_ALG_BITMAP_CAP_IDX].cap_val; + ret = hisi_qm_set_algs(qm, alg_msk, hpre_dev_algs, ARRAY_SIZE(hpre_dev_algs)); if (ret) { pci_err(pdev, "Failed to set hpre algs!\n"); hisi_qm_uninit(qm); @@ -1180,11 +1190,12 @@ { int cluster_dfx_regs_num = ARRAY_SIZE(hpre_cluster_dfx_regs); int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs); - u8 clusters_num = hpre_cluster_num(qm); struct qm_debug *debug = &qm->debug; void __iomem *io_base; + u8 clusters_num; int i, j, idx; + clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; debug->last_words = kcalloc(cluster_dfx_regs_num * clusters_num + com_dfx_regs_num, sizeof(unsigned int), GFP_KERNEL); if (!debug->last_words) @@ -1221,10 +1232,10 @@ { int cluster_dfx_regs_num = ARRAY_SIZE(hpre_cluster_dfx_regs); int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs); - u8 clusters_num = hpre_cluster_num(qm); struct qm_debug *debug = &qm->debug; struct pci_dev *pdev = qm->pdev; void __iomem *io_base; + u8 clusters_num; int i, j, idx; u32 val; @@ -1239,6 +1250,7 @@ hpre_com_dfx_regs[i].name, debug->last_words[i], val); } + clusters_num = qm->cap_tables.dev_cap_table[HPRE_CLUSTER_NUM_CAP_IDX].cap_val; for (i = 0; i < clusters_num; i++) { io_base = qm->io_base + hpre_cluster_offsets[i]; for (j = 0; j < cluster_dfx_regs_num; j++) { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/qm.c linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/qm.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/qm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/qm.c @@ -226,6 +226,8 @@ #define QM_QOS_MAX_CIR_U 6 #define QM_AUTOSUSPEND_DELAY 3000 +#define QM_DEV_ALG_MAX_LEN 256 + #define QM_MK_CQC_DW3_V1(hop_num, pg_sz, buf_sz, cqe_sz) \ (((hop_num) << QM_CQ_HOP_NUM_SHIFT) | \ ((pg_sz) << QM_CQ_PAGE_SIZE_SHIFT) | \ @@ -304,6 +306,13 @@ QM_VF_IRQ_NUM_CAP, }; +enum qm_pre_store_cap_idx { + QM_EQ_IRQ_TYPE_CAP_IDX = 0x0, + QM_AEQ_IRQ_TYPE_CAP_IDX, + QM_ABN_IRQ_TYPE_CAP_IDX, + QM_PF2VF_IRQ_TYPE_CAP_IDX, +}; + static const struct hisi_qm_cap_info qm_cap_info_comm[] = { {QM_SUPPORT_DB_ISOLATION, 0x30, 0, BIT(0), 0x0, 0x0, 0x0}, {QM_SUPPORT_FUNC_QOS, 0x3100, 0, BIT(8), 0x0, 0x0, 0x1}, @@ -333,6 +342,13 @@ {QM_VF_IRQ_NUM_CAP, 0x311c, 0, GENMASK(15, 0), 0x1, 0x2, 0x3}, }; +static const u32 qm_pre_store_caps[] = { + QM_EQ_IRQ_TYPE_CAP, + QM_AEQ_IRQ_TYPE_CAP, + QM_ABN_IRQ_TYPE_CAP, + QM_PF2VF_IRQ_TYPE_CAP, +}; + struct qm_mailbox { __le16 w0; __le16 queue_num; @@ -785,6 +801,40 @@ *high_bits = (depth >> QM_XQ_DEPTH_SHIFT) & QM_XQ_DEPTH_MASK; } +int hisi_qm_set_algs(struct hisi_qm *qm, u64 alg_msk, const struct qm_dev_alg *dev_algs, + u32 dev_algs_size) +{ + struct device *dev = &qm->pdev->dev; + char *algs, *ptr; + int i; + + if (!qm->uacce) + return 0; + + if (dev_algs_size >= QM_DEV_ALG_MAX_LEN) { + dev_err(dev, "algs size %u is equal or larger than %d.\n", + dev_algs_size, QM_DEV_ALG_MAX_LEN); + return -EINVAL; + } + + algs = devm_kzalloc(dev, QM_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); + if (!algs) + return -ENOMEM; + + for (i = 0; i < dev_algs_size; i++) + if (alg_msk & dev_algs[i].alg_msk) + strcat(algs, dev_algs[i].alg); + + ptr = strrchr(algs, '\n'); + if (ptr) { + *ptr = '\0'; + qm->uacce->algs = algs; + } + + return 0; +} +EXPORT_SYMBOL_GPL(hisi_qm_set_algs); + static u32 qm_get_irq_num(struct hisi_qm *qm) { if (qm->fun_type == QM_HW_PF) @@ -4891,7 +4941,7 @@ if (qm->fun_type == QM_HW_VF) return; - val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver); + val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) return; @@ -4908,7 +4958,7 @@ if (qm->fun_type == QM_HW_VF) return 0; - val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_ABN_IRQ_TYPE_CAP, qm->cap_ver); + val = qm->cap_tables.qm_cap_table[QM_ABN_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_ABN_IRQ_TYPE_MASK)) return 0; @@ -4925,7 +4975,7 @@ struct pci_dev *pdev = qm->pdev; u32 irq_vector, val; - val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver); + val = qm->cap_tables.qm_cap_table[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return; @@ -4939,7 +4989,7 @@ u32 irq_vector, val; int ret; - val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_PF2VF_IRQ_TYPE_CAP, qm->cap_ver); + val = qm->cap_tables.qm_cap_table[QM_PF2VF_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return 0; @@ -4956,7 +5006,7 @@ struct pci_dev *pdev = qm->pdev; u32 irq_vector, val; - val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver); + val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return; @@ -4970,7 +5020,7 @@ u32 irq_vector, val; int ret; - val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_AEQ_IRQ_TYPE_CAP, qm->cap_ver); + val = qm->cap_tables.qm_cap_table[QM_AEQ_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return 0; @@ -4988,7 +5038,7 @@ struct pci_dev *pdev = qm->pdev; u32 irq_vector, val; - val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver); + val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return; @@ -5002,7 +5052,7 @@ u32 irq_vector, val; int ret; - val = hisi_qm_get_hw_info(qm, qm_basic_info, QM_EQ_IRQ_TYPE_CAP, qm->cap_ver); + val = qm->cap_tables.qm_cap_table[QM_EQ_IRQ_TYPE_CAP_IDX].cap_val; if (!((val >> QM_IRQ_TYPE_SHIFT) & QM_IRQ_TYPE_MASK)) return 0; @@ -5090,7 +5140,29 @@ return 0; } -static void qm_get_hw_caps(struct hisi_qm *qm) +static int qm_pre_store_irq_type_caps(struct hisi_qm *qm) +{ + struct hisi_qm_cap_record *qm_cap; + struct pci_dev *pdev = qm->pdev; + size_t i, size; + + size = ARRAY_SIZE(qm_pre_store_caps); + qm_cap = devm_kzalloc(&pdev->dev, sizeof(*qm_cap) * size, GFP_KERNEL); + if (!qm_cap) + return -ENOMEM; + + for (i = 0; i < size; i++) { + qm_cap[i].type = qm_pre_store_caps[i]; + qm_cap[i].cap_val = hisi_qm_get_hw_info(qm, qm_basic_info, + qm_pre_store_caps[i], qm->cap_ver); + } + + qm->cap_tables.qm_cap_table = qm_cap; + + return 0; +} + +static int qm_get_hw_caps(struct hisi_qm *qm) { const struct hisi_qm_cap_info *cap_info = qm->fun_type == QM_HW_PF ? qm_cap_info_pf : qm_cap_info_vf; @@ -5121,6 +5193,9 @@ if (val) set_bit(cap_info[i].type, &qm->caps); } + + /* Fetch and save the value of irq type related capability registers */ + return qm_pre_store_irq_type_caps(qm); } static int qm_get_pci_res(struct hisi_qm *qm) @@ -5142,7 +5217,10 @@ goto err_request_mem_regions; } - qm_get_hw_caps(qm); + ret = qm_get_hw_caps(qm); + if (ret) + goto err_ioremap; + if (test_bit(QM_SUPPORT_DB_ISOLATION, &qm->caps)) { qm->db_interval = QM_QP_DB_INTERVAL; qm->db_phys_base = pci_resource_start(pdev, PCI_BAR_4); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/sec2/sec_main.c linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/sec2/sec_main.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/sec2/sec_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/sec2/sec_main.c @@ -120,7 +120,6 @@ GENMASK_ULL(42, 25)) #define SEC_AEAD_BITMAP (GENMASK_ULL(7, 6) | GENMASK_ULL(18, 17) | \ GENMASK_ULL(45, 43)) -#define SEC_DEV_ALG_MAX_LEN 256 struct sec_hw_error { u32 int_msk; @@ -132,11 +131,6 @@ u32 offset; }; -struct sec_dev_alg { - u64 alg_msk; - const char *algs; -}; - static const char sec_name[] = "hisi_sec2"; static struct dentry *sec_debugfs_root; @@ -173,15 +167,22 @@ {SEC_CORE4_ALG_BITMAP_HIGH, 0x3170, 0, GENMASK(31, 0), 0x3FFF, 0x3FFF, 0x3FFF}, }; -static const struct sec_dev_alg sec_dev_algs[] = { { +static const u32 sec_pre_store_caps[] = { + SEC_DRV_ALG_BITMAP_LOW, + SEC_DRV_ALG_BITMAP_HIGH, + SEC_DEV_ALG_BITMAP_LOW, + SEC_DEV_ALG_BITMAP_HIGH, +}; + +static const struct qm_dev_alg sec_dev_algs[] = { { .alg_msk = SEC_CIPHER_BITMAP, - .algs = "cipher\n", + .alg = "cipher\n", }, { .alg_msk = SEC_DIGEST_BITMAP, - .algs = "digest\n", + .alg = "digest\n", }, { .alg_msk = SEC_AEAD_BITMAP, - .algs = "aead\n", + .alg = "aead\n", }, }; @@ -394,8 +395,8 @@ { u32 cap_val_h, cap_val_l; - cap_val_h = hisi_qm_get_hw_info(qm, sec_basic_info, high, qm->cap_ver); - cap_val_l = hisi_qm_get_hw_info(qm, sec_basic_info, low, qm->cap_ver); + cap_val_h = qm->cap_tables.dev_cap_table[high].cap_val; + cap_val_l = qm->cap_tables.dev_cap_table[low].cap_val; return ((u64)cap_val_h << SEC_ALG_BITMAP_SHIFT) | (u64)cap_val_l; } @@ -1077,37 +1078,31 @@ return ret; } -static int sec_set_qm_algs(struct hisi_qm *qm) +static int sec_pre_store_cap_reg(struct hisi_qm *qm) { - struct device *dev = &qm->pdev->dev; - char *algs, *ptr; - u64 alg_mask; - int i; - - if (!qm->use_sva) - return 0; - - algs = devm_kzalloc(dev, SEC_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); - if (!algs) + struct hisi_qm_cap_record *sec_cap; + struct pci_dev *pdev = qm->pdev; + size_t i, size; + + size = ARRAY_SIZE(sec_pre_store_caps); + sec_cap = devm_kzalloc(&pdev->dev, sizeof(*sec_cap) * size, GFP_KERNEL); + if (!sec_cap) return -ENOMEM; - alg_mask = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH, SEC_DEV_ALG_BITMAP_LOW); - - for (i = 0; i < ARRAY_SIZE(sec_dev_algs); i++) - if (alg_mask & sec_dev_algs[i].alg_msk) - strcat(algs, sec_dev_algs[i].algs); - - ptr = strrchr(algs, '\n'); - if (ptr) - *ptr = '\0'; + for (i = 0; i < size; i++) { + sec_cap[i].type = sec_pre_store_caps[i]; + sec_cap[i].cap_val = hisi_qm_get_hw_info(qm, sec_basic_info, + sec_pre_store_caps[i], qm->cap_ver); + } - qm->uacce->algs = algs; + qm->cap_tables.dev_cap_table = sec_cap; return 0; } static int sec_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) { + u64 alg_msk; int ret; qm->pdev = pdev; @@ -1142,7 +1137,16 @@ return ret; } - ret = sec_set_qm_algs(qm); + /* Fetch and save the value of capability registers */ + ret = sec_pre_store_cap_reg(qm); + if (ret) { + pci_err(qm->pdev, "Failed to pre-store capability registers!\n"); + hisi_qm_uninit(qm); + return ret; + } + + alg_msk = sec_get_alg_bitmap(qm, SEC_DEV_ALG_BITMAP_HIGH_IDX, SEC_DEV_ALG_BITMAP_LOW_IDX); + ret = hisi_qm_set_algs(qm, alg_msk, sec_dev_algs, ARRAY_SIZE(sec_dev_algs)); if (ret) { pci_err(qm->pdev, "Failed to set sec algs!\n"); hisi_qm_uninit(qm); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/zip/zip_main.c linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/zip/zip_main.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/zip/zip_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/zip/zip_main.c @@ -73,7 +73,6 @@ #define HZIP_AXI_SHUTDOWN_ENABLE BIT(14) #define HZIP_WR_PORT BIT(11) -#define HZIP_DEV_ALG_MAX_LEN 256 #define HZIP_ALG_ZLIB_BIT GENMASK(1, 0) #define HZIP_ALG_GZIP_BIT GENMASK(3, 2) #define HZIP_ALG_DEFLATE_BIT GENMASK(5, 4) @@ -106,6 +105,14 @@ #define HZIP_CLOCK_GATED_EN (HZIP_CORE_GATED_EN | \ HZIP_CORE_GATED_OOO_EN) +/* zip comp high performance */ +#define HZIP_HIGH_PERF_OFFSET 0x301208 + +enum { + HZIP_HIGH_COMP_RATE, + HZIP_HIGH_COMP_PERF, +}; + static const char hisi_zip_name[] = "hisi_zip"; static struct dentry *hzip_debugfs_root; @@ -119,23 +126,18 @@ u32 offset; }; -struct zip_dev_alg { - u32 alg_msk; - const char *algs; -}; - -static const struct zip_dev_alg zip_dev_algs[] = { { +static const struct qm_dev_alg zip_dev_algs[] = { { .alg_msk = HZIP_ALG_ZLIB_BIT, - .algs = "zlib\n", + .alg = "zlib\n", }, { .alg_msk = HZIP_ALG_GZIP_BIT, - .algs = "gzip\n", + .alg = "gzip\n", }, { .alg_msk = HZIP_ALG_DEFLATE_BIT, - .algs = "deflate\n", + .alg = "deflate\n", }, { .alg_msk = HZIP_ALG_LZ77_BIT, - .algs = "lz77_zstd\n", + .alg = "lz77_zstd\n", }, }; @@ -246,6 +248,26 @@ {ZIP_CAP_MAX, 0x317c, 0, GENMASK(0, 0), 0x0, 0x0, 0x0} }; +enum zip_pre_store_cap_idx { + ZIP_CORE_NUM_CAP_IDX = 0x0, + ZIP_CLUSTER_COMP_NUM_CAP_IDX, + ZIP_CLUSTER_DECOMP_NUM_CAP_IDX, + ZIP_DECOMP_ENABLE_BITMAP_IDX, + ZIP_COMP_ENABLE_BITMAP_IDX, + ZIP_DRV_ALG_BITMAP_IDX, + ZIP_DEV_ALG_BITMAP_IDX, +}; + +static const u32 zip_pre_store_caps[] = { + ZIP_CORE_NUM_CAP, + ZIP_CLUSTER_COMP_NUM_CAP, + ZIP_CLUSTER_DECOMP_NUM_CAP, + ZIP_DECOMP_ENABLE_BITMAP, + ZIP_COMP_ENABLE_BITMAP, + ZIP_DRV_ALG_BITMAP, + ZIP_DEV_ALG_BITMAP, +}; + enum { HZIP_COMP_CORE0, HZIP_COMP_CORE1, @@ -351,6 +373,37 @@ return 0; } DEFINE_SHOW_ATTRIBUTE(hzip_diff_regs); + +static int perf_mode_set(const char *val, const struct kernel_param *kp) +{ + int ret; + u32 n; + + if (!val) + return -EINVAL; + + ret = kstrtou32(val, 10, &n); + if (ret != 0 || (n != HZIP_HIGH_COMP_PERF && + n != HZIP_HIGH_COMP_RATE)) + return -EINVAL; + + return param_set_int(val, kp); +} + +static const struct kernel_param_ops zip_com_perf_ops = { + .set = perf_mode_set, + .get = param_get_int, +}; + +/* + * perf_mode = 0 means enable high compression rate mode, + * perf_mode = 1 means enable high compression performance mode. + * These two modes only apply to the compression direction. + */ +static u32 perf_mode = HZIP_HIGH_COMP_RATE; +module_param_cb(perf_mode, &zip_com_perf_ops, &perf_mode, 0444); +MODULE_PARM_DESC(perf_mode, "ZIP high perf mode 0(default), 1(enable)"); + static const struct kernel_param_ops zip_uacce_mode_ops = { .set = uacce_mode_set, .get = param_get_int, @@ -409,40 +462,33 @@ { u32 cap_val; - cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DRV_ALG_BITMAP, qm->cap_ver); + cap_val = qm->cap_tables.dev_cap_table[ZIP_DRV_ALG_BITMAP_IDX].cap_val; if ((alg & cap_val) == alg) return true; return false; } -static int hisi_zip_set_qm_algs(struct hisi_qm *qm) +static int hisi_zip_set_high_perf(struct hisi_qm *qm) { - struct device *dev = &qm->pdev->dev; - char *algs, *ptr; - u32 alg_mask; - int i; - - if (!qm->use_sva) - return 0; - - algs = devm_kzalloc(dev, HZIP_DEV_ALG_MAX_LEN * sizeof(char), GFP_KERNEL); - if (!algs) - return -ENOMEM; - - alg_mask = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_DEV_ALG_BITMAP, qm->cap_ver); - - for (i = 0; i < ARRAY_SIZE(zip_dev_algs); i++) - if (alg_mask & zip_dev_algs[i].alg_msk) - strcat(algs, zip_dev_algs[i].algs); - - ptr = strrchr(algs, '\n'); - if (ptr) - *ptr = '\0'; + u32 val; + int ret; - qm->uacce->algs = algs; + val = readl_relaxed(qm->io_base + HZIP_HIGH_PERF_OFFSET); + if (perf_mode == HZIP_HIGH_COMP_PERF) + val |= HZIP_HIGH_COMP_PERF; + else + val &= ~HZIP_HIGH_COMP_PERF; + + /* Set perf mode */ + writel(val, qm->io_base + HZIP_HIGH_PERF_OFFSET); + ret = readl_relaxed_poll_timeout(qm->io_base + HZIP_HIGH_PERF_OFFSET, + val, val == perf_mode, HZIP_DELAY_1_US, + HZIP_POLL_TIMEOUT_US); + if (ret) + pci_err(qm->pdev, "failed to set perf mode\n"); - return 0; + return ret; } static void hisi_zip_open_sva_prefetch(struct hisi_qm *qm) @@ -541,10 +587,8 @@ } /* let's open all compression/decompression cores */ - dcomp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info, - ZIP_DECOMP_ENABLE_BITMAP, qm->cap_ver); - comp_bm = hisi_qm_get_hw_info(qm, zip_basic_cap_info, - ZIP_COMP_ENABLE_BITMAP, qm->cap_ver); + dcomp_bm = qm->cap_tables.dev_cap_table[ZIP_DECOMP_ENABLE_BITMAP_IDX].cap_val; + comp_bm = qm->cap_tables.dev_cap_table[ZIP_COMP_ENABLE_BITMAP_IDX].cap_val; writel(HZIP_DECOMP_CHECK_ENABLE | dcomp_bm | comp_bm, base + HZIP_CLOCK_GATE_CTRL); /* enable sqc,cqc writeback */ @@ -771,9 +815,8 @@ char buf[HZIP_BUF_SIZE]; int i; - zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); - zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP, - qm->cap_ver); + zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; + zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val; for (i = 0; i < zip_core_num; i++) { if (i < zip_comp_core_num) @@ -915,7 +958,7 @@ u32 zip_core_num; int i, j, idx; - zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); + zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; debug->last_words = kcalloc(core_dfx_regs_num * zip_core_num + com_dfx_regs_num, sizeof(unsigned int), GFP_KERNEL); @@ -971,9 +1014,9 @@ hzip_com_dfx_regs[i].name, debug->last_words[i], val); } - zip_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CORE_NUM_CAP, qm->cap_ver); - zip_comp_core_num = hisi_qm_get_hw_info(qm, zip_basic_cap_info, ZIP_CLUSTER_COMP_NUM_CAP, - qm->cap_ver); + zip_core_num = qm->cap_tables.dev_cap_table[ZIP_CORE_NUM_CAP_IDX].cap_val; + zip_comp_core_num = qm->cap_tables.dev_cap_table[ZIP_CLUSTER_COMP_NUM_CAP_IDX].cap_val; + for (i = 0; i < zip_core_num; i++) { if (i < zip_comp_core_num) scnprintf(buf, sizeof(buf), "Comp_core-%d", i); @@ -1114,6 +1157,10 @@ if (ret) return ret; + ret = hisi_zip_set_high_perf(qm); + if (ret) + return ret; + hisi_zip_open_sva_prefetch(qm); hisi_qm_dev_err_init(qm); hisi_zip_debug_regs_clear(qm); @@ -1125,8 +1172,31 @@ return ret; } +static int zip_pre_store_cap_reg(struct hisi_qm *qm) +{ + struct hisi_qm_cap_record *zip_cap; + struct pci_dev *pdev = qm->pdev; + size_t i, size; + + size = ARRAY_SIZE(zip_pre_store_caps); + zip_cap = devm_kzalloc(&pdev->dev, sizeof(*zip_cap) * size, GFP_KERNEL); + if (!zip_cap) + return -ENOMEM; + + for (i = 0; i < size; i++) { + zip_cap[i].type = zip_pre_store_caps[i]; + zip_cap[i].cap_val = hisi_qm_get_hw_info(qm, zip_basic_cap_info, + zip_pre_store_caps[i], qm->cap_ver); + } + + qm->cap_tables.dev_cap_table = zip_cap; + + return 0; +} + static int hisi_zip_qm_init(struct hisi_qm *qm, struct pci_dev *pdev) { + u64 alg_msk; int ret; qm->pdev = pdev; @@ -1162,7 +1232,16 @@ return ret; } - ret = hisi_zip_set_qm_algs(qm); + /* Fetch and save the value of capability registers */ + ret = zip_pre_store_cap_reg(qm); + if (ret) { + pci_err(qm->pdev, "Failed to pre-store capability registers!\n"); + hisi_qm_uninit(qm); + return ret; + } + + alg_msk = qm->cap_tables.dev_cap_table[ZIP_DEV_ALG_BITMAP_IDX].cap_val; + ret = hisi_qm_set_algs(qm, alg_msk, zip_dev_algs, ARRAY_SIZE(zip_dev_algs)); if (ret) { pci_err(qm->pdev, "Failed to set zip algs!\n"); hisi_qm_uninit(qm); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/virtio/virtio_crypto_common.h linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/virtio/virtio_crypto_common.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/virtio/virtio_crypto_common.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/virtio/virtio_crypto_common.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ char name[32]; struct crypto_engine *engine; + struct tasklet_struct done_task; }; struct virtio_crypto { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/virtio/virtio_crypto_core.c linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/virtio/virtio_crypto_core.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/virtio/virtio_crypto_core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/virtio/virtio_crypto_core.c @@ -72,27 +72,28 @@ return 0; } -static void virtcrypto_dataq_callback(struct virtqueue *vq) +static void virtcrypto_done_task(unsigned long data) { - struct virtio_crypto *vcrypto = vq->vdev->priv; + struct data_queue *data_vq = (struct data_queue *)data; + struct virtqueue *vq = data_vq->vq; struct virtio_crypto_request *vc_req; - unsigned long flags; unsigned int len; - unsigned int qid = vq->index; - spin_lock_irqsave(&vcrypto->data_vq[qid].lock, flags); do { virtqueue_disable_cb(vq); while ((vc_req = virtqueue_get_buf(vq, &len)) != NULL) { - spin_unlock_irqrestore( - &vcrypto->data_vq[qid].lock, flags); if (vc_req->alg_cb) vc_req->alg_cb(vc_req, len); - spin_lock_irqsave( - &vcrypto->data_vq[qid].lock, flags); } } while (!virtqueue_enable_cb(vq)); - spin_unlock_irqrestore(&vcrypto->data_vq[qid].lock, flags); +} + +static void virtcrypto_dataq_callback(struct virtqueue *vq) +{ + struct virtio_crypto *vcrypto = vq->vdev->priv; + struct data_queue *dq = &vcrypto->data_vq[vq->index]; + + tasklet_schedule(&dq->done_task); } static int virtcrypto_find_vqs(struct virtio_crypto *vi) @@ -150,6 +151,8 @@ ret = -ENOMEM; goto err_engine; } + tasklet_init(&vi->data_vq[i].done_task, virtcrypto_done_task, + (unsigned long)&vi->data_vq[i]); } kfree(names); @@ -497,12 +500,15 @@ static void virtcrypto_remove(struct virtio_device *vdev) { struct virtio_crypto *vcrypto = vdev->priv; + int i; dev_info(&vdev->dev, "Start virtcrypto_remove.\n"); flush_work(&vcrypto->config_work); if (virtcrypto_dev_started(vcrypto)) virtcrypto_dev_stop(vcrypto); + for (i = 0; i < vcrypto->max_data_queues; i++) + tasklet_kill(&vcrypto->data_vq[i].done_task); virtio_reset_device(vdev); virtcrypto_free_unused_reqs(vcrypto); virtcrypto_clear_crypto_engines(vcrypto); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/core/port.c linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/core/port.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/core/port.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/core/port.c @@ -172,14 +172,10 @@ { struct cxl_switch_decoder *cxlsd = to_cxl_switch_decoder(dev); ssize_t offset; - unsigned int seq; int rc; - do { - seq = read_seqbegin(&cxlsd->target_lock); - rc = emit_target_list(cxlsd, buf); - } while (read_seqretry(&cxlsd->target_lock, seq)); - + guard(rwsem_read)(&cxl_region_rwsem); + rc = emit_target_list(cxlsd, buf); if (rc < 0) return rc; offset = rc; @@ -1579,7 +1575,7 @@ static int decoder_populate_targets(struct cxl_switch_decoder *cxlsd, struct cxl_port *port, int *target_map) { - int i, rc = 0; + int i; if (!target_map) return 0; @@ -1589,19 +1585,16 @@ if (xa_empty(&port->dports)) return -EINVAL; - write_seqlock(&cxlsd->target_lock); - for (i = 0; i < cxlsd->nr_targets; i++) { + guard(rwsem_write)(&cxl_region_rwsem); + for (i = 0; i < cxlsd->cxld.interleave_ways; i++) { struct cxl_dport *dport = find_dport(port, target_map[i]); - if (!dport) { - rc = -ENXIO; - break; - } + if (!dport) + return -ENXIO; cxlsd->target[i] = dport; } - write_sequnlock(&cxlsd->target_lock); - return rc; + return 0; } struct cxl_dport *cxl_hb_modulo(struct cxl_root_decoder *cxlrd, int pos) @@ -1671,7 +1664,6 @@ return -EINVAL; cxlsd->nr_targets = nr_targets; - seqlock_init(&cxlsd->target_lock); return cxl_decoder_init(port, &cxlsd->cxld); } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/core/region.c linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/core/region.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/core/region.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/core/region.c @@ -397,7 +397,7 @@ return rc; /* - * Even for x3, x9, and x12 interleaves the region interleave must be a + * Even for x3, x6, and x12 interleaves the region interleave must be a * power of 2 multiple of the host bridge interleave. */ if (!is_power_of_2(val / cxld->interleave_ways) || @@ -525,7 +525,7 @@ struct cxl_root_decoder *cxlrd = to_cxl_root_decoder(cxlr->dev.parent); struct cxl_region_params *p = &cxlr->params; struct resource *res; - u32 remainder = 0; + u64 remainder = 0; lockdep_assert_held_write(&cxl_region_rwsem); @@ -545,7 +545,7 @@ (cxlr->mode == CXL_DECODER_PMEM && uuid_is_null(&p->uuid))) return -ENXIO; - div_u64_rem(size, SZ_256M * p->interleave_ways, &remainder); + div64_u64_rem(size, (u64)SZ_256M * p->interleave_ways, &remainder); if (remainder) return -EINVAL; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/cxl.h linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/cxl.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/cxl.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/cxl/cxl.h @@ -404,7 +404,6 @@ /** * struct cxl_switch_decoder - Switch specific CXL HDM Decoder * @cxld: base cxl_decoder object - * @target_lock: coordinate coherent reads of the target list * @nr_targets: number of elements in @target * @target: active ordered target list in current decoder configuration * @@ -416,7 +415,6 @@ */ struct cxl_switch_decoder { struct cxl_decoder cxld; - seqlock_t target_lock; int nr_targets; struct cxl_dport *target[]; }; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/devfreq/devfreq.c linux-lowlatency-hwe-6.5-6.5.0/drivers/devfreq/devfreq.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/devfreq/devfreq.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/devfreq/devfreq.c @@ -461,10 +461,14 @@ if (err) dev_err(&devfreq->dev, "dvfs failed with (%d) error\n", err); + if (devfreq->stop_polling) + goto out; + queue_delayed_work(devfreq_wq, &devfreq->work, msecs_to_jiffies(devfreq->profile->polling_ms)); - mutex_unlock(&devfreq->lock); +out: + mutex_unlock(&devfreq->lock); trace_devfreq_monitor(devfreq); } @@ -482,6 +486,10 @@ if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN)) return; + mutex_lock(&devfreq->lock); + if (delayed_work_pending(&devfreq->work)) + goto out; + switch (devfreq->profile->timer) { case DEVFREQ_TIMER_DEFERRABLE: INIT_DEFERRABLE_WORK(&devfreq->work, devfreq_monitor); @@ -490,12 +498,16 @@ INIT_DELAYED_WORK(&devfreq->work, devfreq_monitor); break; default: - return; + goto out; } if (devfreq->profile->polling_ms) queue_delayed_work(devfreq_wq, &devfreq->work, msecs_to_jiffies(devfreq->profile->polling_ms)); + +out: + devfreq->stop_polling = false; + mutex_unlock(&devfreq->lock); } EXPORT_SYMBOL(devfreq_monitor_start); @@ -512,6 +524,14 @@ if (IS_SUPPORTED_FLAG(devfreq->governor->flags, IRQ_DRIVEN)) return; + mutex_lock(&devfreq->lock); + if (devfreq->stop_polling) { + mutex_unlock(&devfreq->lock); + return; + } + + devfreq->stop_polling = true; + mutex_unlock(&devfreq->lock); cancel_delayed_work_sync(&devfreq->work); } EXPORT_SYMBOL(devfreq_monitor_stop); @@ -1687,7 +1707,7 @@ struct device_attribute *attr, char *buf) { struct devfreq *df = to_devfreq(dev); - ssize_t len; + ssize_t len = 0; int i, j; unsigned int max_state; @@ -1696,7 +1716,7 @@ max_state = df->max_state; if (max_state == 0) - return sprintf(buf, "Not Supported.\n"); + return scnprintf(buf, PAGE_SIZE, "Not Supported.\n"); mutex_lock(&df->lock); if (!df->stop_polling && @@ -1706,31 +1726,52 @@ } mutex_unlock(&df->lock); - len = sprintf(buf, " From : To\n"); - len += sprintf(buf + len, " :"); - for (i = 0; i < max_state; i++) - len += sprintf(buf + len, "%10lu", - df->freq_table[i]); + len += scnprintf(buf + len, PAGE_SIZE - len, " From : To\n"); + len += scnprintf(buf + len, PAGE_SIZE - len, " :"); + for (i = 0; i < max_state; i++) { + if (len >= PAGE_SIZE - 1) + break; + len += scnprintf(buf + len, PAGE_SIZE - len, "%10lu", + df->freq_table[i]); + } + if (len >= PAGE_SIZE - 1) + return PAGE_SIZE - 1; - len += sprintf(buf + len, " time(ms)\n"); + len += scnprintf(buf + len, PAGE_SIZE - len, " time(ms)\n"); for (i = 0; i < max_state; i++) { + if (len >= PAGE_SIZE - 1) + break; if (df->freq_table[i] == df->previous_freq) - len += sprintf(buf + len, "*"); + len += scnprintf(buf + len, PAGE_SIZE - len, "*"); else - len += sprintf(buf + len, " "); + len += scnprintf(buf + len, PAGE_SIZE - len, " "); + if (len >= PAGE_SIZE - 1) + break; + + len += scnprintf(buf + len, PAGE_SIZE - len, "%10lu:", + df->freq_table[i]); + for (j = 0; j < max_state; j++) { + if (len >= PAGE_SIZE - 1) + break; + len += scnprintf(buf + len, PAGE_SIZE - len, "%10u", + df->stats.trans_table[(i * max_state) + j]); + } + if (len >= PAGE_SIZE - 1) + break; + len += scnprintf(buf + len, PAGE_SIZE - len, "%10llu\n", (u64) + jiffies64_to_msecs(df->stats.time_in_state[i])); + } - len += sprintf(buf + len, "%10lu:", df->freq_table[i]); - for (j = 0; j < max_state; j++) - len += sprintf(buf + len, "%10u", - df->stats.trans_table[(i * max_state) + j]); + if (len < PAGE_SIZE - 1) + len += scnprintf(buf + len, PAGE_SIZE - len, "Total transition : %u\n", + df->stats.total_trans); - len += sprintf(buf + len, "%10llu\n", (u64) - jiffies64_to_msecs(df->stats.time_in_state[i])); + if (len >= PAGE_SIZE - 1) { + pr_warn_once("devfreq transition table exceeds PAGE_SIZE. Disabling\n"); + return -EFBIG; } - len += sprintf(buf + len, "Total transition : %u\n", - df->stats.total_trans); return len; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/dma/idxd/device.c linux-lowlatency-hwe-6.5-6.5.0/drivers/dma/idxd/device.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/dma/idxd/device.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/dma/idxd/device.c @@ -819,6 +819,9 @@ static void idxd_device_evl_free(struct idxd_device *idxd) { + void *evl_log; + unsigned int evl_log_size; + dma_addr_t evl_dma; union gencfg_reg gencfg; union genctrl_reg genctrl; struct device *dev = &idxd->pdev->dev; @@ -839,11 +842,15 @@ iowrite64(0, idxd->reg_base + IDXD_EVLCFG_OFFSET); iowrite64(0, idxd->reg_base + IDXD_EVLCFG_OFFSET + 8); - dma_free_coherent(dev, evl->log_size, evl->log, evl->dma); bitmap_free(evl->bmap); + evl_log = evl->log; + evl_log_size = evl->log_size; + evl_dma = evl->dma; evl->log = NULL; evl->size = IDXD_EVL_SIZE_MIN; spin_unlock(&evl->lock); + + dma_free_coherent(dev, evl_log_size, evl_log, evl_dma); } static void idxd_group_config_write(struct idxd_group *group) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/firmware/ti_sci.c linux-lowlatency-hwe-6.5-6.5.0/drivers/firmware/ti_sci.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/firmware/ti_sci.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/firmware/ti_sci.c @@ -161,7 +161,7 @@ { struct device *dev = &pdev->dev; struct resource *res; - char debug_name[50] = "ti_sci_debug@"; + char debug_name[50]; /* Debug region is optional */ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, @@ -178,10 +178,10 @@ /* Setup NULL termination */ info->debug_buffer[info->debug_region_size] = 0; - info->d = debugfs_create_file(strncat(debug_name, dev_name(dev), - sizeof(debug_name) - - sizeof("ti_sci_debug@")), - 0444, NULL, info, &ti_sci_debug_fops); + snprintf(debug_name, sizeof(debug_name), "ti_sci_debug@%s", + dev_name(dev)); + info->d = debugfs_create_file(debug_name, 0444, NULL, info, + &ti_sci_debug_fops); if (IS_ERR(info->d)) return PTR_ERR(info->d); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpiolib-acpi.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpiolib-acpi.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpiolib-acpi.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpiolib-acpi.c @@ -1675,6 +1675,20 @@ .ignore_interrupt = "INT33FC:00@3", }, }, + { + /* + * Spurious wakeups from TP_ATTN# pin + * Found in BIOS 0.35 + * https://gitlab.freedesktop.org/drm/amd/-/issues/3073 + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "GPD"), + DMI_MATCH(DMI_PRODUCT_NAME, "G1619-04"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "PNP0C50:00@8", + }, + }, {} /* Terminating entry */ }; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpiolib-sysfs.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpiolib-sysfs.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpiolib-sysfs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpiolib-sysfs.c @@ -817,7 +817,7 @@ * gpiochip_sysfs_register() acquires a mutex. This is unsafe * and needs to be fixed. * - * Also it would be nice to use gpiochip_find() here so we + * Also it would be nice to use gpio_device_find() here so we * can keep gpio_chips local to gpiolib.c, but the yield of * gpio_lock prevents us from doing this. */ diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -754,7 +754,7 @@ int r; if (!adev->smc_rreg) - return -EPERM; + return -EOPNOTSUPP; if (size & 0x3 || *pos & 0x3) return -EINVAL; @@ -813,7 +813,7 @@ int r; if (!adev->smc_wreg) - return -EPERM; + return -EOPNOTSUPP; if (size & 0x3 || *pos & 0x3) return -EINVAL; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1442,6 +1442,7 @@ return true; fw_ver = *((uint32_t *)adev->pm.fw->data + 69); + release_firmware(adev->pm.fw); if (fw_ver < 0x00160e00) return true; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -954,6 +954,11 @@ op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER; op_input.set_shader_debugger.process_context_addr = process_context_addr; op_input.set_shader_debugger.flags.u32all = flags; + + /* use amdgpu mes_flush_shader_debugger instead */ + if (op_input.set_shader_debugger.flags.process_ctx_flush) + return -EINVAL; + op_input.set_shader_debugger.spi_gdbg_per_vmid_cntl = spi_gdbg_per_vmid_cntl; memcpy(op_input.set_shader_debugger.tcp_watch_cntl, tcp_watch_cntl, sizeof(op_input.set_shader_debugger.tcp_watch_cntl)); @@ -973,6 +978,32 @@ return r; } +int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev, + uint64_t process_context_addr) +{ + struct mes_misc_op_input op_input = {0}; + int r; + + if (!adev->mes.funcs->misc_op) { + DRM_ERROR("mes flush shader debugger is not supported!\n"); + return -EINVAL; + } + + op_input.op = MES_MISC_OP_SET_SHADER_DEBUGGER; + op_input.set_shader_debugger.process_context_addr = process_context_addr; + op_input.set_shader_debugger.flags.process_ctx_flush = true; + + amdgpu_mes_lock(&adev->mes); + + r = adev->mes.funcs->misc_op(&adev->mes, &op_input); + if (r) + DRM_ERROR("failed to set_shader_debugger\n"); + + amdgpu_mes_unlock(&adev->mes); + + return r; +} + static void amdgpu_mes_ring_to_queue_props(struct amdgpu_device *adev, struct amdgpu_ring *ring, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h @@ -342,9 +342,7 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, size_t buffer_size, uint32_t *metadata_size, uint64_t *flags); -void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, - bool evict, - struct ttm_resource *new_mem); +void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict); void amdgpu_bo_release_notify(struct ttm_buffer_object *bo); vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo); void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -4003,16 +4003,13 @@ if (!amdgpu_sriov_vf(adev)) { snprintf(fw_name, sizeof(fw_name), "amdgpu/%s_rlc.bin", ucode_prefix); - err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw, fw_name); - /* don't check this. There are apparently firmwares in the wild with - * incorrect size in the header - */ - if (err == -ENODEV) - goto out; + err = request_firmware(&adev->gfx.rlc_fw, fw_name, adev->dev); if (err) - dev_dbg(adev->dev, - "gfx10: amdgpu_ucode_request() failed \"%s\"\n", - fw_name); + goto out; + + /* don't validate this firmware. There are apparently firmwares + * in the wild with incorrect size in the header + */ rlc_hdr = (const struct rlc_firmware_header_v2_0 *)adev->gfx.rlc_fw->data; version_major = le16_to_cpu(rlc_hdr->header.header_version_major); version_minor = le16_to_cpu(rlc_hdr->header.header_version_minor); @@ -6584,7 +6581,7 @@ #ifdef __BIG_ENDIAN tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, ENDIAN_SWAP, 1); #endif - tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0); + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 1); tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 0); tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -3807,7 +3807,7 @@ (order_base_2(prop->queue_size / 4) - 1)); tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, RPTR_BLOCK_SIZE, (order_base_2(AMDGPU_GPU_PAGE_SIZE / 4) - 1)); - tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 0); + tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, UNORD_DISPATCH, 1); tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, TUNNEL_DISPATCH, 0); tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, PRIV_STATE, 1); tmp = REG_SET_FIELD(tmp, CP_HQD_PQ_CONTROL, KMD_QUEUE, 1); @@ -6379,6 +6379,9 @@ mutex_lock(&adev->grbm_idx_mutex); for (i = 0; i < adev->gfx.config.max_shader_engines; i++) { for (j = 0; j < adev->gfx.config.max_sh_per_se; j++) { + bitmap = i * adev->gfx.config.max_sh_per_se + j; + if (!((gfx_v11_0_get_sa_active_bitmap(adev) >> bitmap) & 1)) + continue; mask = 1; counter = 0; gfx_v11_0_select_se_sh(adev, i, j, 0xffffffff, 0); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -1148,6 +1148,10 @@ amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); + if (adev->gmc.ecc_irq.funcs && + amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) + amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); + return 0; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -975,6 +975,11 @@ } amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); + + if (adev->gmc.ecc_irq.funcs && + amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) + amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); + gmc_v11_0_gart_disable(adev); return 0; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -2364,8 +2364,8 @@ if (amdgpu_emu_mode == 1) return amdgpu_gmc_vram_checking(adev); - else - return r; + + return 0; } /** @@ -2404,6 +2404,10 @@ amdgpu_irq_put(adev, &adev->gmc.vm_fault, 0); + if (adev->gmc.ecc_irq.funcs && + amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__UMC)) + amdgpu_irq_put(adev, &adev->gmc.ecc_irq, 0); + return 0; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c @@ -170,6 +170,7 @@ m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT; m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1; + m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK; pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control); m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c @@ -224,6 +224,7 @@ m->cp_hqd_pq_control = 5 << CP_HQD_PQ_CONTROL__RPTR_BLOCK_SIZE__SHIFT; m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int)) - 1 - 1; + m->cp_hqd_pq_control |= CP_HQD_PQ_CONTROL__UNORD_DISPATCH_MASK; pr_debug("cp_hqd_pq_control 0x%x\n", m->cp_hqd_pq_control); m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_priv.h linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_priv.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -984,7 +984,7 @@ struct work_struct debug_event_workarea; /* Tracks debug per-vmid request for debug flags */ - bool dbg_flags; + u32 dbg_flags; atomic_t poison; /* Queues are in paused stated because we are in the process of doing a CRIU checkpoint */ diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -87,6 +87,8 @@ return; dev->dqm->ops.process_termination(dev->dqm, &pdd->qpd); + if (dev->kfd->shared_resources.enable_mes) + amdgpu_mes_flush_shader_debugger(dev->adev, pdd->proc_ctx_gpu_addr); pdd->already_dequeued = true; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_svm.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_svm.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -380,14 +380,9 @@ spin_lock(&svm_bo->list_lock); } spin_unlock(&svm_bo->list_lock); - if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base)) { - /* We're not in the eviction worker. - * Signal the fence and synchronize with any - * pending eviction work. - */ + if (!dma_fence_is_signaled(&svm_bo->eviction_fence->base)) + /* We're not in the eviction worker. Signal the fence. */ dma_fence_signal(&svm_bo->eviction_fence->base); - cancel_work_sync(&svm_bo->eviction_work); - } dma_fence_put(&svm_bo->eviction_fence->base); amdgpu_bo_unref(&svm_bo->bo); kfree(svm_bo); @@ -2310,8 +2305,10 @@ mutex_unlock(&svms->lock); mmap_write_unlock(mm); - /* Pairs with mmget in svm_range_add_list_work */ - mmput(mm); + /* Pairs with mmget in svm_range_add_list_work. If dropping the + * last mm refcount, schedule release work to avoid circular locking + */ + mmput_async(mm); spin_lock(&svms->deferred_list_lock); } @@ -2622,6 +2619,7 @@ { struct vm_area_struct *vma; struct interval_tree_node *node; + struct rb_node *rb_node; unsigned long start_limit, end_limit; vma = vma_lookup(p->mm, addr << PAGE_SHIFT); @@ -2644,16 +2642,15 @@ if (node) { end_limit = min(end_limit, node->start); /* Last range that ends before the fault address */ - node = container_of(rb_prev(&node->rb), - struct interval_tree_node, rb); + rb_node = rb_prev(&node->rb); } else { /* Last range must end before addr because * there was no range after addr */ - node = container_of(rb_last(&p->svms.objects.rb_root), - struct interval_tree_node, rb); + rb_node = rb_last(&p->svms.objects.rb_root); } - if (node) { + if (rb_node) { + node = container_of(rb_node, struct interval_tree_node, rb); if (node->last >= addr) { WARN(1, "Overlap with prev node and page fault addr\n"); return -EFAULT; @@ -3389,13 +3386,14 @@ int svm_range_schedule_evict_svm_bo(struct amdgpu_amdkfd_fence *fence) { - if (!fence) - return -EINVAL; - - if (dma_fence_is_signaled(&fence->base)) - return 0; - - if (fence->svm_bo) { + /* Dereferencing fence->svm_bo is safe here because the fence hasn't + * signaled yet and we're under the protection of the fence->lock. + * After the fence is signaled in svm_range_bo_release, we cannot get + * here any more. + * + * Reference is dropped in svm_range_evict_svm_bo_worker. + */ + if (svm_bo_ref_unless_zero(fence->svm_bo)) { WRITE_ONCE(fence->svm_bo->evicting, 1); schedule_work(&fence->svm_bo->eviction_work); } @@ -3410,8 +3408,6 @@ int r = 0; svm_bo = container_of(work, struct svm_range_bo, eviction_work); - if (!svm_bo_ref_unless_zero(svm_bo)) - return; /* svm_bo was freed while eviction was pending */ if (mmget_not_zero(svm_bo->eviction_fence->mm)) { mm = svm_bo->eviction_fence->mm; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_topology.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_topology.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -1396,10 +1396,11 @@ num_cpu++; } + if (list_empty(&kdev->io_link_props)) + return -ENODATA; + gpu_link = list_first_entry(&kdev->io_link_props, - struct kfd_iolink_properties, list); - if (!gpu_link) - return -ENOMEM; + struct kfd_iolink_properties, list); for (i = 0; i < num_cpu; i++) { /* CPU <--> GPU */ @@ -1477,15 +1478,17 @@ peer->gpu->adev)) return ret; + if (list_empty(&kdev->io_link_props)) + return -ENODATA; + iolink1 = list_first_entry(&kdev->io_link_props, - struct kfd_iolink_properties, list); - if (!iolink1) - return -ENOMEM; + struct kfd_iolink_properties, list); + + if (list_empty(&peer->io_link_props)) + return -ENODATA; iolink2 = list_first_entry(&peer->io_link_props, - struct kfd_iolink_properties, list); - if (!iolink2) - return -ENOMEM; + struct kfd_iolink_properties, list); props = kfd_alloc_struct(props); if (!props) @@ -1503,17 +1506,19 @@ /* CPU->CPU link*/ cpu_dev = kfd_topology_device_by_proximity_domain(iolink1->node_to); if (cpu_dev) { - list_for_each_entry(iolink3, &cpu_dev->io_link_props, list) - if (iolink3->node_to == iolink2->node_to) - break; - - props->weight += iolink3->weight; - props->min_latency += iolink3->min_latency; - props->max_latency += iolink3->max_latency; - props->min_bandwidth = min(props->min_bandwidth, - iolink3->min_bandwidth); - props->max_bandwidth = min(props->max_bandwidth, - iolink3->max_bandwidth); + list_for_each_entry(iolink3, &cpu_dev->io_link_props, list) { + if (iolink3->node_to != iolink2->node_to) + continue; + + props->weight += iolink3->weight; + props->min_latency += iolink3->min_latency; + props->max_latency += iolink3->max_latency; + props->min_bandwidth = min(props->min_bandwidth, + iolink3->min_bandwidth); + props->max_bandwidth = min(props->max_bandwidth, + iolink3->max_bandwidth); + break; + } } else { WARN(1, "CPU node not found"); } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1246,7 +1246,9 @@ /* AGP aperture is disabled */ if (agp_bot == agp_top) { logical_addr_low = adev->gmc.fb_start >> 18; - if (adev->apu_flags & AMD_APU_IS_RAVEN2) + if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | + AMD_APU_IS_RENOIR | + AMD_APU_IS_GREEN_SARDINE)) /* * Raven2 has a HW issue that it is unable to use the vram which * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the @@ -1258,7 +1260,9 @@ logical_addr_high = adev->gmc.fb_end >> 18; } else { logical_addr_low = min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18; - if (adev->apu_flags & AMD_APU_IS_RAVEN2) + if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | + AMD_APU_IS_RENOIR | + AMD_APU_IS_GREEN_SARDINE)) /* * Raven2 has a HW issue that it is unable to use the vram which * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the @@ -6849,7 +6853,7 @@ max_bpc); bpp = convert_dc_color_depth_into_bpc(color_depth) * 3; clock = adjusted_mode->clock; - dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp, false); + dm_new_connector_state->pbn = drm_dp_calc_pbn_mode(clock, bpp << 4); } dm_new_connector_state->vcpi_slots = @@ -10371,7 +10375,7 @@ DRM_DEBUG_DRIVER("drm_dp_mst_atomic_check() failed\n"); goto fail; } - status = dc_validate_global_state(dc, dm_state->context, true); + status = dc_validate_global_state(dc, dm_state->context, false); if (status != DC_OK) { DRM_DEBUG_DRIVER("DC global validation failure: %s (%d)", dc_status_to_str(status), status); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -1629,7 +1629,7 @@ } else { /* check if mode could be supported within full_pbn */ bpp = convert_dc_color_depth_into_bpc(stream->timing.display_color_depth) * 3; - pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp, false); + pbn = drm_dp_calc_pbn_mode(stream->timing.pix_clk_100hz / 10, bpp << 4); if (pbn > full_pbn) return DC_FAIL_BANDWIDTH_VALIDATE; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/core/dc.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/core/dc.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/core/dc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1941,6 +1941,10 @@ wait_for_no_pipes_pending(dc, context); /* pplib is notified if disp_num changed */ dc->hwss.optimize_bandwidth(dc, context); + /* Need to do otg sync again as otg could be out of sync due to otg + * workaround applied during clock update + */ + dc_trigger_sync(dc, context); } if (dc->debug.enable_double_buffered_dsc_pg_support) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dc.h linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dc.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dc.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dc.h @@ -866,6 +866,7 @@ bool psr_skip_crtc_disable; union dpia_debug_options dpia_debug; bool disable_fixed_vs_aux_timeout_wa; + uint32_t fixed_vs_aux_delay_config_wa; bool force_disable_subvp; bool force_subvp_mclk_switch; bool allow_sw_cursor_fallback; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dc_hw_types.h linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dc_hw_types.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -244,7 +244,7 @@ #define DC_MAX_DIRTY_RECTS 3 struct dc_flip_addrs { struct dc_plane_address address; - unsigned int flip_timestamp_in_us; + unsigned long long flip_timestamp_in_us; bool flip_immediate; /* TODO: add flip duration for FreeSync */ bool triplebuffer_flips; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -2112,7 +2112,8 @@ BREAK_TO_DEBUGGER(); } pipe_ctx_old->stream_res.tg->funcs->disable_crtc(pipe_ctx_old->stream_res.tg); - pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0; + if (dc_is_hdmi_tmds_signal(pipe_ctx_old->stream->signal)) + pipe_ctx_old->stream->link->phy_state.symclk_ref_cnts.otg = 0; pipe_ctx_old->plane_res.mi->funcs->free_mem_input( pipe_ctx_old->plane_res.mi, dc->current_state->stream_count); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -1054,7 +1054,8 @@ if (pipe_ctx->stream_res.tg->funcs->set_drr) pipe_ctx->stream_res.tg->funcs->set_drr( pipe_ctx->stream_res.tg, NULL); - pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; + if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) + pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; } for (i = 0; i < dc->res_pool->pipe_count; i++) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1808,6 +1808,8 @@ int i; struct dce_hwseq *hws = dc->hwseq; DC_LOGGER_INIT(dc->ctx->logger); + unsigned int prev_hubp_count = 0; + unsigned int hubp_count = 0; /* Carry over GSL groups in case the context is changing. */ for (i = 0; i < dc->res_pool->pipe_count; i++) { @@ -1831,6 +1833,20 @@ } } + for (i = 0; i < dc->res_pool->pipe_count; i++) { + if (dc->current_state->res_ctx.pipe_ctx[i].plane_state) + prev_hubp_count++; + if (context->res_ctx.pipe_ctx[i].plane_state) + hubp_count++; + } + + if (prev_hubp_count == 0 && hubp_count > 0) { + if (dc->res_pool->hubbub->funcs->force_pstate_change_control) + dc->res_pool->hubbub->funcs->force_pstate_change_control( + dc->res_pool->hubbub, true, false); + udelay(500); + } + /* Set pipe update flags and lock pipes */ for (i = 0; i < dc->res_pool->pipe_count; i++) dcn20_detect_pipe_changes(&dc->current_state->res_ctx.pipe_ctx[i], @@ -1978,6 +1994,10 @@ } } + if (dc->res_pool->hubbub->funcs->force_pstate_change_control) + dc->res_pool->hubbub->funcs->force_pstate_change_control( + dc->res_pool->hubbub, false, false); + for (i = 0; i < dc->res_pool->pipe_count; i++) { struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; @@ -2529,7 +2549,8 @@ * the case where the same symclk is shared across multiple otg * instances */ - link->phy_state.symclk_ref_cnts.otg = 0; + if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) + link->phy_state.symclk_ref_cnts.otg = 0; if (link->phy_state.symclk_state == SYMCLK_ON_TX_OFF) { link_hwss->disable_link_output(link, &pipe_ctx->link_res, pipe_ctx->stream->signal); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c @@ -3423,6 +3423,7 @@ unsigned int SwathHeightC, double TWait, double TPreReq, + bool ExtendPrefetchIfPossible, /* Output */ double *DSTXAfterScaler, double *DSTYAfterScaler, @@ -3892,12 +3893,32 @@ /* Clamp to oto for bandwidth calculation */ LinesForPrefetchBandwidth = dst_y_prefetch_oto; } else { - *DestinationLinesForPrefetch = dst_y_prefetch_equ; - TimeForFetchingMetaPTE = Tvm_equ; - TimeForFetchingRowInVBlank = Tr0_equ; - *PrefetchBandwidth = prefetch_bw_equ; - /* Clamp to equ for bandwidth calculation */ - LinesForPrefetchBandwidth = dst_y_prefetch_equ; + /* For mode programming we want to extend the prefetch as much as possible + * (up to oto, or as long as we can for equ) if we're not already applying + * the 60us prefetch requirement. This is to avoid intermittent underflow + * issues during prefetch. + * + * The prefetch extension is applied under the following scenarios: + * 1. We're in prefetch mode > 0 (i.e. we don't support MCLK switch in blank) + * 2. We're using subvp or drr methods of p-state switch, in which case we + * we don't care if prefetch takes up more of the blanking time + * + * Mode programming typically chooses the smallest prefetch time possible + * (i.e. highest bandwidth during prefetch) presumably to create margin between + * p-states / c-states that happen in vblank and prefetch. Therefore we only + * apply this prefetch extension when p-state in vblank is not required (UCLK + * p-states take up the most vblank time). + */ + if (ExtendPrefetchIfPossible && TPreReq == 0 && VStartup < MaxVStartup) { + MyError = true; + } else { + *DestinationLinesForPrefetch = dst_y_prefetch_equ; + TimeForFetchingMetaPTE = Tvm_equ; + TimeForFetchingRowInVBlank = Tr0_equ; + *PrefetchBandwidth = prefetch_bw_equ; + /* Clamp to equ for bandwidth calculation */ + LinesForPrefetchBandwidth = dst_y_prefetch_equ; + } } *DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/link_detection.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/link_detection.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -1086,6 +1086,9 @@ if (sink->edid_caps.panel_patch.skip_scdc_overwrite) link->ctx->dc->debug.hdmi20_disable = true; + if (sink->edid_caps.panel_patch.remove_sink_ext_caps) + link->dpcd_sink_ext_caps.raw = 0; + if (dc_is_hdmi_signal(link->connector_signal)) read_scdc_caps(link->ddc, link->local_sink); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/link_dpms.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/link_dpms.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -876,11 +876,15 @@ { struct display_stream_compressor *dsc = pipe_ctx->stream_res.dsc; struct dc_stream_state *stream = pipe_ctx->stream; - DC_LOGGER_INIT(dsc->ctx->logger); - if (!pipe_ctx->stream->timing.flags.DSC || !dsc) + if (!pipe_ctx->stream->timing.flags.DSC) + return false; + + if (!dsc) return false; + DC_LOGGER_INIT(dsc->ctx->logger); + if (enable) { struct dsc_config dsc_cfg; uint8_t dsc_packed_pps[128]; @@ -1058,18 +1062,21 @@ uint32_t denominator = 1; /* - * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006 + * The 1.006 factor (margin 5300ppm + 300ppm ~ 0.6% as per spec) is not + * required when determining PBN/time slot utilization on the link between + * us and the branch, since that overhead is already accounted for in + * the get_pbn_per_slot function. + * * The unit of 54/64Mbytes/sec is an arbitrary unit chosen based on * common multiplier to render an integer PBN for all link rate/lane * counts combinations * calculate - * peak_kbps *= (1006/1000) * peak_kbps *= (64/54) - * peak_kbps *= 8 convert to bytes + * peak_kbps /= (8 * 1000) convert to bytes */ - numerator = 64 * PEAK_FACTOR_X1000; - denominator = 54 * 8 * 1000 * 1000; + numerator = 64; + denominator = 54 * 8 * 1000; kbps *= numerator; peak_kbps = dc_fixpt_from_fraction(kbps, denominator); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_fixed_vs_pe_retimer.c @@ -244,10 +244,6 @@ uint8_t toggle_rate; uint8_t rate; - if (link->local_sink) - pre_disable_intercept_delay_ms = - link->local_sink->edid_caps.panel_patch.delay_disable_aux_intercept_ms; - /* Only 8b/10b is supported */ ASSERT(link_dp_get_encoding_format(<_settings->link_settings) == DP_8b_10b_ENCODING); @@ -260,10 +256,13 @@ if (offset != 0xFF) { vendor_lttpr_write_address += ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); + if (offset == 2) { + pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa; /* Certain display and cable configuration require extra delay */ - if (offset > 2) - pre_disable_intercept_delay_ms = pre_disable_intercept_delay_ms * 2; + } else if (offset > 2) { + pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa * 2; + } } /* Vendor specific: Reset lane settings */ @@ -596,9 +595,10 @@ const uint8_t vendor_lttpr_write_data_adicora_eq1[4] = {0x1, 0x55, 0x63, 0x2E}; const uint8_t vendor_lttpr_write_data_adicora_eq2[4] = {0x1, 0x55, 0x63, 0x01}; const uint8_t vendor_lttpr_write_data_adicora_eq3[4] = {0x1, 0x55, 0x63, 0x68}; + uint32_t pre_disable_intercept_delay_ms = 0; uint8_t vendor_lttpr_write_data_vs[4] = {0x1, 0x51, 0x63, 0x0}; uint8_t vendor_lttpr_write_data_pe[4] = {0x1, 0x52, 0x63, 0x0}; - uint32_t pre_disable_intercept_delay_ms = 0; + uint32_t vendor_lttpr_write_address = 0xF004F; enum link_training_result status = LINK_TRAINING_SUCCESS; uint8_t lane = 0; @@ -607,10 +607,6 @@ uint8_t toggle_rate; uint8_t rate; - if (link->local_sink) - pre_disable_intercept_delay_ms = - link->local_sink->edid_caps.panel_patch.delay_disable_aux_intercept_ms; - /* Only 8b/10b is supported */ ASSERT(link_dp_get_encoding_format(<_settings->link_settings) == DP_8b_10b_ENCODING); @@ -623,10 +619,13 @@ if (offset != 0xFF) { vendor_lttpr_write_address += ((DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE) * (offset - 1)); + if (offset == 2) { + pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa; /* Certain display and cable configuration require extra delay */ - if (offset > 2) - pre_disable_intercept_delay_ms = pre_disable_intercept_delay_ms * 2; + } else if (offset > 2) { + pre_disable_intercept_delay_ms = link->dc->debug.fixed_vs_aux_delay_config_wa * 2; + } } /* Vendor specific: Reset lane settings */ reverted: --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/modules/power/power_helpers.c +++ linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/modules/power/power_helpers.c @@ -839,8 +839,6 @@ ((dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x08) || (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x07))) isPSRSUSupported = false; - else if (dpcd_caps->sink_dev_id_str[1] == 0x08 && dpcd_caps->sink_dev_id_str[0] == 0x03) - isPSRSUSupported = false; else if (dpcd_caps->psr_info.force_psrsu_cap == 0x1) isPSRSUSupported = true; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -2974,6 +2974,8 @@ result = smu7_get_evv_voltages(hwmgr); if (result) { pr_info("Get EVV Voltage Failed. Abort Driver loading!\n"); + kfree(hwmgr->backend); + hwmgr->backend = NULL; return -EINVAL; } } else { @@ -3019,8 +3021,10 @@ } result = smu7_update_edc_leakage_table(hwmgr); - if (result) + if (result) { + smu7_hwmgr_backend_fini(hwmgr); return result; + } return 0; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -24,6 +24,7 @@ #include #include +#include #include #include "amdgpu.h" @@ -741,16 +742,8 @@ * handle the switch automatically. Driver involvement * is unnecessary. */ - if (!smu->dc_controlled_by_gpio) { - ret = smu_set_power_source(smu, - adev->pm.ac_power ? SMU_POWER_SOURCE_AC : - SMU_POWER_SOURCE_DC); - if (ret) { - dev_err(adev->dev, "Failed to switch to %s mode!\n", - adev->pm.ac_power ? "AC" : "DC"); - return ret; - } - } + adev->pm.ac_power = power_supply_is_system_supplied() > 0; + smu_set_ac_dc(smu); if ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 1)) || (adev->ip_versions[MP1_HWIP][0] == IP_VERSION(13, 0, 3))) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -1382,10 +1382,12 @@ case 0x3: dev_dbg(adev->dev, "Switched to AC mode!\n"); smu_v13_0_ack_ac_dc_interrupt(smu); + adev->pm.ac_power = true; break; case 0x4: dev_dbg(adev->dev, "Switched to DC mode!\n"); smu_v13_0_ack_ac_dc_interrupt(smu); + adev->pm.ac_power = false; break; case 0x7: /* diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/analogix/anx7625.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/analogix/anx7625.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/analogix/anx7625.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -1298,10 +1298,32 @@ XTAL_FRQ_SEL, XTAL_FRQ_27M); } +static int anx7625_hpd_timer_config(struct anx7625_data *ctx) +{ + int ret; + + /* Set irq detect window to 2ms */ + ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, + HPD_DET_TIMER_BIT0_7, HPD_TIME & 0xFF); + ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, + HPD_DET_TIMER_BIT8_15, + (HPD_TIME >> 8) & 0xFF); + ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, + HPD_DET_TIMER_BIT16_23, + (HPD_TIME >> 16) & 0xFF); + + return ret; +} + +static int anx7625_read_hpd_gpio_config_status(struct anx7625_data *ctx) +{ + return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, GPIO_CTRL_2); +} + static void anx7625_disable_pd_protocol(struct anx7625_data *ctx) { struct device *dev = &ctx->client->dev; - int ret; + int ret, val; /* Reset main ocm */ ret = anx7625_reg_write(ctx, ctx->i2c.rx_p0_client, 0x88, 0x40); @@ -1315,6 +1337,19 @@ DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature fail.\n"); else DRM_DEV_DEBUG_DRIVER(dev, "disable PD feature succeeded.\n"); + + /* + * Make sure the HPD GPIO already be configured after OCM release before + * setting HPD detect window register. Here we poll the status register + * at maximum 40ms, then config HPD irq detect window register + */ + readx_poll_timeout(anx7625_read_hpd_gpio_config_status, + ctx, val, + ((val & HPD_SOURCE) || (val < 0)), + 2000, 2000 * 20); + + /* Set HPD irq detect window to 2ms */ + anx7625_hpd_timer_config(ctx); } static int anx7625_ocm_loading_check(struct anx7625_data *ctx) @@ -1437,20 +1472,6 @@ static int anx7625_read_hpd_status_p0(struct anx7625_data *ctx) { - int ret; - - /* Set irq detect window to 2ms */ - ret = anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, - HPD_DET_TIMER_BIT0_7, HPD_TIME & 0xFF); - ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, - HPD_DET_TIMER_BIT8_15, - (HPD_TIME >> 8) & 0xFF); - ret |= anx7625_reg_write(ctx, ctx->i2c.tx_p2_client, - HPD_DET_TIMER_BIT16_23, - (HPD_TIME >> 16) & 0xFF); - if (ret < 0) - return ret; - return anx7625_reg_read(ctx, ctx->i2c.rx_p0_client, SYSTEM_STSTUS); } @@ -1739,6 +1760,7 @@ u8 request = msg->request & ~DP_AUX_I2C_MOT; int ret = 0; + mutex_lock(&ctx->aux_lock); pm_runtime_get_sync(dev); msg->reply = 0; switch (request) { @@ -1755,6 +1777,7 @@ msg->size, msg->buffer); pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); + mutex_unlock(&ctx->aux_lock); return ret; } @@ -2451,7 +2474,9 @@ ctx->connector = NULL; anx7625_dp_stop(ctx); - pm_runtime_put_sync(dev); + mutex_lock(&ctx->aux_lock); + pm_runtime_put_sync_suspend(dev); + mutex_unlock(&ctx->aux_lock); } static enum drm_connector_status @@ -2645,6 +2670,7 @@ mutex_init(&platform->lock); mutex_init(&platform->hdcp_wq_lock); + mutex_init(&platform->aux_lock); INIT_DELAYED_WORK(&platform->hdcp_work, hdcp_check_work_func); platform->hdcp_workqueue = create_workqueue("hdcp workqueue"); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/parade-ps8640.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/parade-ps8640.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/parade-ps8640.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/parade-ps8640.c @@ -108,6 +108,7 @@ struct edid *edid; bool pre_enabled; bool need_post_hpd_delay; + struct mutex aux_lock; }; static const struct regmap_config ps8640_regmap_config[] = { @@ -363,11 +364,20 @@ struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev; int ret; + mutex_lock(&ps_bridge->aux_lock); pm_runtime_get_sync(dev); + ret = _ps8640_wait_hpd_asserted(ps_bridge, 200 * 1000); + if (ret) { + pm_runtime_put_sync_suspend(dev); + goto exit; + } ret = ps8640_aux_transfer_msg(aux, msg); pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); +exit: + mutex_unlock(&ps_bridge->aux_lock); + return ret; } @@ -488,7 +498,18 @@ ps_bridge->pre_enabled = false; ps8640_bridge_vdo_control(ps_bridge, DISABLE); + + /* + * The bridge seems to expect everything to be power cycled at the + * disable process, so grab a lock here to make sure + * ps8640_aux_transfer() is not holding a runtime PM reference and + * preventing the bridge from suspend. + */ + mutex_lock(&ps_bridge->aux_lock); + pm_runtime_put_sync_suspend(&ps_bridge->page[PAGE0_DP_CNTL]->dev); + + mutex_unlock(&ps_bridge->aux_lock); } static int ps8640_bridge_attach(struct drm_bridge *bridge, @@ -682,6 +703,8 @@ if (!ps_bridge) return -ENOMEM; + mutex_init(&ps_bridge->aux_lock); + ps_bridge->supplies[0].supply = "vdd12"; ps_bridge->supplies[1].supply = "vdd33"; ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies), diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/samsung-dsim.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/samsung-dsim.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/samsung-dsim.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/samsung-dsim.c @@ -940,10 +940,6 @@ reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG); reg &= ~DSIM_STOP_STATE_CNT_MASK; reg |= DSIM_STOP_STATE_CNT(driver_data->reg_values[STOP_STATE_CNT]); - - if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) - reg |= DSIM_FORCE_STOP_STATE; - samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg); reg = DSIM_BTA_TIMEOUT(0xff) | DSIM_LPDR_TIMEOUT(0xffff); @@ -1400,18 +1396,6 @@ disable_irq(dsi->irq); } -static void samsung_dsim_set_stop_state(struct samsung_dsim *dsi, bool enable) -{ - u32 reg = samsung_dsim_read(dsi, DSIM_ESCMODE_REG); - - if (enable) - reg |= DSIM_FORCE_STOP_STATE; - else - reg &= ~DSIM_FORCE_STOP_STATE; - - samsung_dsim_write(dsi, DSIM_ESCMODE_REG, reg); -} - static int samsung_dsim_init(struct samsung_dsim *dsi) { const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; @@ -1461,9 +1445,6 @@ ret = samsung_dsim_init(dsi); if (ret) return; - - samsung_dsim_set_display_mode(dsi); - samsung_dsim_set_display_enable(dsi, true); } } @@ -1472,12 +1453,8 @@ { struct samsung_dsim *dsi = bridge_to_dsi(bridge); - if (samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) { - samsung_dsim_set_display_mode(dsi); - samsung_dsim_set_display_enable(dsi, true); - } else { - samsung_dsim_set_stop_state(dsi, false); - } + samsung_dsim_set_display_mode(dsi); + samsung_dsim_set_display_enable(dsi, true); dsi->state |= DSIM_STATE_VIDOUT_AVAILABLE; } @@ -1490,9 +1467,6 @@ if (!(dsi->state & DSIM_STATE_ENABLED)) return; - if (!samsung_dsim_hw_is_exynos(dsi->plat_data->hw_type)) - samsung_dsim_set_stop_state(dsi, true); - dsi->state &= ~DSIM_STATE_VIDOUT_AVAILABLE; } @@ -1794,8 +1768,6 @@ if (ret) return ret; - samsung_dsim_set_stop_state(dsi, false); - ret = mipi_dsi_create_packet(&xfer.packet, msg); if (ret < 0) return ret; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/display/drm_dp_mst_topology.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/display/drm_dp_mst_topology.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -4690,13 +4690,12 @@ /** * drm_dp_calc_pbn_mode() - Calculate the PBN for a mode. - * @clock: dot clock for the mode - * @bpp: bpp for the mode. - * @dsc: DSC mode. If true, bpp has units of 1/16 of a bit per pixel + * @clock: dot clock + * @bpp: bpp as .4 binary fixed point * * This uses the formula in the spec to calculate the PBN value for a mode. */ -int drm_dp_calc_pbn_mode(int clock, int bpp, bool dsc) +int drm_dp_calc_pbn_mode(int clock, int bpp) { /* * margin 5300ppm + 300ppm ~ 0.6% as per spec, factor is 1.006 @@ -4707,18 +4706,9 @@ * peak_kbps *= (1006/1000) * peak_kbps *= (64/54) * peak_kbps *= 8 convert to bytes - * - * If the bpp is in units of 1/16, further divide by 16. Put this - * factor in the numerator rather than the denominator to avoid - * integer overflow */ - - if (dsc) - return DIV_ROUND_UP_ULL(mul_u32_u32(clock * (bpp / 16), 64 * 1006), - 8 * 54 * 1000 * 1000); - - return DIV_ROUND_UP_ULL(mul_u32_u32(clock * bpp, 64 * 1006), - 8 * 54 * 1000 * 1000); + return DIV_ROUND_UP_ULL(mul_u32_u32(clock * bpp, 64 * 1006 >> 4), + 1000 * 8 * 54 * 1000); } EXPORT_SYMBOL(drm_dp_calc_pbn_mode); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/drm_file.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/drm_file.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/drm_file.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/drm_file.c @@ -410,7 +410,7 @@ { struct drm_device *dev; struct drm_minor *minor; - int retcode; + int retcode = 0; int need_setup = 0; minor = drm_minor_acquire(iminor(inode)); @@ -958,7 +958,7 @@ { struct drm_gem_object *obj; struct drm_memory_stats status = {}; - enum drm_gem_object_status supported_status; + enum drm_gem_object_status supported_status = 0; int id; spin_lock(&file->table_lock); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/i915/display/intel_dp_mst.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/i915/display/intel_dp_mst.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -109,8 +109,7 @@ continue; crtc_state->pbn = drm_dp_calc_pbn_mode(adjusted_mode->crtc_clock, - dsc ? bpp << 4 : bpp, - dsc); + bpp << 4); slots = drm_dp_atomic_find_time_slots(state, &intel_dp->mst_mgr, connector->port, @@ -941,7 +940,7 @@ return ret; if (mode_rate > max_rate || mode->clock > max_dotclk || - drm_dp_calc_pbn_mode(mode->clock, min_bpp, false) > port->full_pbn) { + drm_dp_calc_pbn_mode(mode->clock, min_bpp << 4) > port->full_pbn) { *status = MODE_CLOCK_HIGH; return 0; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/mediatek/mtk_dp.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/mediatek/mtk_dp.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/mediatek/mtk_dp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/mediatek/mtk_dp.c @@ -2671,0 +2672 @@ +MODULE_SOFTDEP("pre: phy_mtk_dp"); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -212,6 +212,7 @@ .min_llcc_ib = 800000, .min_dram_ib = 800000, .danger_lut_tbl = {0xf, 0xffff, 0x0}, + .safe_lut_tbl = {0xfff0, 0xf000, 0xffff}, .qos_lut_tbl = { {.nentry = ARRAY_SIZE(sc7180_qos_linear), .entries = sc7180_qos_linear diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h @@ -39,7 +39,7 @@ .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, - .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, + .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, }, }; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h @@ -31,7 +31,7 @@ .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, - .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, + .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, }, }; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -37,6 +37,7 @@ .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, }, }; @@ -184,2 +185,17 @@ +static const struct dpu_wb_cfg sm8350_wb[] = { + { + .name = "wb_2", .id = WB_2, + .base = 0x65000, .len = 0x2c8, + .features = WB_SM8250_MASK, + .format_list = wb2_formats, + .num_formats = ARRAY_SIZE(wb2_formats), + .clk_ctrl = DPU_CLK_CTRL_WB2, + .xin_id = 6, + .vbif_idx = VBIF_RT, + .maxlinewidth = 4096, + .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), + }, +}; + static const struct dpu_intf_cfg sm8350_intf[] = { @@ -248,6 +264,8 @@ .dsc = sm8350_dsc, .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), .merge_3d = sm8350_merge_3d, + .wb_count = ARRAY_SIZE(sm8350_wb), + .wb = sm8350_wb, .intf_count = ARRAY_SIZE(sm8350_intf), .intf = sm8350_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -31,7 +31,7 @@ .clk_ctrls[DPU_CLK_CTRL_DMA0] = { .reg_off = 0x2ac, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2c4, .bit_off = 8 }, - .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x3b8, .bit_off = 24 }, + .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, }, }; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -38,6 +38,7 @@ .clk_ctrls[DPU_CLK_CTRL_DMA1] = { .reg_off = 0x2b4, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA2] = { .reg_off = 0x2bc, .bit_off = 8 }, .clk_ctrls[DPU_CLK_CTRL_DMA3] = { .reg_off = 0x2c4, .bit_off = 8 }, + .clk_ctrls[DPU_CLK_CTRL_WB2] = { .reg_off = 0x2bc, .bit_off = 16 }, .clk_ctrls[DPU_CLK_CTRL_REG_DMA] = { .reg_off = 0x2bc, .bit_off = 20 }, }, }; @@ -192,2 +193,17 @@ +static const struct dpu_wb_cfg sm8450_wb[] = { + { + .name = "wb_2", .id = WB_2, + .base = 0x65000, .len = 0x2c8, + .features = WB_SM8250_MASK, + .format_list = wb2_formats, + .num_formats = ARRAY_SIZE(wb2_formats), + .clk_ctrl = DPU_CLK_CTRL_WB2, + .xin_id = 6, + .vbif_idx = VBIF_RT, + .maxlinewidth = 4096, + .intr_wb_done = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 4), + }, +}; + static const struct dpu_intf_cfg sm8450_intf[] = { @@ -256,6 +272,8 @@ .dsc = sm8450_dsc, .merge_3d_count = ARRAY_SIZE(sm8450_merge_3d), .merge_3d = sm8450_merge_3d, + .wb_count = ARRAY_SIZE(sm8450_wb), + .wb = sm8450_wb, .intf_count = ARRAY_SIZE(sm8450_intf), .intf = sm8450_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/nouveau/dispnv50/disp.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/nouveau/dispnv50/disp.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -966,8 +966,7 @@ const int clock = crtc_state->adjusted_mode.clock; asyh->or.bpc = connector->display_info.bpc; - asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, asyh->or.bpc * 3, - false); + asyh->dp.pbn = drm_dp_calc_pbn_mode(clock, asyh->or.bpc * 3 << 4); } mst_state = drm_atomic_get_mst_topology_state(state, &mstm->mgr); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/panel/panel-simple.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/panel/panel-simple.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/panel/panel-simple.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/panel/panel-simple.c @@ -3722,6 +3722,7 @@ }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .connector_type = DRM_MODE_CONNECTOR_LVDS, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, }; static const struct panel_desc tianma_tm070jvhg33 = { @@ -3734,6 +3735,7 @@ }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .connector_type = DRM_MODE_CONNECTOR_LVDS, + .bus_flags = DRM_BUS_FLAG_DE_HIGH, }; static const struct display_timing tianma_tm070rvhg71_timing = { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/radeon/si.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/radeon/si.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/radeon/si.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/radeon/si.c @@ -3611,6 +3611,10 @@ for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) { ring = &rdev->ring[i]; r = radeon_ring_lock(rdev, ring, 2); + if (r) { + DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); + return r; + } /* clear the compute context state */ radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0)); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/tilcdc/tilcdc_drv.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/tilcdc/tilcdc_drv.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/tilcdc/tilcdc_drv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/tilcdc/tilcdc_drv.c @@ -138,7 +138,7 @@ if (ret) return ret; - priv->irq_enabled = false; + priv->irq_enabled = true; return 0; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/vboxvideo/vbox_drv.c linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/vboxvideo/vbox_drv.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/vboxvideo/vbox_drv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/vboxvideo/vbox_drv.c @@ -182,7 +182,7 @@ static const struct drm_driver driver = { .driver_features = - DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, + DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC | DRIVER_CURSOR_HOTSPOT, .fops = &vbox_fops, .name = DRIVER_NAME, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/hid/wacom_wac.c linux-lowlatency-hwe-6.5-6.5.0/drivers/hid/wacom_wac.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/hid/wacom_wac.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/hid/wacom_wac.c @@ -2651,8 +2651,8 @@ { struct hid_data *hid_data = &wacom_wac->hid_data; bool mt = wacom_wac->features.touch_max > 1; - bool prox = hid_data->tipswitch && - report_touch_events(wacom_wac); + bool touch_down = hid_data->tipswitch && hid_data->confidence; + bool prox = touch_down && report_touch_events(wacom_wac); if (touch_is_muted(wacom_wac)) { if (!wacom_wac->shared->touch_down) @@ -2702,24 +2702,6 @@ } } -static bool wacom_wac_slot_is_active(struct input_dev *dev, int key) -{ - struct input_mt *mt = dev->mt; - struct input_mt_slot *s; - - if (!mt) - return false; - - for (s = mt->slots; s != mt->slots + mt->num_slots; s++) { - if (s->key == key && - input_mt_get_value(s, ABS_MT_TRACKING_ID) >= 0) { - return true; - } - } - - return false; -} - static void wacom_wac_finger_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { @@ -2770,14 +2752,8 @@ } if (usage->usage_index + 1 == field->report_count) { - if (equivalent_usage == wacom_wac->hid_data.last_slot_field) { - bool touch_removed = wacom_wac_slot_is_active(wacom_wac->touch_input, - wacom_wac->hid_data.id) && !wacom_wac->hid_data.tipswitch; - - if (wacom_wac->hid_data.confidence || touch_removed) { - wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); - } - } + if (equivalent_usage == wacom_wac->hid_data.last_slot_field) + wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); } } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/i2c/busses/i2c-rk3x.c linux-lowlatency-hwe-6.5-6.5.0/drivers/i2c/busses/i2c-rk3x.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/i2c/busses/i2c-rk3x.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/i2c/busses/i2c-rk3x.c @@ -1295,8 +1295,12 @@ return -EINVAL; } - /* 27+i: write mask, 11+i: value */ - value = BIT(27 + bus_nr) | BIT(11 + bus_nr); + /* rv1126 i2c2 uses non-sequential write mask 20, value 4 */ + if (i2c->soc_data == &rv1126_soc_data && bus_nr == 2) + value = BIT(20) | BIT(4); + else + /* 27+i: write mask, 11+i: value */ + value = BIT(27 + bus_nr) | BIT(11 + bus_nr); ret = regmap_write(grf, i2c->soc_data->grf_offset, value); if (ret != 0) { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/i3c/master/i3c-master-cdns.c linux-lowlatency-hwe-6.5-6.5.0/drivers/i3c/master/i3c-master-cdns.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/i3c/master/i3c-master-cdns.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/i3c/master/i3c-master-cdns.c @@ -77,7 +77,8 @@ #define PRESCL_CTRL0 0x14 #define PRESCL_CTRL0_I2C(x) ((x) << 16) #define PRESCL_CTRL0_I3C(x) (x) -#define PRESCL_CTRL0_MAX GENMASK(9, 0) +#define PRESCL_CTRL0_I3C_MAX GENMASK(9, 0) +#define PRESCL_CTRL0_I2C_MAX GENMASK(15, 0) #define PRESCL_CTRL1 0x18 #define PRESCL_CTRL1_PP_LOW_MASK GENMASK(15, 8) @@ -1234,7 +1235,7 @@ return -EINVAL; pres = DIV_ROUND_UP(sysclk_rate, (bus->scl_rate.i3c * 4)) - 1; - if (pres > PRESCL_CTRL0_MAX) + if (pres > PRESCL_CTRL0_I3C_MAX) return -ERANGE; bus->scl_rate.i3c = sysclk_rate / ((pres + 1) * 4); @@ -1247,7 +1248,7 @@ max_i2cfreq = bus->scl_rate.i2c; pres = (sysclk_rate / (max_i2cfreq * 5)) - 1; - if (pres > PRESCL_CTRL0_MAX) + if (pres > PRESCL_CTRL0_I2C_MAX) return -ERANGE; bus->scl_rate.i2c = sysclk_rate / ((pres + 1) * 5); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.c linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -2708,6 +2708,10 @@ return 0; create_failed_qp: + for (i--; i >= 0; i--) { + hns_roce_v2_destroy_qp(&free_mr->rsv_qp[i]->ibqp, NULL); + kfree(free_mr->rsv_qp[i]); + } hns_roce_destroy_cq(cq, NULL); kfree(cq); @@ -5649,7 +5653,7 @@ /* Resizing SRQs is not supported yet */ if (srq_attr_mask & IB_SRQ_MAX_WR) - return -EINVAL; + return -EOPNOTSUPP; if (srq_attr_mask & IB_SRQ_LIMIT) { if (srq_attr->srq_limit > srq->wqe_cnt) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/input/keyboard/atkbd.c linux-lowlatency-hwe-6.5-6.5.0/drivers/input/keyboard/atkbd.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/input/keyboard/atkbd.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/input/keyboard/atkbd.c @@ -791,9 +791,9 @@ * not work. So in this case simply assume a keyboard is connected to avoid * confusing some laptop keyboards. * - * Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using a fake id is - * ok in translated mode, only atkbd_select_set() checks atkbd->id and in - * translated mode that is a no-op. + * Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using the standard + * 0xab83 id is ok in translated mode, only atkbd_select_set() checks atkbd->id + * and in translated mode that is a no-op. */ static bool atkbd_skip_getid(struct atkbd *atkbd) { @@ -811,6 +811,7 @@ { struct ps2dev *ps2dev = &atkbd->ps2dev; unsigned char param[2]; + bool skip_getid; /* * Some systems, where the bit-twiddling when testing the io-lines of the @@ -832,7 +833,8 @@ */ param[0] = param[1] = 0xa5; /* initialize with invalid values */ - if (atkbd_skip_getid(atkbd) || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { + skip_getid = atkbd_skip_getid(atkbd); + if (skip_getid || ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { /* * If the get ID command was skipped or failed, we check if we can at least set @@ -842,7 +844,7 @@ param[0] = 0; if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) return -1; - atkbd->id = 0xabba; + atkbd->id = skip_getid ? 0xab83 : 0xabba; return 0; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/iommu/of_iommu.c linux-lowlatency-hwe-6.5-6.5.0/drivers/iommu/of_iommu.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/iommu/of_iommu.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/iommu/of_iommu.c @@ -260,7 +260,14 @@ phys_addr_t iova; size_t length; + if (of_dma_is_coherent(dev->of_node)) + prot |= IOMMU_CACHE; + maps = of_translate_dma_region(np, maps, &iova, &length); + if (length == 0) { + dev_warn(dev, "Cannot reserve IOVA region of 0 size\n"); + continue; + } type = iommu_resv_region_get_type(dev, &phys, iova, length); region = iommu_alloc_resv_region(iova, length, prot, type, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/leds/Kconfig linux-lowlatency-hwe-6.5-6.5.0/drivers/leds/Kconfig --- linux-lowlatency-hwe-6.5-6.5.0/drivers/leds/Kconfig +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/leds/Kconfig @@ -122,6 +122,7 @@ config LEDS_AW2013 tristate "LED support for Awinic AW2013" depends on LEDS_CLASS && I2C && OF + select REGMAP_I2C help This option enables support for the AW2013 3-channel LED driver. diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/leds/leds-aw200xx.c linux-lowlatency-hwe-6.5-6.5.0/drivers/leds/leds-aw200xx.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/leds/leds-aw200xx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/leds/leds-aw200xx.c @@ -74,6 +74,10 @@ #define AW200XX_LED2REG(x, columns) \ ((x) + (((x) / (columns)) * (AW200XX_DSIZE_COLUMNS_MAX - (columns)))) +/* DIM current configuration register on page 1 */ +#define AW200XX_REG_DIM_PAGE1(x, columns) \ + AW200XX_REG(AW200XX_PAGE1, AW200XX_LED2REG(x, columns)) + /* * DIM current configuration register (page 4). * The even address for current DIM configuration. @@ -153,7 +157,8 @@ if (dim >= 0) { ret = regmap_write(chip->regmap, - AW200XX_REG_DIM(led->num, columns), dim); + AW200XX_REG_DIM_PAGE1(led->num, columns), + dim); if (ret) goto out_unlock; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/md/md.c linux-lowlatency-hwe-6.5-6.5.0/drivers/md/md.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/md/md.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/md/md.c @@ -496,6 +496,9 @@ rdev_dec_pending(rdev, mddev); if (atomic_dec_and_test(&mddev->flush_pending)) { + /* The pair is percpu_ref_get() from md_flush_request() */ + percpu_ref_put(&mddev->active_io); + /* The pre-request flush has finished */ queue_work(md_wq, &mddev->flush_work); } @@ -515,12 +518,8 @@ rdev_for_each_rcu(rdev, mddev) if (rdev->raid_disk >= 0 && !test_bit(Faulty, &rdev->flags)) { - /* Take two references, one is dropped - * when request finishes, one after - * we reclaim rcu_read_lock - */ struct bio *bi; - atomic_inc(&rdev->nr_pending); + atomic_inc(&rdev->nr_pending); rcu_read_unlock(); bi = bio_alloc_bioset(rdev->bdev, 0, @@ -531,7 +530,6 @@ atomic_inc(&mddev->flush_pending); submit_bio(bi); rcu_read_lock(); - rdev_dec_pending(rdev, mddev); } rcu_read_unlock(); if (atomic_dec_and_test(&mddev->flush_pending)) @@ -584,6 +582,18 @@ /* new request after previous flush is completed */ if (ktime_after(req_start, mddev->prev_flush_start)) { WARN_ON(mddev->flush_bio); + /* + * Grab a reference to make sure mddev_suspend() will wait for + * this flush to be done. + * + * md_flush_reqeust() is called under md_handle_request() and + * 'active_io' is already grabbed, hence percpu_ref_is_zero() + * won't pass, percpu_ref_tryget_live() can't be used because + * percpu_ref_kill() can be called by mddev_suspend() + * concurrently. + */ + WARN_ON(percpu_ref_is_zero(&mddev->active_io)); + percpu_ref_get(&mddev->active_io); mddev->flush_bio = bio; bio = NULL; } @@ -1112,6 +1122,7 @@ struct md_rdev *refdev, int minor_version); int (*validate_super)(struct mddev *mddev, + struct md_rdev *freshest, struct md_rdev *rdev); void (*sync_super)(struct mddev *mddev, struct md_rdev *rdev); @@ -1249,8 +1260,9 @@ /* * validate_super for 0.90.0 + * note: we are not using "freshest" for 0.9 superblock */ -static int super_90_validate(struct mddev *mddev, struct md_rdev *rdev) +static int super_90_validate(struct mddev *mddev, struct md_rdev *freshest, struct md_rdev *rdev) { mdp_disk_t *desc; mdp_super_t *sb = page_address(rdev->sb_page); @@ -1762,7 +1774,7 @@ return ret; } -static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) +static int super_1_validate(struct mddev *mddev, struct md_rdev *freshest, struct md_rdev *rdev) { struct mdp_superblock_1 *sb = page_address(rdev->sb_page); __u64 ev1 = le64_to_cpu(sb->events); @@ -1858,13 +1870,15 @@ } } else if (mddev->pers == NULL) { /* Insist of good event counter while assembling, except for - * spares (which don't need an event count) */ - ++ev1; + * spares (which don't need an event count). + * Similar to mdadm, we allow event counter difference of 1 + * from the freshest device. + */ if (rdev->desc_nr >= 0 && rdev->desc_nr < le32_to_cpu(sb->max_dev) && (le16_to_cpu(sb->dev_roles[rdev->desc_nr]) < MD_DISK_ROLE_MAX || le16_to_cpu(sb->dev_roles[rdev->desc_nr]) == MD_DISK_ROLE_JOURNAL)) - if (ev1 < mddev->events) + if (ev1 + 1 < mddev->events) return -EINVAL; } else if (mddev->bitmap) { /* If adding to array with a bitmap, then we can accept an @@ -1885,8 +1899,38 @@ rdev->desc_nr >= le32_to_cpu(sb->max_dev)) { role = MD_DISK_ROLE_SPARE; rdev->desc_nr = -1; - } else + } else if (mddev->pers == NULL && freshest && ev1 < mddev->events) { + /* + * If we are assembling, and our event counter is smaller than the + * highest event counter, we cannot trust our superblock about the role. + * It could happen that our rdev was marked as Faulty, and all other + * superblocks were updated with +1 event counter. + * Then, before the next superblock update, which typically happens when + * remove_and_add_spares() removes the device from the array, there was + * a crash or reboot. + * If we allow current rdev without consulting the freshest superblock, + * we could cause data corruption. + * Note that in this case our event counter is smaller by 1 than the + * highest, otherwise, this rdev would not be allowed into array; + * both kernel and mdadm allow event counter difference of 1. + */ + struct mdp_superblock_1 *freshest_sb = page_address(freshest->sb_page); + u32 freshest_max_dev = le32_to_cpu(freshest_sb->max_dev); + + if (rdev->desc_nr >= freshest_max_dev) { + /* this is unexpected, better not proceed */ + pr_warn("md: %s: rdev[%pg]: desc_nr(%d) >= freshest(%pg)->sb->max_dev(%u)\n", + mdname(mddev), rdev->bdev, rdev->desc_nr, + freshest->bdev, freshest_max_dev); + return -EUCLEAN; + } + + role = le16_to_cpu(freshest_sb->dev_roles[rdev->desc_nr]); + pr_debug("md: %s: rdev[%pg]: role=%d(0x%x) according to freshest %pg\n", + mdname(mddev), rdev->bdev, role, role, freshest->bdev); + } else { role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); + } switch(role) { case MD_DISK_ROLE_SPARE: /* spare */ break; @@ -2794,7 +2838,7 @@ * and should be added immediately. */ super_types[mddev->major_version]. - validate_super(mddev, rdev); + validate_super(mddev, NULL/*freshest*/, rdev); if (add_journal) mddev_suspend(mddev); err = mddev->pers->hot_add_disk(mddev, rdev); @@ -3732,7 +3776,7 @@ } super_types[mddev->major_version]. - validate_super(mddev, freshest); + validate_super(mddev, NULL/*freshest*/, freshest); i = 0; rdev_for_each_safe(rdev, tmp, mddev) { @@ -3747,7 +3791,7 @@ } if (rdev != freshest) { if (super_types[mddev->major_version]. - validate_super(mddev, rdev)) { + validate_super(mddev, freshest, rdev)) { pr_warn("md: kicking non-fresh %pg from array!\n", rdev->bdev); md_kick_rdev_from_array(rdev); @@ -6758,7 +6802,7 @@ rdev->saved_raid_disk = rdev->raid_disk; } else super_types[mddev->major_version]. - validate_super(mddev, rdev); + validate_super(mddev, NULL/*freshest*/, rdev); if ((info->state & (1<raid_disk != info->raid_disk) { /* This was a hot-add request, but events doesn't diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/md/raid1.c linux-lowlatency-hwe-6.5-6.5.0/drivers/md/raid1.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/md/raid1.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/md/raid1.c @@ -1975,12 +1975,12 @@ } static int r1_sync_page_io(struct md_rdev *rdev, sector_t sector, - int sectors, struct page *page, int rw) + int sectors, struct page *page, blk_opf_t rw) { if (sync_page_io(rdev, sector, sectors << 9, page, rw, false)) /* success */ return 1; - if (rw == WRITE) { + if (rw == REQ_OP_WRITE) { set_bit(WriteErrorSeen, &rdev->flags); if (!test_and_set_bit(WantReplacement, &rdev->flags)) @@ -2097,7 +2097,7 @@ rdev = conf->mirrors[d].rdev; if (r1_sync_page_io(rdev, sect, s, pages[idx], - WRITE) == 0) { + REQ_OP_WRITE) == 0) { r1_bio->bios[d]->bi_end_io = NULL; rdev_dec_pending(rdev, mddev); } @@ -2112,7 +2112,7 @@ rdev = conf->mirrors[d].rdev; if (r1_sync_page_io(rdev, sect, s, pages[idx], - READ) != 0) + REQ_OP_READ) != 0) atomic_add(s, &rdev->corrected_errors); } sectors -= s; @@ -2324,7 +2324,7 @@ atomic_inc(&rdev->nr_pending); rcu_read_unlock(); r1_sync_page_io(rdev, sect, s, - conf->tmppage, WRITE); + conf->tmppage, REQ_OP_WRITE); rdev_dec_pending(rdev, mddev); } else rcu_read_unlock(); @@ -2341,7 +2341,7 @@ atomic_inc(&rdev->nr_pending); rcu_read_unlock(); if (r1_sync_page_io(rdev, sect, s, - conf->tmppage, READ)) { + conf->tmppage, REQ_OP_READ)) { atomic_add(s, &rdev->corrected_errors); pr_info("md/raid1:%s: read error corrected (%d sectors at %llu on %pg)\n", mdname(mddev), s, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/media/dvb-frontends/m88ds3103.c linux-lowlatency-hwe-6.5-6.5.0/drivers/media/dvb-frontends/m88ds3103.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/media/dvb-frontends/m88ds3103.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/dvb-frontends/m88ds3103.c @@ -1894,7 +1894,7 @@ /* get frontend address */ ret = regmap_read(dev->regmap, 0x29, &utmp); if (ret) - goto err_kfree; + goto err_del_adapters; dev->dt_addr = ((utmp & 0x80) == 0) ? 0x42 >> 1 : 0x40 >> 1; dev_dbg(&client->dev, "dt addr is 0x%02x\n", dev->dt_addr); @@ -1902,11 +1902,14 @@ dev->dt_addr); if (IS_ERR(dev->dt_client)) { ret = PTR_ERR(dev->dt_client); - goto err_kfree; + goto err_del_adapters; } } return 0; + +err_del_adapters: + i2c_mux_del_adapters(dev->muxc); err_kfree: kfree(dev); err: diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu.h linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu.h @@ -154,7 +154,6 @@ struct vpu_mbox tx_type; struct vpu_mbox tx_data; struct vpu_mbox rx; - unsigned long cmd_seq; wait_queue_head_t ack_wq; struct completion cmp; @@ -253,6 +252,8 @@ struct list_head cmd_q; void *pending; + unsigned long cmd_seq; + atomic_long_t last_response_cmd; struct vpu_inst_ops *ops; const struct vpu_format *formats; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_cmds.c linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_cmds.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_cmds.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_cmds.c @@ -34,6 +34,7 @@ struct vpu_cmd_request *request; struct vpu_rpc_event *pkt; unsigned long key; + atomic_long_t *last_response_cmd; }; static struct vpu_cmd_request vpu_cmd_requests[] = { @@ -117,6 +118,8 @@ { if (!cmd) return; + if (cmd->last_response_cmd) + atomic_long_set(cmd->last_response_cmd, cmd->key); vfree(cmd->pkt); vfree(cmd); } @@ -174,7 +177,8 @@ return -ENOMEM; mutex_lock(&core->cmd_lock); - cmd->key = core->cmd_seq++; + cmd->key = ++inst->cmd_seq; + cmd->last_response_cmd = &inst->last_response_cmd; if (key) *key = cmd->key; if (sync) @@ -248,26 +252,12 @@ static bool check_is_responsed(struct vpu_inst *inst, unsigned long key) { - struct vpu_core *core = inst->core; - struct vpu_cmd_t *cmd; - bool flag = true; + unsigned long last_response = atomic_long_read(&inst->last_response_cmd); - mutex_lock(&core->cmd_lock); - cmd = inst->pending; - if (cmd && key == cmd->key) { - flag = false; - goto exit; - } - list_for_each_entry(cmd, &inst->cmd_q, list) { - if (key == cmd->key) { - flag = false; - break; - } - } -exit: - mutex_unlock(&core->cmd_lock); + if (key <= last_response && (last_response - key) < (ULONG_MAX >> 1)) + return true; - return flag; + return false; } static int sync_session_response(struct vpu_inst *inst, unsigned long key, long timeout, int try) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_core.c linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_core.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_core.c @@ -642,7 +642,7 @@ return -ENODEV; core->type = core->res->type; - core->id = of_alias_get_id(dev->of_node, "vpu_core"); + core->id = of_alias_get_id(dev->of_node, "vpu-core"); if (core->id < 0) { dev_err(dev, "can't get vpu core id\n"); return core->id; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_v4l2.c linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_v4l2.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_v4l2.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/amphion/vpu_v4l2.c @@ -716,6 +716,7 @@ func = &vpu->decoder; atomic_set(&inst->ref_count, 0); + atomic_long_set(&inst->last_response_cmd, 0); vpu_inst_get(inst); inst->vpu = vpu; inst->core = vpu_request_core(vpu, inst->type); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -1021,13 +1021,13 @@ if (ret < 0) goto dec_end; - schedule_delayed_work(&jpeg->job_timeout_work, - msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); - mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs); if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, &dst_buf->vb2_buf, &fb)) goto dec_end; + schedule_delayed_work(&jpeg->job_timeout_work, + msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); + spin_lock_irqsave(&jpeg->hw_lock, flags); mtk_jpeg_dec_reset(jpeg->reg_base); mtk_jpeg_dec_set_config(jpeg->reg_base, @@ -1403,7 +1403,6 @@ { struct mtk_jpeg_dev *jpeg = platform_get_drvdata(pdev); - cancel_delayed_work_sync(&jpeg->job_timeout_work); pm_runtime_disable(&pdev->dev); video_unregister_device(jpeg->vdev); v4l2_m2m_release(jpeg->m2m_dev); @@ -1750,9 +1749,6 @@ v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); - schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work, - msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); - mtk_jpeg_set_dec_src(ctx, &src_buf->vb2_buf, &bs); if (mtk_jpeg_set_dec_dst(ctx, &jpeg_src_buf->dec_param, @@ -1762,6 +1758,9 @@ goto setdst_end; } + schedule_delayed_work(&comp_jpeg[hw_id]->job_timeout_work, + msecs_to_jiffies(MTK_JPEG_HW_TIMEOUT_MSEC)); + spin_lock_irqsave(&comp_jpeg[hw_id]->hw_lock, flags); ctx->total_frame_num++; mtk_jpeg_dec_reset(comp_jpeg[hw_id]->reg_base); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/verisilicon/hantro_drv.c linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/verisilicon/hantro_drv.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/verisilicon/hantro_drv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/verisilicon/hantro_drv.c @@ -904,6 +904,8 @@ if (funcid == MEDIA_ENT_F_PROC_VIDEO_ENCODER) { vpu->encoder = func; + v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD); + v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD); } else { vpu->decoder = func; v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/verisilicon/hantro_v4l2.c linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/verisilicon/hantro_v4l2.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/verisilicon/hantro_v4l2.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/verisilicon/hantro_v4l2.c @@ -785,6 +785,9 @@ .vidioc_g_selection = vidioc_g_selection, .vidioc_s_selection = vidioc_s_selection, + .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, + .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, + .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd, .vidioc_encoder_cmd = vidioc_encoder_cmd, }; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/mfd/Kconfig linux-lowlatency-hwe-6.5-6.5.0/drivers/mfd/Kconfig --- linux-lowlatency-hwe-6.5-6.5.0/drivers/mfd/Kconfig +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mfd/Kconfig @@ -1458,6 +1458,7 @@ config MFD_TI_AM335X_TSCADC tristate "TI ADC / Touch Screen chip support" + depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST select MFD_CORE select REGMAP select REGMAP_MMIO diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/mmc/core/block.c linux-lowlatency-hwe-6.5-6.5.0/drivers/mmc/core/block.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/mmc/core/block.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mmc/core/block.c @@ -400,6 +400,10 @@ struct mmc_ioc_cmd ic; unsigned char *buf; u64 buf_bytes; + unsigned int flags; +#define MMC_BLK_IOC_DROP BIT(0) /* drop this mrq */ +#define MMC_BLK_IOC_SBC BIT(1) /* use mrq.sbc */ + struct mmc_rpmb_data *rpmb; }; @@ -465,7 +469,7 @@ } static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md, - struct mmc_blk_ioc_data *idata) + struct mmc_blk_ioc_data **idatas, int i) { struct mmc_command cmd = {}, sbc = {}; struct mmc_data data = {}; @@ -475,10 +479,18 @@ unsigned int busy_timeout_ms; int err; unsigned int target_part; + struct mmc_blk_ioc_data *idata = idatas[i]; + struct mmc_blk_ioc_data *prev_idata = NULL; if (!card || !md || !idata) return -EINVAL; + if (idata->flags & MMC_BLK_IOC_DROP) + return 0; + + if (idata->flags & MMC_BLK_IOC_SBC) + prev_idata = idatas[i - 1]; + /* * The RPMB accesses comes in from the character device, so we * need to target these explicitly. Else we just target the @@ -532,7 +544,7 @@ return err; } - if (idata->rpmb) { + if (idata->rpmb || prev_idata) { sbc.opcode = MMC_SET_BLOCK_COUNT; /* * We don't do any blockcount validation because the max size @@ -540,6 +552,8 @@ * 'Reliable Write' bit here. */ sbc.arg = data.blocks | (idata->ic.write_flag & BIT(31)); + if (prev_idata) + sbc.arg = prev_idata->ic.arg; sbc.flags = MMC_RSP_R1 | MMC_CMD_AC; mrq.sbc = &sbc; } @@ -557,6 +571,15 @@ mmc_wait_for_req(card->host, &mrq); memcpy(&idata->ic.response, cmd.resp, sizeof(cmd.resp)); + if (prev_idata) { + memcpy(&prev_idata->ic.response, sbc.resp, sizeof(sbc.resp)); + if (sbc.error) { + dev_err(mmc_dev(card->host), "%s: sbc error %d\n", + __func__, sbc.error); + return sbc.error; + } + } + if (cmd.error) { dev_err(mmc_dev(card->host), "%s: cmd error %d\n", __func__, cmd.error); @@ -1042,6 +1065,20 @@ md->reset_done &= ~type; } +static void mmc_blk_check_sbc(struct mmc_queue_req *mq_rq) +{ + struct mmc_blk_ioc_data **idata = mq_rq->drv_op_data; + int i; + + for (i = 1; i < mq_rq->ioc_count; i++) { + if (idata[i - 1]->ic.opcode == MMC_SET_BLOCK_COUNT && + mmc_op_multi(idata[i]->ic.opcode)) { + idata[i - 1]->flags |= MMC_BLK_IOC_DROP; + idata[i]->flags |= MMC_BLK_IOC_SBC; + } + } +} + /* * The non-block commands come back from the block layer after it queued it and * processed it with all other requests and then they get issued in this @@ -1069,11 +1106,14 @@ if (ret) break; } + + mmc_blk_check_sbc(mq_rq); + fallthrough; case MMC_DRV_OP_IOCTL_RPMB: idata = mq_rq->drv_op_data; for (i = 0, ret = 0; i < mq_rq->ioc_count; i++) { - ret = __mmc_blk_ioctl_cmd(card, md, idata[i]); + ret = __mmc_blk_ioctl_cmd(card, md, idata, i); if (ret) break; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/mmc/host/Kconfig linux-lowlatency-hwe-6.5-6.5.0/drivers/mmc/host/Kconfig --- linux-lowlatency-hwe-6.5-6.5.0/drivers/mmc/host/Kconfig +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mmc/host/Kconfig @@ -1018,14 +1018,15 @@ config MMC_SDHCI_OMAP tristate "TI SDHCI Controller Support" + depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST depends on MMC_SDHCI_PLTFM && OF select THERMAL imply TI_SOC_THERMAL select MMC_SDHCI_EXTERNAL_DMA if DMA_ENGINE help This selects the Secure Digital Host Controller Interface (SDHCI) - support present in TI's DRA7 SOCs. The controller supports - SD/MMC/SDIO devices. + support present in TI's Keystone/OMAP2+/DRA7 SOCs. The controller + supports SD/MMC/SDIO devices. If you have a controller with this interface, say Y or M here. @@ -1033,14 +1034,15 @@ config MMC_SDHCI_AM654 tristate "Support for the SDHCI Controller in TI's AM654 SOCs" + depends on ARCH_K3 || COMPILE_TEST depends on MMC_SDHCI_PLTFM && OF select MMC_SDHCI_IO_ACCESSORS select MMC_CQHCI select REGMAP_MMIO help This selects the Secure Digital Host Controller Interface (SDHCI) - support present in TI's AM654 SOCs. The controller supports - SD/MMC/SDIO devices. + support present in TI's AM65x/AM64x/AM62x/J721E SOCs. The controller + supports SD/MMC/SDIO devices. If you have a controller with this interface, say Y or M here. diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/mtd/nand/raw/nand_base.c linux-lowlatency-hwe-6.5-6.5.0/drivers/mtd/nand/raw/nand_base.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/mtd/nand/raw/nand_base.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mtd/nand/raw/nand_base.c @@ -1208,6 +1208,23 @@ return nand_exec_op(chip, &op); } +static void rawnand_cap_cont_reads(struct nand_chip *chip) +{ + struct nand_memory_organization *memorg; + unsigned int pages_per_lun, first_lun, last_lun; + + memorg = nanddev_get_memorg(&chip->base); + pages_per_lun = memorg->pages_per_eraseblock * memorg->eraseblocks_per_lun; + first_lun = chip->cont_read.first_page / pages_per_lun; + last_lun = chip->cont_read.last_page / pages_per_lun; + + /* Prevent sequential cache reads across LUN boundaries */ + if (first_lun != last_lun) + chip->cont_read.pause_page = first_lun * pages_per_lun + pages_per_lun - 1; + else + chip->cont_read.pause_page = chip->cont_read.last_page; +} + static int nand_lp_exec_cont_read_page_op(struct nand_chip *chip, unsigned int page, unsigned int offset_in_page, void *buf, unsigned int len, bool check_only) @@ -1226,7 +1243,7 @@ NAND_OP_DATA_IN(len, buf, 0), }; struct nand_op_instr cont_instrs[] = { - NAND_OP_CMD(page == chip->cont_read.last_page ? + NAND_OP_CMD(page == chip->cont_read.pause_page ? NAND_CMD_READCACHEEND : NAND_CMD_READCACHESEQ, NAND_COMMON_TIMING_NS(conf, tWB_max)), NAND_OP_WAIT_RDY(NAND_COMMON_TIMING_MS(conf, tR_max), @@ -1263,16 +1280,29 @@ } if (page == chip->cont_read.first_page) - return nand_exec_op(chip, &start_op); + ret = nand_exec_op(chip, &start_op); else - return nand_exec_op(chip, &cont_op); + ret = nand_exec_op(chip, &cont_op); + if (ret) + return ret; + + if (!chip->cont_read.ongoing) + return 0; + + if (page == chip->cont_read.pause_page && + page != chip->cont_read.last_page) { + chip->cont_read.first_page = chip->cont_read.pause_page + 1; + rawnand_cap_cont_reads(chip); + } else if (page == chip->cont_read.last_page) { + chip->cont_read.ongoing = false; + } + + return 0; } static bool rawnand_cont_read_ongoing(struct nand_chip *chip, unsigned int page) { - return chip->cont_read.ongoing && - page >= chip->cont_read.first_page && - page <= chip->cont_read.last_page; + return chip->cont_read.ongoing && page >= chip->cont_read.first_page; } /** @@ -3430,21 +3460,42 @@ u32 readlen, int col) { struct mtd_info *mtd = nand_to_mtd(chip); + unsigned int end_page, end_col; + + chip->cont_read.ongoing = false; if (!chip->controller->supported_op.cont_read) return; - if ((col && col + readlen < (3 * mtd->writesize)) || - (!col && readlen < (2 * mtd->writesize))) { - chip->cont_read.ongoing = false; + end_page = DIV_ROUND_UP(col + readlen, mtd->writesize); + end_col = (col + readlen) % mtd->writesize; + + if (col) + page++; + + if (end_col && end_page) + end_page--; + + if (page + 1 > end_page) return; - } - chip->cont_read.ongoing = true; chip->cont_read.first_page = page; - if (col) + chip->cont_read.last_page = end_page; + chip->cont_read.ongoing = true; + + rawnand_cap_cont_reads(chip); +} + +static void rawnand_cont_read_skip_first_page(struct nand_chip *chip, unsigned int page) +{ + if (!chip->cont_read.ongoing || page != chip->cont_read.first_page) + return; + + chip->cont_read.first_page++; + if (chip->cont_read.first_page == chip->cont_read.pause_page) chip->cont_read.first_page++; - chip->cont_read.last_page = page + ((readlen >> chip->page_shift) & chip->pagemask); + if (chip->cont_read.first_page >= chip->cont_read.last_page) + chip->cont_read.ongoing = false; } /** @@ -3621,6 +3672,8 @@ buf += bytes; max_bitflips = max_t(unsigned int, max_bitflips, chip->pagecache.bitflips); + + rawnand_cont_read_skip_first_page(chip, page); } readlen -= bytes; @@ -5125,6 +5178,14 @@ /* The supported_op fields should not be set by individual drivers */ WARN_ON_ONCE(chip->controller->supported_op.cont_read); + /* + * Too many devices do not support sequential cached reads with on-die + * ECC correction enabled, so in this case refuse to perform the + * automation. + */ + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_DIE) + return; + if (!nand_has_exec_op(chip)) return; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/dsa/qca/qca8k-8xxx.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/dsa/qca/qca8k-8xxx.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/dsa/qca/qca8k-8xxx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/dsa/qca/qca8k-8xxx.c @@ -949,10 +949,15 @@ struct dsa_switch *ds = priv->ds; struct device_node *mdio; struct mii_bus *bus; + int err; + + mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); bus = devm_mdiobus_alloc(ds->dev); - if (!bus) - return -ENOMEM; + if (!bus) { + err = -ENOMEM; + goto out_put_node; + } bus->priv = (void *)priv; snprintf(bus->id, MII_BUS_ID_SIZE, "qca8k-%d.%d", @@ -962,12 +967,12 @@ ds->slave_mii_bus = bus; /* Check if the devicetree declare the port:phy mapping */ - mdio = of_get_child_by_name(priv->dev->of_node, "mdio"); if (of_device_is_available(mdio)) { bus->name = "qca8k slave mii"; bus->read = qca8k_internal_mdio_read; bus->write = qca8k_internal_mdio_write; - return devm_of_mdiobus_register(priv->dev, bus, mdio); + err = devm_of_mdiobus_register(priv->dev, bus, mdio); + goto out_put_node; } /* If a mapping can't be found the legacy mapping is used, @@ -976,7 +981,13 @@ bus->name = "qca8k-legacy slave mii"; bus->read = qca8k_legacy_mdio_read; bus->write = qca8k_legacy_mdio_write; - return devm_mdiobus_register(priv->dev, bus); + + err = devm_mdiobus_register(priv->dev, bus); + +out_put_node: + of_node_put(mdio); + + return err; } static int @@ -2034,12 +2045,11 @@ priv->info = of_device_get_match_data(priv->dev); priv->reset_gpio = devm_gpiod_get_optional(priv->dev, "reset", - GPIOD_ASIS); + GPIOD_OUT_HIGH); if (IS_ERR(priv->reset_gpio)) return PTR_ERR(priv->reset_gpio); if (priv->reset_gpio) { - gpiod_set_value_cansleep(priv->reset_gpio, 1); /* The active low duration must be greater than 10 ms * and checkpatch.pl wants 20 ms. */ diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/adminq.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/adminq.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/adminq.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/adminq.c @@ -63,6 +63,15 @@ return nq_work; } +static bool pdsc_adminq_inc_if_up(struct pdsc *pdsc) +{ + if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER) || + pdsc->state & BIT_ULL(PDSC_S_FW_DEAD)) + return false; + + return refcount_inc_not_zero(&pdsc->adminq_refcnt); +} + void pdsc_process_adminq(struct pdsc_qcq *qcq) { union pds_core_adminq_comp *comp; @@ -75,9 +84,9 @@ int aq_work = 0; int credits; - /* Don't process AdminQ when shutting down */ - if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) { - dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n", + /* Don't process AdminQ when it's not up */ + if (!pdsc_adminq_inc_if_up(pdsc)) { + dev_err(pdsc->dev, "%s: called while adminq is unavailable\n", __func__); return; } @@ -124,6 +133,7 @@ pds_core_intr_credits(&pdsc->intr_ctrl[qcq->intx], credits, PDS_CORE_INTR_CRED_REARM); + refcount_dec(&pdsc->adminq_refcnt); } void pdsc_work_thread(struct work_struct *work) @@ -135,18 +145,20 @@ irqreturn_t pdsc_adminq_isr(int irq, void *data) { - struct pdsc_qcq *qcq = data; - struct pdsc *pdsc = qcq->pdsc; + struct pdsc *pdsc = data; + struct pdsc_qcq *qcq; - /* Don't process AdminQ when shutting down */ - if (pdsc->state & BIT_ULL(PDSC_S_STOPPING_DRIVER)) { - dev_err(pdsc->dev, "%s: called while PDSC_S_STOPPING_DRIVER\n", + /* Don't process AdminQ when it's not up */ + if (!pdsc_adminq_inc_if_up(pdsc)) { + dev_err(pdsc->dev, "%s: called while adminq is unavailable\n", __func__); return IRQ_HANDLED; } + qcq = &pdsc->adminqcq; queue_work(pdsc->wq, &qcq->work); pds_core_intr_mask(&pdsc->intr_ctrl[qcq->intx], PDS_CORE_INTR_MASK_CLEAR); + refcount_dec(&pdsc->adminq_refcnt); return IRQ_HANDLED; } @@ -179,10 +191,16 @@ /* Check that the FW is running */ if (!pdsc_is_fw_running(pdsc)) { - u8 fw_status = ioread8(&pdsc->info_regs->fw_status); - - dev_info(pdsc->dev, "%s: post failed - fw not running %#02x:\n", - __func__, fw_status); + if (pdsc->info_regs) { + u8 fw_status = + ioread8(&pdsc->info_regs->fw_status); + + dev_info(pdsc->dev, "%s: post failed - fw not running %#02x:\n", + __func__, fw_status); + } else { + dev_info(pdsc->dev, "%s: post failed - BARs not setup\n", + __func__); + } ret = -ENXIO; goto err_out_unlock; @@ -230,6 +248,12 @@ int err = 0; int index; + if (!pdsc_adminq_inc_if_up(pdsc)) { + dev_dbg(pdsc->dev, "%s: preventing adminq cmd %u\n", + __func__, cmd->opcode); + return -ENXIO; + } + wc.qcq = &pdsc->adminqcq; index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp, &wc); if (index < 0) { @@ -248,10 +272,16 @@ break; if (!pdsc_is_fw_running(pdsc)) { - u8 fw_status = ioread8(&pdsc->info_regs->fw_status); - - dev_dbg(pdsc->dev, "%s: post wait failed - fw not running %#02x:\n", - __func__, fw_status); + if (pdsc->info_regs) { + u8 fw_status = + ioread8(&pdsc->info_regs->fw_status); + + dev_dbg(pdsc->dev, "%s: post wait failed - fw not running %#02x:\n", + __func__, fw_status); + } else { + dev_dbg(pdsc->dev, "%s: post wait failed - BARs not setup\n", + __func__); + } err = -ENXIO; break; } @@ -285,6 +315,8 @@ queue_work(pdsc->wq, &pdsc->health_work); } + refcount_dec(&pdsc->adminq_refcnt); + return err; } EXPORT_SYMBOL_GPL(pdsc_adminq_post); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/core.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/core.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/core.c @@ -125,7 +125,7 @@ snprintf(name, sizeof(name), "%s-%d-%s", PDS_CORE_DRV_NAME, pdsc->pdev->bus->number, qcq->q.name); - index = pdsc_intr_alloc(pdsc, name, pdsc_adminq_isr, qcq); + index = pdsc_intr_alloc(pdsc, name, pdsc_adminq_isr, pdsc); if (index < 0) return index; qcq->intx = index; @@ -407,10 +407,7 @@ int numdescs; int err; - if (init) - err = pdsc_dev_init(pdsc); - else - err = pdsc_dev_reinit(pdsc); + err = pdsc_dev_init(pdsc); if (err) return err; @@ -452,6 +449,7 @@ if (init) pdsc_debugfs_add_viftype(pdsc); + refcount_set(&pdsc->adminq_refcnt, 1); clear_bit(PDSC_S_FW_DEAD, &pdsc->state); return 0; @@ -466,6 +464,8 @@ if (!pdsc->pdev->is_virtfn) pdsc_devcmd_reset(pdsc); + if (pdsc->adminqcq.work.func) + cancel_work_sync(&pdsc->adminqcq.work); pdsc_qcq_free(pdsc, &pdsc->notifyqcq); pdsc_qcq_free(pdsc, &pdsc->adminqcq); @@ -476,10 +476,9 @@ for (i = 0; i < pdsc->nintrs; i++) pdsc_intr_free(pdsc, i); - if (removing) { - kfree(pdsc->intr_info); - pdsc->intr_info = NULL; - } + kfree(pdsc->intr_info); + pdsc->intr_info = NULL; + pdsc->nintrs = 0; } if (pdsc->kern_dbpage) { @@ -487,6 +486,7 @@ pdsc->kern_dbpage = NULL; } + pci_free_irq_vectors(pdsc->pdev); set_bit(PDSC_S_FW_DEAD, &pdsc->state); } @@ -512,7 +512,25 @@ PDS_CORE_INTR_MASK_SET); } -static void pdsc_fw_down(struct pdsc *pdsc) +static void pdsc_adminq_wait_and_dec_once_unused(struct pdsc *pdsc) +{ + /* The driver initializes the adminq_refcnt to 1 when the adminq is + * allocated and ready for use. Other users/requesters will increment + * the refcnt while in use. If the refcnt is down to 1 then the adminq + * is not in use and the refcnt can be cleared and adminq freed. Before + * calling this function the driver will set PDSC_S_FW_DEAD, which + * prevent subsequent attempts to use the adminq and increment the + * refcnt to fail. This guarantees that this function will eventually + * exit. + */ + while (!refcount_dec_if_one(&pdsc->adminq_refcnt)) { + dev_dbg_ratelimited(pdsc->dev, "%s: adminq in use\n", + __func__); + cpu_relax(); + } +} + +void pdsc_fw_down(struct pdsc *pdsc) { union pds_core_notifyq_comp reset_event = { .reset.ecode = cpu_to_le16(PDS_EVENT_RESET), @@ -520,10 +538,15 @@ }; if (test_and_set_bit(PDSC_S_FW_DEAD, &pdsc->state)) { - dev_err(pdsc->dev, "%s: already happening\n", __func__); + dev_warn(pdsc->dev, "%s: already happening\n", __func__); return; } + if (pdsc->pdev->is_virtfn) + return; + + pdsc_adminq_wait_and_dec_once_unused(pdsc); + /* Notify clients of fw_down */ if (pdsc->fw_reporter) devlink_health_report(pdsc->fw_reporter, "FW down reported", pdsc); @@ -533,7 +556,7 @@ pdsc_teardown(pdsc, PDSC_TEARDOWN_RECOVERY); } -static void pdsc_fw_up(struct pdsc *pdsc) +void pdsc_fw_up(struct pdsc *pdsc) { union pds_core_notifyq_comp reset_event = { .reset.ecode = cpu_to_le16(PDS_EVENT_RESET), @@ -546,6 +569,11 @@ return; } + if (pdsc->pdev->is_virtfn) { + clear_bit(PDSC_S_FW_DEAD, &pdsc->state); + return; + } + err = pdsc_setup(pdsc, PDSC_SETUP_RECOVERY); if (err) goto err_out; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/core.h linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/core.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/core.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/core.h @@ -184,6 +184,7 @@ struct mutex devcmd_lock; /* lock for dev_cmd operations */ struct mutex config_lock; /* lock for configuration operations */ spinlock_t adminq_lock; /* lock for adminq operations */ + refcount_t adminq_refcnt; struct pds_core_dev_info_regs __iomem *info_regs; struct pds_core_dev_cmd_regs __iomem *cmd_regs; struct pds_core_intr __iomem *intr_ctrl; @@ -280,7 +281,6 @@ union pds_core_dev_comp *comp, int max_seconds); int pdsc_devcmd_init(struct pdsc *pdsc); int pdsc_devcmd_reset(struct pdsc *pdsc); -int pdsc_dev_reinit(struct pdsc *pdsc); int pdsc_dev_init(struct pdsc *pdsc); int pdsc_intr_alloc(struct pdsc *pdsc, char *name, @@ -311,2 +311,6 @@ struct netlink_ext_ack *extack); + +void pdsc_fw_down(struct pdsc *pdsc); +void pdsc_fw_up(struct pdsc *pdsc); + #endif /* _PDSC_H_ */ diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/dev.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/dev.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/dev.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/dev.c @@ -55,6 +55,9 @@ bool pdsc_is_fw_running(struct pdsc *pdsc) { + if (!pdsc->info_regs) + return false; + pdsc->fw_status = ioread8(&pdsc->info_regs->fw_status); pdsc->last_fw_time = jiffies; pdsc->last_hb = ioread32(&pdsc->info_regs->fw_heartbeat); @@ -175,13 +178,17 @@ { int err; + if (!pdsc->cmd_regs) + return -ENXIO; + memcpy_toio(&pdsc->cmd_regs->cmd, cmd, sizeof(*cmd)); pdsc_devcmd_dbell(pdsc); err = pdsc_devcmd_wait(pdsc, cmd->opcode, max_seconds); - memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp)); if ((err == -ENXIO || err == -ETIMEDOUT) && pdsc->wq) queue_work(pdsc->wq, &pdsc->health_work); + else + memcpy_fromio(comp, &pdsc->cmd_regs->comp, sizeof(*comp)); return err; } @@ -302,13 +309,6 @@ return 0; } -int pdsc_dev_reinit(struct pdsc *pdsc) -{ - pdsc_init_devinfo(pdsc); - - return pdsc_identify(pdsc); -} - int pdsc_dev_init(struct pdsc *pdsc) { unsigned int nintrs; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/devlink.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/devlink.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/devlink.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/devlink.c @@ -111,7 +111,8 @@ mutex_lock(&pdsc->devcmd_lock); err = pdsc_devcmd_locked(pdsc, &cmd, &comp, pdsc->devcmd_timeout * 2); - memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list)); + if (!err) + memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list)); mutex_unlock(&pdsc->devcmd_lock); if (err && err != -EIO) return err; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c @@ -953,8 +953,6 @@ { struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp; unsigned int tx_ring_idx, rx_ring_idx; - struct aq_ring_s *hwts; - struct aq_ring_s *ring; int err; if (!aq_ptp) @@ -962,29 +960,23 @@ tx_ring_idx = aq_ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode); - ring = aq_ring_tx_alloc(&aq_ptp->ptp_tx, aq_nic, - tx_ring_idx, &aq_nic->aq_nic_cfg); - if (!ring) { - err = -ENOMEM; + err = aq_ring_tx_alloc(&aq_ptp->ptp_tx, aq_nic, + tx_ring_idx, &aq_nic->aq_nic_cfg); + if (err) goto err_exit; - } rx_ring_idx = aq_ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode); - ring = aq_ring_rx_alloc(&aq_ptp->ptp_rx, aq_nic, - rx_ring_idx, &aq_nic->aq_nic_cfg); - if (!ring) { - err = -ENOMEM; + err = aq_ring_rx_alloc(&aq_ptp->ptp_rx, aq_nic, + rx_ring_idx, &aq_nic->aq_nic_cfg); + if (err) goto err_exit_ptp_tx; - } - hwts = aq_ring_hwts_rx_alloc(&aq_ptp->hwts_rx, aq_nic, PTP_HWST_RING_IDX, - aq_nic->aq_nic_cfg.rxds, - aq_nic->aq_nic_cfg.aq_hw_caps->rxd_size); - if (!hwts) { - err = -ENOMEM; + err = aq_ring_hwts_rx_alloc(&aq_ptp->hwts_rx, aq_nic, PTP_HWST_RING_IDX, + aq_nic->aq_nic_cfg.rxds, + aq_nic->aq_nic_cfg.aq_hw_caps->rxd_size); + if (err) goto err_exit_ptp_rx; - } err = aq_ptp_skb_ring_init(&aq_ptp->skb_ring, aq_nic->aq_nic_cfg.rxds); if (err != 0) { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/aquantia/atlantic/aq_ring.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/aquantia/atlantic/aq_ring.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -132,8 +132,8 @@ return 0; } -static struct aq_ring_s *aq_ring_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic) +static int aq_ring_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic) { int err = 0; @@ -156,46 +156,29 @@ err_exit: if (err < 0) { aq_ring_free(self); - self = NULL; } - return self; + return err; } -struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic, - unsigned int idx, - struct aq_nic_cfg_s *aq_nic_cfg) +int aq_ring_tx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg) { - int err = 0; - self->aq_nic = aq_nic; self->idx = idx; self->size = aq_nic_cfg->txds; self->dx_size = aq_nic_cfg->aq_hw_caps->txd_size; - self = aq_ring_alloc(self, aq_nic); - if (!self) { - err = -ENOMEM; - goto err_exit; - } - -err_exit: - if (err < 0) { - aq_ring_free(self); - self = NULL; - } - - return self; + return aq_ring_alloc(self, aq_nic); } -struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic, - unsigned int idx, - struct aq_nic_cfg_s *aq_nic_cfg) +int aq_ring_rx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg) { - int err = 0; - self->aq_nic = aq_nic; self->idx = idx; self->size = aq_nic_cfg->rxds; @@ -217,22 +200,10 @@ self->tail_size = 0; } - self = aq_ring_alloc(self, aq_nic); - if (!self) { - err = -ENOMEM; - goto err_exit; - } - -err_exit: - if (err < 0) { - aq_ring_free(self); - self = NULL; - } - - return self; + return aq_ring_alloc(self, aq_nic); } -struct aq_ring_s * +int aq_ring_hwts_rx_alloc(struct aq_ring_s *self, struct aq_nic_s *aq_nic, unsigned int idx, unsigned int size, unsigned int dx_size) { @@ -250,10 +221,10 @@ GFP_KERNEL); if (!self->dx_ring) { aq_ring_free(self); - return NULL; + return -ENOMEM; } - return self; + return 0; } int aq_ring_init(struct aq_ring_s *self, const enum atl_ring_type ring_type) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/broadcom/bnxt/bnxt.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/broadcom/bnxt/bnxt.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -11165,10 +11165,12 @@ netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc); goto half_open_err; } + bnxt_init_napi(bp); set_bit(BNXT_STATE_HALF_OPEN, &bp->state); rc = bnxt_init_nic(bp, true); if (rc) { clear_bit(BNXT_STATE_HALF_OPEN, &bp->state); + bnxt_del_napi(bp); netdev_err(bp->dev, "bnxt_init_nic err: %x\n", rc); goto half_open_err; } @@ -11187,6 +11189,7 @@ void bnxt_half_close_nic(struct bnxt *bp) { bnxt_hwrm_resource_free(bp, false, true); + bnxt_del_napi(bp); bnxt_free_skbs(bp); bnxt_free_mem(bp, true); clear_bit(BNXT_STATE_HALF_OPEN, &bp->state); @@ -12836,6 +12839,11 @@ bp->fw_cap = 0; rc = bnxt_hwrm_ver_get(bp); + /* FW may be unresponsive after FLR. FLR must complete within 100 msec + * so wait before continuing with recovery. + */ + if (rc) + msleep(100); bnxt_try_map_fw_health_reg(bp); if (rc) { rc = bnxt_try_recover_fw(bp); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/engleder/tsnep_main.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/engleder/tsnep_main.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/engleder/tsnep_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/engleder/tsnep_main.c @@ -1433,7 +1433,7 @@ xdp_prepare_buff(&xdp, page_address(entry->page), XDP_PACKET_HEADROOM + TSNEP_RX_INLINE_METADATA_SIZE, - length, false); + length - ETH_FCS_LEN, false); consume = tsnep_xdp_run_prog(rx, prog, &xdp, &xdp_status, tx_nq, tx); @@ -1516,7 +1516,7 @@ prefetch(entry->xdp->data); length = __le32_to_cpu(entry->desc_wb->properties) & TSNEP_DESC_LENGTH_MASK; - xsk_buff_set_size(entry->xdp, length); + xsk_buff_set_size(entry->xdp, length - ETH_FCS_LEN); xsk_buff_dma_sync_for_cpu(entry->xdp, rx->xsk_pool); /* RX metadata with timestamps is in front of actual data, @@ -1710,6 +1710,19 @@ allocated--; } } + + /* set need wakeup flag immediately if ring is not filled completely, + * first polling would be too late as need wakeup signalisation would + * be delayed for an indefinite time + */ + if (xsk_uses_need_wakeup(rx->xsk_pool)) { + int desc_available = tsnep_rx_desc_available(rx); + + if (desc_available) + xsk_set_rx_need_wakeup(rx->xsk_pool); + else + xsk_clear_rx_need_wakeup(rx->xsk_pool); + } } static bool tsnep_pending(struct tsnep_queue *queue) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/freescale/fec_main.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/freescale/fec_main.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/freescale/fec_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/freescale/fec_main.c @@ -1986,6 +1986,7 @@ /* if any of the above changed restart the FEC */ if (status_change) { + netif_stop_queue(ndev); napi_disable(&fep->napi); netif_tx_lock_bh(ndev); fec_restart(ndev); @@ -1995,6 +1996,7 @@ } } else { if (fep->link) { + netif_stop_queue(ndev); napi_disable(&fep->napi); netif_tx_lock_bh(ndev); fec_stop(ndev); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/google/gve/gve_rx.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/google/gve/gve_rx.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/google/gve/gve_rx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/google/gve/gve_rx.c @@ -362,7 +362,7 @@ static struct sk_buff *gve_rx_add_frags(struct napi_struct *napi, struct gve_rx_slot_page_info *page_info, - u16 packet_buffer_size, u16 len, + unsigned int truesize, u16 len, struct gve_rx_ctx *ctx) { u32 offset = page_info->page_offset + page_info->pad; @@ -395,10 +395,10 @@ if (skb != ctx->skb_head) { ctx->skb_head->len += len; ctx->skb_head->data_len += len; - ctx->skb_head->truesize += packet_buffer_size; + ctx->skb_head->truesize += truesize; } skb_add_rx_frag(skb, num_frags, page_info->page, - offset, len, packet_buffer_size); + offset, len, truesize); return ctx->skb_head; } @@ -492,7 +492,7 @@ memcpy(alloc_page_info.page_address, src, page_info->pad + len); skb = gve_rx_add_frags(napi, &alloc_page_info, - rx->packet_buffer_size, + PAGE_SIZE, len, ctx); u64_stats_update_begin(&rx->statss); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_main.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_main.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -3578,45 +3578,53 @@ struct i40e_hmc_obj_rxq rx_ctx; int err = 0; bool ok; - int ret; bitmap_zero(ring->state, __I40E_RING_STATE_NBITS); /* clear the context structure first */ memset(&rx_ctx, 0, sizeof(rx_ctx)); - if (ring->vsi->type == I40E_VSI_MAIN) - xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); + ring->rx_buf_len = vsi->rx_buf_len; + + /* XDP RX-queue info only needed for RX rings exposed to XDP */ + if (ring->vsi->type != I40E_VSI_MAIN) + goto skip; + + if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) { + err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, + ring->queue_index, + ring->q_vector->napi.napi_id, + ring->rx_buf_len); + if (err) + return err; + } ring->xsk_pool = i40e_xsk_pool(ring); if (ring->xsk_pool) { - ring->rx_buf_len = - xsk_pool_get_rx_frame_size(ring->xsk_pool); + ring->rx_buf_len = xsk_pool_get_rx_frame_size(ring->xsk_pool); /* For AF_XDP ZC, we disallow packets to span on * multiple buffers, thus letting us skip that * handling in the fast-path. */ chain_len = 1; - ret = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, + err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, MEM_TYPE_XSK_BUFF_POOL, NULL); - if (ret) - return ret; + if (err) + return err; dev_info(&vsi->back->pdev->dev, "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n", ring->queue_index); } else { - ring->rx_buf_len = vsi->rx_buf_len; - if (ring->vsi->type == I40E_VSI_MAIN) { - ret = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, - MEM_TYPE_PAGE_SHARED, - NULL); - if (ret) - return ret; - } + err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, + MEM_TYPE_PAGE_SHARED, + NULL); + if (err) + return err; } +skip: xdp_init_buff(&ring->xdp, i40e_rx_pg_size(ring) / 2, &ring->xdp_rxq); rx_ctx.dbuff = DIV_ROUND_UP(ring->rx_buf_len, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_txrx.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_txrx.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1556,7 +1556,6 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring) { struct device *dev = rx_ring->dev; - int err; u64_stats_init(&rx_ring->syncp); @@ -1577,14 +1576,6 @@ rx_ring->next_to_process = 0; rx_ring->next_to_use = 0; - /* XDP RX-queue info only needed for RX rings exposed to XDP */ - if (rx_ring->vsi->type == I40E_VSI_MAIN) { - err = xdp_rxq_info_reg(&rx_ring->xdp_rxq, rx_ring->netdev, - rx_ring->queue_index, rx_ring->q_vector->napi.napi_id); - if (err < 0) - return err; - } - rx_ring->xdp_prog = rx_ring->vsi->xdp_prog; rx_ring->rx_bi = @@ -2100,7 +2091,8 @@ static void i40e_process_rx_buffs(struct i40e_ring *rx_ring, int xdp_res, struct xdp_buff *xdp) { - u32 next = rx_ring->next_to_clean; + u32 nr_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags; + u32 next = rx_ring->next_to_clean, i = 0; struct i40e_rx_buffer *rx_buffer; xdp->flags = 0; @@ -2113,10 +2105,10 @@ if (!rx_buffer->page) continue; - if (xdp_res == I40E_XDP_CONSUMED) - rx_buffer->pagecnt_bias++; - else + if (xdp_res != I40E_XDP_CONSUMED) i40e_rx_buffer_flip(rx_buffer, xdp->frame_sz); + else if (i++ <= nr_frags) + rx_buffer->pagecnt_bias++; /* EOP buffer will be put in i40e_clean_rx_irq() */ if (next == rx_ring->next_to_process) @@ -2130,20 +2122,20 @@ * i40e_construct_skb - Allocate skb and populate it * @rx_ring: rx descriptor ring to transact packets on * @xdp: xdp_buff pointing to the data - * @nr_frags: number of buffers for the packet * * This function allocates an skb. It then populates it with the page * data from the current receive descriptor, taking care to set up the * skb correctly. */ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring, - struct xdp_buff *xdp, - u32 nr_frags) + struct xdp_buff *xdp) { unsigned int size = xdp->data_end - xdp->data; struct i40e_rx_buffer *rx_buffer; + struct skb_shared_info *sinfo; unsigned int headlen; struct sk_buff *skb; + u32 nr_frags = 0; /* prefetch first cache line of first page */ net_prefetch(xdp->data); @@ -2181,6 +2173,10 @@ memcpy(__skb_put(skb, headlen), xdp->data, ALIGN(headlen, sizeof(long))); + if (unlikely(xdp_buff_has_frags(xdp))) { + sinfo = xdp_get_shared_info_from_buff(xdp); + nr_frags = sinfo->nr_frags; + } rx_buffer = i40e_rx_bi(rx_ring, rx_ring->next_to_clean); /* update all of the pointers */ size -= headlen; @@ -2200,9 +2196,8 @@ } if (unlikely(xdp_buff_has_frags(xdp))) { - struct skb_shared_info *sinfo, *skinfo = skb_shinfo(skb); + struct skb_shared_info *skinfo = skb_shinfo(skb); - sinfo = xdp_get_shared_info_from_buff(xdp); memcpy(&skinfo->frags[skinfo->nr_frags], &sinfo->frags[0], sizeof(skb_frag_t) * nr_frags); @@ -2225,17 +2220,17 @@ * i40e_build_skb - Build skb around an existing buffer * @rx_ring: Rx descriptor ring to transact packets on * @xdp: xdp_buff pointing to the data - * @nr_frags: number of buffers for the packet * * This function builds an skb around an existing Rx buffer, taking care * to set up the skb correctly and avoid any memcpy overhead. */ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring, - struct xdp_buff *xdp, - u32 nr_frags) + struct xdp_buff *xdp) { unsigned int metasize = xdp->data - xdp->data_meta; + struct skb_shared_info *sinfo; struct sk_buff *skb; + u32 nr_frags; /* Prefetch first cache line of first page. If xdp->data_meta * is unused, this points exactly as xdp->data, otherwise we @@ -2244,6 +2239,11 @@ */ net_prefetch(xdp->data_meta); + if (unlikely(xdp_buff_has_frags(xdp))) { + sinfo = xdp_get_shared_info_from_buff(xdp); + nr_frags = sinfo->nr_frags; + } + /* build an skb around the page buffer */ skb = napi_build_skb(xdp->data_hard_start, xdp->frame_sz); if (unlikely(!skb)) @@ -2256,9 +2256,6 @@ skb_metadata_set(skb, metasize); if (unlikely(xdp_buff_has_frags(xdp))) { - struct skb_shared_info *sinfo; - - sinfo = xdp_get_shared_info_from_buff(xdp); xdp_update_skb_shared_info(skb, nr_frags, sinfo->xdp_frags_size, nr_frags * xdp->frame_sz, @@ -2603,9 +2600,9 @@ total_rx_bytes += size; } else { if (ring_uses_build_skb(rx_ring)) - skb = i40e_build_skb(rx_ring, xdp, nfrags); + skb = i40e_build_skb(rx_ring, xdp); else - skb = i40e_construct_skb(rx_ring, xdp, nfrags); + skb = i40e_construct_skb(rx_ring, xdp); /* drop if we failed to retrieve a buffer */ if (!skb) { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -2604,6 +2604,14 @@ int aq_ret = 0; int i; + if (vf->is_disabled_from_host) { + aq_ret = -EPERM; + dev_info(&pf->pdev->dev, + "Admin has disabled VF %d, will not enable queues\n", + vf->vf_id); + goto error_param; + } + if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { aq_ret = I40E_ERR_PARAM; goto error_param; @@ -4723,9 +4731,12 @@ struct i40e_link_status *ls = &pf->hw.phy.link_info; struct virtchnl_pf_event pfe; struct i40e_hw *hw = &pf->hw; + struct i40e_vsi *vsi; + unsigned long q_map; struct i40e_vf *vf; int abs_vf_id; int ret = 0; + int tmp; if (test_and_set_bit(__I40E_VIRTCHNL_OP_PENDING, pf->state)) { dev_warn(&pf->pdev->dev, "Unable to configure VFs, other operation is pending.\n"); @@ -4748,17 +4759,38 @@ switch (link) { case IFLA_VF_LINK_STATE_AUTO: vf->link_forced = false; + vf->is_disabled_from_host = false; + /* reset needed to reinit VF resources */ + i40e_vc_reset_vf(vf, true); i40e_set_vf_link_state(vf, &pfe, ls); break; case IFLA_VF_LINK_STATE_ENABLE: vf->link_forced = true; vf->link_up = true; + vf->is_disabled_from_host = false; + /* reset needed to reinit VF resources */ + i40e_vc_reset_vf(vf, true); i40e_set_vf_link_state(vf, &pfe, ls); break; case IFLA_VF_LINK_STATE_DISABLE: vf->link_forced = true; vf->link_up = false; i40e_set_vf_link_state(vf, &pfe, ls); + + vsi = pf->vsi[vf->lan_vsi_idx]; + q_map = BIT(vsi->num_queue_pairs) - 1; + + vf->is_disabled_from_host = true; + + /* Try to stop both Tx&Rx rings even if one of the calls fails + * to ensure we stop the rings even in case of errors. + * If any of them returns with an error then the first + * error that occurred will be returned. + */ + tmp = i40e_ctrl_vf_tx_rings(vsi, q_map, false); + ret = i40e_ctrl_vf_rx_rings(vsi, q_map, false); + + ret = tmp ? tmp : ret; break; default: ret = -EINVAL; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h @@ -98,6 +98,7 @@ bool link_forced; bool link_up; /* only valid if VF link is forced */ bool spoofchk; + bool is_disabled_from_host; /* PF ctrl of VF enable/disable */ u16 num_vlan; /* ADq related variables */ diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h @@ -416,10 +416,10 @@ #define ICE_AQ_VSI_INNER_VLAN_INSERT_PVID BIT(2) #define ICE_AQ_VSI_INNER_VLAN_EMODE_S 3 #define ICE_AQ_VSI_INNER_VLAN_EMODE_M (0x3 << ICE_AQ_VSI_INNER_VLAN_EMODE_S) -#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH (0x0 << ICE_AQ_VSI_INNER_VLAN_EMODE_S) -#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR_UP (0x1 << ICE_AQ_VSI_INNER_VLAN_EMODE_S) -#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR (0x2 << ICE_AQ_VSI_INNER_VLAN_EMODE_S) -#define ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING (0x3 << ICE_AQ_VSI_INNER_VLAN_EMODE_S) +#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH 0x0U +#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR_UP 0x1U +#define ICE_AQ_VSI_INNER_VLAN_EMODE_STR 0x2U +#define ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING 0x3U u8 inner_vlan_reserved2[3]; /* ingress egress up sections */ __le32 ingress_table; /* bitmap, 3 bits per up */ @@ -485,11 +485,11 @@ #define ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_S 2 #define ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_M (0xF << ICE_AQ_VSI_Q_OPT_RSS_GBL_LUT_S) #define ICE_AQ_VSI_Q_OPT_RSS_HASH_S 6 -#define ICE_AQ_VSI_Q_OPT_RSS_HASH_M (0x3 << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) -#define ICE_AQ_VSI_Q_OPT_RSS_TPLZ (0x0 << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) -#define ICE_AQ_VSI_Q_OPT_RSS_SYM_TPLZ (0x1 << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) -#define ICE_AQ_VSI_Q_OPT_RSS_XOR (0x2 << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) -#define ICE_AQ_VSI_Q_OPT_RSS_JHASH (0x3 << ICE_AQ_VSI_Q_OPT_RSS_HASH_S) +#define ICE_AQ_VSI_Q_OPT_RSS_HASH_M GENMASK(7, 6) +#define ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ 0x0U +#define ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ 0x1U +#define ICE_AQ_VSI_Q_OPT_RSS_HASH_XOR 0x2U +#define ICE_AQ_VSI_Q_OPT_RSS_HASH_JHASH 0x3U u8 q_opt_tc; #define ICE_AQ_VSI_Q_OPT_TC_OVR_S 0 #define ICE_AQ_VSI_Q_OPT_TC_OVR_M (0x1F << ICE_AQ_VSI_Q_OPT_TC_OVR_S) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_lib.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_lib.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_lib.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_lib.c @@ -979,7 +979,8 @@ */ if (ice_is_dvm_ena(hw)) { ctxt->info.inner_vlan_flags |= - ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING; + FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_EMODE_M, + ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING); ctxt->info.outer_vlan_flags = (ICE_AQ_VSI_OUTER_VLAN_TX_MODE_ALL << ICE_AQ_VSI_OUTER_VLAN_TX_MODE_S) & @@ -1186,12 +1187,12 @@ case ICE_VSI_PF: /* PF VSI will inherit RSS instance of PF */ lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_PF; - hash_type = ICE_AQ_VSI_Q_OPT_RSS_TPLZ; + hash_type = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; break; case ICE_VSI_VF: /* VF VSI will gets a small RSS table which is a VSI LUT type */ lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI; - hash_type = ICE_AQ_VSI_Q_OPT_RSS_TPLZ; + hash_type = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; break; default: dev_dbg(dev, "Unsupported VSI type %s\n", diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_virtchnl.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_virtchnl.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_virtchnl.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_virtchnl.c @@ -820,8 +820,8 @@ int status; lut_type = ICE_AQ_VSI_Q_OPT_RSS_LUT_VSI; - hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_XOR : - ICE_AQ_VSI_Q_OPT_RSS_TPLZ; + hash_type = add ? ICE_AQ_VSI_Q_OPT_RSS_HASH_XOR : + ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (!ctx) { @@ -829,11 +829,9 @@ goto error_param; } - ctx->info.q_opt_rss = ((lut_type << - ICE_AQ_VSI_Q_OPT_RSS_LUT_S) & - ICE_AQ_VSI_Q_OPT_RSS_LUT_M) | - (hash_type & - ICE_AQ_VSI_Q_OPT_RSS_HASH_M); + ctx->info.q_opt_rss = + FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_LUT_M, lut_type) | + FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_HASH_M, hash_type); /* Preserve existing queueing option setting */ ctx->info.q_opt_rss |= (vsi->info.q_opt_rss & diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -1329,7 +1329,7 @@ break; default: e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); - retval = IXGBE_ERR_MBX; + retval = -EIO; break; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -614,12 +614,38 @@ mvpp2_write(priv, MVPP22_BM_POOL_BASE_ADDR_HIGH_REG, val); } +/* Cleanup pool before actual initialization in the OS */ +static void mvpp2_bm_pool_cleanup(struct mvpp2 *priv, int pool_id) +{ + unsigned int thread = mvpp2_cpu_to_thread(priv, get_cpu()); + u32 val; + int i; + + /* Drain the BM from all possible residues left by firmware */ + for (i = 0; i < MVPP2_BM_POOL_SIZE_MAX; i++) + mvpp2_thread_read(priv, thread, MVPP2_BM_PHY_ALLOC_REG(pool_id)); + + put_cpu(); + + /* Stop the BM pool */ + val = mvpp2_read(priv, MVPP2_BM_POOL_CTRL_REG(pool_id)); + val |= MVPP2_BM_STOP_MASK; + mvpp2_write(priv, MVPP2_BM_POOL_CTRL_REG(pool_id), val); +} + static int mvpp2_bm_init(struct device *dev, struct mvpp2 *priv) { enum dma_data_direction dma_dir = DMA_FROM_DEVICE; int i, err, poolnum = MVPP2_BM_POOLS_NUM; struct mvpp2_port *port; + if (priv->percpu_pools) + poolnum = mvpp2_get_nrxqs(priv) * 2; + + /* Clean up the pool state in case it contains stale state */ + for (i = 0; i < poolnum; i++) + mvpp2_bm_pool_cleanup(priv, i); + if (priv->percpu_pools) { for (i = 0; i < priv->port_count; i++) { port = priv->port_list[i]; @@ -629,7 +655,6 @@ } } - poolnum = mvpp2_get_nrxqs(priv) * 2; for (i = 0; i < poolnum; i++) { /* the pool in use */ int pn = i / (poolnum / 2); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/af/rpm.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/af/rpm.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/af/rpm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/af/rpm.c @@ -506,6 +506,7 @@ rpm_t *rpm = rpmd; u8 num_lmacs; u32 fifo_len; + u16 max_lmac; lmac_info = rpm_read(rpm, 0, RPM2_CMRX_RX_LMACS); /* LMACs are divided into two groups and each group @@ -513,7 +514,11 @@ * Group0 lmac_id range {0..3} * Group1 lmac_id range {4..7} */ - fifo_len = rpm->mac_ops->fifo_len / 2; + max_lmac = (rpm_read(rpm, 0, CGX_CONST) >> 24) & 0xFF; + if (max_lmac > 4) + fifo_len = rpm->mac_ops->fifo_len / 2; + else + fifo_len = rpm->mac_ops->fifo_len; if (lmac_id < 4) { num_lmacs = hweight8(lmac_info & 0xF); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c @@ -2678,18 +2678,17 @@ rsp->entry = NPC_MCAM_ENTRY_INVALID; rsp->free_count = 0; - /* Check if ref_entry is within range */ - if (req->priority && req->ref_entry >= mcam->bmap_entries) { - dev_err(rvu->dev, "%s: reference entry %d is out of range\n", - __func__, req->ref_entry); - return NPC_MCAM_INVALID_REQ; - } + /* Check if ref_entry is greater that the range + * then set it to max value. + */ + if (req->ref_entry > mcam->bmap_entries) + req->ref_entry = mcam->bmap_entries; /* ref_entry can't be '0' if requested priority is high. * Can't be last entry if requested priority is low. */ if ((!req->ref_entry && req->priority == NPC_MCAM_HIGHER_PRIO) || - ((req->ref_entry == (mcam->bmap_entries - 1)) && + ((req->ref_entry == mcam->bmap_entries) && req->priority == NPC_MCAM_LOWER_PRIO)) return NPC_MCAM_INVALID_REQ; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ethtool.c @@ -314,7 +314,6 @@ pfvf->hw.tx_queues = channel->tx_count; if (pfvf->xdp_prog) pfvf->hw.xdp_queues = channel->rx_count; - pfvf->hw.non_qos_queues = pfvf->hw.tx_queues + pfvf->hw.xdp_queues; if (if_up) err = dev->netdev_ops->ndo_open(dev); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -1743,6 +1743,7 @@ /* RQ and SQs are mapped to different CQs, * so find out max CQ IRQs (i.e CINTs) needed. */ + pf->hw.non_qos_queues = pf->hw.tx_queues + pf->hw.xdp_queues; pf->hw.cint_cnt = max3(pf->hw.rx_queues, pf->hw.tx_queues, pf->hw.tc_tx_queues); @@ -2642,8 +2643,6 @@ xdp_features_clear_redirect_target(dev); } - pf->hw.non_qos_queues += pf->hw.xdp_queues; - if (if_up) otx2_open(pf->netdev); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c @@ -1403,7 +1403,7 @@ struct otx2_cq_queue *cq, bool *need_xdp_flush) { - unsigned char *hard_start, *data; + unsigned char *hard_start; int qidx = cq->cq_idx; struct xdp_buff xdp; struct page *page; @@ -1417,9 +1417,8 @@ xdp_init_buff(&xdp, pfvf->rbsize, &cq->xdp_rxq); - data = (unsigned char *)phys_to_virt(pa); - hard_start = page_address(page); - xdp_prepare_buff(&xdp, hard_start, data - hard_start, + hard_start = (unsigned char *)phys_to_virt(pa); + xdp_prepare_buff(&xdp, hard_start, OTX2_HEAD_ROOM, cqe->sg.seg_size, false); act = bpf_prog_run_xdp(prog, &xdp); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c @@ -436,6 +436,7 @@ in = kvzalloc(inlen, GFP_KERNEL); if (!in || !ft->g) { kfree(ft->g); + ft->g = NULL; kvfree(in); return -ENOMEM; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c @@ -213,7 +213,7 @@ mlx5e_ptpsq_mark_ts_cqes_undelivered(ptpsq, hwtstamp); out: napi_consume_skb(skb, budget); - md_buff[*md_buff_sz++] = metadata_id; + md_buff[(*md_buff_sz)++] = metadata_id; if (unlikely(mlx5e_ptp_metadata_map_unhealthy(&ptpsq->metadata_map)) && !test_and_set_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) queue_work(ptpsq->txqsq.priv->wq, &ptpsq->report_unhealthy_work); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -334,12 +334,17 @@ /* iv len */ aes_gcm->icv_len = x->aead->alg_icv_len; + attrs->dir = x->xso.dir; + /* esn */ if (x->props.flags & XFRM_STATE_ESN) { attrs->replay_esn.trigger = true; attrs->replay_esn.esn = sa_entry->esn_state.esn; attrs->replay_esn.esn_msb = sa_entry->esn_state.esn_msb; attrs->replay_esn.overlap = sa_entry->esn_state.overlap; + if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) + goto skip_replay_window; + switch (x->replay_esn->replay_window) { case 32: attrs->replay_esn.replay_window = @@ -363,7 +368,7 @@ } } - attrs->dir = x->xso.dir; +skip_replay_window: /* spi */ attrs->spi = be32_to_cpu(x->id.spi); @@ -476,7 +481,8 @@ return -EINVAL; } - if (x->replay_esn && x->replay_esn->replay_window != 32 && + if (x->replay_esn && x->xso.dir == XFRM_DEV_OFFLOAD_IN && + x->replay_esn->replay_window != 32 && x->replay_esn->replay_window != 64 && x->replay_esn->replay_window != 128 && x->replay_esn->replay_window != 256) { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -2015,9 +2015,10 @@ list_for_each_entry_safe(peer_flow, tmp, &flow->peer_flows, peer_flows) { if (peer_index != mlx5_get_dev_index(peer_flow->priv->mdev)) continue; + + list_del(&peer_flow->peer_flows); if (refcount_dec_and_test(&peer_flow->refcnt)) { mlx5e_tc_del_fdb_flow(peer_flow->priv, peer_flow); - list_del(&peer_flow->peer_flows); kfree(peer_flow); } } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_rx.c @@ -142,6 +142,9 @@ writeq(MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS_EN, priv->base + MLXBF_GIGE_RX_MAC_FILTER_COUNT_PASS); + writeq(ilog2(priv->rx_q_entries), + priv->base + MLXBF_GIGE_RX_WQE_SIZE_LOG2); + /* Clear MLXBF_GIGE_INT_MASK 'receive pkt' bit to * indicate readiness to receive interrupts */ @@ -154,9 +157,6 @@ data |= MLXBF_GIGE_RX_DMA_EN; writeq(data, priv->base + MLXBF_GIGE_RX_DMA); - writeq(ilog2(priv->rx_q_entries), - priv->base + MLXBF_GIGE_RX_WQE_SIZE_LOG2); - return 0; free_wqe_and_skb: diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/pensando/ionic/ionic_dev.h linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/pensando/ionic/ionic_dev.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/pensando/ionic/ionic_dev.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/pensando/ionic/ionic_dev.h @@ -152,6 +152,7 @@ bool fw_hb_ready; bool fw_status_ready; u8 fw_generation; + u8 opcode; u64 __iomem *db_pages; dma_addr_t phy_db_pages; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/pensando/ionic/ionic_lif.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/pensando/ionic/ionic_lif.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -3238,6 +3238,9 @@ { struct ionic_dev *idev = &lif->ionic->idev; + if (!ionic_is_fw_running(idev)) + return; + mutex_lock(&lif->ionic->dev_cmd_lock); ionic_dev_cmd_lif_reset(idev, lif->index); ionic_dev_cmd_wait(lif->ionic, DEVCMD_TIMEOUT); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/renesas/ravb_main.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/renesas/ravb_main.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/renesas/ravb_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/renesas/ravb_main.c @@ -1950,7 +1950,7 @@ struct ravb_tstamp_skb *ts_skb; struct ravb_tx_desc *desc; unsigned long flags; - u32 dma_addr; + dma_addr_t dma_addr; void *buffer; u32 entry; u32 len; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3530,6 +3530,7 @@ /* Request the Wake IRQ in case of another line * is used for WoL */ + priv->wol_irq_disabled = true; if (priv->wol_irq > 0 && priv->wol_irq != dev->irq) { int_name = priv->int_name_wol; sprintf(int_name, "%s:%s", dev->name, "wol"); @@ -4334,6 +4335,28 @@ } /** + * stmmac_has_ip_ethertype() - Check if packet has IP ethertype + * @skb: socket buffer to check + * + * Check if a packet has an ethertype that will trigger the IP header checks + * and IP/TCP checksum engine of the stmmac core. + * + * Return: true if the ethertype can trigger the checksum engine, false + * otherwise + */ +static bool stmmac_has_ip_ethertype(struct sk_buff *skb) +{ + int depth = 0; + __be16 proto; + + proto = __vlan_get_protocol(skb, eth_header_parse_protocol(skb), + &depth); + + return (depth <= ETH_HLEN) && + (proto == htons(ETH_P_IP) || proto == htons(ETH_P_IPV6)); +} + +/** * stmmac_xmit - Tx entry point of the driver * @skb : the socket buffer * @dev : device pointer @@ -4391,6 +4414,20 @@ WARN_ON(tx_q->tx_skbuff[first_entry]); csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL); + /* DWMAC IPs can be synthesized to support tx coe only for a few tx + * queues. In that case, checksum offloading for those queues that don't + * support tx coe needs to fallback to software checksum calculation. + * + * Packets that won't trigger the COE e.g. most DSA-tagged packets will + * also have to be checksummed in software. + */ + if (csum_insertion && + (priv->plat->tx_queues_cfg[queue].coe_unsupported || + !stmmac_has_ip_ethertype(skb))) { + if (unlikely(skb_checksum_help(skb))) + goto dma_map_err; + csum_insertion = !csum_insertion; + } if (likely(priv->extend_desc)) desc = (struct dma_desc *)(tx_q->dma_etx + entry); @@ -4937,7 +4974,7 @@ stmmac_rx_vlan(priv->dev, skb); skb->protocol = eth_type_trans(skb, priv->dev); - if (unlikely(!coe)) + if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb)) skb_checksum_none_assert(skb); else skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -5445,7 +5482,7 @@ stmmac_rx_vlan(priv->dev, skb); skb->protocol = eth_type_trans(skb, priv->dev); - if (unlikely(!coe)) + if (unlikely(!coe) || !stmmac_has_ip_ethertype(skb)) skb_checksum_none_assert(skb); else skb->ip_summed = CHECKSUM_UNNECESSARY; @@ -7201,6 +7238,9 @@ dev_err(priv->device, "unable to bring out of ahb reset: %pe\n", ERR_PTR(ret)); + /* Wait a bit for the reset to take effect */ + udelay(10); + /* Init MAC and get the capabilities */ ret = stmmac_hw_init(priv); if (ret) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -277,6 +277,9 @@ plat->tx_queues_cfg[queue].use_prio = true; } + plat->tx_queues_cfg[queue].coe_unsupported = + of_property_read_bool(q_node, "snps,coe-unsupported"); + queue++; } if (queue != plat->tx_queues_to_use) { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/ti/am65-cpsw-nuss.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/ti/am65-cpsw-nuss.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -55,7 +55,7 @@ #define AM65_CPSW_MAX_PORTS 8 #define AM65_CPSW_MIN_PACKET_SIZE VLAN_ETH_ZLEN -#define AM65_CPSW_MAX_PACKET_SIZE (VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) +#define AM65_CPSW_MAX_PACKET_SIZE 2024 #define AM65_CPSW_REG_CTL 0x004 #define AM65_CPSW_REG_STAT_PORT_EN 0x014 @@ -2166,7 +2166,8 @@ eth_hw_addr_set(port->ndev, port->slave.mac_addr); port->ndev->min_mtu = AM65_CPSW_MIN_PACKET_SIZE; - port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE; + port->ndev->max_mtu = AM65_CPSW_MAX_PACKET_SIZE - + (VLAN_ETH_HLEN + ETH_FCS_LEN); port->ndev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | NETIF_F_HW_CSUM | diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/hyperv/netvsc_drv.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/hyperv/netvsc_drv.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/hyperv/netvsc_drv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/hyperv/netvsc_drv.c @@ -44,7 +44,7 @@ static unsigned int ring_size __ro_after_init = 128; module_param(ring_size, uint, 0444); -MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); +MODULE_PARM_DESC(ring_size, "Ring buffer size (# of 4K pages)"); unsigned int netvsc_ring_bytes __ro_after_init; static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | @@ -2805,7 +2805,7 @@ pr_info("Increased ring_size to %u (min allowed)\n", ring_size); } - netvsc_ring_bytes = ring_size * PAGE_SIZE; + netvsc_ring_bytes = VMBUS_RING_SIZE(ring_size * 4096); register_netdevice_notifier(&netvsc_netdev_notifier); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/phy/micrel.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/phy/micrel.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/phy/micrel.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/phy/micrel.c @@ -120,6 +120,11 @@ */ #define LAN8814_1PPM_FORMAT 17179 +#define PTP_RX_VERSION 0x0248 +#define PTP_TX_VERSION 0x0288 +#define PTP_MAX_VERSION(x) (((x) & GENMASK(7, 0)) << 8) +#define PTP_MIN_VERSION(x) ((x) & GENMASK(7, 0)) + #define PTP_RX_MOD 0x024F #define PTP_RX_MOD_BAD_UDPV4_CHKSUM_FORCE_FCS_DIS_ BIT(3) #define PTP_RX_TIMESTAMP_EN 0x024D @@ -3125,6 +3130,12 @@ lanphy_write_page_reg(phydev, 5, PTP_TX_PARSE_IP_ADDR_EN, 0); lanphy_write_page_reg(phydev, 5, PTP_RX_PARSE_IP_ADDR_EN, 0); + /* Disable checking for minorVersionPTP field */ + lanphy_write_page_reg(phydev, 5, PTP_RX_VERSION, + PTP_MAX_VERSION(0xff) | PTP_MIN_VERSION(0x0)); + lanphy_write_page_reg(phydev, 5, PTP_TX_VERSION, + PTP_MAX_VERSION(0xff) | PTP_MIN_VERSION(0x0)); + skb_queue_head_init(&ptp_priv->tx_queue); skb_queue_head_init(&ptp_priv->rx_queue); INIT_LIST_HEAD(&ptp_priv->rx_ts_list); @@ -3313,8 +3324,10 @@ #define LAN8841_ADC_CHANNEL_MASK 198 #define LAN8841_PTP_RX_PARSE_L2_ADDR_EN 370 #define LAN8841_PTP_RX_PARSE_IP_ADDR_EN 371 +#define LAN8841_PTP_RX_VERSION 374 #define LAN8841_PTP_TX_PARSE_L2_ADDR_EN 434 #define LAN8841_PTP_TX_PARSE_IP_ADDR_EN 435 +#define LAN8841_PTP_TX_VERSION 438 #define LAN8841_PTP_CMD_CTL 256 #define LAN8841_PTP_CMD_CTL_PTP_ENABLE BIT(2) #define LAN8841_PTP_CMD_CTL_PTP_DISABLE BIT(1) @@ -3358,6 +3371,12 @@ phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG, LAN8841_PTP_RX_PARSE_IP_ADDR_EN, 0); + /* Disable checking for minorVersionPTP field */ + phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG, + LAN8841_PTP_RX_VERSION, 0xff00); + phy_write_mmd(phydev, KSZ9131RN_MMD_COMMON_CTRL_REG, + LAN8841_PTP_TX_VERSION, 0xff00); + /* 100BT Clause 40 improvenent errata */ phy_write_mmd(phydev, LAN8841_MMD_ANALOG_REG, LAN8841_ANALOG_CONTROL_1, @@ -3609,12 +3628,8 @@ info->phc_index = ptp_priv->ptp_clock ? ptp_clock_index(ptp_priv->ptp_clock) : -1; - if (info->phc_index == -1) { - info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | - SOF_TIMESTAMPING_RX_SOFTWARE | - SOF_TIMESTAMPING_SOFTWARE; + if (info->phc_index == -1) return 0; - } info->so_timestamping = SOF_TIMESTAMPING_TX_HARDWARE | SOF_TIMESTAMPING_RX_HARDWARE | @@ -4820,6 +4835,7 @@ .flags = PHY_POLL_CABLE_TEST, .driver_data = &ksz9131_type, .probe = kszphy_probe, + .soft_reset = genphy_soft_reset, .config_init = ksz9131_config_init, .config_intr = kszphy_config_intr, .config_aneg = ksz9131_config_aneg, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/phy/phy_device.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/phy/phy_device.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/phy/phy_device.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/phy/phy_device.c @@ -3022,6 +3022,61 @@ return err; } +static __maybe_unused struct device * +phy_led_hw_control_get_device(struct led_classdev *led_cdev) +{ + struct phy_led *phyled = to_phy_led(led_cdev); + struct phy_device *phydev = phyled->phydev; + + if (phydev->attached_dev) + return &phydev->attached_dev->dev; + return NULL; +} + +static int __maybe_unused +phy_led_hw_control_get(struct led_classdev *led_cdev, + unsigned long *rules) +{ + struct phy_led *phyled = to_phy_led(led_cdev); + struct phy_device *phydev = phyled->phydev; + int err; + + mutex_lock(&phydev->lock); + err = phydev->drv->led_hw_control_get(phydev, phyled->index, rules); + mutex_unlock(&phydev->lock); + + return err; +} + +static int __maybe_unused +phy_led_hw_control_set(struct led_classdev *led_cdev, + unsigned long rules) +{ + struct phy_led *phyled = to_phy_led(led_cdev); + struct phy_device *phydev = phyled->phydev; + int err; + + mutex_lock(&phydev->lock); + err = phydev->drv->led_hw_control_set(phydev, phyled->index, rules); + mutex_unlock(&phydev->lock); + + return err; +} + +static __maybe_unused int phy_led_hw_is_supported(struct led_classdev *led_cdev, + unsigned long rules) +{ + struct phy_led *phyled = to_phy_led(led_cdev); + struct phy_device *phydev = phyled->phydev; + int err; + + mutex_lock(&phydev->lock); + err = phydev->drv->led_hw_is_supported(phydev, phyled->index, rules); + mutex_unlock(&phydev->lock); + + return err; +} + static void phy_leds_unregister(struct phy_device *phydev) { struct phy_led *phyled; @@ -3059,6 +3114,19 @@ cdev->brightness_set_blocking = phy_led_set_brightness; if (phydev->drv->led_blink_set) cdev->blink_set = phy_led_blink_set; + +#ifdef CONFIG_LEDS_TRIGGERS + if (phydev->drv->led_hw_is_supported && + phydev->drv->led_hw_control_set && + phydev->drv->led_hw_control_get) { + cdev->hw_control_is_supported = phy_led_hw_is_supported; + cdev->hw_control_set = phy_led_hw_control_set; + cdev->hw_control_get = phy_led_hw_control_get; + cdev->hw_control_trigger = "netdev"; + } + + cdev->hw_control_get_device = phy_led_hw_control_get_device; +#endif cdev->max_brightness = 1; init_data.devicename = dev_name(&phydev->mdio.dev); init_data.fwnode = of_fwnode_handle(led); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/tun.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/tun.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/tun.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/tun.c @@ -1628,13 +1628,19 @@ switch (act) { case XDP_REDIRECT: err = xdp_do_redirect(tun->dev, xdp, xdp_prog); - if (err) + if (err) { + dev_core_stats_rx_dropped_inc(tun->dev); return err; + } + dev_sw_netstats_rx_add(tun->dev, xdp->data_end - xdp->data); break; case XDP_TX: err = tun_xdp_tx(tun->dev, xdp); - if (err < 0) + if (err < 0) { + dev_core_stats_rx_dropped_inc(tun->dev); return err; + } + dev_sw_netstats_rx_add(tun->dev, xdp->data_end - xdp->data); break; case XDP_PASS: break; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/usb/ax88179_178a.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/usb/ax88179_178a.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/usb/ax88179_178a.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/usb/ax88179_178a.c @@ -1315,8 +1315,6 @@ netif_set_tso_max_size(dev->net, 16384); - ax88179_reset(dev); - return 0; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/virtio_net.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/virtio_net.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/virtio_net.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/virtio_net.c @@ -3744,10 +3744,11 @@ { vq_callback_t **callbacks; struct virtqueue **vqs; - int ret = -ENOMEM; - int i, total_vqs; const char **names; + int ret = -ENOMEM; + int total_vqs; bool *ctx; + u16 i; /* We expect 1 RX virtqueue followed by 1 TX virtqueue, followed by * possible N-1 RX/TX queue pairs used in multiqueue mode, followed by @@ -3784,8 +3785,8 @@ for (i = 0; i < vi->max_queue_pairs; i++) { callbacks[rxq2vq(i)] = skb_recv_done; callbacks[txq2vq(i)] = skb_xmit_done; - sprintf(vi->rq[i].name, "input.%d", i); - sprintf(vi->sq[i].name, "output.%d", i); + sprintf(vi->rq[i].name, "input.%u", i); + sprintf(vi->sq[i].name, "output.%u", i); names[rxq2vq(i)] = vi->rq[i].name; names[txq2vq(i)] = vi->sq[i].name; if (ctx) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ath/ath12k/mac.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ath/ath12k/mac.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ath/ath12k/mac.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ath/ath12k/mac.c @@ -5856,8 +5856,8 @@ } if (ab->hw_params->vdev_start_delay && - (arvif->vdev_type == WMI_VDEV_TYPE_AP || - arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)) { + arvif->vdev_type != WMI_VDEV_TYPE_AP && + arvif->vdev_type != WMI_VDEV_TYPE_MONITOR) { param.vdev_id = arvif->vdev_id; param.peer_type = WMI_PEER_TYPE_DEFAULT; param.peer_addr = ar->mac_addr; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -269,17 +269,17 @@ } } + mvmvif->link[link_id]->phy_ctxt = phy_ctxt; + if (iwl_mvm_is_esr_supported(mvm->fwrt.trans) && n_active > 1) { mvmvif->link[link_id]->listen_lmac = true; ret = iwl_mvm_esr_mode_active(mvm, vif); if (ret) { IWL_ERR(mvm, "failed to activate ESR mode (%d)\n", ret); - return ret; + goto out; } } - mvmvif->link[link_id]->phy_ctxt = phy_ctxt; - if (switching_chanctx) { /* reactivate if we turned this off during channel switch */ if (vif->type == NL80211_IFTYPE_AP) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/mvm/tx.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/mvm/tx.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -2236,7 +2236,7 @@ WARN_ON(!iwl_mvm_has_new_tx_api(mvm)); if (iwl_fw_lookup_notif_ver(mvm->fw, LONG_GROUP, TXPATH_FLUSH, 0) > 0) - cmd.flags |= CMD_WANT_SKB; + cmd.flags |= CMD_WANT_SKB | CMD_SEND_IN_RFKILL; IWL_DEBUG_TX_QUEUES(mvm, "flush for sta id %d tid mask 0x%x\n", sta_id, tids); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/internal.h linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/internal.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/internal.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/internal.h @@ -190,17 +190,17 @@ * iwl_get_closed_rb_stts - get closed rb stts from different structs * @rxq - the rxq to get the rb stts from */ -static inline __le16 iwl_get_closed_rb_stts(struct iwl_trans *trans, - struct iwl_rxq *rxq) +static inline u16 iwl_get_closed_rb_stts(struct iwl_trans *trans, + struct iwl_rxq *rxq) { if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210) { __le16 *rb_stts = rxq->rb_stts; - return READ_ONCE(*rb_stts); + return le16_to_cpu(READ_ONCE(*rb_stts)); } else { struct iwl_rb_status *rb_stts = rxq->rb_stts; - return READ_ONCE(rb_stts->closed_rb_num); + return le16_to_cpu(READ_ONCE(rb_stts->closed_rb_num)) & 0xFFF; } } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/rx.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/rx.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/rx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/rx.c @@ -1510,7 +1510,7 @@ spin_lock(&rxq->lock); /* uCode's read index (stored in shared DRAM) indicates the last Rx * buffer that the driver may process (last buffer filled by ucode). */ - r = le16_to_cpu(iwl_get_closed_rb_stts(trans, rxq)) & 0x0FFF; + r = iwl_get_closed_rb_stts(trans, rxq); i = rxq->read; /* W/A 9000 device step A0 wrap-around bug */ diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/trans.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/trans.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -2691,11 +2691,9 @@ pos += scnprintf(buf + pos, bufsz - pos, "\tfree_count: %u\n", rxq->free_count); if (rxq->rb_stts) { - u32 r = __le16_to_cpu(iwl_get_closed_rb_stts(trans, - rxq)); + u32 r = iwl_get_closed_rb_stts(trans, rxq); pos += scnprintf(buf + pos, bufsz - pos, - "\tclosed_rb_num: %u\n", - r & 0x0FFF); + "\tclosed_rb_num: %u\n", r); } else { pos += scnprintf(buf + pos, bufsz - pos, "\tclosed_rb_num: Not Allocated\n"); @@ -3068,7 +3066,7 @@ spin_lock_bh(&rxq->lock); - r = le16_to_cpu(iwl_get_closed_rb_stts(trans, rxq)) & 0x0FFF; + r = iwl_get_closed_rb_stts(trans, rxq); for (i = rxq->read, j = 0; i != r && j < allocated_rb_nums; @@ -3364,9 +3362,7 @@ /* Dump RBs is supported only for pre-9000 devices (1 queue) */ struct iwl_rxq *rxq = &trans_pcie->rxq[0]; /* RBs */ - num_rbs = - le16_to_cpu(iwl_get_closed_rb_stts(trans, rxq)) - & 0x0FFF; + num_rbs = iwl_get_closed_rb_stts(trans, rxq); num_rbs = (num_rbs - rxq->read) & RX_QUEUE_MASK; len += num_rbs * (sizeof(*data) + sizeof(struct iwl_fw_error_dump_rb) + diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/marvell/mwifiex/fw.h linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/marvell/mwifiex/fw.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/marvell/mwifiex/fw.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/marvell/mwifiex/fw.h @@ -165,6 +165,7 @@ #define TLV_TYPE_STA_MAC_ADDR (PROPRIETARY_TLV_BASE_ID + 32) #define TLV_TYPE_BSSID (PROPRIETARY_TLV_BASE_ID + 35) #define TLV_TYPE_CHANNELBANDLIST (PROPRIETARY_TLV_BASE_ID + 42) +#define TLV_TYPE_UAP_MAC_ADDRESS (PROPRIETARY_TLV_BASE_ID + 43) #define TLV_TYPE_UAP_BEACON_PERIOD (PROPRIETARY_TLV_BASE_ID + 44) #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) #define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt76.h linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt76.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt76.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt76.h @@ -568,8 +568,7 @@ struct mt76_worker txrx_worker; struct mt76_worker status_worker; struct mt76_worker net_worker; - - struct work_struct stat_work; + struct mt76_worker stat_worker; u8 *xmit_buf; u32 xmit_buf_sz; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c @@ -742,7 +742,7 @@ res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); if (!res) - return -ENOMEM; + return 0; wed->wlan.platform_dev = plat_dev; wed->wlan.bus_type = MTK_WED_BUS_AXI; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7996/mac.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7996/mac.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -1017,10 +1017,10 @@ struct mt7996_vif *mvif; u16 tx_count = 15; u32 val; - bool beacon = !!(changed & (BSS_CHANGED_BEACON | - BSS_CHANGED_BEACON_ENABLED)); bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP | BSS_CHANGED_FILS_DISCOVERY)); + bool beacon = !!(changed & (BSS_CHANGED_BEACON | + BSS_CHANGED_BEACON_ENABLED)) && (!inband_disc); mvif = vif ? (struct mt7996_vif *)vif->drv_priv : NULL; if (mvif) { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h @@ -221,7 +221,7 @@ u8 short_preamble; u8 bc_fixed_rate; u8 mc_fixed_rate; - u8 __rsv2[1]; + u8 __rsv2[9]; } __packed; struct bss_ra_tlv { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw89/fw.c linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw89/fw.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw89/fw.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw89/fw.c @@ -3403,6 +3403,7 @@ rtw89_core_scan_complete(rtwdev, vif, true); ieee80211_scan_completed(rtwdev->hw, &info); ieee80211_wake_queues(rtwdev->hw); + rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true); rtw89_release_pkt_list(rtwdev); rtwvif = (struct rtw89_vif *)vif->drv_priv; @@ -3420,6 +3421,19 @@ rtw89_hw_scan_complete(rtwdev, vif, true); } +static bool rtw89_is_any_vif_connected_or_connecting(struct rtw89_dev *rtwdev) +{ + struct rtw89_vif *rtwvif; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) { + /* This variable implies connected or during attempt to connect */ + if (!is_zero_ether_addr(rtwvif->bssid)) + return true; + } + + return false; +} + int rtw89_hw_scan_offload(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif, bool enable) { @@ -3432,8 +3446,7 @@ if (!rtwvif) return -EINVAL; - /* This variable implies connected or during attempt to connect */ - connected = !is_zero_ether_addr(rtwvif->bssid); + connected = rtw89_is_any_vif_connected_or_connecting(rtwdev); opt.enable = enable; opt.target_ch_mode = connected; if (enable) { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/nvme/target/tcp.c linux-lowlatency-hwe-6.5-6.5.0/drivers/nvme/target/tcp.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/nvme/target/tcp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/nvme/target/tcp.c @@ -19,6 +19,7 @@ #include "nvmet.h" #define NVMET_TCP_DEF_INLINE_DATA_SIZE (4 * PAGE_SIZE) +#define NVMET_TCP_MAXH2CDATA 0x400000 /* 16M arbitrary limit */ static int param_store_val(const char *str, int *val, int min, int max) { @@ -900,7 +901,7 @@ icresp->hdr.pdo = 0; icresp->hdr.plen = cpu_to_le32(icresp->hdr.hlen); icresp->pfv = cpu_to_le16(NVME_TCP_PFV_1_0); - icresp->maxdata = cpu_to_le32(0x400000); /* 16M arbitrary limit */ + icresp->maxdata = cpu_to_le32(NVMET_TCP_MAXH2CDATA); icresp->cpda = 0; if (queue->hdr_digest) icresp->digest |= NVME_TCP_HDR_DIGEST_ENABLE; @@ -953,6 +954,7 @@ { struct nvme_tcp_data_pdu *data = &queue->pdu.data; struct nvmet_tcp_cmd *cmd; + unsigned int exp_data_len; if (likely(queue->nr_cmds)) { if (unlikely(data->ttag >= queue->nr_cmds)) { @@ -971,12 +973,24 @@ data->ttag, le32_to_cpu(data->data_offset), cmd->rbytes_done); /* FIXME: use path and transport errors */ - nvmet_req_complete(&cmd->req, - NVME_SC_INVALID_FIELD | NVME_SC_DNR); + nvmet_tcp_fatal_error(queue); return -EPROTO; } + exp_data_len = le32_to_cpu(data->hdr.plen) - + nvmet_tcp_hdgst_len(queue) - + nvmet_tcp_ddgst_len(queue) - + sizeof(*data); + cmd->pdu_len = le32_to_cpu(data->data_length); + if (unlikely(cmd->pdu_len != exp_data_len || + cmd->pdu_len == 0 || + cmd->pdu_len > NVMET_TCP_MAXH2CDATA)) { + pr_err("H2CData PDU len %u is invalid\n", cmd->pdu_len); + /* FIXME: use proper transport errors */ + nvmet_tcp_fatal_error(queue); + return -EPROTO; + } cmd->pdu_recv = 0; nvmet_tcp_build_pdu_iovec(cmd); queue->cmd = cmd; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/of/unittest.c linux-lowlatency-hwe-6.5-6.5.0/drivers/of/unittest.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/of/unittest.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/of/unittest.c @@ -455,6 +455,9 @@ unittest(passed, "index %i - data error on node %pOF rc=%i\n", i, args.np, rc); + + if (rc == 0) + of_node_put(args.np); } /* Check for missing list property */ @@ -544,8 +547,9 @@ static void __init of_unittest_parse_phandle_with_args_map(void) { - struct device_node *np, *p0, *p1, *p2, *p3; + struct device_node *np, *p[6] = {}; struct of_phandle_args args; + unsigned int prefs[6]; int i, rc; np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-b"); @@ -554,34 +558,24 @@ return; } - p0 = of_find_node_by_path("/testcase-data/phandle-tests/provider0"); - if (!p0) { - pr_err("missing testcase data\n"); - return; - } - - p1 = of_find_node_by_path("/testcase-data/phandle-tests/provider1"); - if (!p1) { - pr_err("missing testcase data\n"); - return; - } - - p2 = of_find_node_by_path("/testcase-data/phandle-tests/provider2"); - if (!p2) { - pr_err("missing testcase data\n"); - return; - } - - p3 = of_find_node_by_path("/testcase-data/phandle-tests/provider3"); - if (!p3) { - pr_err("missing testcase data\n"); - return; + p[0] = of_find_node_by_path("/testcase-data/phandle-tests/provider0"); + p[1] = of_find_node_by_path("/testcase-data/phandle-tests/provider1"); + p[2] = of_find_node_by_path("/testcase-data/phandle-tests/provider2"); + p[3] = of_find_node_by_path("/testcase-data/phandle-tests/provider3"); + p[4] = of_find_node_by_path("/testcase-data/phandle-tests/provider4"); + p[5] = of_find_node_by_path("/testcase-data/phandle-tests/provider5"); + for (i = 0; i < ARRAY_SIZE(p); ++i) { + if (!p[i]) { + pr_err("missing testcase data\n"); + return; + } + prefs[i] = kref_read(&p[i]->kobj.kref); } rc = of_count_phandle_with_args(np, "phandle-list", "#phandle-cells"); - unittest(rc == 7, "of_count_phandle_with_args() returned %i, expected 7\n", rc); + unittest(rc == 8, "of_count_phandle_with_args() returned %i, expected 8\n", rc); - for (i = 0; i < 8; i++) { + for (i = 0; i < 9; i++) { bool passed = true; memset(&args, 0, sizeof(args)); @@ -592,13 +586,13 @@ switch (i) { case 0: passed &= !rc; - passed &= (args.np == p1); + passed &= (args.np == p[1]); passed &= (args.args_count == 1); passed &= (args.args[0] == 1); break; case 1: passed &= !rc; - passed &= (args.np == p3); + passed &= (args.np == p[3]); passed &= (args.args_count == 3); passed &= (args.args[0] == 2); passed &= (args.args[1] == 5); @@ -609,28 +603,36 @@ break; case 3: passed &= !rc; - passed &= (args.np == p0); + passed &= (args.np == p[0]); passed &= (args.args_count == 0); break; case 4: passed &= !rc; - passed &= (args.np == p1); + passed &= (args.np == p[1]); passed &= (args.args_count == 1); passed &= (args.args[0] == 3); break; case 5: passed &= !rc; - passed &= (args.np == p0); + passed &= (args.np == p[0]); passed &= (args.args_count == 0); break; case 6: passed &= !rc; - passed &= (args.np == p2); + passed &= (args.np == p[2]); passed &= (args.args_count == 2); passed &= (args.args[0] == 15); passed &= (args.args[1] == 0x20); break; case 7: + passed &= !rc; + passed &= (args.np == p[3]); + passed &= (args.args_count == 3); + passed &= (args.args[0] == 2); + passed &= (args.args[1] == 5); + passed &= (args.args[2] == 3); + break; + case 8: passed &= (rc == -ENOENT); break; default: @@ -639,6 +641,9 @@ unittest(passed, "index %i - data error on node %s rc=%i\n", i, args.np->full_name, rc); + + if (rc == 0) + of_node_put(args.np); } /* Check for missing list property */ @@ -685,6 +690,13 @@ "OF: /testcase-data/phandle-tests/consumer-b: #phandle-cells = 2 found 1"); unittest(rc == -EINVAL, "expected:%i got:%i\n", -EINVAL, rc); + + for (i = 0; i < ARRAY_SIZE(p); ++i) { + unittest(prefs[i] == kref_read(&p[i]->kobj.kref), + "provider%d: expected:%d got:%d\n", + i, prefs[i], kref_read(&p[i]->kobj.kref)); + of_node_put(p[i]); + } } static void __init of_unittest_property_string(void) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/opp/core.c linux-lowlatency-hwe-6.5-6.5.0/drivers/opp/core.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/opp/core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/opp/core.c @@ -1239,12 +1239,12 @@ * value of the frequency. In such a case, do not abort but * configure the hardware to the desired frequency forcefully. */ - forced = opp_table->rate_clk_single != target_freq; + forced = opp_table->rate_clk_single != freq; } - ret = _set_opp(dev, opp_table, opp, &target_freq, forced); + ret = _set_opp(dev, opp_table, opp, &freq, forced); - if (target_freq) + if (freq) dev_pm_opp_put(opp); put_opp_table: diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/parisc/power.c linux-lowlatency-hwe-6.5-6.5.0/drivers/parisc/power.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/parisc/power.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/parisc/power.c @@ -238,7 +238,7 @@ if (running_on_qemu && soft_power_reg) register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_DEFAULT, qemu_power_off, (void *)soft_power_reg); - else + if (!running_on_qemu || soft_power_reg) power_task = kthread_run(kpowerswd, (void*)soft_power_reg, KTHREAD_NAME); if (IS_ERR(power_task)) { diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/controller/dwc/pci-keystone.c linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/controller/dwc/pci-keystone.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/controller/dwc/pci-keystone.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/controller/dwc/pci-keystone.c @@ -1219,7 +1219,16 @@ goto err_link; } + /* Obtain references to the PHYs */ + for (i = 0; i < num_lanes; i++) + phy_pm_runtime_get_sync(ks_pcie->phy[i]); + ret = ks_pcie_enable_phy(ks_pcie); + + /* Release references to the PHYs */ + for (i = 0; i < num_lanes; i++) + phy_pm_runtime_put_sync(ks_pcie->phy[i]); + if (ret) { dev_err(dev, "failed to enable phy\n"); goto err_link; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/pci.h linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/pci.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/pci.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/pci.h @@ -263,7 +263,7 @@ /* PCIe speed to Mb/s reduced by encoding overhead */ #define PCIE_SPEED2MBS_ENC(speed) \ - ((speed) == PCIE_SPEED_64_0GT ? 64000*128/130 : \ + ((speed) == PCIE_SPEED_64_0GT ? 64000*1/1 : \ (speed) == PCIE_SPEED_32_0GT ? 32000*128/130 : \ (speed) == PCIE_SPEED_16_0GT ? 16000*128/130 : \ (speed) == PCIE_SPEED_8_0GT ? 8000*128/130 : \ diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/pcie/aer.c linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/pcie/aer.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/pcie/aer.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/pcie/aer.c @@ -752,7 +752,7 @@ u8 bus = info->id >> 8; u8 devfn = info->id & 0xff; - pci_info(dev, "%s%s error received: %04x:%02x:%02x.%d\n", + pci_info(dev, "%s%s error message received from %04x:%02x:%02x.%d\n", info->multi_error_valid ? "Multiple " : "", aer_error_severity_string[info->severity], pci_domain_nr(dev->bus), bus, PCI_SLOT(devfn), @@ -940,7 +940,12 @@ pci_walk_bus(parent->subordinate, find_device_iter, e_info); if (!e_info->error_dev_num) { - pci_info(parent, "can't find device of ID%04x\n", e_info->id); + u8 bus = e_info->id >> 8; + u8 devfn = e_info->id & 0xff; + + pci_info(parent, "found no error details for %04x:%02x:%02x.%d\n", + pci_domain_nr(parent->bus), bus, PCI_SLOT(devfn), + PCI_FUNC(devfn)); return false; } return true; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/quirks.c linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/quirks.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/quirks.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/quirks.c @@ -715,10 +715,13 @@ { u32 class = pdev->class; - /* Use "USB Device (not host controller)" class */ - pdev->class = PCI_CLASS_SERIAL_USB_DEVICE; - pci_info(pdev, "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n", - class, pdev->class); + if (class != PCI_CLASS_SERIAL_USB_DEVICE) { + /* Use "USB Device (not host controller)" class */ + pdev->class = PCI_CLASS_SERIAL_USB_DEVICE; + pci_info(pdev, + "PCI class overridden (%#08x -> %#08x) so dwc3 driver can claim this instead of xhci\n", + class, pdev->class); + } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB, quirk_amd_dwc_class); @@ -3800,6 +3803,19 @@ PCI_CLASS_DISPLAY_VGA, 8, quirk_no_pm_reset); /* + * Spectrum-{1,2,3,4} devices report that a D3hot->D0 transition causes a reset + * (i.e., they advertise NoSoftRst-). However, this transition does not have + * any effect on the device: It continues to be operational and network ports + * remain up. Advertising this support makes it seem as if a PM reset is viable + * for these devices. Mark it as unavailable to skip it when testing reset + * methods. + */ +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcb84, quirk_no_pm_reset); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcf6c, quirk_no_pm_reset); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcf70, quirk_no_pm_reset); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MELLANOX, 0xcf80, quirk_no_pm_reset); + +/* * Thunderbolt controllers with broken MSI hotplug signaling: * Entire 1st generation (Light Ridge, Eagle Ridge, Light Peak) and part * of the 2nd generation (Cactus Ridge 4C up to revision 1, Port Ridge). diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/perf/arm_pmuv3.c linux-lowlatency-hwe-6.5-6.5.0/drivers/perf/arm_pmuv3.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/perf/arm_pmuv3.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/perf/arm_pmuv3.c @@ -169,7 +169,11 @@ PMU_EVENT_ATTR_ID(name, armv8pmu_events_sysfs_show, config) static struct attribute *armv8_pmuv3_event_attrs[] = { - ARMV8_EVENT_ATTR(sw_incr, ARMV8_PMUV3_PERFCTR_SW_INCR), + /* + * Don't expose the sw_incr event in /sys. It's not usable as writes to + * PMSWINC_EL0 will trap as PMUSERENR.{SW,EN}=={0,0} and event rotation + * means we don't have a fixed event<->counter relationship regardless. + */ ARMV8_EVENT_ATTR(l1i_cache_refill, ARMV8_PMUV3_PERFCTR_L1I_CACHE_REFILL), ARMV8_EVENT_ATTR(l1i_tlb_refill, ARMV8_PMUV3_PERFCTR_L1I_TLB_REFILL), ARMV8_EVENT_ATTR(l1d_cache_refill, ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL), diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c linux-lowlatency-hwe-6.5-6.5.0/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.c @@ -23,23 +23,23 @@ static int (*uncore_write)(struct uncore_data *data, unsigned int input, unsigned int min_max); static int (*uncore_read_freq)(struct uncore_data *data, unsigned int *freq); -static ssize_t show_domain_id(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_domain_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - struct uncore_data *data = container_of(attr, struct uncore_data, domain_id_dev_attr); + struct uncore_data *data = container_of(attr, struct uncore_data, domain_id_kobj_attr); return sprintf(buf, "%u\n", data->domain_id); } -static ssize_t show_fabric_cluster_id(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_fabric_cluster_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - struct uncore_data *data = container_of(attr, struct uncore_data, fabric_cluster_id_dev_attr); + struct uncore_data *data = container_of(attr, struct uncore_data, fabric_cluster_id_kobj_attr); return sprintf(buf, "%u\n", data->cluster_id); } -static ssize_t show_package_id(struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_package_id(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - struct uncore_data *data = container_of(attr, struct uncore_data, package_id_dev_attr); + struct uncore_data *data = container_of(attr, struct uncore_data, package_id_kobj_attr); return sprintf(buf, "%u\n", data->package_id); } @@ -97,30 +97,30 @@ } #define store_uncore_min_max(name, min_max) \ - static ssize_t store_##name(struct device *dev, \ - struct device_attribute *attr, \ + static ssize_t store_##name(struct kobject *kobj, \ + struct kobj_attribute *attr, \ const char *buf, size_t count) \ { \ - struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\ + struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\ \ return store_min_max_freq_khz(data, buf, count, \ min_max); \ } #define show_uncore_min_max(name, min_max) \ - static ssize_t show_##name(struct device *dev, \ - struct device_attribute *attr, char *buf)\ + static ssize_t show_##name(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf)\ { \ - struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\ + struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\ \ return show_min_max_freq_khz(data, buf, min_max); \ } #define show_uncore_perf_status(name) \ - static ssize_t show_##name(struct device *dev, \ - struct device_attribute *attr, char *buf)\ + static ssize_t show_##name(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf)\ { \ - struct uncore_data *data = container_of(attr, struct uncore_data, name##_dev_attr);\ + struct uncore_data *data = container_of(attr, struct uncore_data, name##_kobj_attr);\ \ return show_perf_status_freq_khz(data, buf); \ } @@ -134,11 +134,11 @@ show_uncore_perf_status(current_freq_khz); #define show_uncore_data(member_name) \ - static ssize_t show_##member_name(struct device *dev, \ - struct device_attribute *attr, char *buf)\ + static ssize_t show_##member_name(struct kobject *kobj, \ + struct kobj_attribute *attr, char *buf)\ { \ struct uncore_data *data = container_of(attr, struct uncore_data,\ - member_name##_dev_attr);\ + member_name##_kobj_attr);\ \ return sysfs_emit(buf, "%u\n", \ data->member_name); \ @@ -149,29 +149,29 @@ #define init_attribute_rw(_name) \ do { \ - sysfs_attr_init(&data->_name##_dev_attr.attr); \ - data->_name##_dev_attr.show = show_##_name; \ - data->_name##_dev_attr.store = store_##_name; \ - data->_name##_dev_attr.attr.name = #_name; \ - data->_name##_dev_attr.attr.mode = 0644; \ + sysfs_attr_init(&data->_name##_kobj_attr.attr); \ + data->_name##_kobj_attr.show = show_##_name; \ + data->_name##_kobj_attr.store = store_##_name; \ + data->_name##_kobj_attr.attr.name = #_name; \ + data->_name##_kobj_attr.attr.mode = 0644; \ } while (0) #define init_attribute_ro(_name) \ do { \ - sysfs_attr_init(&data->_name##_dev_attr.attr); \ - data->_name##_dev_attr.show = show_##_name; \ - data->_name##_dev_attr.store = NULL; \ - data->_name##_dev_attr.attr.name = #_name; \ - data->_name##_dev_attr.attr.mode = 0444; \ + sysfs_attr_init(&data->_name##_kobj_attr.attr); \ + data->_name##_kobj_attr.show = show_##_name; \ + data->_name##_kobj_attr.store = NULL; \ + data->_name##_kobj_attr.attr.name = #_name; \ + data->_name##_kobj_attr.attr.mode = 0444; \ } while (0) #define init_attribute_root_ro(_name) \ do { \ - sysfs_attr_init(&data->_name##_dev_attr.attr); \ - data->_name##_dev_attr.show = show_##_name; \ - data->_name##_dev_attr.store = NULL; \ - data->_name##_dev_attr.attr.name = #_name; \ - data->_name##_dev_attr.attr.mode = 0400; \ + sysfs_attr_init(&data->_name##_kobj_attr.attr); \ + data->_name##_kobj_attr.show = show_##_name; \ + data->_name##_kobj_attr.store = NULL; \ + data->_name##_kobj_attr.attr.name = #_name; \ + data->_name##_kobj_attr.attr.mode = 0400; \ } while (0) static int create_attr_group(struct uncore_data *data, char *name) @@ -186,21 +186,21 @@ if (data->domain_id != UNCORE_DOMAIN_ID_INVALID) { init_attribute_root_ro(domain_id); - data->uncore_attrs[index++] = &data->domain_id_dev_attr.attr; + data->uncore_attrs[index++] = &data->domain_id_kobj_attr.attr; init_attribute_root_ro(fabric_cluster_id); - data->uncore_attrs[index++] = &data->fabric_cluster_id_dev_attr.attr; + data->uncore_attrs[index++] = &data->fabric_cluster_id_kobj_attr.attr; init_attribute_root_ro(package_id); - data->uncore_attrs[index++] = &data->package_id_dev_attr.attr; + data->uncore_attrs[index++] = &data->package_id_kobj_attr.attr; } - data->uncore_attrs[index++] = &data->max_freq_khz_dev_attr.attr; - data->uncore_attrs[index++] = &data->min_freq_khz_dev_attr.attr; - data->uncore_attrs[index++] = &data->initial_min_freq_khz_dev_attr.attr; - data->uncore_attrs[index++] = &data->initial_max_freq_khz_dev_attr.attr; + data->uncore_attrs[index++] = &data->max_freq_khz_kobj_attr.attr; + data->uncore_attrs[index++] = &data->min_freq_khz_kobj_attr.attr; + data->uncore_attrs[index++] = &data->initial_min_freq_khz_kobj_attr.attr; + data->uncore_attrs[index++] = &data->initial_max_freq_khz_kobj_attr.attr; ret = uncore_read_freq(data, &freq); if (!ret) - data->uncore_attrs[index++] = &data->current_freq_khz_dev_attr.attr; + data->uncore_attrs[index++] = &data->current_freq_khz_kobj_attr.attr; data->uncore_attrs[index] = NULL; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/power/supply/qcom_pmi8998_charger.c linux-lowlatency-hwe-6.5-6.5.0/drivers/power/supply/qcom_pmi8998_charger.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/power/supply/qcom_pmi8998_charger.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/power/supply/qcom_pmi8998_charger.c @@ -981,10 +981,14 @@ supply_config.of_node = pdev->dev.of_node; desc = devm_kzalloc(chip->dev, sizeof(smb2_psy_desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; memcpy(desc, &smb2_psy_desc, sizeof(smb2_psy_desc)); desc->name = devm_kasprintf(chip->dev, GFP_KERNEL, "%s-charger", (const char *)device_get_match_data(chip->dev)); + if (!desc->name) + return -ENOMEM; chip->chg_psy = devm_power_supply_register(chip->dev, desc, &supply_config); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/regulator/core.c linux-lowlatency-hwe-6.5-6.5.0/drivers/regulator/core.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/regulator/core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/regulator/core.c @@ -2918,7 +2918,8 @@ /* Fallthrough on positive return values - already enabled */ } - rdev->use_count++; + if (regulator->enable_count == 1) + rdev->use_count++; return 0; @@ -2993,37 +2994,40 @@ lockdep_assert_held_once(&rdev->mutex.base); - if (WARN(rdev->use_count <= 0, + if (WARN(regulator->enable_count == 0, "unbalanced disables for %s\n", rdev_get_name(rdev))) return -EIO; - /* are we the last user and permitted to disable ? */ - if (rdev->use_count == 1 && - (rdev->constraints && !rdev->constraints->always_on)) { - - /* we are last user */ - if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) { - ret = _notifier_call_chain(rdev, - REGULATOR_EVENT_PRE_DISABLE, - NULL); - if (ret & NOTIFY_STOP_MASK) - return -EINVAL; - - ret = _regulator_do_disable(rdev); - if (ret < 0) { - rdev_err(rdev, "failed to disable: %pe\n", ERR_PTR(ret)); - _notifier_call_chain(rdev, - REGULATOR_EVENT_ABORT_DISABLE, + if (regulator->enable_count == 1) { + /* disabling last enable_count from this regulator */ + /* are we the last user and permitted to disable ? */ + if (rdev->use_count == 1 && + (rdev->constraints && !rdev->constraints->always_on)) { + + /* we are last user */ + if (regulator_ops_is_valid(rdev, REGULATOR_CHANGE_STATUS)) { + ret = _notifier_call_chain(rdev, + REGULATOR_EVENT_PRE_DISABLE, + NULL); + if (ret & NOTIFY_STOP_MASK) + return -EINVAL; + + ret = _regulator_do_disable(rdev); + if (ret < 0) { + rdev_err(rdev, "failed to disable: %pe\n", ERR_PTR(ret)); + _notifier_call_chain(rdev, + REGULATOR_EVENT_ABORT_DISABLE, + NULL); + return ret; + } + _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, NULL); - return ret; } - _notifier_call_chain(rdev, REGULATOR_EVENT_DISABLE, - NULL); - } - rdev->use_count = 0; - } else if (rdev->use_count > 1) { - rdev->use_count--; + rdev->use_count = 0; + } else if (rdev->use_count > 1) { + rdev->use_count--; + } } if (ret == 0) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/s390/crypto/vfio_ap_ops.c linux-lowlatency-hwe-6.5-6.5.0/drivers/s390/crypto/vfio_ap_ops.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/s390/crypto/vfio_ap_ops.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/s390/crypto/vfio_ap_ops.c @@ -32,7 +32,8 @@ #define AP_RESET_INTERVAL 20 /* Reset sleep interval (20ms) */ -static int vfio_ap_mdev_reset_queues(struct ap_queue_table *qtable); +static int vfio_ap_mdev_reset_queues(struct ap_matrix_mdev *matrix_mdev); +static int vfio_ap_mdev_reset_qlist(struct list_head *qlist); static struct vfio_ap_queue *vfio_ap_find_queue(int apqn); static const struct vfio_device_ops vfio_ap_matrix_dev_ops; static void vfio_ap_mdev_reset_queue(struct vfio_ap_queue *q); @@ -457,6 +458,7 @@ VFIO_AP_DBF_WARN("%s: gisc registration failed: nisc=%d, isc=%d, apqn=%#04x\n", __func__, nisc, isc, q->apqn); + vfio_unpin_pages(&q->matrix_mdev->vdev, nib, 1); status.response_code = AP_RESPONSE_INVALID_GISA; return status; } @@ -661,17 +663,23 @@ * device driver. * * @matrix_mdev: the matrix mdev whose matrix is to be filtered. + * @apm_filtered: a 256-bit bitmap for storing the APIDs filtered from the + * guest's AP configuration that are still in the host's AP + * configuration. * * Note: If an APQN referencing a queue device that is not bound to the vfio_ap * driver, its APID will be filtered from the guest's APCB. The matrix * structure precludes filtering an individual APQN, so its APID will be - * filtered. + * filtered. Consequently, all queues associated with the adapter that + * are in the host's AP configuration must be reset. If queues are + * subsequently made available again to the guest, they should re-appear + * in a reset state * * Return: a boolean value indicating whether the KVM guest's APCB was changed * by the filtering or not. */ -static bool vfio_ap_mdev_filter_matrix(unsigned long *apm, unsigned long *aqm, - struct ap_matrix_mdev *matrix_mdev) +static bool vfio_ap_mdev_filter_matrix(struct ap_matrix_mdev *matrix_mdev, + unsigned long *apm_filtered) { unsigned long apid, apqi, apqn; DECLARE_BITMAP(prev_shadow_apm, AP_DEVICES); @@ -681,6 +689,7 @@ bitmap_copy(prev_shadow_apm, matrix_mdev->shadow_apcb.apm, AP_DEVICES); bitmap_copy(prev_shadow_aqm, matrix_mdev->shadow_apcb.aqm, AP_DOMAINS); vfio_ap_matrix_init(&matrix_dev->info, &matrix_mdev->shadow_apcb); + bitmap_clear(apm_filtered, 0, AP_DEVICES); /* * Copy the adapters, domains and control domains to the shadow_apcb @@ -692,8 +701,9 @@ bitmap_and(matrix_mdev->shadow_apcb.aqm, matrix_mdev->matrix.aqm, (unsigned long *)matrix_dev->info.aqm, AP_DOMAINS); - for_each_set_bit_inv(apid, apm, AP_DEVICES) { - for_each_set_bit_inv(apqi, aqm, AP_DOMAINS) { + for_each_set_bit_inv(apid, matrix_mdev->shadow_apcb.apm, AP_DEVICES) { + for_each_set_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm, + AP_DOMAINS) { /* * If the APQN is not bound to the vfio_ap device * driver, then we can't assign it to the guest's @@ -705,8 +715,16 @@ apqn = AP_MKQID(apid, apqi); q = vfio_ap_mdev_get_queue(matrix_mdev, apqn); if (!q || q->reset_status.response_code) { - clear_bit_inv(apid, - matrix_mdev->shadow_apcb.apm); + clear_bit_inv(apid, matrix_mdev->shadow_apcb.apm); + + /* + * If the adapter was previously plugged into + * the guest, let's let the caller know that + * the APID was filtered. + */ + if (test_bit_inv(apid, prev_shadow_apm)) + set_bit_inv(apid, apm_filtered); + break; } } @@ -808,7 +826,7 @@ mutex_lock(&matrix_dev->guests_lock); mutex_lock(&matrix_dev->mdevs_lock); - vfio_ap_mdev_reset_queues(&matrix_mdev->qtable); + vfio_ap_mdev_reset_queues(matrix_mdev); vfio_ap_mdev_unlink_fr_queues(matrix_mdev); list_del(&matrix_mdev->node); mutex_unlock(&matrix_dev->mdevs_lock); @@ -918,6 +936,47 @@ AP_MKQID(apid, apqi)); } +static void collect_queues_to_reset(struct ap_matrix_mdev *matrix_mdev, + unsigned long apid, + struct list_head *qlist) +{ + struct vfio_ap_queue *q; + unsigned long apqi; + + for_each_set_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm, AP_DOMAINS) { + q = vfio_ap_mdev_get_queue(matrix_mdev, AP_MKQID(apid, apqi)); + if (q) + list_add_tail(&q->reset_qnode, qlist); + } +} + +static void reset_queues_for_apid(struct ap_matrix_mdev *matrix_mdev, + unsigned long apid) +{ + struct list_head qlist; + + INIT_LIST_HEAD(&qlist); + collect_queues_to_reset(matrix_mdev, apid, &qlist); + vfio_ap_mdev_reset_qlist(&qlist); +} + +static int reset_queues_for_apids(struct ap_matrix_mdev *matrix_mdev, + unsigned long *apm_reset) +{ + struct list_head qlist; + unsigned long apid; + + if (bitmap_empty(apm_reset, AP_DEVICES)) + return 0; + + INIT_LIST_HEAD(&qlist); + + for_each_set_bit_inv(apid, apm_reset, AP_DEVICES) + collect_queues_to_reset(matrix_mdev, apid, &qlist); + + return vfio_ap_mdev_reset_qlist(&qlist); +} + /** * assign_adapter_store - parses the APID from @buf and sets the * corresponding bit in the mediated matrix device's APM @@ -958,7 +1017,7 @@ { int ret; unsigned long apid; - DECLARE_BITMAP(apm_delta, AP_DEVICES); + DECLARE_BITMAP(apm_filtered, AP_DEVICES); struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev); mutex_lock(&ap_perms_mutex); @@ -987,12 +1046,11 @@ } vfio_ap_mdev_link_adapter(matrix_mdev, apid); - memset(apm_delta, 0, sizeof(apm_delta)); - set_bit_inv(apid, apm_delta); - if (vfio_ap_mdev_filter_matrix(apm_delta, - matrix_mdev->matrix.aqm, matrix_mdev)) + if (vfio_ap_mdev_filter_matrix(matrix_mdev, apm_filtered)) { vfio_ap_mdev_update_guest_apcb(matrix_mdev); + reset_queues_for_apids(matrix_mdev, apm_filtered); + } ret = count; done: @@ -1023,11 +1081,12 @@ * adapter was assigned. * @matrix_mdev: the matrix mediated device to which the adapter was assigned. * @apid: the APID of the unassigned adapter. - * @qtable: table for storing queues associated with unassigned adapter. + * @qlist: list for storing queues associated with unassigned adapter that + * need to be reset. */ static void vfio_ap_mdev_unlink_adapter(struct ap_matrix_mdev *matrix_mdev, unsigned long apid, - struct ap_queue_table *qtable) + struct list_head *qlist) { unsigned long apqi; struct vfio_ap_queue *q; @@ -1035,11 +1094,10 @@ for_each_set_bit_inv(apqi, matrix_mdev->matrix.aqm, AP_DOMAINS) { q = vfio_ap_unlink_apqn_fr_mdev(matrix_mdev, apid, apqi); - if (q && qtable) { + if (q && qlist) { if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm) && test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) - hash_add(qtable->queues, &q->mdev_qnode, - q->apqn); + list_add_tail(&q->reset_qnode, qlist); } } } @@ -1047,26 +1105,23 @@ static void vfio_ap_mdev_hot_unplug_adapter(struct ap_matrix_mdev *matrix_mdev, unsigned long apid) { - int loop_cursor; - struct vfio_ap_queue *q; - struct ap_queue_table *qtable = kzalloc(sizeof(*qtable), GFP_KERNEL); + struct vfio_ap_queue *q, *tmpq; + struct list_head qlist; - hash_init(qtable->queues); - vfio_ap_mdev_unlink_adapter(matrix_mdev, apid, qtable); + INIT_LIST_HEAD(&qlist); + vfio_ap_mdev_unlink_adapter(matrix_mdev, apid, &qlist); if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm)) { clear_bit_inv(apid, matrix_mdev->shadow_apcb.apm); vfio_ap_mdev_update_guest_apcb(matrix_mdev); } - vfio_ap_mdev_reset_queues(qtable); + vfio_ap_mdev_reset_qlist(&qlist); - hash_for_each(qtable->queues, loop_cursor, q, mdev_qnode) { + list_for_each_entry_safe(q, tmpq, &qlist, reset_qnode) { vfio_ap_unlink_mdev_fr_queue(q); - hash_del(&q->mdev_qnode); + list_del(&q->reset_qnode); } - - kfree(qtable); } /** @@ -1167,7 +1222,7 @@ { int ret; unsigned long apqi; - DECLARE_BITMAP(aqm_delta, AP_DOMAINS); + DECLARE_BITMAP(apm_filtered, AP_DEVICES); struct ap_matrix_mdev *matrix_mdev = dev_get_drvdata(dev); mutex_lock(&ap_perms_mutex); @@ -1196,12 +1251,11 @@ } vfio_ap_mdev_link_domain(matrix_mdev, apqi); - memset(aqm_delta, 0, sizeof(aqm_delta)); - set_bit_inv(apqi, aqm_delta); - if (vfio_ap_mdev_filter_matrix(matrix_mdev->matrix.apm, aqm_delta, - matrix_mdev)) + if (vfio_ap_mdev_filter_matrix(matrix_mdev, apm_filtered)) { vfio_ap_mdev_update_guest_apcb(matrix_mdev); + reset_queues_for_apids(matrix_mdev, apm_filtered); + } ret = count; done: @@ -1214,7 +1268,7 @@ static void vfio_ap_mdev_unlink_domain(struct ap_matrix_mdev *matrix_mdev, unsigned long apqi, - struct ap_queue_table *qtable) + struct list_head *qlist) { unsigned long apid; struct vfio_ap_queue *q; @@ -1222,11 +1276,10 @@ for_each_set_bit_inv(apid, matrix_mdev->matrix.apm, AP_DEVICES) { q = vfio_ap_unlink_apqn_fr_mdev(matrix_mdev, apid, apqi); - if (q && qtable) { + if (q && qlist) { if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm) && test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) - hash_add(qtable->queues, &q->mdev_qnode, - q->apqn); + list_add_tail(&q->reset_qnode, qlist); } } } @@ -1234,26 +1287,23 @@ static void vfio_ap_mdev_hot_unplug_domain(struct ap_matrix_mdev *matrix_mdev, unsigned long apqi) { - int loop_cursor; - struct vfio_ap_queue *q; - struct ap_queue_table *qtable = kzalloc(sizeof(*qtable), GFP_KERNEL); + struct vfio_ap_queue *q, *tmpq; + struct list_head qlist; - hash_init(qtable->queues); - vfio_ap_mdev_unlink_domain(matrix_mdev, apqi, qtable); + INIT_LIST_HEAD(&qlist); + vfio_ap_mdev_unlink_domain(matrix_mdev, apqi, &qlist); if (test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) { clear_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm); vfio_ap_mdev_update_guest_apcb(matrix_mdev); } - vfio_ap_mdev_reset_queues(qtable); + vfio_ap_mdev_reset_qlist(&qlist); - hash_for_each(qtable->queues, loop_cursor, q, mdev_qnode) { + list_for_each_entry_safe(q, tmpq, &qlist, reset_qnode) { vfio_ap_unlink_mdev_fr_queue(q); - hash_del(&q->mdev_qnode); + list_del(&q->reset_qnode); } - - kfree(qtable); } /** @@ -1608,7 +1658,7 @@ get_update_locks_for_kvm(kvm); kvm_arch_crypto_clear_masks(kvm); - vfio_ap_mdev_reset_queues(&matrix_mdev->qtable); + vfio_ap_mdev_reset_queues(matrix_mdev); kvm_put_kvm(kvm); matrix_mdev->kvm = NULL; @@ -1744,15 +1794,33 @@ } } -static int vfio_ap_mdev_reset_queues(struct ap_queue_table *qtable) +static int vfio_ap_mdev_reset_queues(struct ap_matrix_mdev *matrix_mdev) { int ret = 0, loop_cursor; struct vfio_ap_queue *q; - hash_for_each(qtable->queues, loop_cursor, q, mdev_qnode) + hash_for_each(matrix_mdev->qtable.queues, loop_cursor, q, mdev_qnode) vfio_ap_mdev_reset_queue(q); - hash_for_each(qtable->queues, loop_cursor, q, mdev_qnode) { + hash_for_each(matrix_mdev->qtable.queues, loop_cursor, q, mdev_qnode) { + flush_work(&q->reset_work); + + if (q->reset_status.response_code) + ret = -EIO; + } + + return ret; +} + +static int vfio_ap_mdev_reset_qlist(struct list_head *qlist) +{ + int ret = 0; + struct vfio_ap_queue *q; + + list_for_each_entry(q, qlist, reset_qnode) + vfio_ap_mdev_reset_queue(q); + + list_for_each_entry(q, qlist, reset_qnode) { flush_work(&q->reset_work); if (q->reset_status.response_code) @@ -1938,7 +2006,7 @@ ret = vfio_ap_mdev_get_device_info(arg); break; case VFIO_DEVICE_RESET: - ret = vfio_ap_mdev_reset_queues(&matrix_mdev->qtable); + ret = vfio_ap_mdev_reset_queues(matrix_mdev); break; case VFIO_DEVICE_GET_IRQ_INFO: ret = vfio_ap_get_irq_info(arg); @@ -1976,6 +2044,7 @@ { ssize_t nchars = 0; struct vfio_ap_queue *q; + unsigned long apid, apqi; struct ap_matrix_mdev *matrix_mdev; struct ap_device *apdev = to_ap_dev(dev); @@ -1983,8 +2052,21 @@ q = dev_get_drvdata(&apdev->device); matrix_mdev = vfio_ap_mdev_for_queue(q); + /* If the queue is assigned to the matrix mediated device, then + * determine whether it is passed through to a guest; otherwise, + * indicate that it is unassigned. + */ if (matrix_mdev) { - if (matrix_mdev->kvm) + apid = AP_QID_CARD(q->apqn); + apqi = AP_QID_QUEUE(q->apqn); + /* + * If the queue is passed through to the guest, then indicate + * that it is in use; otherwise, indicate that it is + * merely assigned to a matrix mediated device. + */ + if (matrix_mdev->kvm && + test_bit_inv(apid, matrix_mdev->shadow_apcb.apm) && + test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) nchars = scnprintf(buf, PAGE_SIZE, "%s\n", AP_QUEUE_IN_USE); else @@ -2069,6 +2151,7 @@ { int ret; struct vfio_ap_queue *q; + DECLARE_BITMAP(apm_filtered, AP_DEVICES); struct ap_matrix_mdev *matrix_mdev; ret = sysfs_create_group(&apdev->device.kobj, &vfio_queue_attr_group); @@ -2090,15 +2173,28 @@ if (matrix_mdev) { vfio_ap_mdev_link_queue(matrix_mdev, q); - if (vfio_ap_mdev_filter_matrix(matrix_mdev->matrix.apm, - matrix_mdev->matrix.aqm, - matrix_mdev)) + /* + * If we're in the process of handling the adding of adapters or + * domains to the host's AP configuration, then let the + * vfio_ap device driver's on_scan_complete callback filter the + * matrix and update the guest's AP configuration after all of + * the new queue devices are probed. + */ + if (!bitmap_empty(matrix_mdev->apm_add, AP_DEVICES) || + !bitmap_empty(matrix_mdev->aqm_add, AP_DOMAINS)) + goto done; + + if (vfio_ap_mdev_filter_matrix(matrix_mdev, apm_filtered)) { vfio_ap_mdev_update_guest_apcb(matrix_mdev); + reset_queues_for_apids(matrix_mdev, apm_filtered); + } } + +done: dev_set_drvdata(&apdev->device, q); release_update_locks_for_mdev(matrix_mdev); - return 0; + return ret; err_remove_group: sysfs_remove_group(&apdev->device.kobj, &vfio_queue_attr_group); @@ -2115,26 +2211,40 @@ q = dev_get_drvdata(&apdev->device); get_update_locks_for_queue(q); matrix_mdev = q->matrix_mdev; + apid = AP_QID_CARD(q->apqn); + apqi = AP_QID_QUEUE(q->apqn); if (matrix_mdev) { - vfio_ap_unlink_queue_fr_mdev(q); - - apid = AP_QID_CARD(q->apqn); - apqi = AP_QID_QUEUE(q->apqn); - - /* - * If the queue is assigned to the guest's APCB, then remove - * the adapter's APID from the APCB and hot it into the guest. - */ + /* If the queue is assigned to the guest's AP configuration */ if (test_bit_inv(apid, matrix_mdev->shadow_apcb.apm) && test_bit_inv(apqi, matrix_mdev->shadow_apcb.aqm)) { + /* + * Since the queues are defined via a matrix of adapters + * and domains, it is not possible to hot unplug a + * single queue; so, let's unplug the adapter. + */ clear_bit_inv(apid, matrix_mdev->shadow_apcb.apm); vfio_ap_mdev_update_guest_apcb(matrix_mdev); + reset_queues_for_apid(matrix_mdev, apid); + goto done; } } - vfio_ap_mdev_reset_queue(q); - flush_work(&q->reset_work); + /* + * If the queue is not in the host's AP configuration, then resetting + * it will fail with response code 01, (APQN not valid); so, let's make + * sure it is in the host's config. + */ + if (test_bit_inv(apid, (unsigned long *)matrix_dev->info.apm) && + test_bit_inv(apqi, (unsigned long *)matrix_dev->info.aqm)) { + vfio_ap_mdev_reset_queue(q); + flush_work(&q->reset_work); + } + +done: + if (matrix_mdev) + vfio_ap_unlink_queue_fr_mdev(q); + dev_set_drvdata(&apdev->device, NULL); kfree(q); release_update_locks_for_mdev(matrix_mdev); @@ -2442,39 +2552,30 @@ static void vfio_ap_mdev_hot_plug_cfg(struct ap_matrix_mdev *matrix_mdev) { - bool do_hotplug = false; - int filter_domains = 0; - int filter_adapters = 0; - DECLARE_BITMAP(apm, AP_DEVICES); - DECLARE_BITMAP(aqm, AP_DOMAINS); + DECLARE_BITMAP(apm_filtered, AP_DEVICES); + bool filter_domains, filter_adapters, filter_cdoms, do_hotplug = false; mutex_lock(&matrix_mdev->kvm->lock); mutex_lock(&matrix_dev->mdevs_lock); - filter_adapters = bitmap_and(apm, matrix_mdev->matrix.apm, - matrix_mdev->apm_add, AP_DEVICES); - filter_domains = bitmap_and(aqm, matrix_mdev->matrix.aqm, - matrix_mdev->aqm_add, AP_DOMAINS); - - if (filter_adapters && filter_domains) - do_hotplug |= vfio_ap_mdev_filter_matrix(apm, aqm, matrix_mdev); - else if (filter_adapters) - do_hotplug |= - vfio_ap_mdev_filter_matrix(apm, - matrix_mdev->shadow_apcb.aqm, - matrix_mdev); - else - do_hotplug |= - vfio_ap_mdev_filter_matrix(matrix_mdev->shadow_apcb.apm, - aqm, matrix_mdev); + filter_adapters = bitmap_intersects(matrix_mdev->matrix.apm, + matrix_mdev->apm_add, AP_DEVICES); + filter_domains = bitmap_intersects(matrix_mdev->matrix.aqm, + matrix_mdev->aqm_add, AP_DOMAINS); + filter_cdoms = bitmap_intersects(matrix_mdev->matrix.adm, + matrix_mdev->adm_add, AP_DOMAINS); - if (bitmap_intersects(matrix_mdev->matrix.adm, matrix_mdev->adm_add, - AP_DOMAINS)) + if (filter_adapters || filter_domains) + do_hotplug = vfio_ap_mdev_filter_matrix(matrix_mdev, apm_filtered); + + if (filter_cdoms) do_hotplug |= vfio_ap_mdev_filter_cdoms(matrix_mdev); if (do_hotplug) vfio_ap_mdev_update_guest_apcb(matrix_mdev); + reset_queues_for_apids(matrix_mdev, apm_filtered); + mutex_unlock(&matrix_dev->mdevs_lock); mutex_unlock(&matrix_mdev->kvm->lock); } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/s390/crypto/vfio_ap_private.h linux-lowlatency-hwe-6.5-6.5.0/drivers/s390/crypto/vfio_ap_private.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/s390/crypto/vfio_ap_private.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/s390/crypto/vfio_ap_private.h @@ -133,6 +133,8 @@ * @apqn: the APQN of the AP queue device * @saved_isc: the guest ISC registered with the GIB interface * @mdev_qnode: allows the vfio_ap_queue struct to be added to a hashtable + * @reset_qnode: allows the vfio_ap_queue struct to be added to a list of queues + * that need to be reset * @reset_status: the status from the last reset of the queue * @reset_work: work to wait for queue reset to complete */ @@ -143,6 +145,7 @@ #define VFIO_AP_ISC_INVALID 0xff unsigned char saved_isc; struct hlist_node mdev_qnode; + struct list_head reset_qnode; struct ap_queue_status reset_status; struct work_struct reset_work; }; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -1606,6 +1606,11 @@ } phy->port_id = port_id; + spin_lock(&phy->lock); + /* Delete timer and set phy_attached atomically */ + del_timer(&phy->timer); + phy->phy_attached = 1; + spin_unlock(&phy->lock); /* * Call pm_runtime_get_noresume() which pairs with @@ -1619,11 +1624,6 @@ res = IRQ_HANDLED; - spin_lock(&phy->lock); - /* Delete timer and set phy_attached atomically */ - del_timer(&phy->timer); - phy->phy_attached = 1; - spin_unlock(&phy->lock); end: if (phy->reset_completion) complete(phy->reset_completion); @@ -3474,7 +3474,7 @@ u32 *databuf = hisi_hba->debugfs_regs[dump_index][DEBUGFS_GLOBAL].data; int i; - for (i = 0; i < debugfs_axi_reg.count; i++, databuf++) + for (i = 0; i < debugfs_global_reg.count; i++, databuf++) *databuf = hisi_sas_read32(hisi_hba, 4 * i); } @@ -5145,7 +5145,7 @@ } if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) - return -1; + return -EPERM; dev_warn(dev, "entering suspend state\n"); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc.h linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc.h @@ -33,6 +33,7 @@ struct lpfc_sli2_slim; #define ELX_MODEL_NAME_SIZE 80 +#define ELX_FW_NAME_SIZE 84 #define LPFC_PCI_DEV_LP 0x1 #define LPFC_PCI_DEV_OC 0x2 diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc_els.c linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc_els.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc_els.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc_els.c @@ -1120,12 +1120,12 @@ vport->port_state, vport->fc_flag, sp->cmn.priority_tagging, kref_read(&ndlp->kref)); - if (sp->cmn.priority_tagging) - vport->phba->pport->vmid_flag |= (LPFC_VMID_ISSUE_QFPA | - LPFC_VMID_TYPE_PRIO); /* reinitialize the VMID datastructure before returning */ if (lpfc_is_vmid_enabled(phba)) lpfc_reinit_vmid(vport); + if (sp->cmn.priority_tagging) + vport->phba->pport->vmid_flag |= (LPFC_VMID_ISSUE_QFPA | + LPFC_VMID_TYPE_PRIO); /* * Address a timing race with dev_loss. If dev_loss is active on @@ -11094,6 +11094,14 @@ lpfc_nlp_put(ndlp); mempool_free(pmb, phba->mbox_mem_pool); + + /* reinitialize the VMID datastructure before returning. + * this is specifically for vport + */ + if (lpfc_is_vmid_enabled(phba)) + lpfc_reinit_vmid(vport); + vport->vmid_flag = vport->phba->pport->vmid_flag; + return; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc_init.c linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc_init.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc_init.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc_init.c @@ -14742,7 +14742,7 @@ int lpfc_sli4_request_firmware_update(struct lpfc_hba *phba, uint8_t fw_upgrade) { - uint8_t file_name[ELX_MODEL_NAME_SIZE]; + char file_name[ELX_FW_NAME_SIZE] = {0}; int ret; const struct firmware *fw; @@ -14751,7 +14751,7 @@ LPFC_SLI_INTF_IF_TYPE_2) return -EPERM; - snprintf(file_name, ELX_MODEL_NAME_SIZE, "%s.grp", phba->ModelName); + scnprintf(file_name, sizeof(file_name), "%s.grp", phba->ModelName); if (fw_upgrade == INT_FW_UPGRADE) { ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_UEVENT, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_error.c linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_error.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_error.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_error.c @@ -61,11 +61,11 @@ static enum scsi_disposition scsi_try_to_abort_cmd(const struct scsi_host_template *, struct scsi_cmnd *); -void scsi_eh_wakeup(struct Scsi_Host *shost) +void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy) { lockdep_assert_held(shost->host_lock); - if (scsi_host_busy(shost) == shost->host_failed) { + if (busy == shost->host_failed) { trace_scsi_eh_wakeup(shost); wake_up_process(shost->ehandler); SCSI_LOG_ERROR_RECOVERY(5, shost_printk(KERN_INFO, shost, @@ -88,7 +88,7 @@ if (scsi_host_set_state(shost, SHOST_RECOVERY) == 0 || scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY) == 0) { shost->host_eh_scheduled++; - scsi_eh_wakeup(shost); + scsi_eh_wakeup(shost, scsi_host_busy(shost)); } spin_unlock_irqrestore(shost->host_lock, flags); @@ -286,7 +286,7 @@ spin_lock_irqsave(shost->host_lock, flags); shost->host_failed++; - scsi_eh_wakeup(shost); + scsi_eh_wakeup(shost, scsi_host_busy(shost)); spin_unlock_irqrestore(shost->host_lock, flags); } @@ -2196,15 +2196,18 @@ struct scsi_cmnd *scmd, *next; list_for_each_entry_safe(scmd, next, done_q, eh_entry) { + struct scsi_device *sdev = scmd->device; + list_del_init(&scmd->eh_entry); - if (scsi_device_online(scmd->device) && - !scsi_noretry_cmd(scmd) && scsi_cmd_retry_allowed(scmd) && - scsi_eh_should_retry_cmd(scmd)) { + if (scsi_device_online(sdev) && !scsi_noretry_cmd(scmd) && + scsi_cmd_retry_allowed(scmd) && + scsi_eh_should_retry_cmd(scmd)) { SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd, "%s: flush retry cmd\n", current->comm)); scsi_queue_insert(scmd, SCSI_MLQUEUE_EH_RETRY); + blk_mq_kick_requeue_list(sdev->request_queue); } else { /* * If just we got sense for the device (called diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_lib.c linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_lib.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_lib.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_lib.c @@ -280,7 +280,7 @@ if (unlikely(scsi_host_in_recovery(shost))) { spin_lock_irqsave(shost->host_lock, flags); if (shost->host_failed || shost->host_eh_scheduled) - scsi_eh_wakeup(shost); + scsi_eh_wakeup(shost, scsi_host_busy(shost)); spin_unlock_irqrestore(shost->host_lock, flags); } rcu_read_unlock(); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_priv.h linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_priv.h --- linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_priv.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/scsi_priv.h @@ -92,7 +92,7 @@ extern enum blk_eh_timer_return scsi_timeout(struct request *req); extern int scsi_error_handler(void *host); extern enum scsi_disposition scsi_decide_disposition(struct scsi_cmnd *cmd); -extern void scsi_eh_wakeup(struct Scsi_Host *shost); +extern void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy); extern void scsi_eh_scmd_add(struct scsi_cmnd *); void scsi_eh_ready_devs(struct Scsi_Host *shost, struct list_head *work_q, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/soc/qcom/llcc-qcom.c linux-lowlatency-hwe-6.5-6.5.0/drivers/soc/qcom/llcc-qcom.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/soc/qcom/llcc-qcom.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soc/qcom/llcc-qcom.c @@ -47,7 +47,7 @@ #define LLCC_TRP_STATUSn(n) (4 + n * SZ_4K) #define LLCC_TRP_ATTR0_CFGn(n) (0x21000 + SZ_8 * n) #define LLCC_TRP_ATTR1_CFGn(n) (0x21004 + SZ_8 * n) -#define LLCC_TRP_ATTR2_CFGn(n) (0x21100 + SZ_8 * n) +#define LLCC_TRP_ATTR2_CFGn(n) (0x21100 + SZ_4 * n) #define LLCC_TRP_SCID_DIS_CAP_ALLOC 0x21f00 #define LLCC_TRP_PCB_ACT 0x21f04 @@ -786,15 +786,17 @@ u32 disable_cap_alloc, retain_pc; disable_cap_alloc = config->dis_cap_alloc << config->slice_id; - ret = regmap_write(drv_data->bcast_regmap, - LLCC_TRP_SCID_DIS_CAP_ALLOC, disable_cap_alloc); + ret = regmap_update_bits(drv_data->bcast_regmap, LLCC_TRP_SCID_DIS_CAP_ALLOC, + BIT(config->slice_id), disable_cap_alloc); if (ret) return ret; if (drv_data->version < LLCC_VERSION_4_1_0_0) { retain_pc = config->retain_on_pc << config->slice_id; - ret = regmap_write(drv_data->bcast_regmap, - LLCC_TRP_PCB_ACT, retain_pc); + ret = regmap_update_bits(drv_data->bcast_regmap, + LLCC_TRP_PCB_ACT, + BIT(config->slice_id), + retain_pc); if (ret) return ret; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/soc/qcom/pmic_glink_altmode.c linux-lowlatency-hwe-6.5-6.5.0/drivers/soc/qcom/pmic_glink_altmode.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/soc/qcom/pmic_glink_altmode.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soc/qcom/pmic_glink_altmode.c @@ -241,7 +241,7 @@ svid = mux == 2 ? USB_TYPEC_DP_SID : 0; - if (!altmode->ports[port].altmode) { + if (port >= ARRAY_SIZE(altmode->ports) || !altmode->ports[port].altmode) { dev_dbg(altmode->dev, "notification on undefined port %d\n", port); return; } @@ -284,7 +284,7 @@ hpd_state = FIELD_GET(SC8280XP_HPD_STATE_MASK, notify->payload[8]); hpd_irq = FIELD_GET(SC8280XP_HPD_IRQ_MASK, notify->payload[8]); - if (!altmode->ports[port].altmode) { + if (port >= ARRAY_SIZE(altmode->ports) || !altmode->ports[port].altmode) { dev_dbg(altmode->dev, "notification on undefined port %d\n", port); return; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/Kconfig linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/Kconfig --- linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/Kconfig +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/Kconfig @@ -1132,9 +1132,10 @@ config SPI_ZYNQMP_GQSPI tristate "Xilinx ZynqMP GQSPI controller" - depends on (SPI_MASTER && HAS_DMA) || COMPILE_TEST + depends on (SPI_MEM && HAS_DMA) || COMPILE_TEST help Enables Xilinx GQSPI controller driver for Zynq UltraScale+ MPSoC. + This controller only supports SPI memory interface. config SPI_AMD tristate "AMD SPI controller" diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi-cadence.c linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi-cadence.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi-cadence.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi-cadence.c @@ -317,6 +317,15 @@ xspi->rx_bytes -= nrx; while (ntx || nrx) { + if (nrx) { + u8 data = cdns_spi_read(xspi, CDNS_SPI_RXD); + + if (xspi->rxbuf) + *xspi->rxbuf++ = data; + + nrx--; + } + if (ntx) { if (xspi->txbuf) cdns_spi_write(xspi, CDNS_SPI_TXD, *xspi->txbuf++); @@ -326,14 +335,6 @@ ntx--; } - if (nrx) { - u8 data = cdns_spi_read(xspi, CDNS_SPI_RXD); - - if (xspi->rxbuf) - *xspi->rxbuf++ = data; - - nrx--; - } } } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi-intel-pci.c linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi-intel-pci.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi-intel-pci.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi-intel-pci.c @@ -84,7 +84,6 @@ { PCI_VDEVICE(INTEL, 0xa2a4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info }, - { PCI_VDEVICE(INTEL, 0xae23), (unsigned long)&cnl_info }, { }, }; MODULE_DEVICE_TABLE(pci, intel_spi_pci_ids); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi.c linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi.c @@ -1644,6 +1644,10 @@ pm_runtime_put_noidle(ctlr->dev.parent); dev_err(&ctlr->dev, "Failed to power device: %d\n", ret); + + msg->status = ret; + spi_finalize_current_message(ctlr); + return ret; } } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/staging/media/rkvdec/rkvdec.c linux-lowlatency-hwe-6.5-6.5.0/drivers/staging/media/rkvdec/rkvdec.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/staging/media/rkvdec/rkvdec.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/staging/media/rkvdec/rkvdec.c @@ -461,6 +461,9 @@ .vidioc_streamon = v4l2_m2m_ioctl_streamon, .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + + .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, + .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, }; static int rkvdec_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_core.c linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_core.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_core.c @@ -37,8 +37,6 @@ static DEFINE_MUTEX(thermal_list_lock); static DEFINE_MUTEX(thermal_governor_lock); -static atomic_t in_suspend; - static struct thermal_governor *def_governor; /* @@ -406,7 +404,7 @@ { int count; - if (atomic_read(&in_suspend)) + if (tz->suspended) return; if (WARN_ONCE(!tz->ops->get_temp, @@ -584,7 +582,7 @@ /** * thermal_zone_bind_cooling_device() - bind a cooling device to a thermal zone * @tz: pointer to struct thermal_zone_device - * @trip: indicates which trip point the cooling devices is + * @trip_index: indicates which trip point the cooling devices is * associated with in this thermal zone. * @cdev: pointer to struct thermal_cooling_device * @upper: the Maximum cooling state for this trip point. @@ -604,7 +602,7 @@ * Return: 0 on success, the proper error value otherwise. */ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, - int trip, + int trip_index, struct thermal_cooling_device *cdev, unsigned long upper, unsigned long lower, unsigned int weight) @@ -613,12 +611,15 @@ struct thermal_instance *pos; struct thermal_zone_device *pos1; struct thermal_cooling_device *pos2; + const struct thermal_trip *trip; bool upper_no_limit; int result; - if (trip >= tz->num_trips || trip < 0) + if (trip_index >= tz->num_trips || trip_index < 0) return -EINVAL; + trip = &tz->trips[trip_index]; + list_for_each_entry(pos1, &thermal_tz_list, node) { if (pos1 == tz) break; @@ -723,7 +724,7 @@ * thermal_zone_unbind_cooling_device() - unbind a cooling device from a * thermal zone. * @tz: pointer to a struct thermal_zone_device. - * @trip: indicates which trip point the cooling devices is + * @trip_index: indicates which trip point the cooling devices is * associated with in this thermal zone. * @cdev: pointer to a struct thermal_cooling_device. * @@ -734,13 +735,15 @@ * Return: 0 on success, the proper error value otherwise. */ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz, - int trip, + int trip_index, struct thermal_cooling_device *cdev) { struct thermal_instance *pos, *next; + const struct thermal_trip *trip; mutex_lock(&tz->lock); mutex_lock(&cdev->lock); + trip = &tz->trips[trip_index]; list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) { if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { list_del(&pos->tz_node); @@ -1360,7 +1363,6 @@ device_del(&tz->device); release_device: put_device(&tz->device); - tz = NULL; remove_id: ida_free(&thermal_tz_ida, id); free_tzp: @@ -1506,17 +1508,35 @@ case PM_HIBERNATION_PREPARE: case PM_RESTORE_PREPARE: case PM_SUSPEND_PREPARE: - atomic_set(&in_suspend, 1); + mutex_lock(&thermal_list_lock); + + list_for_each_entry(tz, &thermal_tz_list, node) { + mutex_lock(&tz->lock); + + tz->suspended = true; + + mutex_unlock(&tz->lock); + } + + mutex_unlock(&thermal_list_lock); break; case PM_POST_HIBERNATION: case PM_POST_RESTORE: case PM_POST_SUSPEND: - atomic_set(&in_suspend, 0); + mutex_lock(&thermal_list_lock); + list_for_each_entry(tz, &thermal_tz_list, node) { + mutex_lock(&tz->lock); + + tz->suspended = false; + thermal_zone_device_init(tz); - thermal_zone_device_update(tz, - THERMAL_EVENT_UNSPECIFIED); + __thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED); + + mutex_unlock(&tz->lock); } + + mutex_unlock(&thermal_list_lock); break; default: break; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_sysfs.c linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_sysfs.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_sysfs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_sysfs.c @@ -943,7 +943,8 @@ instance = container_of(attr, struct thermal_instance, attr); - return sprintf(buf, "%d\n", instance->trip); + return sprintf(buf, "%d\n", + thermal_zone_trip_id(instance->tz, instance->trip)); } ssize_t diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_trip.c linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_trip.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_trip.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_trip.c @@ -197,0 +198,13 @@ + +int thermal_zone_trip_id(struct thermal_zone_device *tz, + const struct thermal_trip *trip) +{ + int i; + + for (i = 0; i < tz->num_trips; i++) { + if (&tz->trips[i] == trip) + return i; + } + + return -ENODATA; +} diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/8250/8250_omap.c linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/8250/8250_omap.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/8250/8250_omap.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/8250/8250_omap.c @@ -1582,7 +1582,7 @@ err = pm_runtime_resume_and_get(&pdev->dev); if (err) - return err; + dev_err(&pdev->dev, "Failed to resume hardware\n"); up = serial8250_get_port(priv->line); omap_8250_shutdown(&up->port); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/sc16is7xx.c linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/sc16is7xx.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/sc16is7xx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/sc16is7xx.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define SC16IS7XX_NAME "sc16is7xx" @@ -300,8 +301,8 @@ /* Misc definitions */ +#define SC16IS7XX_SPI_READ_BIT BIT(7) #define SC16IS7XX_FIFO_SIZE (64) -#define SC16IS7XX_REG_SHIFT 2 #define SC16IS7XX_GPIOS_PER_BANK 4 struct sc16is7xx_devtype { @@ -322,7 +323,8 @@ struct sc16is7xx_one { struct uart_port port; - u8 line; + struct regmap *regmap; + struct mutex efr_lock; /* EFR registers access */ struct kthread_work tx_work; struct kthread_work reg_work; struct kthread_delayed_work ms_work; @@ -333,7 +335,6 @@ struct sc16is7xx_port { const struct sc16is7xx_devtype *devtype; - struct regmap *regmap; struct clk *clk; #ifdef CONFIG_GPIOLIB struct gpio_chip gpio; @@ -343,7 +344,6 @@ unsigned char buf[SC16IS7XX_FIFO_SIZE]; struct kthread_worker kworker; struct task_struct *kworker_task; - struct mutex efr_lock; struct sc16is7xx_one p[]; }; @@ -361,48 +361,35 @@ #define to_sc16is7xx_port(p,e) ((container_of((p), struct sc16is7xx_port, e))) #define to_sc16is7xx_one(p,e) ((container_of((p), struct sc16is7xx_one, e))) -static int sc16is7xx_line(struct uart_port *port) -{ - struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); - - return one->line; -} - static u8 sc16is7xx_port_read(struct uart_port *port, u8 reg) { - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); unsigned int val = 0; - const u8 line = sc16is7xx_line(port); - regmap_read(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line, &val); + regmap_read(one->regmap, reg, &val); return val; } static void sc16is7xx_port_write(struct uart_port *port, u8 reg, u8 val) { - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); - const u8 line = sc16is7xx_line(port); + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); - regmap_write(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line, val); + regmap_write(one->regmap, reg, val); } static void sc16is7xx_fifo_read(struct uart_port *port, unsigned int rxlen) { struct sc16is7xx_port *s = dev_get_drvdata(port->dev); - const u8 line = sc16is7xx_line(port); - u8 addr = (SC16IS7XX_RHR_REG << SC16IS7XX_REG_SHIFT) | line; + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); - regcache_cache_bypass(s->regmap, true); - regmap_raw_read(s->regmap, addr, s->buf, rxlen); - regcache_cache_bypass(s->regmap, false); + regmap_noinc_read(one->regmap, SC16IS7XX_RHR_REG, s->buf, rxlen); } static void sc16is7xx_fifo_write(struct uart_port *port, u8 to_send) { struct sc16is7xx_port *s = dev_get_drvdata(port->dev); - const u8 line = sc16is7xx_line(port); - u8 addr = (SC16IS7XX_THR_REG << SC16IS7XX_REG_SHIFT) | line; + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); /* * Don't send zero-length data, at least on SPI it confuses the chip @@ -411,32 +398,15 @@ if (unlikely(!to_send)) return; - regcache_cache_bypass(s->regmap, true); - regmap_raw_write(s->regmap, addr, s->buf, to_send); - regcache_cache_bypass(s->regmap, false); + regmap_noinc_write(one->regmap, SC16IS7XX_THR_REG, s->buf, to_send); } static void sc16is7xx_port_update(struct uart_port *port, u8 reg, u8 mask, u8 val) { - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); - const u8 line = sc16is7xx_line(port); - - regmap_update_bits(s->regmap, (reg << SC16IS7XX_REG_SHIFT) | line, - mask, val); -} - -static int sc16is7xx_alloc_line(void) -{ - int i; - - BUILD_BUG_ON(SC16IS7XX_MAX_DEVS > BITS_PER_LONG); - - for (i = 0; i < SC16IS7XX_MAX_DEVS; i++) - if (!test_and_set_bit(i, &sc16is7xx_lines)) - break; + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); - return i; + regmap_update_bits(one->regmap, reg, mask, val); } static void sc16is7xx_power(struct uart_port *port, int on) @@ -478,7 +448,7 @@ static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg) { - switch (reg >> SC16IS7XX_REG_SHIFT) { + switch (reg) { case SC16IS7XX_RHR_REG: case SC16IS7XX_IIR_REG: case SC16IS7XX_LSR_REG: @@ -497,7 +467,7 @@ static bool sc16is7xx_regmap_precious(struct device *dev, unsigned int reg) { - switch (reg >> SC16IS7XX_REG_SHIFT) { + switch (reg) { case SC16IS7XX_RHR_REG: return true; default: @@ -507,9 +477,14 @@ return false; } +static bool sc16is7xx_regmap_noinc(struct device *dev, unsigned int reg) +{ + return reg == SC16IS7XX_RHR_REG; +} + static int sc16is7xx_set_baud(struct uart_port *port, int baud) { - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); u8 lcr; u8 prescaler = 0; unsigned long clk = port->uartclk, div = clk / 16 / baud; @@ -532,7 +507,7 @@ * because the bulk of the interrupt processing is run as a workqueue * job in thread context. */ - mutex_lock(&s->efr_lock); + mutex_lock(&one->efr_lock); lcr = sc16is7xx_port_read(port, SC16IS7XX_LCR_REG); @@ -541,17 +516,17 @@ SC16IS7XX_LCR_CONF_MODE_B); /* Enable enhanced features */ - regcache_cache_bypass(s->regmap, true); + regcache_cache_bypass(one->regmap, true); sc16is7xx_port_update(port, SC16IS7XX_EFR_REG, SC16IS7XX_EFR_ENABLE_BIT, SC16IS7XX_EFR_ENABLE_BIT); - regcache_cache_bypass(s->regmap, false); + regcache_cache_bypass(one->regmap, false); /* Put LCR back to the normal mode */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); - mutex_unlock(&s->efr_lock); + mutex_unlock(&one->efr_lock); sc16is7xx_port_update(port, SC16IS7XX_MCR_REG, SC16IS7XX_MCR_CLKSEL_BIT, @@ -562,10 +537,10 @@ SC16IS7XX_LCR_CONF_MODE_A); /* Write the new divisor */ - regcache_cache_bypass(s->regmap, true); + regcache_cache_bypass(one->regmap, true); sc16is7xx_port_write(port, SC16IS7XX_DLH_REG, div / 256); sc16is7xx_port_write(port, SC16IS7XX_DLL_REG, div % 256); - regcache_cache_bypass(s->regmap, false); + regcache_cache_bypass(one->regmap, false); /* Put LCR back to the normal mode */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); @@ -666,9 +641,9 @@ } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_stop_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return; } @@ -694,13 +669,15 @@ sc16is7xx_fifo_write(port, to_send); } - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (uart_circ_empty(xmit)) sc16is7xx_stop_tx(port); - spin_unlock_irqrestore(&port->lock, flags); + else + sc16is7xx_ier_set(port, SC16IS7XX_IER_THRI_BIT); + uart_port_unlock_irqrestore(port, flags); } static unsigned int sc16is7xx_get_hwmctrl(struct uart_port *port) @@ -718,11 +695,10 @@ static void sc16is7xx_update_mlines(struct sc16is7xx_one *one) { struct uart_port *port = &one->port; - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); unsigned long flags; unsigned int status, changed; - lockdep_assert_held_once(&s->efr_lock); + lockdep_assert_held_once(&one->efr_lock); status = sc16is7xx_get_hwmctrl(port); changed = status ^ one->old_mctrl; @@ -732,7 +708,7 @@ one->old_mctrl = status; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); if ((changed & TIOCM_RNG) && (status & TIOCM_RNG)) port->icount.rng++; if (changed & TIOCM_DSR) @@ -743,79 +719,82 @@ uart_handle_cts_change(port, status & TIOCM_CTS); wake_up_interruptible(&port->state->port.delta_msr_wait); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static bool sc16is7xx_port_irq(struct sc16is7xx_port *s, int portno) { + bool rc = true; + unsigned int iir, rxlen; struct uart_port *port = &s->p[portno].port; + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); - do { - unsigned int iir, rxlen; - struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); + mutex_lock(&one->efr_lock); + + iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG); + if (iir & SC16IS7XX_IIR_NO_INT_BIT) { + rc = false; + goto out_port_irq; + } - iir = sc16is7xx_port_read(port, SC16IS7XX_IIR_REG); - if (iir & SC16IS7XX_IIR_NO_INT_BIT) - return false; - - iir &= SC16IS7XX_IIR_ID_MASK; - - switch (iir) { - case SC16IS7XX_IIR_RDI_SRC: - case SC16IS7XX_IIR_RLSE_SRC: - case SC16IS7XX_IIR_RTOI_SRC: - case SC16IS7XX_IIR_XOFFI_SRC: - rxlen = sc16is7xx_port_read(port, SC16IS7XX_RXLVL_REG); - - /* - * There is a silicon bug that makes the chip report a - * time-out interrupt but no data in the FIFO. This is - * described in errata section 18.1.4. - * - * When this happens, read one byte from the FIFO to - * clear the interrupt. - */ - if (iir == SC16IS7XX_IIR_RTOI_SRC && !rxlen) - rxlen = 1; - - if (rxlen) - sc16is7xx_handle_rx(port, rxlen, iir); - break; + iir &= SC16IS7XX_IIR_ID_MASK; + + switch (iir) { + case SC16IS7XX_IIR_RDI_SRC: + case SC16IS7XX_IIR_RLSE_SRC: + case SC16IS7XX_IIR_RTOI_SRC: + case SC16IS7XX_IIR_XOFFI_SRC: + rxlen = sc16is7xx_port_read(port, SC16IS7XX_RXLVL_REG); + + /* + * There is a silicon bug that makes the chip report a + * time-out interrupt but no data in the FIFO. This is + * described in errata section 18.1.4. + * + * When this happens, read one byte from the FIFO to + * clear the interrupt. + */ + if (iir == SC16IS7XX_IIR_RTOI_SRC && !rxlen) + rxlen = 1; + + if (rxlen) + sc16is7xx_handle_rx(port, rxlen, iir); + break; /* CTSRTS interrupt comes only when CTS goes inactive */ - case SC16IS7XX_IIR_CTSRTS_SRC: - case SC16IS7XX_IIR_MSI_SRC: - sc16is7xx_update_mlines(one); - break; - case SC16IS7XX_IIR_THRI_SRC: - sc16is7xx_handle_tx(port); - break; - default: - dev_err_ratelimited(port->dev, - "ttySC%i: Unexpected interrupt: %x", - port->line, iir); - break; - } - } while (0); - return true; + case SC16IS7XX_IIR_CTSRTS_SRC: + case SC16IS7XX_IIR_MSI_SRC: + sc16is7xx_update_mlines(one); + break; + case SC16IS7XX_IIR_THRI_SRC: + sc16is7xx_handle_tx(port); + break; + default: + dev_err_ratelimited(port->dev, + "ttySC%i: Unexpected interrupt: %x", + port->line, iir); + break; + } + +out_port_irq: + mutex_unlock(&one->efr_lock); + + return rc; } static irqreturn_t sc16is7xx_irq(int irq, void *dev_id) { - struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id; + bool keep_polling; - mutex_lock(&s->efr_lock); + struct sc16is7xx_port *s = (struct sc16is7xx_port *)dev_id; - while (1) { - bool keep_polling = false; + do { int i; + keep_polling = false; + for (i = 0; i < s->devtype->nr_uart; ++i) keep_polling |= sc16is7xx_port_irq(s, i); - if (!keep_polling) - break; - } - - mutex_unlock(&s->efr_lock); + } while (keep_polling); return IRQ_HANDLED; } @@ -823,20 +802,15 @@ static void sc16is7xx_tx_proc(struct kthread_work *ws) { struct uart_port *port = &(to_sc16is7xx_one(ws, tx_work)->port); - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); - unsigned long flags; + struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); if ((port->rs485.flags & SER_RS485_ENABLED) && (port->rs485.delay_rts_before_send > 0)) msleep(port->rs485.delay_rts_before_send); - mutex_lock(&s->efr_lock); + mutex_lock(&one->efr_lock); sc16is7xx_handle_tx(port); - mutex_unlock(&s->efr_lock); - - spin_lock_irqsave(&port->lock, flags); - sc16is7xx_ier_set(port, SC16IS7XX_IER_THRI_BIT); - spin_unlock_irqrestore(&port->lock, flags); + mutex_unlock(&one->efr_lock); } static void sc16is7xx_reconf_rs485(struct uart_port *port) @@ -847,14 +821,14 @@ struct serial_rs485 *rs485 = &port->rs485; unsigned long irqflags; - spin_lock_irqsave(&port->lock, irqflags); + uart_port_lock_irqsave(port, &irqflags); if (rs485->flags & SER_RS485_ENABLED) { efcr |= SC16IS7XX_EFCR_AUTO_RS485_BIT; if (rs485->flags & SER_RS485_RTS_AFTER_SEND) efcr |= SC16IS7XX_EFCR_RTS_INVERT_BIT; } - spin_unlock_irqrestore(&port->lock, irqflags); + uart_port_unlock_irqrestore(port, irqflags); sc16is7xx_port_update(port, SC16IS7XX_EFCR_REG, mask, efcr); } @@ -865,10 +839,10 @@ struct sc16is7xx_one_config config; unsigned long irqflags; - spin_lock_irqsave(&one->port.lock, irqflags); + uart_port_lock_irqsave(&one->port, &irqflags); config = one->config; memset(&one->config, 0, sizeof(one->config)); - spin_unlock_irqrestore(&one->port.lock, irqflags); + uart_port_unlock_irqrestore(&one->port, irqflags); if (config.flags & SC16IS7XX_RECONF_MD) { u8 mcr = 0; @@ -939,9 +913,9 @@ struct sc16is7xx_port *s = dev_get_drvdata(one->port.dev); if (one->port.state) { - mutex_lock(&s->efr_lock); + mutex_lock(&one->efr_lock); sc16is7xx_update_mlines(one); - mutex_unlock(&s->efr_lock); + mutex_unlock(&one->efr_lock); kthread_queue_delayed_work(&s->kworker, &one->ms_work, HZ); } @@ -974,18 +948,18 @@ * value set in MCR register. Stop reading data from RX FIFO so the * AutoRTS feature will de-activate RTS output. */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_ier_clear(port, SC16IS7XX_IER_RDI_BIT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static void sc16is7xx_unthrottle(struct uart_port *port) { unsigned long flags; - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_ier_set(port, SC16IS7XX_IER_RDI_BIT); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static unsigned int sc16is7xx_tx_empty(struct uart_port *port) @@ -1025,7 +999,6 @@ struct ktermios *termios, const struct ktermios *old) { - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); unsigned int lcr, flow = 0; int baud; @@ -1084,13 +1057,13 @@ port->ignore_status_mask |= SC16IS7XX_LSR_BRK_ERROR_MASK; /* As above, claim the mutex while accessing the EFR. */ - mutex_lock(&s->efr_lock); + mutex_lock(&one->efr_lock); sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_CONF_MODE_B); /* Configure flow control */ - regcache_cache_bypass(s->regmap, true); + regcache_cache_bypass(one->regmap, true); sc16is7xx_port_write(port, SC16IS7XX_XON1_REG, termios->c_cc[VSTART]); sc16is7xx_port_write(port, SC16IS7XX_XOFF1_REG, termios->c_cc[VSTOP]); @@ -1109,12 +1082,12 @@ SC16IS7XX_EFR_REG, SC16IS7XX_EFR_FLOWCTRL_BITS, flow); - regcache_cache_bypass(s->regmap, false); + regcache_cache_bypass(one->regmap, false); /* Update LCR register */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); - mutex_unlock(&s->efr_lock); + mutex_unlock(&one->efr_lock); /* Get baud rate generator configuration */ baud = uart_get_baud_rate(port, termios, old, @@ -1124,7 +1097,7 @@ /* Setup baudrate generator */ baud = sc16is7xx_set_baud(port, baud); - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); /* Update timeout according to new baud rate */ uart_update_timeout(port, termios->c_cflag, baud); @@ -1132,7 +1105,7 @@ if (UART_ENABLE_MS(port, termios->c_cflag)) sc16is7xx_enable_ms(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); } static int sc16is7xx_config_rs485(struct uart_port *port, struct ktermios *termios, @@ -1160,7 +1133,6 @@ static int sc16is7xx_startup(struct uart_port *port) { struct sc16is7xx_one *one = to_sc16is7xx_one(port, port); - struct sc16is7xx_port *s = dev_get_drvdata(port->dev); unsigned int val; unsigned long flags; @@ -1177,7 +1149,7 @@ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_CONF_MODE_B); - regcache_cache_bypass(s->regmap, true); + regcache_cache_bypass(one->regmap, true); /* Enable write access to enhanced features and internal clock div */ sc16is7xx_port_update(port, SC16IS7XX_EFR_REG, @@ -1195,7 +1167,7 @@ SC16IS7XX_TCR_RX_RESUME(24) | SC16IS7XX_TCR_RX_HALT(48)); - regcache_cache_bypass(s->regmap, false); + regcache_cache_bypass(one->regmap, false); /* Now, initialize the UART */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_WORD_LEN_8); @@ -1219,9 +1191,9 @@ sc16is7xx_port_write(port, SC16IS7XX_IER_REG, val); /* Enable modem status polling */ - spin_lock_irqsave(&port->lock, flags); + uart_port_lock_irqsave(port, &flags); sc16is7xx_enable_ms(port); - spin_unlock_irqrestore(&port->lock, flags); + uart_port_unlock_irqrestore(port, flags); return 0; } @@ -1423,7 +1395,8 @@ /* * Configure ports designated to operate as modem control lines. */ -static int sc16is7xx_setup_mctrl_ports(struct sc16is7xx_port *s) +static int sc16is7xx_setup_mctrl_ports(struct sc16is7xx_port *s, + struct regmap *regmap) { int i; int ret; @@ -1452,8 +1425,8 @@ if (s->mctrl_mask) regmap_update_bits( - s->regmap, - SC16IS7XX_IOCONTROL_REG << SC16IS7XX_REG_SHIFT, + regmap, + SC16IS7XX_IOCONTROL_REG, SC16IS7XX_IOCONTROL_MODEM_A_BIT | SC16IS7XX_IOCONTROL_MODEM_B_BIT, s->mctrl_mask); @@ -1468,7 +1441,7 @@ static int sc16is7xx_probe(struct device *dev, const struct sc16is7xx_devtype *devtype, - struct regmap *regmap, int irq) + struct regmap *regmaps[], int irq) { unsigned long freq = 0, *pfreq = dev_get_platdata(dev); unsigned int val; @@ -1476,16 +1449,20 @@ int i, ret; struct sc16is7xx_port *s; - if (IS_ERR(regmap)) - return PTR_ERR(regmap); + for (i = 0; i < devtype->nr_uart; i++) + if (IS_ERR(regmaps[i])) + return PTR_ERR(regmaps[i]); /* * This device does not have an identification register that would * tell us if we are really connected to the correct device. * The best we can do is to check if communication is at all possible. + * + * Note: regmap[0] is used in the probe function to access registers + * common to all channels/ports, as it is guaranteed to be present on + * all variants. */ - ret = regmap_read(regmap, - SC16IS7XX_LSR_REG << SC16IS7XX_REG_SHIFT, &val); + ret = regmap_read(regmaps[0], SC16IS7XX_LSR_REG, &val); if (ret < 0) return -EPROBE_DEFER; @@ -1519,10 +1496,8 @@ return -EINVAL; } - s->regmap = regmap; s->devtype = devtype; dev_set_drvdata(dev, s); - mutex_init(&s->efr_lock); kthread_init_worker(&s->kworker); s->kworker_task = kthread_run(kthread_worker_fn, &s->kworker, @@ -1534,11 +1509,17 @@ sched_set_fifo(s->kworker_task); /* reset device, purging any pending irq / data */ - regmap_write(s->regmap, SC16IS7XX_IOCONTROL_REG << SC16IS7XX_REG_SHIFT, - SC16IS7XX_IOCONTROL_SRESET_BIT); + regmap_write(regmaps[0], SC16IS7XX_IOCONTROL_REG, + SC16IS7XX_IOCONTROL_SRESET_BIT); for (i = 0; i < devtype->nr_uart; ++i) { - s->p[i].line = i; + s->p[i].port.line = find_first_zero_bit(&sc16is7xx_lines, + SC16IS7XX_MAX_DEVS); + if (s->p[i].port.line >= SC16IS7XX_MAX_DEVS) { + ret = -ERANGE; + goto out_ports; + } + /* Initialize port data */ s->p[i].port.dev = dev; s->p[i].port.irq = irq; @@ -1558,12 +1539,9 @@ s->p[i].port.rs485_supported = sc16is7xx_rs485_supported; s->p[i].port.ops = &sc16is7xx_ops; s->p[i].old_mctrl = 0; - s->p[i].port.line = sc16is7xx_alloc_line(); + s->p[i].regmap = regmaps[i]; - if (s->p[i].port.line >= SC16IS7XX_MAX_DEVS) { - ret = -ENOMEM; - goto out_ports; - } + mutex_init(&s->p[i].efr_lock); ret = uart_get_rs485_mode(&s->p[i].port); if (ret) @@ -1580,20 +1558,25 @@ kthread_init_work(&s->p[i].tx_work, sc16is7xx_tx_proc); kthread_init_work(&s->p[i].reg_work, sc16is7xx_reg_proc); kthread_init_delayed_work(&s->p[i].ms_work, sc16is7xx_ms_proc); + /* Register port */ - uart_add_one_port(&sc16is7xx_uart, &s->p[i].port); + ret = uart_add_one_port(&sc16is7xx_uart, &s->p[i].port); + if (ret) + goto out_ports; + + set_bit(s->p[i].port.line, &sc16is7xx_lines); /* Enable EFR */ sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_CONF_MODE_B); - regcache_cache_bypass(s->regmap, true); + regcache_cache_bypass(regmaps[i], true); /* Enable write access to enhanced features */ sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_EFR_REG, SC16IS7XX_EFR_ENABLE_BIT); - regcache_cache_bypass(s->regmap, false); + regcache_cache_bypass(regmaps[i], false); /* Restore access to general registers */ sc16is7xx_port_write(&s->p[i].port, SC16IS7XX_LCR_REG, 0x00); @@ -1613,7 +1596,7 @@ s->p[u].irda_mode = true; } - ret = sc16is7xx_setup_mctrl_ports(s); + ret = sc16is7xx_setup_mctrl_ports(s, regmaps[0]); if (ret) goto out_ports; @@ -1648,10 +1631,9 @@ #endif out_ports: - for (i--; i >= 0; i--) { - uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port); - clear_bit(s->p[i].port.line, &sc16is7xx_lines); - } + for (i = 0; i < devtype->nr_uart; i++) + if (test_and_clear_bit(s->p[i].port.line, &sc16is7xx_lines)) + uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port); kthread_stop(s->kworker_task); @@ -1673,8 +1655,8 @@ for (i = 0; i < s->devtype->nr_uart; i++) { kthread_cancel_delayed_work_sync(&s->p[i].ms_work); - uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port); - clear_bit(s->p[i].port.line, &sc16is7xx_lines); + if (test_and_clear_bit(s->p[i].port.line, &sc16is7xx_lines)) + uart_remove_one_port(&sc16is7xx_uart, &s->p[i].port); sc16is7xx_power(&s->p[i].port, 0); } @@ -1696,26 +1678,52 @@ MODULE_DEVICE_TABLE(of, sc16is7xx_dt_ids); static struct regmap_config regcfg = { - .reg_bits = 7, - .pad_bits = 1, + .reg_bits = 5, + .pad_bits = 3, .val_bits = 8, .cache_type = REGCACHE_RBTREE, .volatile_reg = sc16is7xx_regmap_volatile, .precious_reg = sc16is7xx_regmap_precious, + .writeable_noinc_reg = sc16is7xx_regmap_noinc, + .readable_noinc_reg = sc16is7xx_regmap_noinc, + .max_raw_read = SC16IS7XX_FIFO_SIZE, + .max_raw_write = SC16IS7XX_FIFO_SIZE, + .max_register = SC16IS7XX_EFCR_REG, }; +static const char *sc16is7xx_regmap_name(u8 port_id) +{ + switch (port_id) { + case 0: return "port0"; + case 1: return "port1"; + default: + WARN_ON(true); + return NULL; + } +} + +static unsigned int sc16is7xx_regmap_port_mask(unsigned int port_id) +{ + /* CH1,CH0 are at bits 2:1. */ + return port_id << 1; +} + #ifdef CONFIG_SERIAL_SC16IS7XX_SPI static int sc16is7xx_spi_probe(struct spi_device *spi) { const struct sc16is7xx_devtype *devtype; - struct regmap *regmap; + struct regmap *regmaps[2]; + unsigned int i; int ret; /* Setup SPI bus */ spi->bits_per_word = 8; - /* only supports mode 0 on SC16IS762 */ + /* For all variants, only mode 0 is supported */ + if ((spi->mode & SPI_MODE_X_MASK) != SPI_MODE_0) + return dev_err_probe(&spi->dev, -EINVAL, "Unsupported SPI mode\n"); + spi->mode = spi->mode ? : SPI_MODE_0; - spi->max_speed_hz = spi->max_speed_hz ? : 15000000; + spi->max_speed_hz = spi->max_speed_hz ? : 4 * HZ_PER_MHZ; ret = spi_setup(spi); if (ret) return ret; @@ -1730,11 +1738,20 @@ devtype = (struct sc16is7xx_devtype *)id_entry->driver_data; } - regcfg.max_register = (0xf << SC16IS7XX_REG_SHIFT) | - (devtype->nr_uart - 1); - regmap = devm_regmap_init_spi(spi, ®cfg); + for (i = 0; i < devtype->nr_uart; i++) { + regcfg.name = sc16is7xx_regmap_name(i); + /* + * If read_flag_mask is 0, the regmap code sets it to a default + * of 0x80. Since we specify our own mask, we must add the READ + * bit ourselves: + */ + regcfg.read_flag_mask = sc16is7xx_regmap_port_mask(i) | + SC16IS7XX_SPI_READ_BIT; + regcfg.write_flag_mask = sc16is7xx_regmap_port_mask(i); + regmaps[i] = devm_regmap_init_spi(spi, ®cfg); + } - return sc16is7xx_probe(&spi->dev, devtype, regmap, spi->irq); + return sc16is7xx_probe(&spi->dev, devtype, regmaps, spi->irq); } static void sc16is7xx_spi_remove(struct spi_device *spi) @@ -1773,7 +1790,8 @@ { const struct i2c_device_id *id = i2c_client_get_device_id(i2c); const struct sc16is7xx_devtype *devtype; - struct regmap *regmap; + struct regmap *regmaps[2]; + unsigned int i; if (i2c->dev.of_node) { devtype = device_get_match_data(&i2c->dev); @@ -1783,11 +1801,14 @@ devtype = (struct sc16is7xx_devtype *)id->driver_data; } - regcfg.max_register = (0xf << SC16IS7XX_REG_SHIFT) | - (devtype->nr_uart - 1); - regmap = devm_regmap_init_i2c(i2c, ®cfg); + for (i = 0; i < devtype->nr_uart; i++) { + regcfg.name = sc16is7xx_regmap_name(i); + regcfg.read_flag_mask = sc16is7xx_regmap_port_mask(i); + regcfg.write_flag_mask = sc16is7xx_regmap_port_mask(i); + regmaps[i] = devm_regmap_init_i2c(i2c, ®cfg); + } - return sc16is7xx_probe(&i2c->dev, devtype, regmap, i2c->irq); + return sc16is7xx_probe(&i2c->dev, devtype, regmaps, i2c->irq); } static void sc16is7xx_i2c_remove(struct i2c_client *client) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/serial_core.c linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/serial_core.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/serial_core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/serial_core.c @@ -1376,19 +1376,27 @@ return; } + rs485->flags &= supported_flags; + /* Pick sane settings if the user hasn't */ - if ((supported_flags & (SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND)) && - !(rs485->flags & SER_RS485_RTS_ON_SEND) == + if (!(rs485->flags & SER_RS485_RTS_ON_SEND) == !(rs485->flags & SER_RS485_RTS_AFTER_SEND)) { - dev_warn_ratelimited(port->dev, - "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n", - port->name, port->line); - rs485->flags |= SER_RS485_RTS_ON_SEND; - rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; - supported_flags |= SER_RS485_RTS_ON_SEND|SER_RS485_RTS_AFTER_SEND; - } + if (supported_flags & SER_RS485_RTS_ON_SEND) { + rs485->flags |= SER_RS485_RTS_ON_SEND; + rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; - rs485->flags &= supported_flags; + dev_warn_ratelimited(port->dev, + "%s (%d): invalid RTS setting, using RTS_ON_SEND instead\n", + port->name, port->line); + } else { + rs485->flags |= SER_RS485_RTS_AFTER_SEND; + rs485->flags &= ~SER_RS485_RTS_ON_SEND; + + dev_warn_ratelimited(port->dev, + "%s (%d): invalid RTS setting, using RTS_AFTER_SEND instead\n", + port->name, port->line); + } + } uart_sanitize_serial_rs485_delays(port, rs485); @@ -1407,6 +1415,16 @@ !!(rs485->flags & SER_RS485_TERMINATE_BUS)); } +static void uart_set_rs485_rx_during_tx(struct uart_port *port, + const struct serial_rs485 *rs485) +{ + if (!(rs485->flags & SER_RS485_ENABLED)) + return; + + gpiod_set_value_cansleep(port->rs485_rx_during_tx_gpio, + !!(rs485->flags & SER_RS485_RX_DURING_TX)); +} + static int uart_rs485_config(struct uart_port *port) { struct serial_rs485 *rs485 = &port->rs485; @@ -1418,12 +1436,17 @@ uart_sanitize_serial_rs485(port, rs485); uart_set_rs485_termination(port, rs485); + uart_set_rs485_rx_during_tx(port, rs485); spin_lock_irqsave(&port->lock, flags); ret = port->rs485_config(port, NULL, rs485); spin_unlock_irqrestore(&port->lock, flags); - if (ret) + if (ret) { memset(rs485, 0, sizeof(*rs485)); + /* unset GPIOs */ + gpiod_set_value_cansleep(port->rs485_term_gpio, 0); + gpiod_set_value_cansleep(port->rs485_rx_during_tx_gpio, 0); + } return ret; } @@ -1451,7 +1474,7 @@ int ret; unsigned long flags; - if (!port->rs485_config) + if (!(port->rs485_supported.flags & SER_RS485_ENABLED)) return -ENOTTY; if (copy_from_user(&rs485, rs485_user, sizeof(*rs485_user))) @@ -1462,6 +1485,7 @@ return ret; uart_sanitize_serial_rs485(port, &rs485); uart_set_rs485_termination(port, &rs485); + uart_set_rs485_rx_during_tx(port, &rs485); spin_lock_irqsave(&port->lock, flags); ret = port->rs485_config(port, &tty->termios, &rs485); @@ -1473,8 +1497,14 @@ port->ops->set_mctrl(port, port->mctrl); } spin_unlock_irqrestore(&port->lock, flags); - if (ret) + if (ret) { + /* restore old GPIO settings */ + gpiod_set_value_cansleep(port->rs485_term_gpio, + !!(port->rs485.flags & SER_RS485_TERMINATE_BUS)); + gpiod_set_value_cansleep(port->rs485_rx_during_tx_gpio, + !!(port->rs485.flags & SER_RS485_RX_DURING_TX)); return ret; + } if (copy_to_user(rs485_user, &port->rs485, sizeof(port->rs485))) return -EFAULT; @@ -3570,9 +3600,13 @@ { struct serial_rs485 *rs485conf = &port->rs485; struct device *dev = port->dev; + enum gpiod_flags dflags; + struct gpio_desc *desc; u32 rs485_delay[2]; int ret; - int rx_during_tx_gpio_flag; + + if (!(port->rs485_supported.flags & SER_RS485_ENABLED)) + return 0; ret = device_property_read_u32_array(dev, "rs485-rts-delay", rs485_delay, 2); @@ -3611,26 +3645,21 @@ * bus participants enable it, no communication is possible at all. * Works fine for short cables and users may enable for longer cables. */ - port->rs485_term_gpio = devm_gpiod_get_optional(dev, "rs485-term", - GPIOD_OUT_LOW); - if (IS_ERR(port->rs485_term_gpio)) { - ret = PTR_ERR(port->rs485_term_gpio); - port->rs485_term_gpio = NULL; - return dev_err_probe(dev, ret, "Cannot get rs485-term-gpios\n"); - } + desc = devm_gpiod_get_optional(dev, "rs485-term", GPIOD_OUT_LOW); + if (IS_ERR(desc)) + return dev_err_probe(dev, PTR_ERR(desc), "Cannot get rs485-term-gpios\n"); + port->rs485_term_gpio = desc; if (port->rs485_term_gpio) port->rs485_supported.flags |= SER_RS485_TERMINATE_BUS; - rx_during_tx_gpio_flag = (rs485conf->flags & SER_RS485_RX_DURING_TX) ? - GPIOD_OUT_HIGH : GPIOD_OUT_LOW; - port->rs485_rx_during_tx_gpio = devm_gpiod_get_optional(dev, - "rs485-rx-during-tx", - rx_during_tx_gpio_flag); - if (IS_ERR(port->rs485_rx_during_tx_gpio)) { - ret = PTR_ERR(port->rs485_rx_during_tx_gpio); - port->rs485_rx_during_tx_gpio = NULL; - return dev_err_probe(dev, ret, "Cannot get rs485-rx-during-tx-gpios\n"); - } + dflags = (rs485conf->flags & SER_RS485_RX_DURING_TX) ? + GPIOD_OUT_HIGH : GPIOD_OUT_LOW; + desc = devm_gpiod_get_optional(dev, "rs485-rx-during-tx", dflags); + if (IS_ERR(desc)) + return dev_err_probe(dev, PTR_ERR(desc), "Cannot get rs485-rx-during-tx-gpios\n"); + port->rs485_rx_during_tx_gpio = desc; + if (port->rs485_rx_during_tx_gpio) + port->rs485_supported.flags |= SER_RS485_RX_DURING_TX; return 0; } diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/ufs/core/ufshcd.c linux-lowlatency-hwe-6.5-6.5.0/drivers/ufs/core/ufshcd.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/ufs/core/ufshcd.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/ufs/core/ufshcd.c @@ -8604,7 +8604,6 @@ ufs_bsg_probe(hba); ufshpb_init(hba); scsi_scan_host(hba->host); - pm_runtime_put_sync(hba->dev); out: return ret; @@ -8871,15 +8870,12 @@ /* Probe and add UFS logical units */ ret = ufshcd_add_lus(hba); + out: - /* - * If we failed to initialize the device or the device is not - * present, turn off the power/clocks etc. - */ - if (ret) { - pm_runtime_put_sync(hba->dev); - ufshcd_hba_exit(hba); - } + pm_runtime_put_sync(hba->dev); + + if (ret) + dev_err(hba->dev, "%s failed: %d\n", __func__, ret); } static enum scsi_timeout_action ufshcd_eh_timed_out(struct scsi_cmnd *scmd) diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/ufs/host/ufs-qcom.c linux-lowlatency-hwe-6.5-6.5.0/drivers/ufs/host/ufs-qcom.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/ufs/host/ufs-qcom.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/ufs/host/ufs-qcom.c @@ -115,7 +115,7 @@ cap = hba->crypto_cap_array[cfg->crypto_cap_idx]; if (cap.algorithm_id != UFS_CRYPTO_ALG_AES_XTS || cap.key_size != UFS_CRYPTO_KEY_SIZE_256) - return -EINVAL; + return -EOPNOTSUPP; if (config_enable) return qcom_ice_program_key(host->ice, @@ -1541,7 +1541,7 @@ if (!res->resource) { dev_info(hba->dev, "Resource %s not provided\n", res->name); if (i == RES_UFS) - return -ENOMEM; + return -ENODEV; continue; } else if (i == RES_UFS) { res_mem = res->resource; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/chipidea/core.c linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/chipidea/core.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/chipidea/core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/chipidea/core.c @@ -523,6 +523,13 @@ u32 otgsc = 0; if (ci->in_lpm) { + /* + * If we already have a wakeup irq pending there, + * let's just return to wait resume finished firstly. + */ + if (ci->wakeup_int) + return IRQ_HANDLED; + disable_irq_nosync(irq); ci->wakeup_int = true; pm_runtime_get(ci->dev); diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/class/cdc-acm.c linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/class/cdc-acm.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/class/cdc-acm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/class/cdc-acm.c @@ -892,6 +892,9 @@ struct acm *acm = tty->driver_data; int retval; + if (!(acm->ctrl_caps & USB_CDC_CAP_BRK)) + return -EOPNOTSUPP; + retval = acm_send_break(acm, state ? 0xffff : 0); if (retval < 0) dev_dbg(&acm->control->dev, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/core/hub.c linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/core/hub.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/core/hub.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/core/hub.c @@ -47,12 +47,18 @@ #define USB_VENDOR_TEXAS_INSTRUMENTS 0x0451 #define USB_PRODUCT_TUSB8041_USB3 0x8140 #define USB_PRODUCT_TUSB8041_USB2 0x8142 -#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01 -#define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02 +#define USB_VENDOR_MICROCHIP 0x0424 +#define USB_PRODUCT_USB4913 0x4913 +#define USB_PRODUCT_USB4914 0x4914 +#define USB_PRODUCT_USB4915 0x4915 +#define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND BIT(0) +#define HUB_QUIRK_DISABLE_AUTOSUSPEND BIT(1) +#define HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL BIT(2) #define USB_TP_TRANSMISSION_DELAY 40 /* ns */ #define USB_TP_TRANSMISSION_DELAY_MAX 65535 /* ns */ #define USB_PING_RESPONSE_TIME 400 /* ns */ +#define USB_REDUCE_FRAME_INTR_BINTERVAL 9 /* Protect struct usb_device->state and ->children members * Note: Both are also protected by ->dev.sem, except that ->state can @@ -1904,6 +1910,14 @@ usb_autopm_get_interface_no_resume(intf); } + if ((id->driver_info & HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL) && + desc->endpoint[0].desc.bInterval > USB_REDUCE_FRAME_INTR_BINTERVAL) { + desc->endpoint[0].desc.bInterval = + USB_REDUCE_FRAME_INTR_BINTERVAL; + /* Tell the HCD about the interrupt ep's new bInterval */ + usb_set_interface(hdev, 0, 0); + } + if (hub_configure(hub, &desc->endpoint[0].desc) >= 0) { onboard_hub_create_pdevs(hdev, &hub->onboard_hub_devs); @@ -5956,6 +5970,21 @@ .idVendor = USB_VENDOR_TEXAS_INSTRUMENTS, .idProduct = USB_PRODUCT_TUSB8041_USB3, .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT, + .idVendor = USB_VENDOR_MICROCHIP, + .idProduct = USB_PRODUCT_USB4913, + .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL}, + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT, + .idVendor = USB_VENDOR_MICROCHIP, + .idProduct = USB_PRODUCT_USB4914, + .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL}, + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT, + .idVendor = USB_VENDOR_MICROCHIP, + .idProduct = USB_PRODUCT_USB4915, + .driver_info = HUB_QUIRK_REDUCE_FRAME_INTR_BINTERVAL}, { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS, .bDeviceClass = USB_CLASS_HUB}, { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/dwc3/core.c linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/dwc3/core.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/dwc3/core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/dwc3/core.c @@ -277,48 +277,11 @@ /* * We're resetting only the device side because, if we're in host mode, * XHCI driver will reset the host block. If dwc3 was configured for - * host-only mode or current role is host, then we can return early. + * host-only mode, then we can return early. */ if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) return 0; - /* - * If the dr_mode is host and the dwc->current_dr_role is not the - * corresponding DWC3_GCTL_PRTCAP_HOST, then the dwc3_core_init_mode - * isn't executed yet. Ensure the phy is ready before the controller - * updates the GCTL.PRTCAPDIR or other settings by soft-resetting - * the phy. - * - * Note: GUSB3PIPECTL[n] and GUSB2PHYCFG[n] are port settings where n - * is port index. If this is a multiport host, then we need to reset - * all active ports. - */ - if (dwc->dr_mode == USB_DR_MODE_HOST) { - u32 usb3_port; - u32 usb2_port; - - usb3_port = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)); - usb3_port |= DWC3_GUSB3PIPECTL_PHYSOFTRST; - dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port); - - usb2_port = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); - usb2_port |= DWC3_GUSB2PHYCFG_PHYSOFTRST; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port); - - /* Small delay for phy reset assertion */ - usleep_range(1000, 2000); - - usb3_port &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST; - dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), usb3_port); - - usb2_port &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), usb2_port); - - /* Wait for clock synchronization */ - msleep(50); - return 0; - } - reg = dwc3_readl(dwc->regs, DWC3_DCTL); reg |= DWC3_DCTL_CSFTRST; reg &= ~DWC3_DCTL_RUN_STOP; diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/host/xhci-plat.c linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/host/xhci-plat.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/host/xhci-plat.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/host/xhci-plat.c @@ -433,7 +433,7 @@ } EXPORT_SYMBOL_GPL(xhci_plat_remove); -static int __maybe_unused xhci_plat_suspend(struct device *dev) +static int xhci_plat_suspend(struct device *dev) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); @@ -461,7 +461,7 @@ return 0; } -static int __maybe_unused xhci_plat_resume(struct device *dev) +static int xhci_plat_resume_common(struct device *dev, struct pm_message pmsg) { struct usb_hcd *hcd = dev_get_drvdata(dev); struct xhci_hcd *xhci = hcd_to_xhci(hcd); @@ -483,7 +483,7 @@ if (ret) goto disable_clks; - ret = xhci_resume(xhci, PMSG_RESUME); + ret = xhci_resume(xhci, pmsg); if (ret) goto disable_clks; @@ -504,2 +504,12 @@ +static int xhci_plat_resume(struct device *dev) +{ + return xhci_plat_resume_common(dev, PMSG_RESUME); +} + +static int xhci_plat_restore(struct device *dev) +{ + return xhci_plat_resume_common(dev, PMSG_RESTORE); +} + static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev) @@ -524,7 +534,12 @@ } const struct dev_pm_ops xhci_plat_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(xhci_plat_suspend, xhci_plat_resume) + .suspend = pm_sleep_ptr(xhci_plat_suspend), + .resume = pm_sleep_ptr(xhci_plat_resume), + .freeze = pm_sleep_ptr(xhci_plat_suspend), + .thaw = pm_sleep_ptr(xhci_plat_resume), + .poweroff = pm_sleep_ptr(xhci_plat_suspend), + .restore = pm_sleep_ptr(xhci_plat_restore), SET_RUNTIME_PM_OPS(xhci_plat_runtime_suspend, xhci_plat_runtime_resume, diff -u linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/phy/phy-mxs-usb.c linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/phy/phy-mxs-usb.c --- linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/phy/phy-mxs-usb.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/phy/phy-mxs-usb.c @@ -388,8 +388,7 @@ static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy) { - return IS_ENABLED(CONFIG_USB_OTG) && - mxs_phy->phy.last_event == USB_EVENT_ID; + return mxs_phy->phy.last_event == USB_EVENT_ID; } static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/extent-tree.c linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/extent-tree.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/extent-tree.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/extent-tree.c @@ -1266,7 +1266,8 @@ u64 bytes_left, end; u64 aligned_start = ALIGN(start, 1 << SECTOR_SHIFT); - if (WARN_ON(start != aligned_start)) { + /* Adjust the range to be aligned to 512B sectors if necessary. */ + if (start != aligned_start) { len -= aligned_start - start; len = round_down(len, 1 << SECTOR_SHIFT); start = aligned_start; @@ -4161,6 +4162,42 @@ return 0; } +static int prepare_allocation_zoned(struct btrfs_fs_info *fs_info, + struct find_free_extent_ctl *ffe_ctl) +{ + if (ffe_ctl->for_treelog) { + spin_lock(&fs_info->treelog_bg_lock); + if (fs_info->treelog_bg) + ffe_ctl->hint_byte = fs_info->treelog_bg; + spin_unlock(&fs_info->treelog_bg_lock); + } else if (ffe_ctl->for_data_reloc) { + spin_lock(&fs_info->relocation_bg_lock); + if (fs_info->data_reloc_bg) + ffe_ctl->hint_byte = fs_info->data_reloc_bg; + spin_unlock(&fs_info->relocation_bg_lock); + } else if (ffe_ctl->flags & BTRFS_BLOCK_GROUP_DATA) { + struct btrfs_block_group *block_group; + + spin_lock(&fs_info->zone_active_bgs_lock); + list_for_each_entry(block_group, &fs_info->zone_active_bgs, active_bg_list) { + /* + * No lock is OK here because avail is monotinically + * decreasing, and this is just a hint. + */ + u64 avail = block_group->zone_capacity - block_group->alloc_offset; + + if (block_group_bits(block_group, ffe_ctl->flags) && + avail >= ffe_ctl->num_bytes) { + ffe_ctl->hint_byte = block_group->start; + break; + } + } + spin_unlock(&fs_info->zone_active_bgs_lock); + } + + return 0; +} + static int prepare_allocation(struct btrfs_fs_info *fs_info, struct find_free_extent_ctl *ffe_ctl, struct btrfs_space_info *space_info, @@ -4171,19 +4208,7 @@ return prepare_allocation_clustered(fs_info, ffe_ctl, space_info, ins); case BTRFS_EXTENT_ALLOC_ZONED: - if (ffe_ctl->for_treelog) { - spin_lock(&fs_info->treelog_bg_lock); - if (fs_info->treelog_bg) - ffe_ctl->hint_byte = fs_info->treelog_bg; - spin_unlock(&fs_info->treelog_bg_lock); - } - if (ffe_ctl->for_data_reloc) { - spin_lock(&fs_info->relocation_bg_lock); - if (fs_info->data_reloc_bg) - ffe_ctl->hint_byte = fs_info->data_reloc_bg; - spin_unlock(&fs_info->relocation_bg_lock); - } - return 0; + return prepare_allocation_zoned(fs_info, ffe_ctl); default: BUG(); } diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/inode.c linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/inode.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/inode.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/inode.c @@ -4602,6 +4602,8 @@ u64 root_flags; int ret; + down_write(&fs_info->subvol_sem); + /* * Don't allow to delete a subvolume with send in progress. This is * inside the inode lock so the error handling that has to drop the bit @@ -4613,25 +4615,25 @@ btrfs_warn(fs_info, "attempt to delete subvolume %llu during send", dest->root_key.objectid); - return -EPERM; + ret = -EPERM; + goto out_up_write; } if (atomic_read(&dest->nr_swapfiles)) { spin_unlock(&dest->root_item_lock); btrfs_warn(fs_info, "attempt to delete subvolume %llu with active swapfile", root->root_key.objectid); - return -EPERM; + ret = -EPERM; + goto out_up_write; } root_flags = btrfs_root_flags(&dest->root_item); btrfs_set_root_flags(&dest->root_item, root_flags | BTRFS_ROOT_SUBVOL_DEAD); spin_unlock(&dest->root_item_lock); - down_write(&fs_info->subvol_sem); - ret = may_destroy_subvol(dest); if (ret) - goto out_up_write; + goto out_undead; btrfs_init_block_rsv(&block_rsv, BTRFS_BLOCK_RSV_TEMP); /* @@ -4641,7 +4643,7 @@ */ ret = btrfs_subvolume_reserve_metadata(root, &block_rsv, 5, true); if (ret) - goto out_up_write; + goto out_undead; trans = btrfs_start_transaction(root, 0); if (IS_ERR(trans)) { @@ -4707,15 +4709,17 @@ inode->i_flags |= S_DEAD; out_release: btrfs_subvolume_release_metadata(root, &block_rsv); -out_up_write: - up_write(&fs_info->subvol_sem); +out_undead: if (ret) { spin_lock(&dest->root_item_lock); root_flags = btrfs_root_flags(&dest->root_item); btrfs_set_root_flags(&dest->root_item, root_flags & ~BTRFS_ROOT_SUBVOL_DEAD); spin_unlock(&dest->root_item_lock); - } else { + } +out_up_write: + up_write(&fs_info->subvol_sem); + if (!ret) { d_invalidate(dentry); btrfs_prune_dentries(dest); ASSERT(dest->send_in_progress == 0); diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/ioctl.c linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/ioctl.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/ioctl.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/ioctl.c @@ -790,6 +790,9 @@ return -EOPNOTSUPP; } + if (btrfs_root_refs(&root->root_item) == 0) + return -ENOENT; + if (!test_bit(BTRFS_ROOT_SHAREABLE, &root->state)) return -EINVAL; @@ -2608,6 +2611,10 @@ ret = -EFAULT; goto out; } + if (range.flags & ~BTRFS_DEFRAG_RANGE_FLAGS_SUPP) { + ret = -EOPNOTSUPP; + goto out; + } /* compression requires us to start the IO */ if ((range.flags & BTRFS_DEFRAG_RANGE_COMPRESS)) { range.flags |= BTRFS_DEFRAG_RANGE_START_IO; diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/ref-verify.c linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/ref-verify.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/ref-verify.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/ref-verify.c @@ -886,8 +886,10 @@ out_unlock: spin_unlock(&fs_info->ref_verify_lock); out: - if (ret) + if (ret) { + btrfs_free_ref_cache(fs_info); btrfs_clear_opt(fs_info->mount_opt, REF_VERIFY); + } return ret; } @@ -1018,8 +1020,8 @@ } } if (ret) { - btrfs_clear_opt(fs_info->mount_opt, REF_VERIFY); btrfs_free_ref_cache(fs_info); + btrfs_clear_opt(fs_info->mount_opt, REF_VERIFY); } btrfs_free_path(path); return ret; diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/scrub.c linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/scrub.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/scrub.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/btrfs/scrub.c @@ -1077,12 +1077,22 @@ static void scrub_read_endio(struct btrfs_bio *bbio) { struct scrub_stripe *stripe = bbio->private; + struct bio_vec *bvec; + int sector_nr = calc_sector_number(stripe, bio_first_bvec_all(&bbio->bio)); + int num_sectors; + u32 bio_size = 0; + int i; + + ASSERT(sector_nr < stripe->nr_sectors); + bio_for_each_bvec_all(bvec, &bbio->bio, i) + bio_size += bvec->bv_len; + num_sectors = bio_size >> stripe->bg->fs_info->sectorsize_bits; if (bbio->bio.bi_status) { - bitmap_set(&stripe->io_error_bitmap, 0, stripe->nr_sectors); - bitmap_set(&stripe->error_bitmap, 0, stripe->nr_sectors); + bitmap_set(&stripe->io_error_bitmap, sector_nr, num_sectors); + bitmap_set(&stripe->error_bitmap, sector_nr, num_sectors); } else { - bitmap_clear(&stripe->io_error_bitmap, 0, stripe->nr_sectors); + bitmap_clear(&stripe->io_error_bitmap, sector_nr, num_sectors); } bio_put(&bbio->bio); if (atomic_dec_and_test(&stripe->pending_io)) { @@ -1619,6 +1629,9 @@ { struct btrfs_fs_info *fs_info = sctx->fs_info; struct btrfs_bio *bbio; + unsigned int nr_sectors = min_t(u64, BTRFS_STRIPE_LEN, stripe->bg->start + + stripe->bg->length - stripe->logical) >> + fs_info->sectorsize_bits; int mirror = stripe->mirror_num; ASSERT(stripe->bg); @@ -1628,14 +1641,16 @@ bbio = btrfs_bio_alloc(SCRUB_STRIPE_PAGES, REQ_OP_READ, fs_info, scrub_read_endio, stripe); - /* Read the whole stripe. */ bbio->bio.bi_iter.bi_sector = stripe->logical >> SECTOR_SHIFT; - for (int i = 0; i < BTRFS_STRIPE_LEN >> PAGE_SHIFT; i++) { + /* Read the whole range inside the chunk boundary. */ + for (unsigned int cur = 0; cur < nr_sectors; cur++) { + struct page *page = scrub_stripe_get_page(stripe, cur); + unsigned int pgoff = scrub_stripe_get_page_offset(stripe, cur); int ret; - ret = bio_add_page(&bbio->bio, stripe->pages[i], PAGE_SIZE, 0); + ret = bio_add_page(&bbio->bio, page, fs_info->sectorsize, pgoff); /* We should have allocated enough bio vectors. */ - ASSERT(ret == PAGE_SIZE); + ASSERT(ret == fs_info->sectorsize); } atomic_inc(&stripe->pending_io); diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/caps.c linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/caps.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/caps.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/caps.c @@ -4886,13 +4886,15 @@ struct inode *dir, int mds, int drop, int unless) { - struct dentry *parent = NULL; struct ceph_mds_request_release *rel = *p; struct ceph_dentry_info *di = ceph_dentry(dentry); struct ceph_client *cl; int force = 0; int ret; + /* This shouldn't happen */ + BUG_ON(!dir); + /* * force an record for the directory caps if we have a dentry lease. * this is racy (can't take i_ceph_lock and d_lock together), but it @@ -4902,14 +4904,9 @@ spin_lock(&dentry->d_lock); if (di->lease_session && di->lease_session->s_mds == mds) force = 1; - if (!dir) { - parent = dget(dentry->d_parent); - dir = d_inode(parent); - } spin_unlock(&dentry->d_lock); ret = ceph_encode_inode_release(p, dir, mds, drop, unless, force); - dput(parent); cl = ceph_inode_to_client(dir); spin_lock(&dentry->d_lock); diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/mds_client.c linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/mds_client.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/mds_client.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/mds_client.c @@ -4123,12 +4123,12 @@ pr_info_client(cl, "mds%d reconnect success\n", session->s_mds); + session->s_features = features; if (session->s_state == CEPH_MDS_SESSION_OPEN) { pr_notice_client(cl, "mds%d is already opened\n", session->s_mds); } else { session->s_state = CEPH_MDS_SESSION_OPEN; - session->s_features = features; renewed_caps(mdsc, session, 0); if (test_bit(CEPHFS_FEATURE_METRIC_COLLECT, &session->s_features)) diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/quota.c linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/quota.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/quota.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/ceph/quota.c @@ -197,10 +197,10 @@ } /* - * This function walks through the snaprealm for an inode and returns the - * ceph_snap_realm for the first snaprealm that has quotas set (max_files, + * This function walks through the snaprealm for an inode and set the + * realmp with the first snaprealm that has quotas set (max_files, * max_bytes, or any, depending on the 'which_quota' argument). If the root is - * reached, return the root ceph_snap_realm instead. + * reached, set the realmp with the root ceph_snap_realm instead. * * Note that the caller is responsible for calling ceph_put_snap_realm() on the * returned realm. @@ -211,10 +211,9 @@ * this function will return -EAGAIN; otherwise, the snaprealms walk-through * will be restarted. */ -static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, - struct inode *inode, - enum quota_get_realm which_quota, - bool retry) +static int get_quota_realm(struct ceph_mds_client *mdsc, struct inode *inode, + enum quota_get_realm which_quota, + struct ceph_snap_realm **realmp, bool retry) { struct ceph_client *cl = mdsc->fsc->client; struct ceph_inode_info *ci = NULL; @@ -222,8 +221,10 @@ struct inode *in; bool has_quota; + if (realmp) + *realmp = NULL; if (ceph_snap(inode) != CEPH_NOSNAP) - return NULL; + return 0; restart: realm = ceph_inode(inode)->i_snap_realm; @@ -250,7 +251,7 @@ break; ceph_put_snap_realm(mdsc, realm); if (!retry) - return ERR_PTR(-EAGAIN); + return -EAGAIN; goto restart; } @@ -259,8 +260,11 @@ iput(in); next = realm->parent; - if (has_quota || !next) - return realm; + if (has_quota || !next) { + if (realmp) + *realmp = realm; + return 0; + } ceph_get_snap_realm(mdsc, next); ceph_put_snap_realm(mdsc, realm); @@ -269,7 +273,7 @@ if (realm) ceph_put_snap_realm(mdsc, realm); - return NULL; + return 0; } bool ceph_quota_is_same_realm(struct inode *old, struct inode *new) @@ -277,6 +281,7 @@ struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(old->i_sb); struct ceph_snap_realm *old_realm, *new_realm; bool is_same; + int ret; restart: /* @@ -286,9 +291,9 @@ * dropped and we can then restart the whole operation. */ down_read(&mdsc->snap_rwsem); - old_realm = get_quota_realm(mdsc, old, QUOTA_GET_ANY, true); - new_realm = get_quota_realm(mdsc, new, QUOTA_GET_ANY, false); - if (PTR_ERR(new_realm) == -EAGAIN) { + get_quota_realm(mdsc, old, QUOTA_GET_ANY, &old_realm, true); + ret = get_quota_realm(mdsc, new, QUOTA_GET_ANY, &new_realm, false); + if (ret == -EAGAIN) { up_read(&mdsc->snap_rwsem); if (old_realm) ceph_put_snap_realm(mdsc, old_realm); @@ -492,8 +497,8 @@ bool is_updated = false; down_read(&mdsc->snap_rwsem); - realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), - QUOTA_GET_MAX_BYTES, true); + get_quota_realm(mdsc, d_inode(fsc->sb->s_root), QUOTA_GET_MAX_BYTES, + &realm, true); up_read(&mdsc->snap_rwsem); if (!realm) return false; diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/ecryptfs/inode.c linux-lowlatency-hwe-6.5-6.5.0/fs/ecryptfs/inode.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/ecryptfs/inode.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/ecryptfs/inode.c @@ -78,6 +78,14 @@ if (lower_inode->i_sb != ecryptfs_superblock_to_lower(sb)) return ERR_PTR(-EXDEV); + + /* Reject dealing with casefold directories. */ + if (IS_CASEFOLDED(lower_inode)) { + pr_err_ratelimited("%s: Can't handle casefolded directory.\n", + __func__); + return ERR_PTR(-EREMOTE); + } + if (!igrab(lower_inode)) return ERR_PTR(-ESTALE); inode = iget5_locked(sb, (unsigned long)lower_inode, diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/efivarfs/super.c linux-lowlatency-hwe-6.5-6.5.0/fs/efivarfs/super.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/efivarfs/super.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/efivarfs/super.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "internal.h" @@ -275,8 +276,19 @@ return get_tree_single(fc, efivarfs_fill_super); } +static int efivarfs_reconfigure(struct fs_context *fc) +{ + if (!efivar_supports_writes() && !(fc->sb_flags & SB_RDONLY)) { + pr_err("Firmware does not support SetVariableRT. Can not remount with rw\n"); + return -EINVAL; + } + + return 0; +} + static const struct fs_context_operations efivarfs_context_ops = { .get_tree = efivarfs_get_tree, + .reconfigure = efivarfs_reconfigure, }; static int efivarfs_init_fs_context(struct fs_context *fc) @@ -287,6 +299,8 @@ static void efivarfs_kill_sb(struct super_block *sb) { + struct efivarfs_fs_info *sfi = sb->s_fs_info; + kill_litter_super(sb); if (!efivar_is_available()) @@ -294,6 +308,7 @@ /* Remove all entries and destroy */ efivar_entry_iter(efivarfs_destroy, &efivarfs_list, NULL); + kfree(sfi); } static struct file_system_type efivarfs_type = { diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/erofs/zdata.c linux-lowlatency-hwe-6.5-6.5.0/fs/erofs/zdata.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/erofs/zdata.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/erofs/zdata.c @@ -824,7 +824,6 @@ if (ztailpacking) { pcl->obj.index = 0; /* which indicates ztailpacking */ - pcl->pageofs_in = erofs_blkoff(fe->inode->i_sb, map->m_pa); pcl->tailpacking_size = map->m_plen; } else { pcl->obj.index = map->m_pa >> PAGE_SHIFT; @@ -1022,6 +1021,7 @@ get_page(fe->map.buf.page); WRITE_ONCE(fe->pcl->compressed_bvecs[0].page, fe->map.buf.page); + fe->pcl->pageofs_in = map->m_pa & ~PAGE_MASK; fe->mode = Z_EROFS_PCLUSTER_FOLLOWED_NOINPLACE; } else { /* bind cache first when cached decompression is preferred */ @@ -1350,12 +1350,11 @@ put_page(page); } else { for (i = 0; i < pclusterpages; ++i) { - page = pcl->compressed_bvecs[i].page; + /* consider shortlived pages added when decompressing */ + page = be->compressed_pages[i]; if (erofs_page_is_managed(sbi, page)) continue; - - /* recycle all individual short-lived pages */ (void)z_erofs_put_shortlivedpage(be->pagepool, page); WRITE_ONCE(pcl->compressed_bvecs[i].page, NULL); } diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/extents.c linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/extents.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/extents.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/extents.c @@ -4522,7 +4522,8 @@ * Round up offset. This is not fallocate, we need to zero out * blocks, so convert interior block aligned part of the range to * unwritten and possibly manually zero out unaligned parts of the - * range. + * range. Here, start and partial_begin are inclusive, end and + * partial_end are exclusive. */ start = round_up(offset, 1 << blkbits); end = round_down((offset + len), 1 << blkbits); @@ -4608,7 +4609,8 @@ * disk in case of crash before zeroing trans is committed. */ if (ext4_should_journal_data(inode)) { - ret = filemap_write_and_wait_range(mapping, start, end); + ret = filemap_write_and_wait_range(mapping, start, + end - 1); if (ret) { filemap_invalidate_unlock(mapping); goto out_mutex; diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/mballoc.c linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/mballoc.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/mballoc.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/mballoc.c @@ -6928,11 +6928,16 @@ static ext4_grpblk_t ext4_last_grp_cluster(struct super_block *sb, ext4_group_t grp) { - if (grp < ext4_get_groups_count(sb)) - return EXT4_CLUSTERS_PER_GROUP(sb) - 1; - return (ext4_blocks_count(EXT4_SB(sb)->s_es) - - ext4_group_first_block_no(sb, grp) - 1) >> - EXT4_CLUSTER_BITS(sb); + unsigned long nr_clusters_in_group; + + if (grp < (ext4_get_groups_count(sb) - 1)) + nr_clusters_in_group = EXT4_CLUSTERS_PER_GROUP(sb); + else + nr_clusters_in_group = (ext4_blocks_count(EXT4_SB(sb)->s_es) - + ext4_group_first_block_no(sb, grp)) + >> EXT4_CLUSTER_BITS(sb); + + return nr_clusters_in_group - 1; } static bool ext4_trim_interrupted(void) @@ -6946,13 +6951,15 @@ __acquires(ext4_group_lock_ptr(sb, e4b->bd_group)) __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) { - ext4_grpblk_t next, count, free_count; + ext4_grpblk_t next, count, free_count, last, origin_start; bool set_trimmed = false; void *bitmap; + last = ext4_last_grp_cluster(sb, e4b->bd_group); bitmap = e4b->bd_bitmap; - if (start == 0 && max >= ext4_last_grp_cluster(sb, e4b->bd_group)) + if (start == 0 && max >= last) set_trimmed = true; + origin_start = start; start = max(e4b->bd_info->bb_first_free, start); count = 0; free_count = 0; @@ -6961,7 +6968,10 @@ start = mb_find_next_zero_bit(bitmap, max + 1, start); if (start > max) break; - next = mb_find_next_bit(bitmap, max + 1, start); + + next = mb_find_next_bit(bitmap, last + 1, start); + if (origin_start == 0 && next >= last) + set_trimmed = true; if ((next - start) >= minblocks) { int ret = ext4_trim_extent(sb, start, next - start, e4b); diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/resize.c linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/resize.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/resize.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/ext4/resize.c @@ -231,17 +231,24 @@ in the flex group */ __u16 *bg_flags; /* block group flags of groups in @groups */ + ext4_group_t resize_bg; /* number of allocated + new_group_data */ ext4_group_t count; /* number of groups in @groups */ }; /* + * Avoiding memory allocation failures due to too many groups added each time. + */ +#define MAX_RESIZE_BG 16384 + +/* * alloc_flex_gd() allocates a ext4_new_flex_group_data with size of * @flexbg_size. * * Returns NULL on failure otherwise address of the allocated structure. */ -static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned long flexbg_size) +static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned int flexbg_size) { struct ext4_new_flex_group_data *flex_gd; @@ -249,17 +256,18 @@ if (flex_gd == NULL) goto out3; - if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_group_data)) - goto out2; - flex_gd->count = flexbg_size; + if (unlikely(flexbg_size > MAX_RESIZE_BG)) + flex_gd->resize_bg = MAX_RESIZE_BG; + else + flex_gd->resize_bg = flexbg_size; - flex_gd->groups = kmalloc_array(flexbg_size, + flex_gd->groups = kmalloc_array(flex_gd->resize_bg, sizeof(struct ext4_new_group_data), GFP_NOFS); if (flex_gd->groups == NULL) goto out2; - flex_gd->bg_flags = kmalloc_array(flexbg_size, sizeof(__u16), + flex_gd->bg_flags = kmalloc_array(flex_gd->resize_bg, sizeof(__u16), GFP_NOFS); if (flex_gd->bg_flags == NULL) goto out1; @@ -296,7 +304,7 @@ */ static int ext4_alloc_group_tables(struct super_block *sb, struct ext4_new_flex_group_data *flex_gd, - int flexbg_size) + unsigned int flexbg_size) { struct ext4_new_group_data *group_data = flex_gd->groups; ext4_fsblk_t start_blk; @@ -397,12 +405,12 @@ group = group_data[0].group; printk(KERN_DEBUG "EXT4-fs: adding a flex group with " - "%d groups, flexbg size is %d:\n", flex_gd->count, + "%u groups, flexbg size is %u:\n", flex_gd->count, flexbg_size); for (i = 0; i < flex_gd->count; i++) { ext4_debug( - "adding %s group %u: %u blocks (%d free, %d mdata blocks)\n", + "adding %s group %u: %u blocks (%u free, %u mdata blocks)\n", ext4_bg_has_super(sb, group + i) ? "normal" : "no-super", group + i, group_data[i].blocks_count, @@ -1622,8 +1630,7 @@ static int ext4_setup_next_flex_gd(struct super_block *sb, struct ext4_new_flex_group_data *flex_gd, - ext4_fsblk_t n_blocks_count, - unsigned long flexbg_size) + ext4_fsblk_t n_blocks_count) { struct ext4_sb_info *sbi = EXT4_SB(sb); struct ext4_super_block *es = sbi->s_es; @@ -1647,7 +1654,7 @@ BUG_ON(last); ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &last); - last_group = group | (flexbg_size - 1); + last_group = group | (flex_gd->resize_bg - 1); if (last_group > n_group) last_group = n_group; @@ -2007,8 +2014,9 @@ ext4_fsblk_t o_blocks_count; ext4_fsblk_t n_blocks_count_retry = 0; unsigned long last_update_time = 0; - int err = 0, flexbg_size = 1 << sbi->s_log_groups_per_flex; + int err = 0; int meta_bg; + unsigned int flexbg_size = ext4_flex_bg_size(sbi); /* See if the device is actually as big as what was requested */ bh = ext4_sb_bread(sb, n_blocks_count - 1, 0); @@ -2149,8 +2157,7 @@ /* Add flex groups. Note that a regular group is a * flex group with 1 group. */ - while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count, - flexbg_size)) { + while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count)) { if (time_is_before_jiffies(last_update_time + HZ * 10)) { if (last_update_time) ext4_msg(sb, KERN_INFO, diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/compress.c linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/compress.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/compress.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/compress.c @@ -1034,8 +1034,10 @@ int i; for (i = 0; i < cc->cluster_size; i++) - if (cc->rpages[i]) + if (cc->rpages[i]) { set_page_dirty(cc->rpages[i]); + set_page_private_gcing(cc->rpages[i]); + } } static int prepare_compress_overwrite(struct compress_ctx *cc, diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/data.c linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/data.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/data.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/data.c @@ -2565,9 +2565,6 @@ page = fio->compressed_page ? fio->compressed_page : fio->page; - /* wait for GCed page writeback via META_MAPPING */ - f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); - if (fscrypt_inode_uses_inline_crypto(inode)) return 0; @@ -2749,6 +2746,10 @@ goto out_writepage; } + /* wait for GCed page writeback via META_MAPPING */ + if (fio->post_read) + f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); + /* * If current allocation needs SSR, * it had better in-place writes for updated data. diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/file.c linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/file.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/file.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/file.c @@ -42,7 +42,7 @@ vm_fault_t ret; ret = filemap_fault(vmf); - if (!ret) + if (ret & VM_FAULT_LOCKED) f2fs_update_iostat(F2FS_I_SB(inode), inode, APP_MAPPED_READ_IO, F2FS_BLKSIZE); @@ -1317,6 +1317,7 @@ } memcpy_page(pdst, 0, psrc, 0, PAGE_SIZE); set_page_dirty(pdst); + set_page_private_gcing(pdst); f2fs_put_page(pdst, 1); f2fs_put_page(psrc, 1); @@ -2818,6 +2819,11 @@ goto out; } + if (f2fs_compressed_file(src) || f2fs_compressed_file(dst)) { + ret = -EOPNOTSUPP; + goto out_unlock; + } + ret = -EINVAL; if (pos_in + len > src->i_size || pos_in + len < pos_in) goto out_unlock; @@ -4054,6 +4060,7 @@ f2fs_bug_on(F2FS_I_SB(inode), !page); set_page_dirty(page); + set_page_private_gcing(page); f2fs_put_page(page, 1); f2fs_put_page(page, 0); } diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/node.c linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/node.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/node.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/node.c @@ -2751,11 +2751,11 @@ f2fs_update_inode_page(inode); /* 3: update and set xattr node page dirty */ - if (page) + if (page) { memcpy(F2FS_NODE(xpage), F2FS_NODE(page), VALID_XATTR_BLOCK_SIZE); - - set_page_dirty(xpage); + set_page_dirty(xpage); + } f2fs_put_page(xpage, 1); return 0; diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/recovery.c linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/recovery.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/recovery.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/recovery.c @@ -712,7 +712,16 @@ */ if (dest == NEW_ADDR) { f2fs_truncate_data_blocks_range(&dn, 1); - f2fs_reserve_new_block(&dn); + do { + err = f2fs_reserve_new_block(&dn); + if (err == -ENOSPC) { + f2fs_bug_on(sbi, 1); + break; + } + } while (err && + IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)); + if (err) + goto err; continue; } @@ -720,12 +729,14 @@ if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) { if (src == NULL_ADDR) { - err = f2fs_reserve_new_block(&dn); - while (err && - IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)) + do { err = f2fs_reserve_new_block(&dn); - /* We should not get -ENOSPC */ - f2fs_bug_on(sbi, err); + if (err == -ENOSPC) { + f2fs_bug_on(sbi, 1); + break; + } + } while (err && + IS_ENABLED(CONFIG_F2FS_FAULT_INJECTION)); if (err) goto err; } @@ -906,6 +917,8 @@ if (!err && fix_curseg_write_pointer && !f2fs_readonly(sbi->sb) && f2fs_sb_has_blkzoned(sbi)) { err = f2fs_fix_curseg_write_pointer(sbi); + if (!err) + err = f2fs_check_write_pointer(sbi); ret = err; } diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/xattr.c linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/xattr.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/xattr.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/f2fs/xattr.c @@ -660,11 +660,14 @@ here = __find_xattr(base_addr, last_base_addr, NULL, index, len, name); if (!here) { if (!F2FS_I(inode)->i_xattr_nid) { + error = f2fs_recover_xattr_data(inode, NULL); f2fs_notice(F2FS_I_SB(inode), - "recover xattr in inode (%lu)", inode->i_ino); - f2fs_recover_xattr_data(inode, NULL); - kfree(base_addr); - goto retry; + "recover xattr in inode (%lu), error(%d)", + inode->i_ino, error); + if (!error) { + kfree(base_addr); + goto retry; + } } f2fs_err(F2FS_I_SB(inode), "set inode (%lu) has corrupted xattr", inode->i_ino); diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/ioctl.c linux-lowlatency-hwe-6.5-6.5.0/fs/ioctl.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/ioctl.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/ioctl.c @@ -920,8 +920,7 @@ if (!f.file) return -EBADF; - /* RED-PEN how should LSM module know it's handling 32bit? */ - error = security_file_ioctl(f.file, cmd, arg); + error = security_file_ioctl_compat(f.file, cmd, arg); if (error) goto out; diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/jfs/jfs_dmap.c linux-lowlatency-hwe-6.5-6.5.0/fs/jfs/jfs_dmap.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/jfs/jfs_dmap.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/jfs/jfs_dmap.c @@ -63,10 +63,10 @@ */ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, int nblocks); -static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval); -static int dbBackSplit(dmtree_t * tp, int leafno); -static int dbJoin(dmtree_t * tp, int leafno, int newval); -static void dbAdjTree(dmtree_t * tp, int leafno, int newval); +static void dbSplit(dmtree_t *tp, int leafno, int splitsz, int newval, bool is_ctl); +static int dbBackSplit(dmtree_t *tp, int leafno, bool is_ctl); +static int dbJoin(dmtree_t *tp, int leafno, int newval, bool is_ctl); +static void dbAdjTree(dmtree_t *tp, int leafno, int newval, bool is_ctl); static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level); static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results); @@ -2103,7 +2103,7 @@ * system. */ if (dp->tree.stree[word] == NOFREE) - dbBackSplit((dmtree_t *) & dp->tree, word); + dbBackSplit((dmtree_t *)&dp->tree, word, false); dbAllocBits(bmp, dp, blkno, nblocks); } @@ -2189,7 +2189,7 @@ * the binary system of the leaves if need be. */ dbSplit(tp, word, BUDMIN, - dbMaxBud((u8 *) & dp->wmap[word])); + dbMaxBud((u8 *)&dp->wmap[word]), false); word += 1; } else { @@ -2229,7 +2229,7 @@ * system of the leaves to reflect the current * allocation (size). */ - dbSplit(tp, word, size, NOFREE); + dbSplit(tp, word, size, NOFREE, false); /* get the number of dmap words handled */ nw = BUDSIZE(size, BUDMIN); @@ -2336,7 +2336,7 @@ /* update the leaf for this dmap word. */ rc = dbJoin(tp, word, - dbMaxBud((u8 *) & dp->wmap[word])); + dbMaxBud((u8 *)&dp->wmap[word]), false); if (rc) return rc; @@ -2369,7 +2369,7 @@ /* update the leaf. */ - rc = dbJoin(tp, word, size); + rc = dbJoin(tp, word, size, false); if (rc) return rc; @@ -2521,16 +2521,16 @@ * that it is at the front of a binary buddy system. */ if (oldval == NOFREE) { - rc = dbBackSplit((dmtree_t *) dcp, leafno); + rc = dbBackSplit((dmtree_t *)dcp, leafno, true); if (rc) { release_metapage(mp); return rc; } oldval = dcp->stree[ti]; } - dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval); + dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval, true); } else { - rc = dbJoin((dmtree_t *) dcp, leafno, newval); + rc = dbJoin((dmtree_t *) dcp, leafno, newval, true); if (rc) { release_metapage(mp); return rc; @@ -2561,7 +2561,7 @@ */ if (alloc) { dbJoin((dmtree_t *) dcp, leafno, - oldval); + oldval, true); } else { /* the dbJoin() above might have * caused a larger binary buddy system @@ -2571,9 +2571,9 @@ */ if (dcp->stree[ti] == NOFREE) dbBackSplit((dmtree_t *) - dcp, leafno); + dcp, leafno, true); dbSplit((dmtree_t *) dcp, leafno, - dcp->budmin, oldval); + dcp->budmin, oldval, true); } /* release the buffer and return the error. @@ -2621,7 +2621,7 @@ * * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; */ -static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval) +static void dbSplit(dmtree_t *tp, int leafno, int splitsz, int newval, bool is_ctl) { int budsz; int cursz; @@ -2643,7 +2643,7 @@ while (cursz >= splitsz) { /* update the buddy's leaf with its new value. */ - dbAdjTree(tp, leafno ^ budsz, cursz); + dbAdjTree(tp, leafno ^ budsz, cursz, is_ctl); /* on to the next size and buddy. */ @@ -2655,7 +2655,7 @@ /* adjust the dmap tree to reflect the specified leaf's new * value. */ - dbAdjTree(tp, leafno, newval); + dbAdjTree(tp, leafno, newval, is_ctl); } @@ -2686,7 +2686,7 @@ * * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; */ -static int dbBackSplit(dmtree_t * tp, int leafno) +static int dbBackSplit(dmtree_t *tp, int leafno, bool is_ctl) { int budsz, bud, w, bsz, size; int cursz; @@ -2737,7 +2737,7 @@ * system in two. */ cursz = leaf[bud] - 1; - dbSplit(tp, bud, cursz, cursz); + dbSplit(tp, bud, cursz, cursz, is_ctl); break; } } @@ -2765,7 +2765,7 @@ * * RETURN VALUES: none */ -static int dbJoin(dmtree_t * tp, int leafno, int newval) +static int dbJoin(dmtree_t *tp, int leafno, int newval, bool is_ctl) { int budsz, buddy; s8 *leaf; @@ -2820,12 +2820,12 @@ if (leafno < buddy) { /* leafno is the left buddy. */ - dbAdjTree(tp, buddy, NOFREE); + dbAdjTree(tp, buddy, NOFREE, is_ctl); } else { /* buddy is the left buddy and becomes * leafno. */ - dbAdjTree(tp, leafno, NOFREE); + dbAdjTree(tp, leafno, NOFREE, is_ctl); leafno = buddy; } @@ -2838,7 +2838,7 @@ /* update the leaf value. */ - dbAdjTree(tp, leafno, newval); + dbAdjTree(tp, leafno, newval, is_ctl); return 0; } @@ -2859,15 +2859,20 @@ * * RETURN VALUES: none */ -static void dbAdjTree(dmtree_t * tp, int leafno, int newval) +static void dbAdjTree(dmtree_t *tp, int leafno, int newval, bool is_ctl) { int lp, pp, k; - int max; + int max, size; + + size = is_ctl ? CTLTREESIZE : TREESIZE; /* pick up the index of the leaf for this leafno. */ lp = leafno + le32_to_cpu(tp->dmt_leafidx); + if (WARN_ON_ONCE(lp >= size || lp < 0)) + return; + /* is the current value the same as the old value ? if so, * there is nothing to do. */ diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/jfs/jfs_imap.c linux-lowlatency-hwe-6.5-6.5.0/fs/jfs/jfs_imap.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/jfs/jfs_imap.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/jfs/jfs_imap.c @@ -2179,6 +2179,9 @@ /* get the ag and iag numbers for this iag. */ agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi); + if (agno >= MAXAG || agno < 0) + return -EIO; + iagno = le32_to_cpu(iagp->iagnum); /* check if this is the last free extent within the diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/kernfs/dir.c linux-lowlatency-hwe-6.5-6.5.0/fs/kernfs/dir.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/kernfs/dir.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/kernfs/dir.c @@ -27,7 +27,7 @@ */ static DEFINE_SPINLOCK(kernfs_pr_cont_lock); static char kernfs_pr_cont_buf[PATH_MAX]; /* protected by pr_cont_lock */ -static DEFINE_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */ +static DEFINE_RAW_SPINLOCK(kernfs_idr_lock); /* root->ino_idr */ #define rb_to_kn(X) rb_entry((X), struct kernfs_node, rb) @@ -539,6 +539,7 @@ { struct kernfs_node *parent; struct kernfs_root *root; + unsigned long flags; if (!kn || !atomic_dec_and_test(&kn->count)) return; @@ -563,9 +564,9 @@ simple_xattrs_free(&kn->iattr->xattrs); kmem_cache_free(kernfs_iattrs_cache, kn->iattr); } - spin_lock(&kernfs_idr_lock); + raw_spin_lock_irqsave(&kernfs_idr_lock, flags); idr_remove(&root->ino_idr, (u32)kernfs_ino(kn)); - spin_unlock(&kernfs_idr_lock); + raw_spin_unlock_irqrestore(&kernfs_idr_lock, flags); kmem_cache_free(kernfs_node_cache, kn); kn = parent; @@ -607,6 +608,7 @@ struct kernfs_node *kn; u32 id_highbits; int ret; + unsigned long irqflags; name = kstrdup_const(name, GFP_KERNEL); if (!name) @@ -617,13 +619,13 @@ goto err_out1; idr_preload(GFP_KERNEL); - spin_lock(&kernfs_idr_lock); + raw_spin_lock_irqsave(&kernfs_idr_lock, irqflags); ret = idr_alloc_cyclic(&root->ino_idr, kn, 1, 0, GFP_ATOMIC); if (ret >= 0 && ret < root->last_id_lowbits) root->id_highbits++; id_highbits = root->id_highbits; root->last_id_lowbits = ret; - spin_unlock(&kernfs_idr_lock); + raw_spin_unlock_irqrestore(&kernfs_idr_lock, irqflags); idr_preload_end(); if (ret < 0) goto err_out2; @@ -659,9 +661,9 @@ return kn; err_out3: - spin_lock(&kernfs_idr_lock); + raw_spin_lock_irqsave(&kernfs_idr_lock, irqflags); idr_remove(&root->ino_idr, (u32)kernfs_ino(kn)); - spin_unlock(&kernfs_idr_lock); + raw_spin_unlock_irqrestore(&kernfs_idr_lock, irqflags); err_out2: kmem_cache_free(kernfs_node_cache, kn); err_out1: @@ -676,6 +678,18 @@ { struct kernfs_node *kn; + if (parent->mode & S_ISGID) { + /* this code block imitates inode_init_owner() for + * kernfs + */ + + if (parent->iattr) + gid = parent->iattr->ia_gid; + + if (flags & KERNFS_DIR) + mode |= S_ISGID; + } + kn = __kernfs_new_node(kernfs_root(parent), parent, name, mode, uid, gid, flags); if (kn) { @@ -702,8 +716,9 @@ struct kernfs_node *kn; ino_t ino = kernfs_id_ino(id); u32 gen = kernfs_id_gen(id); + unsigned long flags; - spin_lock(&kernfs_idr_lock); + raw_spin_lock_irqsave(&kernfs_idr_lock, flags); kn = idr_find(&root->ino_idr, (u32)ino); if (!kn) @@ -727,10 +742,10 @@ if (unlikely(!__kernfs_active(kn) || !atomic_inc_not_zero(&kn->count))) goto err_unlock; - spin_unlock(&kernfs_idr_lock); + raw_spin_unlock_irqrestore(&kernfs_idr_lock, flags); return kn; err_unlock: - spin_unlock(&kernfs_idr_lock); + raw_spin_unlock_irqrestore(&kernfs_idr_lock, flags); return NULL; } diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/namei.c linux-lowlatency-hwe-6.5-6.5.0/fs/namei.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/namei.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/namei.c @@ -3021,20 +3021,14 @@ p = d_ancestor(p2, p1); if (p) { inode_lock_nested(p2->d_inode, I_MUTEX_PARENT); - inode_lock_nested(p1->d_inode, I_MUTEX_CHILD); + inode_lock_nested(p1->d_inode, I_MUTEX_PARENT2); return p; } p = d_ancestor(p1, p2); - if (p) { - inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); - inode_lock_nested(p2->d_inode, I_MUTEX_CHILD); - return p; - } - - lock_two_inodes(p1->d_inode, p2->d_inode, - I_MUTEX_PARENT, I_MUTEX_PARENT2); - return NULL; + inode_lock_nested(p1->d_inode, I_MUTEX_PARENT); + inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2); + return p; } /* @@ -4733,11 +4727,12 @@ * * a) we can get into loop creation. * b) race potential - two innocent renames can create a loop together. - * That's where 4.4 screws up. Current fix: serialization on + * That's where 4.4BSD screws up. Current fix: serialization on * sb->s_vfs_rename_mutex. We might be more accurate, but that's another * story. - * c) we have to lock _four_ objects - parents and victim (if it exists), - * and source. + * c) we may have to lock up to _four_ objects - parents and victim (if it exists), + * and source (if it's a non-directory or a subdirectory that moves to + * different parent). * And that - after we got ->i_mutex on parents (until then we don't know * whether the target exists). Solution: try to be smart with locking * order for inodes. We rely on the fact that tree topology may change @@ -4769,6 +4764,7 @@ bool new_is_dir = false; unsigned max_links = new_dir->i_sb->s_max_links; struct name_snapshot old_name; + bool lock_old_subdir, lock_new_subdir; if (source == target) return 0; @@ -4822,15 +4818,32 @@ take_dentry_name_snapshot(&old_name, old_dentry); dget(new_dentry); /* - * Lock all moved children. Moved directories may need to change parent - * pointer so they need the lock to prevent against concurrent - * directory changes moving parent pointer. For regular files we've - * historically always done this. The lockdep locking subclasses are - * somewhat arbitrary but RENAME_EXCHANGE in particular can swap - * regular files and directories so it's difficult to tell which - * subclasses to use. + * Lock children. + * The source subdirectory needs to be locked on cross-directory + * rename or cross-directory exchange since its parent changes. + * The target subdirectory needs to be locked on cross-directory + * exchange due to parent change and on any rename due to becoming + * a victim. + * Non-directories need locking in all cases (for NFS reasons); + * they get locked after any subdirectories (in inode address order). + * + * NOTE: WE ONLY LOCK UNRELATED DIRECTORIES IN CROSS-DIRECTORY CASE. + * NEVER, EVER DO THAT WITHOUT ->s_vfs_rename_mutex. */ - lock_two_inodes(source, target, I_MUTEX_NORMAL, I_MUTEX_NONDIR2); + lock_old_subdir = new_dir != old_dir; + lock_new_subdir = new_dir != old_dir || !(flags & RENAME_EXCHANGE); + if (is_dir) { + if (lock_old_subdir) + inode_lock_nested(source, I_MUTEX_CHILD); + if (target && (!new_is_dir || lock_new_subdir)) + inode_lock(target); + } else if (new_is_dir) { + if (lock_new_subdir) + inode_lock_nested(target, I_MUTEX_CHILD); + inode_lock(source); + } else { + lock_two_nondirectories(source, target); + } error = -EPERM; if (IS_SWAPFILE(source) || (target && IS_SWAPFILE(target))) @@ -4878,8 +4891,9 @@ d_exchange(old_dentry, new_dentry); } out: - inode_unlock(source); - if (target) + if (!is_dir || lock_old_subdir) + inode_unlock(source); + if (target && (!new_is_dir || lock_new_subdir)) inode_unlock(target); dput(new_dentry); if (!error) { diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/dir.c linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/dir.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/dir.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/dir.c @@ -2961,7 +2961,7 @@ rcu_read_lock(); for (;;) { parent = rcu_dereference(task->real_parent); - pcred = rcu_dereference(parent->cred); + pcred = __task_cred(parent); if (parent == task || cred_fscmp(pcred, cred) != 0) break; task = parent; diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/direct.c linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/direct.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/direct.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/direct.c @@ -205,9 +205,10 @@ kref_put(&dreq->kref, nfs_direct_req_free); } -ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq) +ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset) { - return dreq->bytes_left; + loff_t start = offset - dreq->io_start; + return dreq->max_count - start; } EXPORT_SYMBOL_GPL(nfs_dreq_bytes_left); diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/internal.h linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/internal.h --- linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/internal.h +++ linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/internal.h @@ -655,7 +655,7 @@ /* direct.c */ void nfs_init_cinfo_from_dreq(struct nfs_commit_info *cinfo, struct nfs_direct_req *dreq); -extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq); +extern ssize_t nfs_dreq_bytes_left(struct nfs_direct_req *dreq, loff_t offset); /* nfs4proc.c */ extern struct nfs_client *nfs4_init_client(struct nfs_client *clp, diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/nfs4proc.c linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/nfs4proc.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/nfs4proc.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/nfs4proc.c @@ -169,6 +169,7 @@ case -NFS4ERR_RESOURCE: case -NFS4ERR_LAYOUTTRYLATER: case -NFS4ERR_RECALLCONFLICT: + case -NFS4ERR_RETURNCONFLICT: return -EREMOTEIO; case -NFS4ERR_WRONGSEC: case -NFS4ERR_WRONG_CRED: @@ -557,6 +558,7 @@ case -NFS4ERR_GRACE: case -NFS4ERR_LAYOUTTRYLATER: case -NFS4ERR_RECALLCONFLICT: + case -NFS4ERR_RETURNCONFLICT: exception->delay = 1; return 0; @@ -9662,6 +9664,7 @@ status = -EBUSY; break; case -NFS4ERR_RECALLCONFLICT: + case -NFS4ERR_RETURNCONFLICT: status = -ERECALLCONFLICT; break; case -NFS4ERR_DELEG_REVOKED: diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/pnfs.c linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/pnfs.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/pnfs.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/nfs/pnfs.c @@ -2729,7 +2729,8 @@ if (pgio->pg_dreq == NULL) rd_size = i_size_read(pgio->pg_inode) - req_offset(req); else - rd_size = nfs_dreq_bytes_left(pgio->pg_dreq); + rd_size = nfs_dreq_bytes_left(pgio->pg_dreq, + req_offset(req)); pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, nfs_req_openctx(req), diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/nfsd/nfs4state.c linux-lowlatency-hwe-6.5-6.5.0/fs/nfsd/nfs4state.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/nfsd/nfs4state.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/nfsd/nfs4state.c @@ -7833,14 +7833,16 @@ { struct file_lock *fl; int status = false; - struct nfsd_file *nf = find_any_file(fp); + struct nfsd_file *nf; struct inode *inode; struct file_lock_context *flctx; + spin_lock(&fp->fi_lock); + nf = find_any_file_locked(fp); if (!nf) { /* Any valid lock stateid should have some sort of access */ WARN_ON_ONCE(1); - return status; + goto out; } inode = file_inode(nf->nf_file); @@ -7856,7 +7858,8 @@ } spin_unlock(&flctx->flc_lock); } - nfsd_file_put(nf); +out: + spin_unlock(&fp->fi_lock); return status; } @@ -7866,10 +7869,8 @@ * @cstate: NFSv4 COMPOUND state * @u: RELEASE_LOCKOWNER arguments * - * The lockowner's so_count is bumped when a lock record is added - * or when copying a conflicting lock. The latter case is brief, - * but can lead to fleeting false positives when looking for - * locks-in-use. + * Check if theree are any locks still held and if not - free the lockowner + * and any lock state that is owned. * * Return values: * %nfs_ok: lockowner released or not found @@ -7905,10 +7906,13 @@ spin_unlock(&clp->cl_lock); return nfs_ok; } - if (atomic_read(&lo->lo_owner.so_count) != 2) { - spin_unlock(&clp->cl_lock); - nfs4_put_stateowner(&lo->lo_owner); - return nfserr_locks_held; + + list_for_each_entry(stp, &lo->lo_owner.so_stateids, st_perstateowner) { + if (check_for_locks(stp->st_stid.sc_file, lo)) { + spin_unlock(&clp->cl_lock); + nfs4_put_stateowner(&lo->lo_owner); + return nfserr_locks_held; + } } unhash_lockowner_locked(lo); while (!list_empty(&lo->lo_owner.so_stateids)) { diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/pstore/ram_core.c linux-lowlatency-hwe-6.5-6.5.0/fs/pstore/ram_core.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/pstore/ram_core.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/pstore/ram_core.c @@ -191,7 +191,7 @@ { int numerr; struct persistent_ram_buffer *buffer = prz->buffer; - int ecc_blocks; + size_t ecc_blocks; size_t ecc_total; if (!ecc_info || !ecc_info->ecc_size) diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifs_debug.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifs_debug.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifs_debug.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifs_debug.c @@ -138,6 +138,11 @@ { struct TCP_Server_Info *server = chan->server; + if (!server) { + seq_printf(m, "\n\n\t\tChannel: %d DISABLED", i+1); + return; + } + seq_printf(m, "\n\n\t\tChannel: %d ConnectionId: 0x%llx" "\n\t\tNumber of credits: %d,%d,%d Dialect 0x%x" "\n\t\tTCP status: %d Instance: %d" diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifsglob.h linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifsglob.h --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifsglob.h +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifsglob.h @@ -633,6 +633,7 @@ bool noautotune; /* do not autotune send buf sizes */ bool nosharesock; bool tcp_nodelay; + bool terminate; unsigned int credits; /* send no more requests at once */ unsigned int max_credits; /* can override large 32000 default at mnt */ unsigned int in_flight; /* number of requests on the wire to server */ @@ -1034,6 +1035,7 @@ spinlock_t chan_lock; /* ========= begin: protected by chan_lock ======== */ #define CIFS_MAX_CHANNELS 16 +#define CIFS_INVAL_CHAN_INDEX (-1) #define CIFS_ALL_CHANNELS_SET(ses) \ ((1UL << (ses)->chan_count) - 1) #define CIFS_ALL_CHANS_GOOD(ses) \ diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifsproto.h linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifsproto.h --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifsproto.h +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/cifsproto.h @@ -132,6 +132,7 @@ struct smb_hdr *in_buf, struct smb_hdr *out_buf, int *bytes_returned); + void cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server, bool all_channels); @@ -611,13 +612,13 @@ struct cifs_chan * cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server); -int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses); +int cifs_try_adding_channels(struct cifs_ses *ses); bool is_server_using_iface(struct TCP_Server_Info *server, struct cifs_server_iface *iface); bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface); void cifs_ses_mark_for_reconnect(struct cifs_ses *ses); -unsigned int +int cifs_ses_get_chan_index(struct cifs_ses *ses, struct TCP_Server_Info *server); void @@ -641,6 +642,8 @@ bool cifs_chan_is_iface_active(struct cifs_ses *ses, struct TCP_Server_Info *server); +void +cifs_disable_secondary_channels(struct cifs_ses *ses); int cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server); int diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/connect.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/connect.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/connect.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/connect.c @@ -128,6 +128,9 @@ */ rc = SMB3_request_interfaces(0, tcon, false); if (rc) { + if (rc == -EOPNOTSUPP) + return; + cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n", __func__, rc); } @@ -169,8 +172,12 @@ list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { spin_lock(&ses->chan_lock); for (i = 0; i < ses->chan_count; i++) { + if (!ses->chans[i].server) + continue; + spin_lock(&ses->chans[i].server->srv_lock); - ses->chans[i].server->tcpStatus = CifsNeedReconnect; + if (ses->chans[i].server->tcpStatus != CifsExiting) + ses->chans[i].server->tcpStatus = CifsNeedReconnect; spin_unlock(&ses->chans[i].server->srv_lock); } spin_unlock(&ses->chan_lock); @@ -205,6 +212,18 @@ /* If server is a channel, select the primary channel */ pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server; + /* + * if the server has been marked for termination, there is a + * chance that the remaining channels all need reconnect. To be + * on the safer side, mark the session and trees for reconnect + * for this scenario. This might cause a few redundant session + * setup and tree connect requests, but it is better than not doing + * a tree connect when needed, and all following requests failing + */ + if (server->terminate) { + mark_smb_session = true; + server = pserver; + } spin_lock(&cifs_tcp_ses_lock); list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) { @@ -245,6 +264,8 @@ spin_lock(&tcon->tc_lock); tcon->status = TID_NEED_RECON; spin_unlock(&tcon->tc_lock); + + cancel_delayed_work(&tcon->query_interfaces); } if (ses->tcon_ipc) { ses->tcon_ipc->need_reconnect = true; @@ -384,7 +405,13 @@ spin_unlock(&server->srv_lock); cifs_swn_reset_server_dstaddr(server); cifs_server_unlock(server); - mod_delayed_work(cifsiod_wq, &server->reconnect, 0); + + /* increase ref count which reconnect work will drop */ + spin_lock(&cifs_tcp_ses_lock); + server->srv_count++; + spin_unlock(&cifs_tcp_ses_lock); + if (mod_delayed_work(cifsiod_wq, &server->reconnect, 0)) + cifs_put_tcp_session(server, false); } } while (server->tcpStatus == CifsNeedReconnect); @@ -514,7 +541,13 @@ spin_unlock(&server->srv_lock); cifs_swn_reset_server_dstaddr(server); cifs_server_unlock(server); - mod_delayed_work(cifsiod_wq, &server->reconnect, 0); + + /* increase ref count which reconnect work will drop */ + spin_lock(&cifs_tcp_ses_lock); + server->srv_count++; + spin_unlock(&cifs_tcp_ses_lock); + if (mod_delayed_work(cifsiod_wq, &server->reconnect, 0)) + cifs_put_tcp_session(server, false); } while (server->tcpStatus == CifsNeedReconnect); mutex_lock(&server->refpath_lock); @@ -1595,22 +1628,25 @@ list_del_init(&server->tcp_ses_list); spin_unlock(&cifs_tcp_ses_lock); - /* For secondary channels, we pick up ref-count on the primary server */ - if (CIFS_SERVER_IS_CHAN(server)) - cifs_put_tcp_session(server->primary_server, from_reconnect); - cancel_delayed_work_sync(&server->echo); - if (from_reconnect) + if (from_reconnect) { /* * Avoid deadlock here: reconnect work calls * cifs_put_tcp_session() at its end. Need to be sure * that reconnect work does nothing with server pointer after * that step. */ - cancel_delayed_work(&server->reconnect); - else - cancel_delayed_work_sync(&server->reconnect); + if (cancel_delayed_work(&server->reconnect)) + cifs_put_tcp_session(server, from_reconnect); + } else { + if (cancel_delayed_work_sync(&server->reconnect)) + cifs_put_tcp_session(server, from_reconnect); + } + + /* For secondary channels, we pick up ref-count on the primary server */ + if (CIFS_SERVER_IS_CHAN(server)) + cifs_put_tcp_session(server->primary_server, from_reconnect); spin_lock(&server->srv_lock); server->tcpStatus = CifsExiting; @@ -3585,7 +3621,7 @@ ctx->prepath = NULL; out: - cifs_try_adding_channels(cifs_sb, mnt_ctx.ses); + cifs_try_adding_channels(mnt_ctx.ses); rc = mount_setup_tlink(cifs_sb, mnt_ctx.ses, mnt_ctx.tcon); if (rc) goto error; diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/sess.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/sess.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/sess.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/sess.c @@ -24,7 +24,7 @@ #include "fs_context.h" static int -cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, +cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface); bool @@ -69,7 +69,7 @@ /* channel helper functions. assumed that chan_lock is held by caller. */ -unsigned int +int cifs_ses_get_chan_index(struct cifs_ses *ses, struct TCP_Server_Info *server) { @@ -85,14 +85,17 @@ cifs_dbg(VFS, "unable to get chan index for server: 0x%llx", server->conn_id); WARN_ON(1); - return 0; + return CIFS_INVAL_CHAN_INDEX; } void cifs_chan_set_in_reconnect(struct cifs_ses *ses, struct TCP_Server_Info *server) { - unsigned int chan_index = cifs_ses_get_chan_index(ses, server); + int chan_index = cifs_ses_get_chan_index(ses, server); + + if (chan_index == CIFS_INVAL_CHAN_INDEX) + return; ses->chans[chan_index].in_reconnect = true; } @@ -102,6 +105,8 @@ struct TCP_Server_Info *server) { unsigned int chan_index = cifs_ses_get_chan_index(ses, server); + if (chan_index == CIFS_INVAL_CHAN_INDEX) + return; ses->chans[chan_index].in_reconnect = false; } @@ -111,6 +116,8 @@ struct TCP_Server_Info *server) { unsigned int chan_index = cifs_ses_get_chan_index(ses, server); + if (chan_index == CIFS_INVAL_CHAN_INDEX) + return true; /* err on the safer side */ return CIFS_CHAN_IN_RECONNECT(ses, chan_index); } @@ -120,6 +127,8 @@ struct TCP_Server_Info *server) { unsigned int chan_index = cifs_ses_get_chan_index(ses, server); + if (chan_index == CIFS_INVAL_CHAN_INDEX) + return; set_bit(chan_index, &ses->chans_need_reconnect); cifs_dbg(FYI, "Set reconnect bitmask for chan %u; now 0x%lx\n", @@ -131,6 +140,8 @@ struct TCP_Server_Info *server) { unsigned int chan_index = cifs_ses_get_chan_index(ses, server); + if (chan_index == CIFS_INVAL_CHAN_INDEX) + return; clear_bit(chan_index, &ses->chans_need_reconnect); cifs_dbg(FYI, "Cleared reconnect bitmask for chan %u; now 0x%lx\n", @@ -142,6 +153,8 @@ struct TCP_Server_Info *server) { unsigned int chan_index = cifs_ses_get_chan_index(ses, server); + if (chan_index == CIFS_INVAL_CHAN_INDEX) + return true; /* err on the safer side */ return CIFS_CHAN_NEEDS_RECONNECT(ses, chan_index); } @@ -151,13 +164,15 @@ struct TCP_Server_Info *server) { unsigned int chan_index = cifs_ses_get_chan_index(ses, server); + if (chan_index == CIFS_INVAL_CHAN_INDEX) + return true; /* err on the safer side */ return ses->chans[chan_index].iface && ses->chans[chan_index].iface->is_active; } /* returns number of channels added */ -int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses) +int cifs_try_adding_channels(struct cifs_ses *ses) { struct TCP_Server_Info *server = ses->server; int old_chan_count, new_chan_count; @@ -240,7 +255,7 @@ kref_get(&iface->refcount); spin_unlock(&ses->iface_lock); - rc = cifs_ses_add_channel(cifs_sb, ses, iface); + rc = cifs_ses_add_channel(ses, iface); spin_lock(&ses->iface_lock); if (rc) { @@ -276,6 +291,64 @@ } /* + * called when multichannel is disabled by the server. + * this always gets called from smb2_reconnect + * and cannot get called in parallel threads. + */ +void +cifs_disable_secondary_channels(struct cifs_ses *ses) +{ + int i, chan_count; + struct TCP_Server_Info *server; + struct cifs_server_iface *iface; + + spin_lock(&ses->chan_lock); + chan_count = ses->chan_count; + if (chan_count == 1) + goto done; + + ses->chan_count = 1; + + /* for all secondary channels reset the need reconnect bit */ + ses->chans_need_reconnect &= 1; + + for (i = 1; i < chan_count; i++) { + iface = ses->chans[i].iface; + server = ses->chans[i].server; + + /* + * remove these references first, since we need to unlock + * the chan_lock here, since iface_lock is a higher lock + */ + ses->chans[i].iface = NULL; + ses->chans[i].server = NULL; + spin_unlock(&ses->chan_lock); + + if (iface) { + spin_lock(&ses->iface_lock); + kref_put(&iface->refcount, release_iface); + iface->num_channels--; + if (iface->weight_fulfilled) + iface->weight_fulfilled--; + spin_unlock(&ses->iface_lock); + } + + if (server) { + if (!server->terminate) { + server->terminate = true; + cifs_signal_cifsd_for_reconnect(server, false); + } + cifs_put_tcp_session(server, false); + } + + spin_lock(&ses->chan_lock); + } + +done: + spin_unlock(&ses->chan_lock); +} + +/* * update the iface for the channel if necessary. * will return 0 when iface is updated, 1 if removed, 2 otherwise * Must be called with chan_lock held. @@ -293,7 +366,7 @@ spin_lock(&ses->chan_lock); chan_index = cifs_ses_get_chan_index(ses, server); - if (!chan_index) { + if (chan_index == CIFS_INVAL_CHAN_INDEX) { spin_unlock(&ses->chan_lock); return 0; } @@ -403,6 +476,11 @@ spin_lock(&ses->chan_lock); chan_index = cifs_ses_get_chan_index(ses, server); + if (chan_index == CIFS_INVAL_CHAN_INDEX) { + spin_unlock(&ses->chan_lock); + return 0; + } + ses->chans[chan_index].iface = iface; /* No iface is found. if secondary chan, drop connection */ @@ -438,7 +516,7 @@ } static int -cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, +cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface) { struct TCP_Server_Info *chan_server; @@ -507,7 +585,7 @@ * This will be used for encoding/decoding user/domain/pw * during sess setup auth. */ - ctx.local_nls = cifs_sb->local_nls; + ctx.local_nls = ses->local_nls; /* Use RDMA if possible */ ctx.rdma = iface->rdma_capable; @@ -553,20 +631,16 @@ rc = cifs_negotiate_protocol(xid, ses, chan->server); if (!rc) - rc = cifs_setup_session(xid, ses, chan->server, cifs_sb->local_nls); + rc = cifs_setup_session(xid, ses, chan->server, ses->local_nls); mutex_unlock(&ses->session_mutex); out: if (rc && chan->server) { - /* - * we should avoid race with these delayed works before we - * remove this channel - */ - cancel_delayed_work_sync(&chan->server->echo); - cancel_delayed_work_sync(&chan->server->reconnect); + cifs_put_tcp_session(chan->server, 0); spin_lock(&ses->chan_lock); + /* we rely on all bits beyond chan_count to be clear */ cifs_chan_clear_need_reconnect(ses, chan->server); ses->chan_count--; @@ -576,8 +650,6 @@ */ WARN_ON(ses->chan_count < 1); spin_unlock(&ses->chan_lock); - - cifs_put_tcp_session(chan->server, 0); } free_xid(xid); diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2ops.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2ops.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2ops.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2ops.c @@ -614,7 +614,8 @@ "multichannel not available\n" "Empty network interface list returned by server %s\n", ses->server->hostname); - rc = -EINVAL; + rc = -EOPNOTSUPP; + ses->iface_last_update = jiffies; goto out; } @@ -712,7 +713,6 @@ ses->iface_count++; spin_unlock(&ses->iface_lock); - ses->iface_last_update = jiffies; next_iface: nb_iface++; next = le32_to_cpu(p->Next); @@ -734,11 +734,7 @@ if ((bytes_left > 8) || p->Next) cifs_dbg(VFS, "%s: incomplete interface info\n", __func__); - - if (!ses->iface_count) { - rc = -EINVAL; - goto out; - } + ses->iface_last_update = jiffies; out: /* diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2pdu.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2pdu.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2pdu.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2pdu.c @@ -150,13 +150,64 @@ return; } +/* helper function for code reuse */ +static int +cifs_chan_skip_or_disable(struct cifs_ses *ses, + struct TCP_Server_Info *server, + bool from_reconnect) +{ + struct TCP_Server_Info *pserver; + unsigned int chan_index; + + if (CIFS_SERVER_IS_CHAN(server)) { + cifs_dbg(VFS, + "server %s does not support multichannel anymore. Skip secondary channel\n", + ses->server->hostname); + + spin_lock(&ses->chan_lock); + chan_index = cifs_ses_get_chan_index(ses, server); + if (chan_index == CIFS_INVAL_CHAN_INDEX) { + spin_unlock(&ses->chan_lock); + goto skip_terminate; + } + + ses->chans[chan_index].server = NULL; + spin_unlock(&ses->chan_lock); + + /* + * the above reference of server by channel + * needs to be dropped without holding chan_lock + * as cifs_put_tcp_session takes a higher lock + * i.e. cifs_tcp_ses_lock + */ + cifs_put_tcp_session(server, from_reconnect); + + server->terminate = true; + cifs_signal_cifsd_for_reconnect(server, false); + + /* mark primary server as needing reconnect */ + pserver = server->primary_server; + cifs_signal_cifsd_for_reconnect(pserver, false); +skip_terminate: + return -EHOSTDOWN; + } + + cifs_server_dbg(VFS, + "server does not support multichannel anymore. Disable all other channels\n"); + cifs_disable_secondary_channels(ses); + + + return 0; +} + static int smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon, - struct TCP_Server_Info *server) + struct TCP_Server_Info *server, bool from_reconnect) { int rc = 0; struct nls_table *nls_codepage = NULL; struct cifs_ses *ses; + int xid; /* * SMB2s NegProt, SessSetup, Logoff do not have tcon yet so @@ -217,6 +268,12 @@ return -EAGAIN; } } + + /* if server is marked for termination, cifsd will cleanup */ + if (server->terminate) { + spin_unlock(&server->srv_lock); + return -EHOSTDOWN; + } spin_unlock(&server->srv_lock); again: @@ -236,11 +293,23 @@ mutex_lock(&ses->session_mutex); /* + * if this is called by delayed work, and the channel has been disabled + * in parallel, the delayed work can continue to execute in parallel + * there's a chance that this channel may not exist anymore + */ + spin_lock(&server->srv_lock); + if (server->tcpStatus == CifsExiting) { + spin_unlock(&server->srv_lock); + mutex_unlock(&ses->session_mutex); + rc = -EHOSTDOWN; + goto out; + } + + /* * Recheck after acquire mutex. If another thread is negotiating * and the server never sends an answer the socket will be closed * and tcpStatus set to reconnect. */ - spin_lock(&server->srv_lock); if (server->tcpStatus == CifsNeedReconnect) { spin_unlock(&server->srv_lock); mutex_unlock(&ses->session_mutex); @@ -277,6 +346,20 @@ rc = cifs_negotiate_protocol(0, ses, server); if (!rc) { + /* + * if server stopped supporting multichannel + * and the first channel reconnected, disable all the others. + */ + if (ses->chan_count > 1 && + !(server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) { + rc = cifs_chan_skip_or_disable(ses, server, + from_reconnect); + if (rc) { + mutex_unlock(&ses->session_mutex); + goto out; + } + } + rc = cifs_setup_session(0, ses, server, nls_codepage); if ((rc == -EACCES) && !tcon->retry) { mutex_unlock(&ses->session_mutex); @@ -301,15 +384,54 @@ tcon->need_reopen_files = true; rc = cifs_tree_connect(0, tcon, nls_codepage); - mutex_unlock(&ses->session_mutex); cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc); if (rc) { /* If sess reconnected but tcon didn't, something strange ... */ + mutex_unlock(&ses->session_mutex); cifs_dbg(VFS, "reconnect tcon failed rc = %d\n", rc); goto out; } + if (!rc && + (server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) { + mutex_unlock(&ses->session_mutex); + + /* + * query server network interfaces, in case they change + */ + xid = get_xid(); + rc = SMB3_request_interfaces(xid, tcon, false); + free_xid(xid); + + if (rc == -EOPNOTSUPP) { + /* + * some servers like Azure SMB server do not advertise + * that multichannel has been disabled with server + * capabilities, rather return STATUS_NOT_IMPLEMENTED. + * treat this as server not supporting multichannel + */ + + rc = cifs_chan_skip_or_disable(ses, server, + from_reconnect); + goto skip_add_channels; + } else if (rc) + cifs_dbg(FYI, "%s: failed to query server interfaces: %d\n", + __func__, rc); + + if (ses->chan_max > ses->chan_count && + ses->iface_count && + !CIFS_SERVER_IS_CHAN(server)) { + if (ses->chan_count == 1) + cifs_server_dbg(VFS, "supports multichannel now\n"); + + cifs_try_adding_channels(ses); + } + } else { + mutex_unlock(&ses->session_mutex); + } +skip_add_channels: + if (smb2_command != SMB2_INTERNAL_CMD) mod_delayed_work(cifsiod_wq, &server->reconnect, 0); @@ -403,7 +525,7 @@ { int rc; - rc = smb2_reconnect(smb2_command, tcon, server); + rc = smb2_reconnect(smb2_command, tcon, server, false); if (rc) return rc; @@ -2179,7 +2301,7 @@ noff = le16_to_cpu(cc->NameOffset); nlen = le16_to_cpu(cc->NameLength); - if (noff + nlen >= doff) + if (noff + nlen > doff) return -EINVAL; name = (char *)cc + noff; @@ -3822,12 +3944,28 @@ int rc; bool resched = false; + /* first check if ref count has reached 0, if not inc ref count */ + spin_lock(&cifs_tcp_ses_lock); + if (!server->srv_count) { + spin_unlock(&cifs_tcp_ses_lock); + return; + } + server->srv_count++; + spin_unlock(&cifs_tcp_ses_lock); + /* If server is a channel, select the primary channel */ pserver = CIFS_SERVER_IS_CHAN(server) ? server->primary_server : server; /* Prevent simultaneous reconnects that can corrupt tcon->rlist list */ mutex_lock(&pserver->reconnect_mutex); + /* if the server is marked for termination, drop the ref count here */ + if (server->terminate) { + cifs_put_tcp_session(server, true); + mutex_unlock(&pserver->reconnect_mutex); + return; + } + INIT_LIST_HEAD(&tmp_list); INIT_LIST_HEAD(&tmp_ses_list); cifs_dbg(FYI, "Reconnecting tcons and channels\n"); @@ -3872,17 +4010,11 @@ } spin_unlock(&ses->chan_lock); } - /* - * Get the reference to server struct to be sure that the last call of - * cifs_put_tcon() in the loop below won't release the server pointer. - */ - if (tcon_exist || ses_exist) - server->srv_count++; spin_unlock(&cifs_tcp_ses_lock); list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) { - rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon, server); + rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon, server, true); if (!rc) cifs_reopen_persistent_handles(tcon); else @@ -3915,7 +4047,7 @@ /* now reconnect sessions for necessary channels */ list_for_each_entry_safe(ses, ses2, &tmp_ses_list, rlist) { tcon->ses = ses; - rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon, server); + rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon, server, true); if (rc) resched = true; list_del_init(&ses->rlist); @@ -3925,13 +4057,17 @@ done: cifs_dbg(FYI, "Reconnecting tcons and channels finished\n"); - if (resched) + if (resched) { queue_delayed_work(cifsiod_wq, &server->reconnect, 2 * HZ); + mutex_unlock(&pserver->reconnect_mutex); + + /* no need to put tcp session as we're retrying */ + return; + } mutex_unlock(&pserver->reconnect_mutex); /* now we can safely release srv struct */ - if (tcon_exist || ses_exist) - cifs_put_tcp_session(server, 1); + cifs_put_tcp_session(server, true); } int @@ -3951,7 +4087,12 @@ server->ops->need_neg(server)) { spin_unlock(&server->srv_lock); /* No need to send echo on newly established connections */ - mod_delayed_work(cifsiod_wq, &server->reconnect, 0); + spin_lock(&cifs_tcp_ses_lock); + server->srv_count++; + spin_unlock(&cifs_tcp_ses_lock); + if (mod_delayed_work(cifsiod_wq, &server->reconnect, 0)) + cifs_put_tcp_session(server, false); + return rc; } spin_unlock(&server->srv_lock); diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2transport.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2transport.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2transport.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/smb2transport.c @@ -413,7 +413,13 @@ ses->ses_status == SES_GOOD); chan_index = cifs_ses_get_chan_index(ses, server); - /* TODO: introduce ref counting for channels when the can be freed */ + if (chan_index == CIFS_INVAL_CHAN_INDEX) { + spin_unlock(&ses->chan_lock); + spin_unlock(&ses->ses_lock); + + return -EINVAL; + } + spin_unlock(&ses->chan_lock); spin_unlock(&ses->ses_lock); diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/transport.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/transport.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/transport.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/client/transport.c @@ -1018,7 +1018,7 @@ spin_lock(&ses->chan_lock); for (i = 0; i < ses->chan_count; i++) { server = ses->chans[i].server; - if (!server) + if (!server || server->terminate) continue; /* diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/asn1.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/asn1.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/asn1.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/asn1.c @@ -214,10 +214,15 @@ { struct ksmbd_conn *conn = context; + if (!vlen) + return -EINVAL; + conn->mechToken = kmemdup_nul(value, vlen, GFP_KERNEL); if (!conn->mechToken) return -ENOMEM; + conn->mechTokenLen = (unsigned int)vlen; + return 0; } diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/connection.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/connection.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/connection.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/connection.c @@ -284,6 +284,7 @@ goto out; conn->last_active = jiffies; + set_freezable(); while (ksmbd_conn_alive(conn)) { if (try_to_freeze()) continue; @@ -415,13 +416,7 @@ again: down_read(&conn_list_lock); list_for_each_entry(conn, &conn_list, conns_list) { - struct task_struct *task; - t = conn->transport; - task = t->handler; - if (task) - ksmbd_debug(CONN, "Stop session handler %s/%d\n", - task->comm, task_pid_nr(task)); ksmbd_conn_set_exiting(conn); if (t->ops->shutdown) { up_read(&conn_list_lock); diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/connection.h linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/connection.h --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/connection.h +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/connection.h @@ -88,6 +88,7 @@ __u16 dialect; char *mechToken; + unsigned int mechTokenLen; struct ksmbd_conn_ops *conn_ops; @@ -134,7 +135,6 @@ struct ksmbd_transport { struct ksmbd_conn *conn; struct ksmbd_transport_ops *ops; - struct task_struct *handler; }; #define KSMBD_TCP_RECV_TIMEOUT (7 * HZ) diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/oplock.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/oplock.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/oplock.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/oplock.c @@ -105,7 +105,7 @@ lease->is_dir = lctx->is_dir; memcpy(lease->parent_lease_key, lctx->parent_lease_key, SMB2_LEASE_KEY_SIZE); lease->version = lctx->version; - lease->epoch = le16_to_cpu(lctx->epoch); + lease->epoch = le16_to_cpu(lctx->epoch) + 1; INIT_LIST_HEAD(&opinfo->lease_entry); opinfo->o_lease = lease; @@ -546,6 +546,7 @@ atomic_read(&ci->sop_count)) == 1) { if (lease->state != SMB2_LEASE_NONE_LE && lease->state == (lctx->req_state & lease->state)) { + lease->epoch++; lease->state |= lctx->req_state; if (lctx->req_state & SMB2_LEASE_WRITE_CACHING_LE) @@ -556,13 +557,17 @@ atomic_read(&ci->sop_count)) > 1) { if (lctx->req_state == (SMB2_LEASE_READ_CACHING_LE | - SMB2_LEASE_HANDLE_CACHING_LE)) + SMB2_LEASE_HANDLE_CACHING_LE)) { + lease->epoch++; lease->state = lctx->req_state; + } } if (lctx->req_state && lease->state == - SMB2_LEASE_NONE_LE) + SMB2_LEASE_NONE_LE) { + lease->epoch++; lease_none_upgrade(opinfo, lctx->req_state); + } } read_lock(&ci->m_lock); } @@ -1035,7 +1040,8 @@ SMB2_LEASE_KEY_SIZE); lease2->duration = lease1->duration; lease2->flags = lease1->flags; - lease2->epoch = lease1->epoch++; + lease2->epoch = lease1->epoch; + lease2->version = lease1->version; } static int add_lease_global_list(struct oplock_info *opinfo) @@ -1191,6 +1197,12 @@ bool prev_op_has_lease; __le32 prev_op_state = 0; + /* Only v2 leases handle the directory */ + if (S_ISDIR(file_inode(fp->filp)->i_mode)) { + if (!lctx || lctx->version != 2) + return 0; + } + opinfo = alloc_opinfo(work, pid, tid); if (!opinfo) return -ENOMEM; @@ -1447,7 +1459,7 @@ memcpy(buf->lcontext.LeaseKey, lease->lease_key, SMB2_LEASE_KEY_SIZE); buf->lcontext.LeaseFlags = lease->flags; - buf->lcontext.Epoch = cpu_to_le16(++lease->epoch); + buf->lcontext.Epoch = cpu_to_le16(lease->epoch); buf->lcontext.LeaseState = lease->state; memcpy(buf->lcontext.ParentLeaseKey, lease->parent_lease_key, SMB2_LEASE_KEY_SIZE); diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/smb2pdu.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/smb2pdu.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/smb2pdu.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/smb2pdu.c @@ -1413,7 +1413,10 @@ char *name; unsigned int name_off, name_len, secbuf_len; - secbuf_len = le16_to_cpu(req->SecurityBufferLength); + if (conn->use_spnego && conn->mechToken) + secbuf_len = conn->mechTokenLen; + else + secbuf_len = le16_to_cpu(req->SecurityBufferLength); if (secbuf_len < sizeof(struct authenticate_message)) { ksmbd_debug(SMB, "blob len %d too small\n", secbuf_len); return NULL; @@ -1504,7 +1507,10 @@ struct authenticate_message *authblob; authblob = user_authblob(conn, req); - sz = le16_to_cpu(req->SecurityBufferLength); + if (conn->use_spnego && conn->mechToken) + sz = conn->mechTokenLen; + else + sz = le16_to_cpu(req->SecurityBufferLength); rc = ksmbd_decode_ntlmssp_auth_blob(authblob, sz, conn, sess); if (rc) { set_user_flag(sess->user, KSMBD_USER_FLAG_BAD_PASSWORD); @@ -1777,8 +1783,7 @@ negblob_off = le16_to_cpu(req->SecurityBufferOffset); negblob_len = le16_to_cpu(req->SecurityBufferLength); - if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer) || - negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) { + if (negblob_off < offsetof(struct smb2_sess_setup_req, Buffer)) { rc = -EINVAL; goto out_err; } @@ -1787,8 +1792,15 @@ negblob_off); if (decode_negotiation_token(conn, negblob, negblob_len) == 0) { - if (conn->mechToken) + if (conn->mechToken) { negblob = (struct negotiate_message *)conn->mechToken; + negblob_len = conn->mechTokenLen; + } + } + + if (negblob_len < offsetof(struct negotiate_message, NegotiateFlags)) { + rc = -EINVAL; + goto out_err; } if (server_conf.auth_mechs & conn->auth_mechs) { @@ -2310,11 +2322,12 @@ * @eabuf: set info command buffer * @buf_len: set info command buffer length * @path: dentry path for get ea + * @get_write: get write access to a mount * * Return: 0 on success, otherwise error */ static int smb2_set_ea(struct smb2_ea_info *eabuf, unsigned int buf_len, - const struct path *path) + const struct path *path, bool get_write) { struct mnt_idmap *idmap = mnt_idmap(path->mnt); char *attr_name = NULL, *value; @@ -3002,7 +3015,7 @@ rc = smb2_set_ea(&ea_buf->ea, le32_to_cpu(ea_buf->ccontext.DataLength), - &path); + &path, false); if (rc == -EOPNOTSUPP) rc = 0; else if (rc) @@ -5567,6 +5580,7 @@ if (!file_info->ReplaceIfExists) flags = RENAME_NOREPLACE; + smb_break_all_levII_oplock(work, fp, 0); rc = ksmbd_vfs_rename(work, &fp->filp->f_path, new_name, flags); out: kfree(new_name); @@ -5979,7 +5993,7 @@ return -EINVAL; return smb2_set_ea((struct smb2_ea_info *)req->Buffer, - buf_len, &fp->filp->f_path); + buf_len, &fp->filp->f_path, true); } case FILE_POSITION_INFORMATION: { diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/smb_common.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/smb_common.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/smb_common.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/smb_common.c @@ -158,8 +158,12 @@ */ bool ksmbd_smb_request(struct ksmbd_conn *conn) { - __le32 *proto = (__le32 *)smb2_get_msg(conn->request_buf); + __le32 *proto; + if (conn->request_buf[0] != 0) + return false; + + proto = (__le32 *)smb2_get_msg(conn->request_buf); if (*proto == SMB2_COMPRESSION_TRANSFORM_ID) { pr_err_ratelimited("smb2 compression not support yet"); return false; diff -u linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/transport_rdma.c linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/transport_rdma.c --- linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/transport_rdma.c +++ linux-lowlatency-hwe-6.5-6.5.0/fs/smb/server/transport_rdma.c @@ -2039,6 +2039,7 @@ static int smb_direct_handle_connect_request(struct rdma_cm_id *new_cm_id) { struct smb_direct_transport *t; + struct task_struct *handler; int ret; if (!rdma_frwr_is_supported(&new_cm_id->device->attrs)) { @@ -2056,11 +2057,11 @@ if (ret) goto out_err; - KSMBD_TRANS(t)->handler = kthread_run(ksmbd_conn_handler_loop, - KSMBD_TRANS(t)->conn, "ksmbd:r%u", - smb_direct_port); - if (IS_ERR(KSMBD_TRANS(t)->handler)) { - ret = PTR_ERR(KSMBD_TRANS(t)->handler); + handler = kthread_run(ksmbd_conn_handler_loop, + KSMBD_TRANS(t)->conn, "ksmbd:r%u", + smb_direct_port); + if (IS_ERR(handler)) { + ret = PTR_ERR(handler); pr_err("Can't start thread\n"); goto out_err; } diff -u linux-lowlatency-hwe-6.5-6.5.0/include/acpi/acpi_bus.h linux-lowlatency-hwe-6.5-6.5.0/include/acpi/acpi_bus.h --- linux-lowlatency-hwe-6.5-6.5.0/include/acpi/acpi_bus.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/acpi/acpi_bus.h @@ -12,11 +12,9 @@ #include #include -/* TBD: Make dynamic */ -#define ACPI_MAX_HANDLES 10 struct acpi_handle_list { u32 count; - acpi_handle handles[ACPI_MAX_HANDLES]; + acpi_handle *handles; }; /* acpi_utils.h */ @@ -32,6 +30,11 @@ acpi_string pathname, struct acpi_object_list *arguments, struct acpi_handle_list *list); +bool acpi_handle_list_equal(struct acpi_handle_list *list1, + struct acpi_handle_list *list2); +void acpi_handle_list_replace(struct acpi_handle_list *dst, + struct acpi_handle_list *src); +void acpi_handle_list_free(struct acpi_handle_list *list); acpi_status acpi_evaluate_ost(acpi_handle handle, u32 source_event, u32 status_code, struct acpi_buffer *status_buf); diff -u linux-lowlatency-hwe-6.5-6.5.0/include/drm/drm_file.h linux-lowlatency-hwe-6.5-6.5.0/include/drm/drm_file.h --- linux-lowlatency-hwe-6.5-6.5.0/include/drm/drm_file.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/drm/drm_file.h @@ -229,6 +229,18 @@ bool is_master; /** + * @supports_virtualized_cursor_plane: + * + * This client is capable of handling the cursor plane with the + * restrictions imposed on it by the virtualized drivers. + * + * This implies that the cursor plane has to behave like a cursor + * i.e. track cursor movement. It also requires setting of the + * hotspot properties by the client on the cursor plane. + */ + bool supports_virtualized_cursor_plane; + + /** * @master: * * Master this node is currently associated with. Protected by struct diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/bpf.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/bpf.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/bpf.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/bpf.h @@ -106,7 +106,11 @@ /* funcs called by prog_array and perf_event_array map */ void *(*map_fd_get_ptr)(struct bpf_map *map, struct file *map_file, int fd); - void (*map_fd_put_ptr)(void *ptr); + /* If need_defer is true, the implementation should guarantee that + * the to-be-put element is still alive before the bpf program, which + * may manipulate it, exists. + */ + void (*map_fd_put_ptr)(struct bpf_map *map, void *ptr, bool need_defer); int (*map_gen_lookup)(struct bpf_map *map, struct bpf_insn *insn_buf); u32 (*map_fd_sys_lookup_elem)(void *ptr); void (*map_seq_show_elem)(struct bpf_map *map, void *key, @@ -259,7 +263,11 @@ */ atomic64_t refcnt ____cacheline_aligned; atomic64_t usercnt; - struct work_struct work; + /* rcu is used before freeing and work is only used during freeing */ + union { + struct work_struct work; + struct rcu_head rcu; + }; struct mutex freeze_mutex; atomic64_t writecnt; /* 'Ownership' of program-containing map is claimed by the first program @@ -275,6 +283,8 @@ } owner; bool bypass_spec_v1; bool frozen; /* write-once; write-protected by freeze_mutex */ + bool free_after_mult_rcu_gp; + s64 __percpu *elem_count; }; static inline const char *btf_field_type_name(enum btf_field_type type) @@ -2050,6 +2060,35 @@ } #endif +static inline int +bpf_map_init_elem_count(struct bpf_map *map) +{ + size_t size = sizeof(*map->elem_count), align = size; + gfp_t flags = GFP_USER | __GFP_NOWARN; + + map->elem_count = bpf_map_alloc_percpu(map, size, align, flags); + if (!map->elem_count) + return -ENOMEM; + + return 0; +} + +static inline void +bpf_map_free_elem_count(struct bpf_map *map) +{ + free_percpu(map->elem_count); +} + +static inline void bpf_map_inc_elem_count(struct bpf_map *map) +{ + this_cpu_inc(*map->elem_count); +} + +static inline void bpf_map_dec_elem_count(struct bpf_map *map) +{ + this_cpu_dec(*map->elem_count); +} + extern int sysctl_unprivileged_bpf_disabled; static inline bool bpf_allow_ptr_leaks(void) diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/bpf_verifier.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/bpf_verifier.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/bpf_verifier.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/bpf_verifier.h @@ -300,6 +300,17 @@ bool in_callback_fn; struct tnum callback_ret_range; bool in_async_callback_fn; + /* For callback calling functions that limit number of possible + * callback executions (e.g. bpf_loop) keeps track of current + * simulated iteration number. + * Value in frame N refers to number of times callback with frame + * N+1 was simulated, e.g. for the following call: + * + * bpf_loop(..., fn, ...); | suppose current frame is N + * | fn would be simulated in frame N+1 + * | number of simulations is tracked in frame N + */ + u32 callback_depth; /* The following fields should be last. See copy_func_state() */ int acquired_refs; @@ -372,10 +383,25 @@ struct bpf_active_lock active_lock; bool speculative; bool active_rcu_lock; + /* If this state was ever pointed-to by other state's loop_entry field + * this flag would be set to true. Used to avoid freeing such states + * while they are still in use. + */ + bool used_as_loop_entry; /* first and last insn idx of this verifier state */ u32 first_insn_idx; u32 last_insn_idx; + /* If this state is a part of states loop this field points to some + * parent of this state such that: + * - it is also a member of the same states loop; + * - DFS states traversal starting from initial state visits loop_entry + * state before this state. + * Used to compute topmost loop entry for state loops. + * State loops might appear because of open coded iterators logic. + * See get_loop_entry() for more information. + */ + struct bpf_verifier_state *loop_entry; /* jmp history recorded from first to last. * backtracking is using it to go from last to first. * For most states jmp_history_cnt is [0-3]. @@ -383,6 +409,8 @@ */ struct bpf_idx_pair *jmp_history; u32 jmp_history_cnt; + u32 dfs_depth; + u32 callback_unroll_depth; }; #define bpf_get_spilled_reg(slot, frame) \ @@ -490,6 +518,10 @@ * this instruction, regardless of any heuristics */ bool force_checkpoint; + /* true if instruction is a call to a helper function that + * accepts callback function as a parameter. + */ + bool calls_callback; }; #define MAX_USED_MAPS 64 /* max number of maps accessed by one eBPF program */ diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/clk-provider.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/clk-provider.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/clk-provider.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/clk-provider.h @@ -448,8 +448,8 @@ */ #define clk_hw_register_fixed_rate_with_accuracy_parent_hw(dev, name, \ parent_hw, flags, fixed_rate, fixed_accuracy) \ - __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, (parent_hw) \ - NULL, NULL, (flags), (fixed_rate), \ + __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, (parent_hw), \ + NULL, (flags), (fixed_rate), \ (fixed_accuracy), 0, false) /** * clk_hw_register_fixed_rate_with_accuracy_parent_data - register fixed-rate diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/hisi_acc_qm.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/hisi_acc_qm.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/hisi_acc_qm.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/hisi_acc_qm.h @@ -160,6 +160,11 @@ QM_SUPPORT_RPM, }; +struct qm_dev_alg { + u64 alg_msk; + const char *alg; +}; + struct dfx_diff_registers { u32 *regs; u32 reg_offset; @@ -265,6 +270,16 @@ u32 v3_val; }; +struct hisi_qm_cap_record { + u32 type; + u32 cap_val; +}; + +struct hisi_qm_cap_tables { + struct hisi_qm_cap_record *qm_cap_table; + struct hisi_qm_cap_record *dev_cap_table; +}; + struct hisi_qm_list { struct mutex lock; struct list_head list; @@ -352,7 +367,6 @@ struct work_struct rst_work; struct work_struct cmd_process; - const char *algs; bool use_sva; resource_size_t phys_base; @@ -363,6 +377,8 @@ u32 mb_qos; u32 type_rate; struct qm_err_isolate isolate_data; + + struct hisi_qm_cap_tables cap_tables; }; struct hisi_qp_status { @@ -536,6 +552,8 @@ u32 hisi_qm_get_hw_info(struct hisi_qm *qm, const struct hisi_qm_cap_info *info_table, u32 index, bool is_read); +int hisi_qm_set_algs(struct hisi_qm *qm, u64 alg_msk, const struct qm_dev_alg *dev_algs, + u32 dev_algs_size); /* Used by VFIO ACC live migration driver */ struct pci_driver *hisi_sec_get_pf_driver(void); diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/lsm_hook_defs.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/lsm_hook_defs.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/lsm_hook_defs.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/lsm_hook_defs.h @@ -171,6 +171,8 @@ LSM_HOOK(void, LSM_RET_VOID, file_free_security, struct file *file) LSM_HOOK(int, 0, file_ioctl, struct file *file, unsigned int cmd, unsigned long arg) +LSM_HOOK(int, 0, file_ioctl_compat, struct file *file, unsigned int cmd, + unsigned long arg) LSM_HOOK(int, 0, mmap_addr, unsigned long addr) LSM_HOOK(int, 0, mmap_file, struct file *file, unsigned long reqprot, unsigned long prot, unsigned long flags) diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/mlx5/mlx5_ifc.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/mlx5/mlx5_ifc.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/mlx5/mlx5_ifc.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/mlx5/mlx5_ifc.h @@ -3576,7 +3576,7 @@ u8 action[0x10]; u8 extended_destination[0x1]; - u8 reserved_at_81[0x1]; + u8 uplink_hairpin_en[0x1]; u8 flow_source[0x2]; u8 encrypt_decrypt_type[0x4]; u8 destination_list_size[0x18]; diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/mmzone.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/mmzone.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/mmzone.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/mmzone.h @@ -1775,6 +1775,7 @@ #define SUBSECTION_ALIGN_DOWN(pfn) ((pfn) & PAGE_SUBSECTION_MASK) struct mem_section_usage { + struct rcu_head rcu; #ifdef CONFIG_SPARSEMEM_VMEMMAP DECLARE_BITMAP(subsection_map, SUBSECTIONS_PER_SECTION); #endif @@ -1968,7 +1969,7 @@ { int idx = subsection_map_index(pfn); - return test_bit(idx, ms->usage->subsection_map); + return test_bit(idx, READ_ONCE(ms->usage)->subsection_map); } #else static inline int pfn_section_valid(struct mem_section *ms, unsigned long pfn) @@ -1992,6 +1993,7 @@ static inline int pfn_valid(unsigned long pfn) { struct mem_section *ms; + int ret; /* * Ensure the upper PAGE_SHIFT bits are clear in the @@ -2005,13 +2007,19 @@ if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS) return 0; ms = __pfn_to_section(pfn); - if (!valid_section(ms)) + rcu_read_lock_sched(); + if (!valid_section(ms)) { + rcu_read_unlock_sched(); return 0; + } /* * Traditionally early sections always returned pfn_valid() for * the entire section-sized span. */ - return early_section(ms) || pfn_section_valid(ms, pfn); + ret = early_section(ms) || pfn_section_valid(ms, pfn); + rcu_read_unlock_sched(); + + return ret; } #endif diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/mtd/rawnand.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/mtd/rawnand.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/mtd/rawnand.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/mtd/rawnand.h @@ -1265,6 +1265,7 @@ * @cont_read: Sequential page read internals * @cont_read.ongoing: Whether a continuous read is ongoing or not * @cont_read.first_page: Start of the continuous read operation + * @cont_read.pause_page: End of the current sequential cache read operation * @cont_read.last_page: End of the continuous read operation * @controller: The hardware controller structure which is shared among multiple * independent devices @@ -1321,6 +1322,7 @@ struct { bool ongoing; unsigned int first_page; + unsigned int pause_page; unsigned int last_page; } cont_read; diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/pci.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/pci.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/pci.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/pci.h @@ -2106,14 +2106,14 @@ (pci_resource_end((dev), (bar)) ? \ resource_size(pci_resource_n((dev), (bar))) : 0) -#define __pci_dev_for_each_res0(dev, res, ...) \ - for (unsigned int __b = 0; \ - res = pci_resource_n(dev, __b), __b < PCI_NUM_RESOURCES; \ +#define __pci_dev_for_each_res0(dev, res, ...) \ + for (unsigned int __b = 0; \ + __b < PCI_NUM_RESOURCES && (res = pci_resource_n(dev, __b)); \ __b++) -#define __pci_dev_for_each_res1(dev, res, __b) \ - for (__b = 0; \ - res = pci_resource_n(dev, __b), __b < PCI_NUM_RESOURCES; \ +#define __pci_dev_for_each_res1(dev, res, __b) \ + for (__b = 0; \ + __b < PCI_NUM_RESOURCES && (res = pci_resource_n(dev, __b)); \ __b++) #define pci_dev_for_each_resource(dev, res, ...) \ diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/pci_ids.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/pci_ids.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/pci_ids.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/pci_ids.h @@ -3013,6 +3013,7 @@ #define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0 #define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2 #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 +#define PCI_DEVICE_ID_INTEL_HDA_ARL 0x7728 #define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119 #define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a #define PCI_DEVICE_ID_INTEL_E6XX_CU 0x8183 diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/security.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/security.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/security.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/security.h @@ -560,6 +560,8 @@ int security_file_alloc(struct file *file); void security_file_free(struct file *file); int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +int security_file_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg); int security_mmap_file(struct file *file, unsigned long prot, unsigned long flags); int security_mmap_addr(unsigned long addr); @@ -1160,6 +1162,13 @@ return 0; } +static inline int security_file_ioctl_compat(struct file *file, + unsigned int cmd, + unsigned long arg) +{ + return 0; +} + static inline int security_mmap_file(struct file *file, unsigned long prot, unsigned long flags) { diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/skmsg.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/skmsg.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/skmsg.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/skmsg.h @@ -500,12 +500,6 @@ return !!psock->saved_data_ready; } -static inline bool sk_is_udp(const struct sock *sk) -{ - return sk->sk_type == SOCK_DGRAM && - sk->sk_protocol == IPPROTO_UDP; -} - #if IS_ENABLED(CONFIG_NET_SOCK_MSG) #define BPF_F_STRPARSER (1UL << 1) diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/stmmac.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/stmmac.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/stmmac.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/stmmac.h @@ -137,6 +137,7 @@ struct stmmac_txq_cfg { u32 weight; + bool coe_unsupported; u8 mode_to_use; /* Credit Base Shaper parameters */ u32 send_slope; diff -u linux-lowlatency-hwe-6.5-6.5.0/include/linux/virtio_net.h linux-lowlatency-hwe-6.5-6.5.0/include/linux/virtio_net.h --- linux-lowlatency-hwe-6.5-6.5.0/include/linux/virtio_net.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/linux/virtio_net.h @@ -3,6 +3,8 @@ #define _LINUX_VIRTIO_NET_H #include +#include +#include #include #include #include @@ -49,6 +51,7 @@ const struct virtio_net_hdr *hdr, bool little_endian) { + unsigned int nh_min_len = sizeof(struct iphdr); unsigned int gso_type = 0; unsigned int thlen = 0; unsigned int p_off = 0; @@ -65,6 +68,7 @@ gso_type = SKB_GSO_TCPV6; ip_proto = IPPROTO_TCP; thlen = sizeof(struct tcphdr); + nh_min_len = sizeof(struct ipv6hdr); break; case VIRTIO_NET_HDR_GSO_UDP: gso_type = SKB_GSO_UDP; @@ -100,7 +104,8 @@ if (!skb_partial_csum_set(skb, start, off)) return -EINVAL; - p_off = skb_transport_offset(skb) + thlen; + nh_min_len = max_t(u32, nh_min_len, skb_transport_offset(skb)); + p_off = nh_min_len + thlen; if (!pskb_may_pull(skb, p_off)) return -EINVAL; } else { @@ -140,7 +145,7 @@ skb_set_transport_header(skb, keys.control.thoff); } else if (gso_type) { - p_off = thlen; + p_off = nh_min_len + thlen; if (!pskb_may_pull(skb, p_off)) return -EINVAL; } diff -u linux-lowlatency-hwe-6.5-6.5.0/include/net/af_unix.h linux-lowlatency-hwe-6.5-6.5.0/include/net/af_unix.h --- linux-lowlatency-hwe-6.5-6.5.0/include/net/af_unix.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/net/af_unix.h @@ -46,12 +46,6 @@ #define UNIXCB(skb) (*(struct unix_skb_parms *)&((skb)->cb)) -#define unix_state_lock(s) spin_lock(&unix_sk(s)->lock) -#define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock) -#define unix_state_lock_nested(s) \ - spin_lock_nested(&unix_sk(s)->lock, \ - SINGLE_DEPTH_NESTING) - /* The AF_UNIX socket */ struct unix_sock { /* WARNING: sk has to be the first member */ @@ -78,4 +72,18 @@ #define unix_peer(sk) (unix_sk(sk)->peer) +#define unix_state_lock(s) spin_lock(&unix_sk(s)->lock) +#define unix_state_unlock(s) spin_unlock(&unix_sk(s)->lock) +enum unix_socket_lock_class { + U_LOCK_NORMAL, + U_LOCK_SECOND, /* for double locking, see unix_state_double_lock(). */ + U_LOCK_DIAG, /* used while dumping icons, see sk_diag_dump_icons(). */ +}; + +static inline void unix_state_lock_nested(struct sock *sk, + enum unix_socket_lock_class subclass) +{ + spin_lock_nested(&unix_sk(sk)->lock, subclass); +} + #define peer_wait peer_wq.wait diff -u linux-lowlatency-hwe-6.5-6.5.0/include/net/bluetooth/hci_core.h linux-lowlatency-hwe-6.5-6.5.0/include/net/bluetooth/hci_core.h --- linux-lowlatency-hwe-6.5-6.5.0/include/net/bluetooth/hci_core.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/net/bluetooth/hci_core.h @@ -957,7 +957,6 @@ /* ----- HCI Connections ----- */ enum { HCI_CONN_AUTH_PEND, - HCI_CONN_REAUTH_PEND, HCI_CONN_ENCRYPT_PEND, HCI_CONN_RSWITCH_PEND, HCI_CONN_MODE_CHANGE_PEND, diff -u linux-lowlatency-hwe-6.5-6.5.0/include/net/ip.h linux-lowlatency-hwe-6.5-6.5.0/include/net/ip.h --- linux-lowlatency-hwe-6.5-6.5.0/include/net/ip.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/net/ip.h @@ -758,7 +758,7 @@ * Functions provided by ip_sockglue.c */ -void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb); +void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb, bool drop_dst); void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk, struct sk_buff *skb, int tlen, int offset); int ip_cmsg_send(struct sock *sk, struct msghdr *msg, diff -u linux-lowlatency-hwe-6.5-6.5.0/include/net/netfilter/nf_tables.h linux-lowlatency-hwe-6.5-6.5.0/include/net/netfilter/nf_tables.h --- linux-lowlatency-hwe-6.5-6.5.0/include/net/netfilter/nf_tables.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/net/netfilter/nf_tables.h @@ -1307,6 +1307,7 @@ * @type: stateful object numeric type * @owner: module owner * @maxattr: maximum netlink attribute + * @family: address family for AF-specific object types * @policy: netlink attribute policy */ struct nft_object_type { @@ -1316,6 +1317,7 @@ struct list_head list; u32 type; unsigned int maxattr; + u8 family; struct module *owner; const struct nla_policy *policy; }; diff -u linux-lowlatency-hwe-6.5-6.5.0/include/net/sock.h linux-lowlatency-hwe-6.5-6.5.0/include/net/sock.h --- linux-lowlatency-hwe-6.5-6.5.0/include/net/sock.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/net/sock.h @@ -2793,9 +2793,25 @@ &skb_shinfo(skb)->tskey); } +static inline bool sk_is_inet(const struct sock *sk) +{ + int family = READ_ONCE(sk->sk_family); + + return family == AF_INET || family == AF_INET6; +} + static inline bool sk_is_tcp(const struct sock *sk) { - return sk->sk_type == SOCK_STREAM && sk->sk_protocol == IPPROTO_TCP; + return sk_is_inet(sk) && + sk->sk_type == SOCK_STREAM && + sk->sk_protocol == IPPROTO_TCP; +} + +static inline bool sk_is_udp(const struct sock *sk) +{ + return sk_is_inet(sk) && + sk->sk_type == SOCK_DGRAM && + sk->sk_protocol == IPPROTO_UDP; } static inline bool sk_is_stream_unix(const struct sock *sk) diff -u linux-lowlatency-hwe-6.5-6.5.0/include/uapi/linux/bpf.h linux-lowlatency-hwe-6.5-6.5.0/include/uapi/linux/bpf.h --- linux-lowlatency-hwe-6.5-6.5.0/include/uapi/linux/bpf.h +++ linux-lowlatency-hwe-6.5-6.5.0/include/uapi/linux/bpf.h @@ -4428,6 +4428,8 @@ * long bpf_get_task_stack(struct task_struct *task, void *buf, u32 size, u64 flags) * Description * Return a user or a kernel stack in bpf program provided buffer. + * Note: the user stack will only be populated if the *task* is + * the current task; all other tasks will return -EOPNOTSUPP. * To achieve this, the helper needs *task*, which is a valid * pointer to **struct task_struct**. To store the stacktrace, the * bpf program provides *buf* with a nonnegative *size*. @@ -4439,6 +4441,7 @@ * * **BPF_F_USER_STACK** * Collect a user space stack instead of a kernel stack. + * The *task* must be the current task. * **BPF_F_USER_BUILD_ID** * Collect buildid+offset instead of ips for user stack, * only valid if **BPF_F_USER_STACK** is also specified. diff -u linux-lowlatency-hwe-6.5-6.5.0/init/do_mounts.c linux-lowlatency-hwe-6.5-6.5.0/init/do_mounts.c --- linux-lowlatency-hwe-6.5-6.5.0/init/do_mounts.c +++ linux-lowlatency-hwe-6.5-6.5.0/init/do_mounts.c @@ -487,5 +487,8 @@ { - if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] && - (!root_fs_names || strstr(root_fs_names, "tmpfs"))) - is_tmpfs = true; + if (IS_ENABLED(CONFIG_TMPFS)) { + if (!saved_root_name[0] && !root_fs_names) + is_tmpfs = true; + else if (root_fs_names && !!strstr(root_fs_names, "tmpfs")) + is_tmpfs = true; + } } diff -u linux-lowlatency-hwe-6.5-6.5.0/io_uring/io_uring.c linux-lowlatency-hwe-6.5-6.5.0/io_uring/io_uring.c --- linux-lowlatency-hwe-6.5-6.5.0/io_uring/io_uring.c +++ linux-lowlatency-hwe-6.5-6.5.0/io_uring/io_uring.c @@ -1337,7 +1337,7 @@ nr_tw = nr_tw_prev + 1; /* Large enough to fail the nr_wait comparison below */ if (!(flags & IOU_F_TWQ_LAZY_WAKE)) - nr_tw = -1U; + nr_tw = INT_MAX; req->nr_tw = nr_tw; req->io_task_work.node.next = first; @@ -1891,7 +1891,11 @@ io_req_complete_defer(req); else io_req_complete_post(req, issue_flags); - } else if (ret != IOU_ISSUE_SKIP_COMPLETE) + + return 0; + } + + if (ret != IOU_ISSUE_SKIP_COMPLETE) return ret; /* If the op doesn't have a file, we're not polling for it */ @@ -2626,8 +2630,6 @@ __set_current_state(TASK_RUNNING); atomic_set(&ctx->cq_wait_nr, 0); - if (ret < 0) - break; /* * Run task_work after scheduling and before io_should_wake(). * If we got woken because of task_work being processed, run it @@ -2637,6 +2639,18 @@ if (!llist_empty(&ctx->work_llist)) io_run_local_work(ctx); + /* + * Non-local task_work will be run on exit to userspace, but + * if we're using DEFER_TASKRUN, then we could have waited + * with a timeout for a number of requests. If the timeout + * hits, we could have some requests ready to process. Ensure + * this break is _after_ we have run task_work, to avoid + * deferring running potentially pending requests until the + * next time we wait for events. + */ + if (ret < 0) + break; + check_cq = READ_ONCE(ctx->check_cq); if (unlikely(check_cq)) { /* let the caller flush overflows, retry */ diff -u linux-lowlatency-hwe-6.5-6.5.0/io_uring/rw.c linux-lowlatency-hwe-6.5-6.5.0/io_uring/rw.c --- linux-lowlatency-hwe-6.5-6.5.0/io_uring/rw.c +++ linux-lowlatency-hwe-6.5-6.5.0/io_uring/rw.c @@ -549,15 +549,19 @@ struct iovec *iov; int ret; + iorw->bytes_done = 0; + iorw->free_iovec = NULL; + /* submission path, ->uring_lock should already be taken */ ret = io_import_iovec(rw, req, &iov, &iorw->s, 0); if (unlikely(ret < 0)) return ret; - iorw->bytes_done = 0; - iorw->free_iovec = iov; - if (iov) + if (iov) { + iorw->free_iovec = iov; req->flags |= REQ_F_NEED_CLEANUP; + } + return 0; } diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/audit.c linux-lowlatency-hwe-6.5-6.5.0/kernel/audit.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/audit.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/audit.c @@ -490,15 +490,19 @@ * @pid: auditd PID * @portid: auditd netlink portid * @net: auditd network namespace pointer + * @skb: the netlink command from the audit daemon + * @ack: netlink ack flag, cleared if ack'd here * * Description: * This function will obtain and drop network namespace references as * necessary. Returns zero on success, negative values on failure. */ -static int auditd_set(struct pid *pid, u32 portid, struct net *net) +static int auditd_set(struct pid *pid, u32 portid, struct net *net, + struct sk_buff *skb, bool *ack) { unsigned long flags; struct auditd_connection *ac_old, *ac_new; + struct nlmsghdr *nlh; if (!pid || !net) return -EINVAL; @@ -510,6 +514,13 @@ ac_new->portid = portid; ac_new->net = get_net(net); + /* send the ack now to avoid a race with the queue backlog */ + if (*ack) { + nlh = nlmsg_hdr(skb); + netlink_ack(skb, nlh, 0, NULL); + *ack = false; + } + spin_lock_irqsave(&auditd_conn_lock, flags); ac_old = rcu_dereference_protected(auditd_conn, lockdep_is_held(&auditd_conn_lock)); @@ -1202,7 +1213,8 @@ return auditd_send_unicast_skb(skb); } -static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh, + bool *ack) { u32 seq; void *data; @@ -1293,7 +1305,8 @@ /* register a new auditd connection */ err = auditd_set(req_pid, NETLINK_CB(skb).portid, - sock_net(NETLINK_CB(skb).sk)); + sock_net(NETLINK_CB(skb).sk), + skb, ack); if (audit_enabled != AUDIT_OFF) audit_log_config_change("audit_pid", new_pid, @@ -1542,9 +1555,10 @@ * Parse the provided skb and deal with any messages that may be present, * malformed skbs are discarded. */ -static void audit_receive(struct sk_buff *skb) +static void audit_receive(struct sk_buff *skb) { struct nlmsghdr *nlh; + bool ack; /* * len MUST be signed for nlmsg_next to be able to dec it below 0 * if the nlmsg_len was not aligned @@ -1557,9 +1571,12 @@ audit_ctl_lock(); while (nlmsg_ok(nlh, len)) { - err = audit_receive_msg(skb, nlh); - /* if err or if this message says it wants a response */ - if (err || (nlh->nlmsg_flags & NLM_F_ACK)) + ack = nlh->nlmsg_flags & NLM_F_ACK; + err = audit_receive_msg(skb, nlh, &ack); + + /* send an ack if the user asked for one and audit_receive_msg + * didn't already do it, or if there was an error. */ + if (ack || err) netlink_ack(skb, nlh, err, NULL); nlh = nlmsg_next(nlh, &len); diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/arraymap.c linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/arraymap.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/arraymap.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/arraymap.c @@ -867,11 +867,11 @@ } if (old_ptr) - map->ops->map_fd_put_ptr(old_ptr); + map->ops->map_fd_put_ptr(map, old_ptr, true); return 0; } -static long fd_array_map_delete_elem(struct bpf_map *map, void *key) +static long __fd_array_map_delete_elem(struct bpf_map *map, void *key, bool need_defer) { struct bpf_array *array = container_of(map, struct bpf_array, map); void *old_ptr; @@ -890,13 +890,18 @@ } if (old_ptr) { - map->ops->map_fd_put_ptr(old_ptr); + map->ops->map_fd_put_ptr(map, old_ptr, need_defer); return 0; } else { return -ENOENT; } } +static long fd_array_map_delete_elem(struct bpf_map *map, void *key) +{ + return __fd_array_map_delete_elem(map, key, true); +} + static void *prog_fd_array_get_ptr(struct bpf_map *map, struct file *map_file, int fd) { @@ -913,8 +918,9 @@ return prog; } -static void prog_fd_array_put_ptr(void *ptr) +static void prog_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer) { + /* bpf_prog is freed after one RCU or tasks trace grace period */ bpf_prog_put(ptr); } @@ -924,13 +930,13 @@ } /* decrement refcnt of all bpf_progs that are stored in this map */ -static void bpf_fd_array_map_clear(struct bpf_map *map) +static void bpf_fd_array_map_clear(struct bpf_map *map, bool need_defer) { struct bpf_array *array = container_of(map, struct bpf_array, map); int i; for (i = 0; i < array->map.max_entries; i++) - fd_array_map_delete_elem(map, &i); + __fd_array_map_delete_elem(map, &i, need_defer); } static void prog_array_map_seq_show_elem(struct bpf_map *map, void *key, @@ -1071,7 +1077,7 @@ { struct bpf_map *map = container_of(work, struct bpf_array_aux, work)->map; - bpf_fd_array_map_clear(map); + bpf_fd_array_map_clear(map, true); bpf_map_put(map); } @@ -1201,8 +1207,9 @@ return ee; } -static void perf_event_fd_array_put_ptr(void *ptr) +static void perf_event_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer) { + /* bpf_perf_event is freed after one RCU grace period */ bpf_event_entry_free_rcu(ptr); } @@ -1220,7 +1227,7 @@ for (i = 0; i < array->map.max_entries; i++) { ee = READ_ONCE(array->ptrs[i]); if (ee && ee->map_file == map_file) - fd_array_map_delete_elem(map, &i); + __fd_array_map_delete_elem(map, &i, true); } rcu_read_unlock(); } @@ -1228,7 +1235,7 @@ static void perf_event_fd_array_map_free(struct bpf_map *map) { if (map->map_flags & BPF_F_PRESERVE_ELEMS) - bpf_fd_array_map_clear(map); + bpf_fd_array_map_clear(map, false); fd_array_map_free(map); } @@ -1256,7 +1263,7 @@ return cgroup_get_from_fd(fd); } -static void cgroup_fd_array_put_ptr(void *ptr) +static void cgroup_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer) { /* cgroup_put free cgrp after a rcu grace period */ cgroup_put(ptr); @@ -1264,7 +1271,7 @@ static void cgroup_fd_array_free(struct bpf_map *map) { - bpf_fd_array_map_clear(map); + bpf_fd_array_map_clear(map, false); fd_array_map_free(map); } @@ -1309,7 +1316,7 @@ * is protected by fdget/fdput. */ bpf_map_meta_free(map->inner_map_meta); - bpf_fd_array_map_clear(map); + bpf_fd_array_map_clear(map, false); fd_array_map_free(map); } diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/btf.c linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/btf.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/btf.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/btf.c @@ -7829,6 +7829,7 @@ case BPF_PROG_TYPE_SYSCALL: return BTF_KFUNC_HOOK_SYSCALL; case BPF_PROG_TYPE_CGROUP_SKB: + case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: return BTF_KFUNC_HOOK_CGROUP_SKB; case BPF_PROG_TYPE_SCHED_ACT: return BTF_KFUNC_HOOK_SCHED_ACT; diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/hashtab.c linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/hashtab.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/hashtab.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/hashtab.c @@ -889,7 +889,7 @@ if (map->ops->map_fd_put_ptr) { ptr = fd_htab_map_get_ptr(map, l); - map->ops->map_fd_put_ptr(ptr); + map->ops->map_fd_put_ptr(map, ptr, true); } } @@ -2466,7 +2466,7 @@ hlist_nulls_for_each_entry_safe(l, n, head, hash_node) { void *ptr = fd_htab_map_get_ptr(map, l); - map->ops->map_fd_put_ptr(ptr); + map->ops->map_fd_put_ptr(map, ptr, false); } } @@ -2507,7 +2507,7 @@ ret = htab_map_update_elem(map, key, &ptr, map_flags); if (ret) - map->ops->map_fd_put_ptr(ptr); + map->ops->map_fd_put_ptr(map, ptr, false); return ret; } diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/helpers.c linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/helpers.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/helpers.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/helpers.c @@ -31,12 +31,13 @@ * * Different map implementations will rely on rcu in map methods * lookup/update/delete, therefore eBPF programs must run under rcu lock - * if program is allowed to access maps, so check rcu_read_lock_held in - * all three functions. + * if program is allowed to access maps, so check rcu_read_lock_held() or + * rcu_read_lock_trace_held() in all three functions. */ BPF_CALL_2(bpf_map_lookup_elem, struct bpf_map *, map, void *, key) { - WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); + WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_trace_held() && + !rcu_read_lock_bh_held()); return (unsigned long) map->ops->map_lookup_elem(map, key); } @@ -52,7 +53,8 @@ BPF_CALL_4(bpf_map_update_elem, struct bpf_map *, map, void *, key, void *, value, u64, flags) { - WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); + WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_trace_held() && + !rcu_read_lock_bh_held()); return map->ops->map_update_elem(map, key, value, flags); } @@ -69,7 +71,8 @@ BPF_CALL_2(bpf_map_delete_elem, struct bpf_map *, map, void *, key) { - WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); + WARN_ON_ONCE(!rcu_read_lock_held() && !rcu_read_lock_trace_held() && + !rcu_read_lock_bh_held()); return map->ops->map_delete_elem(map, key); } diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/syscall.c linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/syscall.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/syscall.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/syscall.c @@ -691,6 +691,7 @@ { struct bpf_map *map = container_of(work, struct bpf_map, work); struct btf_record *rec = map->record; + struct btf *btf = map->btf; security_bpf_map_free(map); bpf_map_release_memcg(map); @@ -706,6 +707,10 @@ * template bpf_map struct used during verification. */ btf_record_free(rec); + /* Delay freeing of btf for maps, as map_free callback may need + * struct_meta info which will be freed with btf_put(). + */ + btf_put(btf); } static void bpf_map_put_uref(struct bpf_map *map) @@ -716,6 +721,28 @@ } } +static void bpf_map_free_in_work(struct bpf_map *map) +{ + INIT_WORK(&map->work, bpf_map_free_deferred); + /* Avoid spawning kworkers, since they all might contend + * for the same mutex like slab_mutex. + */ + queue_work(system_unbound_wq, &map->work); +} + +static void bpf_map_free_rcu_gp(struct rcu_head *rcu) +{ + bpf_map_free_in_work(container_of(rcu, struct bpf_map, rcu)); +} + +static void bpf_map_free_mult_rcu_gp(struct rcu_head *rcu) +{ + if (rcu_trace_implies_rcu_gp()) + bpf_map_free_rcu_gp(rcu); + else + call_rcu(rcu, bpf_map_free_rcu_gp); +} + /* decrement map refcnt and schedule it for freeing via workqueue * (underlying map implementation ops->map_free() might sleep) */ @@ -724,12 +751,11 @@ if (atomic64_dec_and_test(&map->refcnt)) { /* bpf_map_free_id() must be called first */ bpf_map_free_id(map); - btf_put(map->btf); - INIT_WORK(&map->work, bpf_map_free_deferred); - /* Avoid spawning kworkers, since they all might contend - * for the same mutex like slab_mutex. - */ - queue_work(system_unbound_wq, &map->work); + + if (READ_ONCE(map->free_after_mult_rcu_gp)) + call_rcu_tasks_trace(&map->rcu, bpf_map_free_mult_rcu_gp); + else + bpf_map_free_in_work(map); } } EXPORT_SYMBOL_GPL(bpf_map_put); @@ -1672,6 +1698,9 @@ if (!max_count) return 0; + if (put_user(0, &uattr->batch.count)) + return -EFAULT; + key = kvmalloc(map->key_size, GFP_USER | __GFP_NOWARN); if (!key) return -ENOMEM; @@ -1729,6 +1758,9 @@ if (!max_count) return 0; + if (put_user(0, &uattr->batch.count)) + return -EFAULT; + key = kvmalloc(map->key_size, GFP_USER | __GFP_NOWARN); if (!key) return -ENOMEM; @@ -3168,6 +3200,10 @@ * * - if prog->aux->dst_trampoline and tgt_prog is NULL, the program * was detached and is going for re-attachment. + * + * - if prog->aux->dst_trampoline is NULL and tgt_prog and prog->aux->attach_btf + * are NULL, then program was already attached and user did not provide + * tgt_prog_fd so we have no way to find out or create trampoline */ if (!prog->aux->dst_trampoline && !tgt_prog) { /* @@ -3181,6 +3217,11 @@ err = -EINVAL; goto out_unlock; } + /* We can allow re-attach only if we have valid attach_btf. */ + if (!prog->aux->attach_btf) { + err = -EINVAL; + goto out_unlock; + } btf_id = prog->aux->attach_btf_id; key = bpf_trampoline_compute_key(NULL, prog->aux->attach_btf, btf_id); } diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/verifier.c linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/verifier.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/verifier.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/bpf/verifier.c @@ -540,12 +540,11 @@ return func_id == BPF_FUNC_dynptr_data; } -static bool is_callback_calling_kfunc(u32 btf_id); +static bool is_sync_callback_calling_kfunc(u32 btf_id); -static bool is_callback_calling_function(enum bpf_func_id func_id) +static bool is_sync_callback_calling_function(enum bpf_func_id func_id) { return func_id == BPF_FUNC_for_each_map_elem || - func_id == BPF_FUNC_timer_set_callback || func_id == BPF_FUNC_find_vma || func_id == BPF_FUNC_loop || func_id == BPF_FUNC_user_ringbuf_drain; @@ -556,6 +555,18 @@ return func_id == BPF_FUNC_timer_set_callback; } +static bool is_callback_calling_function(enum bpf_func_id func_id) +{ + return is_sync_callback_calling_function(func_id) || + is_async_callback_calling_function(func_id); +} + +static bool is_sync_callback_calling_insn(struct bpf_insn *insn) +{ + return (bpf_helper_call(insn) && is_sync_callback_calling_function(insn->imm)) || + (bpf_pseudo_kfunc_call(insn) && is_sync_callback_calling_kfunc(insn->imm)); +} + static bool is_storage_get_function(enum bpf_func_id func_id) { return func_id == BPF_FUNC_sk_storage_get || @@ -1630,7 +1641,10 @@ return 0; } -static int grow_stack_state(struct bpf_func_state *state, int size) +/* Possibly update state->allocated_stack to be at least size bytes. Also + * possibly update the function's high-water mark in its bpf_subprog_info. + */ +static int grow_stack_state(struct bpf_verifier_env *env, struct bpf_func_state *state, int size) { size_t old_n = state->allocated_stack / BPF_REG_SIZE, n = size / BPF_REG_SIZE; @@ -1642,6 +1656,11 @@ return -ENOMEM; state->allocated_stack = size; + + /* update known max for given subprogram */ + if (env->subprog_info[state->subprogno].stack_depth < size) + env->subprog_info[state->subprogno].stack_depth = size; + return 0; } @@ -1761,6 +1780,9 @@ dst_state->parent = src->parent; dst_state->first_insn_idx = src->first_insn_idx; dst_state->last_insn_idx = src->last_insn_idx; + dst_state->dfs_depth = src->dfs_depth; + dst_state->callback_unroll_depth = src->callback_unroll_depth; + dst_state->used_as_loop_entry = src->used_as_loop_entry; for (i = 0; i <= src->curframe; i++) { dst = dst_state->frame[i]; if (!dst) { @@ -1776,11 +1798,203 @@ return 0; } +static u32 state_htab_size(struct bpf_verifier_env *env) +{ + return env->prog->len; +} + +static struct bpf_verifier_state_list **explored_state(struct bpf_verifier_env *env, int idx) +{ + struct bpf_verifier_state *cur = env->cur_state; + struct bpf_func_state *state = cur->frame[cur->curframe]; + + return &env->explored_states[(idx ^ state->callsite) % state_htab_size(env)]; +} + +static bool same_callsites(struct bpf_verifier_state *a, struct bpf_verifier_state *b) +{ + int fr; + + if (a->curframe != b->curframe) + return false; + + for (fr = a->curframe; fr >= 0; fr--) + if (a->frame[fr]->callsite != b->frame[fr]->callsite) + return false; + + return true; +} + +/* Open coded iterators allow back-edges in the state graph in order to + * check unbounded loops that iterators. + * + * In is_state_visited() it is necessary to know if explored states are + * part of some loops in order to decide whether non-exact states + * comparison could be used: + * - non-exact states comparison establishes sub-state relation and uses + * read and precision marks to do so, these marks are propagated from + * children states and thus are not guaranteed to be final in a loop; + * - exact states comparison just checks if current and explored states + * are identical (and thus form a back-edge). + * + * Paper "A New Algorithm for Identifying Loops in Decompilation" + * by Tao Wei, Jian Mao, Wei Zou and Yu Chen [1] presents a convenient + * algorithm for loop structure detection and gives an overview of + * relevant terminology. It also has helpful illustrations. + * + * [1] https://api.semanticscholar.org/CorpusID:15784067 + * + * We use a similar algorithm but because loop nested structure is + * irrelevant for verifier ours is significantly simpler and resembles + * strongly connected components algorithm from Sedgewick's textbook. + * + * Define topmost loop entry as a first node of the loop traversed in a + * depth first search starting from initial state. The goal of the loop + * tracking algorithm is to associate topmost loop entries with states + * derived from these entries. + * + * For each step in the DFS states traversal algorithm needs to identify + * the following situations: + * + * initial initial initial + * | | | + * V V V + * ... ... .---------> hdr + * | | | | + * V V | V + * cur .-> succ | .------... + * | | | | | | + * V | V | V V + * succ '-- cur | ... ... + * | | | + * | V V + * | succ <- cur + * | | + * | V + * | ... + * | | + * '----' + * + * (A) successor state of cur (B) successor state of cur or it's entry + * not yet traversed are in current DFS path, thus cur and succ + * are members of the same outermost loop + * + * initial initial + * | | + * V V + * ... ... + * | | + * V V + * .------... .------... + * | | | | + * V V V V + * .-> hdr ... ... ... + * | | | | | + * | V V V V + * | succ <- cur succ <- cur + * | | | + * | V V + * | ... ... + * | | | + * '----' exit + * + * (C) successor state of cur is a part of some loop but this loop + * does not include cur or successor state is not in a loop at all. + * + * Algorithm could be described as the following python code: + * + * traversed = set() # Set of traversed nodes + * entries = {} # Mapping from node to loop entry + * depths = {} # Depth level assigned to graph node + * path = set() # Current DFS path + * + * # Find outermost loop entry known for n + * def get_loop_entry(n): + * h = entries.get(n, None) + * while h in entries and entries[h] != h: + * h = entries[h] + * return h + * + * # Update n's loop entry if h's outermost entry comes + * # before n's outermost entry in current DFS path. + * def update_loop_entry(n, h): + * n1 = get_loop_entry(n) or n + * h1 = get_loop_entry(h) or h + * if h1 in path and depths[h1] <= depths[n1]: + * entries[n] = h1 + * + * def dfs(n, depth): + * traversed.add(n) + * path.add(n) + * depths[n] = depth + * for succ in G.successors(n): + * if succ not in traversed: + * # Case A: explore succ and update cur's loop entry + * # only if succ's entry is in current DFS path. + * dfs(succ, depth + 1) + * h = get_loop_entry(succ) + * update_loop_entry(n, h) + * else: + * # Case B or C depending on `h1 in path` check in update_loop_entry(). + * update_loop_entry(n, succ) + * path.remove(n) + * + * To adapt this algorithm for use with verifier: + * - use st->branch == 0 as a signal that DFS of succ had been finished + * and cur's loop entry has to be updated (case A), handle this in + * update_branch_counts(); + * - use st->branch > 0 as a signal that st is in the current DFS path; + * - handle cases B and C in is_state_visited(); + * - update topmost loop entry for intermediate states in get_loop_entry(). + */ +static struct bpf_verifier_state *get_loop_entry(struct bpf_verifier_state *st) +{ + struct bpf_verifier_state *topmost = st->loop_entry, *old; + + while (topmost && topmost->loop_entry && topmost != topmost->loop_entry) + topmost = topmost->loop_entry; + /* Update loop entries for intermediate states to avoid this + * traversal in future get_loop_entry() calls. + */ + while (st && st->loop_entry != topmost) { + old = st->loop_entry; + st->loop_entry = topmost; + st = old; + } + return topmost; +} + +static void update_loop_entry(struct bpf_verifier_state *cur, struct bpf_verifier_state *hdr) +{ + struct bpf_verifier_state *cur1, *hdr1; + + cur1 = get_loop_entry(cur) ?: cur; + hdr1 = get_loop_entry(hdr) ?: hdr; + /* The head1->branches check decides between cases B and C in + * comment for get_loop_entry(). If hdr1->branches == 0 then + * head's topmost loop entry is not in current DFS path, + * hence 'cur' and 'hdr' are not in the same loop and there is + * no need to update cur->loop_entry. + */ + if (hdr1->branches && hdr1->dfs_depth <= cur1->dfs_depth) { + cur->loop_entry = hdr; + hdr->used_as_loop_entry = true; + } +} + static void update_branch_counts(struct bpf_verifier_env *env, struct bpf_verifier_state *st) { while (st) { u32 br = --st->branches; + /* br == 0 signals that DFS exploration for 'st' is finished, + * thus it is necessary to update parent's loop entry if it + * turned out that st is a part of some loop. + * This is a part of 'case A' in get_loop_entry() comment. + */ + if (br == 0 && st->parent && st->loop_entry) + update_loop_entry(st->parent, st->loop_entry); + /* WARN_ON(br > 1) technically makes sense here, * but see comment in push_stack(), hence: */ @@ -3115,13 +3329,11 @@ reg->subreg_def = DEF_NOT_SUBREG; } -static int check_reg_arg(struct bpf_verifier_env *env, u32 regno, - enum reg_arg_type t) +static int __check_reg_arg(struct bpf_verifier_env *env, struct bpf_reg_state *regs, u32 regno, + enum reg_arg_type t) { - struct bpf_verifier_state *vstate = env->cur_state; - struct bpf_func_state *state = vstate->frame[vstate->curframe]; struct bpf_insn *insn = env->prog->insnsi + env->insn_idx; - struct bpf_reg_state *reg, *regs = state->regs; + struct bpf_reg_state *reg; bool rw64; if (regno >= MAX_BPF_REG) { @@ -3162,6 +3374,15 @@ return 0; } +static int check_reg_arg(struct bpf_verifier_env *env, u32 regno, + enum reg_arg_type t) +{ + struct bpf_verifier_state *vstate = env->cur_state; + struct bpf_func_state *state = vstate->frame[vstate->curframe]; + + return __check_reg_arg(env, state->regs, regno, t); +} + static void mark_jmp_point(struct bpf_verifier_env *env, int idx) { env->insn_aux_data[idx].jmp_point = true; @@ -3400,6 +3621,8 @@ } } +static bool calls_callback(struct bpf_verifier_env *env, int insn_idx); + /* For given verifier state backtrack_insn() is called from the last insn to * the first insn. Its purpose is to compute a bitmask of registers and * stack slots that needs precision in the parent verifier state. @@ -3575,16 +3798,13 @@ return -EFAULT; return 0; } - } else if ((bpf_helper_call(insn) && - is_callback_calling_function(insn->imm) && - !is_async_callback_calling_function(insn->imm)) || - (bpf_pseudo_kfunc_call(insn) && is_callback_calling_kfunc(insn->imm))) { - /* callback-calling helper or kfunc call, which means - * we are exiting from subprog, but unlike the subprog - * call handling above, we shouldn't propagate - * precision of r1-r5 (if any requested), as they are - * not actually arguments passed directly to callback - * subprogs + } else if (is_sync_callback_calling_insn(insn) && idx != subseq_idx - 1) { + /* exit from callback subprog to callback-calling helper or + * kfunc call. Use idx/subseq_idx check to discern it from + * straight line code backtracking. + * Unlike the subprog call handling above, we shouldn't + * propagate precision of r1-r5 (if any requested), as they are + * not actually arguments passed directly to callback subprogs */ if (bt_reg_mask(bt) & ~BPF_REGMASK_ARGS) { verbose(env, "BUG regs %x\n", bt_reg_mask(bt)); @@ -3619,10 +3839,18 @@ } else if (opcode == BPF_EXIT) { bool r0_precise; + /* Backtracking to a nested function call, 'idx' is a part of + * the inner frame 'subseq_idx' is a part of the outer frame. + * In case of a regular function call, instructions giving + * precision to registers R1-R5 should have been found already. + * In case of a callback, it is ok to have R1-R5 marked for + * backtracking, as these registers are set by the function + * invoking callback. + */ + if (subseq_idx >= 0 && calls_callback(env, subseq_idx)) + for (i = BPF_REG_1; i <= BPF_REG_5; i++) + bt_clear_reg(bt, i); if (bt_reg_mask(bt) & BPF_REGMASK_ARGS) { - /* if backtracing was looking for registers R1-R5 - * they should have been found already. - */ verbose(env, "BUG regs %x\n", bt_reg_mask(bt)); WARN_ONCE(1, "verifier backtracking bug"); return -EFAULT; @@ -4319,14 +4547,11 @@ struct bpf_reg_state *reg = NULL; u32 dst_reg = insn->dst_reg; - err = grow_stack_state(state, round_up(slot + 1, BPF_REG_SIZE)); - if (err) - return err; /* caller checked that off % size == 0 and -MAX_BPF_STACK <= off < 0, * so it's aligned access and [off, off + size) are within stack limits */ if (!env->allow_ptr_leaks && - state->stack[spi].slot_type[0] == STACK_SPILL && + is_spilled_reg(&state->stack[spi]) && size != BPF_REG_SIZE) { verbose(env, "attempt to corrupt spilled pointer on stack\n"); return -EACCES; @@ -4477,10 +4702,6 @@ (!value_reg && is_bpf_st_mem(insn) && insn->imm == 0)) writing_zero = true; - err = grow_stack_state(state, round_up(-min_off, BPF_REG_SIZE)); - if (err) - return err; - for (i = min_off; i < max_off; i++) { int spi; @@ -5580,20 +5801,6 @@ strict); } -static int update_stack_depth(struct bpf_verifier_env *env, - const struct bpf_func_state *func, - int off) -{ - u16 stack = env->subprog_info[func->subprogno].stack_depth; - - if (stack >= -off) - return 0; - - /* update known max for given subprogram */ - env->subprog_info[func->subprogno].stack_depth = -off; - return 0; -} - /* starting from main bpf function walk all instructions of the function * and recursively walk all callees that given function can call. * Ignore jump and exit insns. @@ -6210,13 +6417,14 @@ * The minimum valid offset is -MAX_BPF_STACK for writes, and * -state->allocated_stack for reads. */ -static int check_stack_slot_within_bounds(int off, - struct bpf_func_state *state, - enum bpf_access_type t) +static int check_stack_slot_within_bounds(struct bpf_verifier_env *env, + s64 off, + struct bpf_func_state *state, + enum bpf_access_type t) { int min_valid_off; - if (t == BPF_WRITE) + if (t == BPF_WRITE || env->allow_uninit_stack) min_valid_off = -MAX_BPF_STACK; else min_valid_off = -state->allocated_stack; @@ -6239,7 +6447,7 @@ struct bpf_reg_state *regs = cur_regs(env); struct bpf_reg_state *reg = regs + regno; struct bpf_func_state *state = func(env, reg); - int min_off, max_off; + s64 min_off, max_off; int err; char *err_extra; @@ -6252,11 +6460,8 @@ err_extra = " write to"; if (tnum_is_const(reg->var_off)) { - min_off = reg->var_off.value + off; - if (access_size > 0) - max_off = min_off + access_size - 1; - else - max_off = min_off; + min_off = (s64)reg->var_off.value + off; + max_off = min_off + access_size; } else { if (reg->smax_value >= BPF_MAX_VAR_OFF || reg->smin_value <= -BPF_MAX_VAR_OFF) { @@ -6265,15 +6470,12 @@ return -EACCES; } min_off = reg->smin_value + off; - if (access_size > 0) - max_off = reg->smax_value + off + access_size - 1; - else - max_off = min_off; + max_off = reg->smax_value + off + access_size; } - err = check_stack_slot_within_bounds(min_off, state, type); - if (!err) - err = check_stack_slot_within_bounds(max_off, state, type); + err = check_stack_slot_within_bounds(env, min_off, state, type); + if (!err && max_off > 0) + err = -EINVAL; /* out of stack access into non-negative offsets */ if (err) { if (tnum_is_const(reg->var_off)) { @@ -6286,8 +6488,10 @@ verbose(env, "invalid variable-offset%s stack R%d var_off=%s size=%d\n", err_extra, regno, tn_buf, access_size); } + return err; } - return err; + + return grow_stack_state(env, state, round_up(-min_off, BPF_REG_SIZE)); } /* check whether memory at (regno + off) is accessible for t = (read | write) @@ -6302,7 +6506,6 @@ { struct bpf_reg_state *regs = cur_regs(env); struct bpf_reg_state *reg = regs + regno; - struct bpf_func_state *state; int size, err = 0; size = bpf_size_to_bytes(bpf_size); @@ -6445,11 +6648,6 @@ if (err) return err; - state = func(env, reg); - err = update_stack_depth(env, state, off); - if (err) - return err; - if (t == BPF_READ) err = check_stack_read(env, regno, off, size, value_regno); @@ -6641,7 +6839,8 @@ /* When register 'regno' is used to read the stack (either directly or through * a helper function) make sure that it's within stack boundary and, depending - * on the access type, that all elements of the stack are initialized. + * on the access type and privileges, that all elements of the stack are + * initialized. * * 'off' includes 'regno->off', but not its dynamic part (if any). * @@ -6749,8 +6948,11 @@ slot = -i - 1; spi = slot / BPF_REG_SIZE; - if (state->allocated_stack <= slot) - goto err; + if (state->allocated_stack <= slot) { + verbose(env, "verifier bug: allocated_stack too small"); + return -EFAULT; + } + stype = &state->stack[spi].slot_type[slot % BPF_REG_SIZE]; if (*stype == STACK_MISC) goto mark; @@ -6774,7 +6976,6 @@ goto mark; } -err: if (tnum_is_const(reg->var_off)) { verbose(env, "invalid%s read from stack R%d off %d+%d size %d\n", err_extra, regno, min_off, i - min_off, access_size); @@ -6799,7 +7000,7 @@ * helper may write to the entire memory range. */ } - return update_stack_depth(env, state, min_off); + return 0; } static int check_helper_mem_access(struct bpf_verifier_env *env, int regno, @@ -7382,6 +7583,81 @@ return 0; } +/* Look for a previous loop entry at insn_idx: nearest parent state + * stopped at insn_idx with callsites matching those in cur->frame. + */ +static struct bpf_verifier_state *find_prev_entry(struct bpf_verifier_env *env, + struct bpf_verifier_state *cur, + int insn_idx) +{ + struct bpf_verifier_state_list *sl; + struct bpf_verifier_state *st; + + /* Explored states are pushed in stack order, most recent states come first */ + sl = *explored_state(env, insn_idx); + for (; sl; sl = sl->next) { + /* If st->branches != 0 state is a part of current DFS verification path, + * hence cur & st for a loop. + */ + st = &sl->state; + if (st->insn_idx == insn_idx && st->branches && same_callsites(st, cur) && + st->dfs_depth < cur->dfs_depth) + return st; + } + + return NULL; +} + +static void reset_idmap_scratch(struct bpf_verifier_env *env); +static bool regs_exact(const struct bpf_reg_state *rold, + const struct bpf_reg_state *rcur, + struct bpf_idmap *idmap); + +static void maybe_widen_reg(struct bpf_verifier_env *env, + struct bpf_reg_state *rold, struct bpf_reg_state *rcur, + struct bpf_idmap *idmap) +{ + if (rold->type != SCALAR_VALUE) + return; + if (rold->type != rcur->type) + return; + if (rold->precise || rcur->precise || regs_exact(rold, rcur, idmap)) + return; + __mark_reg_unknown(env, rcur); +} + +static int widen_imprecise_scalars(struct bpf_verifier_env *env, + struct bpf_verifier_state *old, + struct bpf_verifier_state *cur) +{ + struct bpf_func_state *fold, *fcur; + int i, fr; + + reset_idmap_scratch(env); + for (fr = old->curframe; fr >= 0; fr--) { + fold = old->frame[fr]; + fcur = cur->frame[fr]; + + for (i = 0; i < MAX_BPF_REG; i++) + maybe_widen_reg(env, + &fold->regs[i], + &fcur->regs[i], + &env->idmap_scratch); + + for (i = 0; i < fold->allocated_stack / BPF_REG_SIZE; i++) { + if (!is_spilled_reg(&fold->stack[i]) || + !is_spilled_reg(&fcur->stack[i])) + continue; + + maybe_widen_reg(env, + &fold->stack[i].spilled_ptr, + &fcur->stack[i].spilled_ptr, + &env->idmap_scratch); + } + } + return 0; +} + /* process_iter_next_call() is called when verifier gets to iterator's next * "method" (e.g., bpf_iter_num_next() for numbers iterator) call. We'll refer * to it as just "iter_next()" in comments below. @@ -7423,25 +7699,47 @@ * is some statically known limit on number of iterations (e.g., if there is * an explicit `if n > 100 then break;` statement somewhere in the loop). * - * One very subtle but very important aspect is that we *always* simulate NULL - * condition first (as the current state) before we simulate non-NULL case. - * This has to do with intricacies of scalar precision tracking. By simulating - * "exit condition" of iter_next() returning NULL first, we make sure all the - * relevant precision marks *that will be set **after** we exit iterator loop* - * are propagated backwards to common parent state of NULL and non-NULL - * branches. Thanks to that, state equivalence checks done later in forked - * state, when reaching iter_next() for ACTIVE iterator, can assume that - * precision marks are finalized and won't change. Because simulating another - * ACTIVE iterator iteration won't change them (because given same input - * states we'll end up with exactly same output states which we are currently - * comparing; and verification after the loop already propagated back what - * needs to be **additionally** tracked as precise). It's subtle, grok - * precision tracking for more intuitive understanding. + * Iteration convergence logic in is_state_visited() relies on exact + * states comparison, which ignores read and precision marks. + * This is necessary because read and precision marks are not finalized + * while in the loop. Exact comparison might preclude convergence for + * simple programs like below: + * + * i = 0; + * while(iter_next(&it)) + * i++; + * + * At each iteration step i++ would produce a new distinct state and + * eventually instruction processing limit would be reached. + * + * To avoid such behavior speculatively forget (widen) range for + * imprecise scalar registers, if those registers were not precise at the + * end of the previous iteration and do not match exactly. + * + * This is a conservative heuristic that allows to verify wide range of programs, + * however it precludes verification of programs that conjure an + * imprecise value on the first loop iteration and use it as precise on a second. + * For example, the following safe program would fail to verify: + * + * struct bpf_num_iter it; + * int arr[10]; + * int i = 0, a = 0; + * bpf_iter_num_new(&it, 0, 10); + * while (bpf_iter_num_next(&it)) { + * if (a == 0) { + * a = 1; + * i = 7; // Because i changed verifier would forget + * // it's range on second loop entry. + * } else { + * arr[i] = 42; // This would fail to verify. + * } + * } + * bpf_iter_num_destroy(&it); */ static int process_iter_next_call(struct bpf_verifier_env *env, int insn_idx, struct bpf_kfunc_call_arg_meta *meta) { - struct bpf_verifier_state *cur_st = env->cur_state, *queued_st; + struct bpf_verifier_state *cur_st = env->cur_state, *queued_st, *prev_st; struct bpf_func_state *cur_fr = cur_st->frame[cur_st->curframe], *queued_fr; struct bpf_reg_state *cur_iter, *queued_iter; int iter_frameno = meta->iter.frameno; @@ -7459,6 +7757,19 @@ } if (cur_iter->iter.state == BPF_ITER_STATE_ACTIVE) { + /* Because iter_next() call is a checkpoint is_state_visitied() + * should guarantee parent state with same call sites and insn_idx. + */ + if (!cur_st->parent || cur_st->parent->insn_idx != insn_idx || + !same_callsites(cur_st->parent, cur_st)) { + verbose(env, "bug: bad parent state for iter next call"); + return -EFAULT; + } + /* Note cur_st->parent in the call below, it is necessary to skip + * checkpoint created for cur_st by is_state_visited() + * right at this instruction. + */ + prev_st = find_prev_entry(env, cur_st->parent, insn_idx); /* branch out active iter state */ queued_st = push_stack(env, insn_idx + 1, insn_idx, false); if (!queued_st) @@ -7467,6 +7778,8 @@ queued_iter = &queued_st->frame[iter_frameno]->stack[iter_spi].spilled_ptr; queued_iter->iter.state = BPF_ITER_STATE_ACTIVE; queued_iter->iter.depth++; + if (prev_st) + widen_imprecise_scalars(env, prev_st, queued_st); queued_fr = queued_st->frame[queued_st->curframe]; mark_ptr_not_null_reg(&queued_fr->regs[BPF_REG_0]); @@ -8696,7 +9009,7 @@ /* after the call registers r0 - r5 were scratched */ for (i = 0; i < CALLER_SAVED_REGS; i++) { mark_reg_not_init(env, regs, caller_saved[i]); - check_reg_arg(env, caller_saved[i], DST_OP_NO_MARK); + __check_reg_arg(env, regs, caller_saved[i], DST_OP_NO_MARK); } } @@ -8709,11 +9022,10 @@ struct bpf_func_state *caller, struct bpf_func_state *callee, int insn_idx); -static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn, - int *insn_idx, int subprog, - set_callee_state_fn set_callee_state_cb) +static int setup_func_entry(struct bpf_verifier_env *env, int subprog, int callsite, + set_callee_state_fn set_callee_state_cb, + struct bpf_verifier_state *state) { - struct bpf_verifier_state *state = env->cur_state; struct bpf_func_state *caller, *callee; int err; @@ -8723,53 +9035,71 @@ return -E2BIG; } - caller = state->frame[state->curframe]; if (state->frame[state->curframe + 1]) { verbose(env, "verifier bug. Frame %d already allocated\n", state->curframe + 1); return -EFAULT; } + caller = state->frame[state->curframe]; + callee = kzalloc(sizeof(*callee), GFP_KERNEL); + if (!callee) + return -ENOMEM; + state->frame[state->curframe + 1] = callee; + + /* callee cannot access r0, r6 - r9 for reading and has to write + * into its own stack before reading from it. + * callee can read/write into caller's stack + */ + init_func_state(env, callee, + /* remember the callsite, it will be used by bpf_exit */ + callsite, + state->curframe + 1 /* frameno within this callchain */, + subprog /* subprog number within this prog */); + /* Transfer references to the callee */ + err = copy_reference_state(callee, caller); + err = err ?: set_callee_state_cb(env, caller, callee, callsite); + if (err) + goto err_out; + + /* only increment it after check_reg_arg() finished */ + state->curframe++; + + return 0; + +err_out: + free_func_state(callee); + state->frame[state->curframe + 1] = NULL; + return err; +} + +static int push_callback_call(struct bpf_verifier_env *env, struct bpf_insn *insn, + int insn_idx, int subprog, + set_callee_state_fn set_callee_state_cb) +{ + struct bpf_verifier_state *state = env->cur_state, *callback_state; + struct bpf_func_state *caller, *callee; + int err; + + caller = state->frame[state->curframe]; err = btf_check_subprog_call(env, subprog, caller->regs); if (err == -EFAULT) return err; - if (subprog_is_global(env, subprog)) { - if (err) { - verbose(env, "Caller passes invalid args into func#%d\n", - subprog); - return err; - } else { - if (env->log.level & BPF_LOG_LEVEL) - verbose(env, - "Func#%d is global and valid. Skipping.\n", - subprog); - clear_caller_saved_regs(env, caller->regs); - - /* All global functions return a 64-bit SCALAR_VALUE */ - mark_reg_unknown(env, caller->regs, BPF_REG_0); - caller->regs[BPF_REG_0].subreg_def = DEF_NOT_SUBREG; - - /* continue with next insn after call */ - return 0; - } - } /* set_callee_state is used for direct subprog calls, but we are * interested in validating only BPF helpers that can call subprogs as * callbacks */ - if (set_callee_state_cb != set_callee_state) { - if (bpf_pseudo_kfunc_call(insn) && - !is_callback_calling_kfunc(insn->imm)) { - verbose(env, "verifier bug: kfunc %s#%d not marked as callback-calling\n", - func_id_name(insn->imm), insn->imm); - return -EFAULT; - } else if (!bpf_pseudo_kfunc_call(insn) && - !is_callback_calling_function(insn->imm)) { /* helper */ - verbose(env, "verifier bug: helper %s#%d not marked as callback-calling\n", - func_id_name(insn->imm), insn->imm); - return -EFAULT; - } + if (bpf_pseudo_kfunc_call(insn) && + !is_sync_callback_calling_kfunc(insn->imm)) { + verbose(env, "verifier bug: kfunc %s#%d not marked as callback-calling\n", + func_id_name(insn->imm), insn->imm); + return -EFAULT; + } else if (!bpf_pseudo_kfunc_call(insn) && + !is_callback_calling_function(insn->imm)) { /* helper */ + verbose(env, "verifier bug: helper %s#%d not marked as callback-calling\n", + func_id_name(insn->imm), insn->imm); + return -EFAULT; } if (insn->code == (BPF_JMP | BPF_CALL) && @@ -8780,53 +9110,83 @@ /* there is no real recursion here. timer callbacks are async */ env->subprog_info[subprog].is_async_cb = true; async_cb = push_async_cb(env, env->subprog_info[subprog].start, - *insn_idx, subprog); + insn_idx, subprog); if (!async_cb) return -EFAULT; callee = async_cb->frame[0]; callee->async_entry_cnt = caller->async_entry_cnt + 1; /* Convert bpf_timer_set_callback() args into timer callback args */ - err = set_callee_state_cb(env, caller, callee, *insn_idx); + err = set_callee_state_cb(env, caller, callee, insn_idx); if (err) return err; + return 0; + } + + /* for callback functions enqueue entry to callback and + * proceed with next instruction within current frame. + */ + callback_state = push_stack(env, env->subprog_info[subprog].start, insn_idx, false); + if (!callback_state) + return -ENOMEM; + + err = setup_func_entry(env, subprog, insn_idx, set_callee_state_cb, + callback_state); + if (err) + return err; + + callback_state->callback_unroll_depth++; + callback_state->frame[callback_state->curframe - 1]->callback_depth++; + caller->callback_depth = 0; + return 0; +} + +static int check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn, + int *insn_idx) +{ + struct bpf_verifier_state *state = env->cur_state; + struct bpf_func_state *caller; + int err, subprog, target_insn; + + target_insn = *insn_idx + insn->imm + 1; + subprog = find_subprog(env, target_insn); + if (subprog < 0) { + verbose(env, "verifier bug. No program starts at insn %d\n", target_insn); + return -EFAULT; + } + + caller = state->frame[state->curframe]; + err = btf_check_subprog_call(env, subprog, caller->regs); + if (err == -EFAULT) + return err; + if (subprog_is_global(env, subprog)) { + if (err) { + verbose(env, "Caller passes invalid args into func#%d\n", subprog); + return err; + } + + if (env->log.level & BPF_LOG_LEVEL) + verbose(env, "Func#%d is global and valid. Skipping.\n", subprog); clear_caller_saved_regs(env, caller->regs); + + /* All global functions return a 64-bit SCALAR_VALUE */ mark_reg_unknown(env, caller->regs, BPF_REG_0); caller->regs[BPF_REG_0].subreg_def = DEF_NOT_SUBREG; + /* continue with next insn after call */ return 0; } - callee = kzalloc(sizeof(*callee), GFP_KERNEL); - if (!callee) - return -ENOMEM; - state->frame[state->curframe + 1] = callee; - - /* callee cannot access r0, r6 - r9 for reading and has to write - * into its own stack before reading from it. - * callee can read/write into caller's stack + /* for regular function entry setup new frame and continue + * from that frame. */ - init_func_state(env, callee, - /* remember the callsite, it will be used by bpf_exit */ - *insn_idx /* callsite */, - state->curframe + 1 /* frameno within this callchain */, - subprog /* subprog number within this prog */); - - /* Transfer references to the callee */ - err = copy_reference_state(callee, caller); - if (err) - goto err_out; - - err = set_callee_state_cb(env, caller, callee, *insn_idx); + err = setup_func_entry(env, subprog, *insn_idx, set_callee_state, state); if (err) - goto err_out; + return err; clear_caller_saved_regs(env, caller->regs); - /* only increment it after check_reg_arg() finished */ - state->curframe++; - /* and go analyze first insn of the callee */ *insn_idx = env->subprog_info[subprog].start - 1; @@ -8834,14 +9194,10 @@ verbose(env, "caller:\n"); print_verifier_state(env, caller, true); verbose(env, "callee:\n"); - print_verifier_state(env, callee, true); + print_verifier_state(env, state->frame[state->curframe], true); } - return 0; -err_out: - free_func_state(callee); - state->frame[state->curframe + 1] = NULL; - return err; + return 0; } int map_set_for_each_callback_args(struct bpf_verifier_env *env, @@ -8885,22 +9241,6 @@ return 0; } -static int check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn, - int *insn_idx) -{ - int subprog, target_insn; - - target_insn = *insn_idx + insn->imm + 1; - subprog = find_subprog(env, target_insn); - if (subprog < 0) { - verbose(env, "verifier bug. No program starts at insn %d\n", - target_insn); - return -EFAULT; - } - - return __check_func_call(env, insn, insn_idx, subprog, set_callee_state); -} - static int set_map_elem_callback_state(struct bpf_verifier_env *env, struct bpf_func_state *caller, struct bpf_func_state *callee, @@ -9093,9 +9433,10 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx) { - struct bpf_verifier_state *state = env->cur_state; + struct bpf_verifier_state *state = env->cur_state, *prev_st; struct bpf_func_state *caller, *callee; struct bpf_reg_state *r0; + bool in_callback_fn; int err; callee = state->frame[state->curframe]; @@ -9120,10 +9461,22 @@ verbose(env, "R0 not a scalar value\n"); return -EACCES; } + + /* we are going to rely on register's precise value */ + err = mark_reg_read(env, r0, r0->parent, REG_LIVE_READ64); + err = err ?: mark_chain_precision(env, BPF_REG_0); + if (err) + return err; + if (!tnum_in(range, r0->var_off)) { verbose_invalid_scalar(env, r0, &range, "callback return", "R0"); return -EINVAL; } + if (!calls_callback(env, callee->callsite)) { + verbose(env, "BUG: in callback at %d, callsite %d !calls_callback\n", + *insn_idx, callee->callsite); + return -EFAULT; + } } else { /* return to the caller whatever r0 had in the callee */ caller->regs[BPF_REG_0] = *r0; @@ -9141,7 +9494,16 @@ return err; } - *insn_idx = callee->callsite + 1; + /* for callbacks like bpf_loop or bpf_for_each_map_elem go back to callsite, + * there function call logic would reschedule callback visit. If iteration + * converges is_state_visited() would prune that visit eventually. + */ + in_callback_fn = callee->in_callback_fn; + if (in_callback_fn) + *insn_idx = callee->callsite; + else + *insn_idx = callee->callsite + 1; + if (env->log.level & BPF_LOG_LEVEL) { verbose(env, "returning from callee:\n"); print_verifier_state(env, callee, true); @@ -9151,6 +9513,24 @@ /* clear everything in the callee */ free_func_state(callee); state->frame[state->curframe--] = NULL; + + /* for callbacks widen imprecise scalars to make programs like below verify: + * + * struct ctx { int i; } + * void cb(int idx, struct ctx *ctx) { ctx->i++; ... } + * ... + * struct ctx = { .i = 0; } + * bpf_loop(100, cb, &ctx, 0); + * + * This is similar to what is done in process_iter_next_call() for open + * coded iterators. + */ + prev_st = in_callback_fn ? find_prev_entry(env, state, *insn_idx) : NULL; + if (prev_st) { + err = widen_imprecise_scalars(env, prev_st, state); + if (err) + return err; + } return 0; } @@ -9518,24 +9898,37 @@ } break; case BPF_FUNC_for_each_map_elem: - err = __check_func_call(env, insn, insn_idx_p, meta.subprogno, - set_map_elem_callback_state); + err = push_callback_call(env, insn, insn_idx, meta.subprogno, + set_map_elem_callback_state); break; case BPF_FUNC_timer_set_callback: - err = __check_func_call(env, insn, insn_idx_p, meta.subprogno, - set_timer_callback_state); + err = push_callback_call(env, insn, insn_idx, meta.subprogno, + set_timer_callback_state); break; case BPF_FUNC_find_vma: - err = __check_func_call(env, insn, insn_idx_p, meta.subprogno, - set_find_vma_callback_state); + err = push_callback_call(env, insn, insn_idx, meta.subprogno, + set_find_vma_callback_state); break; case BPF_FUNC_snprintf: err = check_bpf_snprintf_call(env, regs); break; case BPF_FUNC_loop: update_loop_inline_state(env, meta.subprogno); - err = __check_func_call(env, insn, insn_idx_p, meta.subprogno, - set_loop_callback_state); + /* Verifier relies on R1 value to determine if bpf_loop() iteration + * is finished, thus mark it precise. + */ + err = mark_chain_precision(env, BPF_REG_1); + if (err) + return err; + if (cur_func(env)->callback_depth < regs[BPF_REG_1].umax_value) { + err = push_callback_call(env, insn, insn_idx, meta.subprogno, + set_loop_callback_state); + } else { + cur_func(env)->callback_depth = 0; + if (env->log.level & BPF_LOG_LEVEL2) + verbose(env, "frame%d bpf_loop iteration limit reached\n", + env->cur_state->curframe); + } break; case BPF_FUNC_dynptr_from_mem: if (regs[BPF_REG_1].type != PTR_TO_MAP_VALUE) { @@ -9614,8 +10007,8 @@ break; } case BPF_FUNC_user_ringbuf_drain: - err = __check_func_call(env, insn, insn_idx_p, meta.subprogno, - set_user_ringbuf_callback_state); + err = push_callback_call(env, insn, insn_idx, meta.subprogno, + set_user_ringbuf_callback_state); break; } @@ -10474,7 +10867,7 @@ btf_id == special_kfunc_list[KF_bpf_refcount_acquire_impl]; } -static bool is_callback_calling_kfunc(u32 btf_id) +static bool is_sync_callback_calling_kfunc(u32 btf_id) { return btf_id == special_kfunc_list[KF_bpf_rbtree_add_impl]; } @@ -11181,6 +11574,21 @@ return -EACCES; } + /* Check the arguments */ + err = check_kfunc_args(env, &meta, insn_idx); + if (err < 0) + return err; + + if (meta.func_id == special_kfunc_list[KF_bpf_rbtree_add_impl]) { + err = push_callback_call(env, insn, insn_idx, meta.subprogno, + set_rbtree_add_callback_state); + if (err) { + verbose(env, "kfunc %s#%d failed callback verification\n", + func_name, meta.func_id); + return err; + } + } + rcu_lock = is_kfunc_bpf_rcu_read_lock(&meta); rcu_unlock = is_kfunc_bpf_rcu_read_unlock(&meta); @@ -11215,10 +11623,6 @@ return -EINVAL; } - /* Check the arguments */ - err = check_kfunc_args(env, &meta, insn_idx); - if (err < 0) - return err; /* In case of release function, we get register number of refcounted * PTR_TO_BTF_ID in bpf_kfunc_arg_meta, do the release now. */ @@ -11252,16 +11656,6 @@ } } - if (meta.func_id == special_kfunc_list[KF_bpf_rbtree_add_impl]) { - err = __check_func_call(env, insn, insn_idx_p, meta.subprogno, - set_rbtree_add_callback_state); - if (err) { - verbose(env, "kfunc %s#%d failed callback verification\n", - func_name, meta.func_id); - return err; - } - } - for (i = 0; i < CALLER_SAVED_REGS; i++) mark_reg_not_init(env, regs, caller_saved[i]); @@ -11933,6 +12327,10 @@ } switch (base_type(ptr_reg->type)) { + case PTR_TO_FLOW_KEYS: + if (known) + break; + fallthrough; case CONST_PTR_TO_MAP: /* smin_val represents the known value */ if (known && smin_val == 0 && opcode == BPF_ADD) @@ -14490,21 +14888,6 @@ BRANCH = 2, }; -static u32 state_htab_size(struct bpf_verifier_env *env) -{ - return env->prog->len; -} - -static struct bpf_verifier_state_list **explored_state( - struct bpf_verifier_env *env, - int idx) -{ - struct bpf_verifier_state *cur = env->cur_state; - struct bpf_func_state *state = cur->frame[cur->curframe]; - - return &env->explored_states[(idx ^ state->callsite) % state_htab_size(env)]; -} - static void mark_prune_point(struct bpf_verifier_env *env, int idx) { env->insn_aux_data[idx].prune_point = true; @@ -14525,6 +14908,15 @@ return env->insn_aux_data[insn_idx].force_checkpoint; } +static void mark_calls_callback(struct bpf_verifier_env *env, int idx) +{ + env->insn_aux_data[idx].calls_callback = true; +} + +static bool calls_callback(struct bpf_verifier_env *env, int insn_idx) +{ + return env->insn_aux_data[insn_idx].calls_callback; +} enum { DONE_EXPLORING = 0, @@ -14644,6 +15036,21 @@ * async state will be pushed for further exploration. */ mark_prune_point(env, t); + /* For functions that invoke callbacks it is not known how many times + * callback would be called. Verifier models callback calling functions + * by repeatedly visiting callback bodies and returning to origin call + * instruction. + * In order to stop such iteration verifier needs to identify when a + * state identical some state from a previous iteration is reached. + * Check below forces creation of checkpoint before callback calling + * instruction to allow search for such identical states. + */ + if (is_sync_callback_calling_insn(insn)) { + mark_calls_callback(env, t); + mark_force_checkpoint(env, t); + mark_prune_point(env, t); + mark_jmp_point(env, t); + } if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) { struct bpf_kfunc_call_arg_meta meta; @@ -15318,18 +15725,14 @@ struct bpf_verifier_state *cur) { struct bpf_verifier_state_list *sl; - int i; sl = *explored_state(env, insn); while (sl) { if (sl->state.branches) goto next; if (sl->state.insn_idx != insn || - sl->state.curframe != cur->curframe) + !same_callsites(&sl->state, cur)) goto next; - for (i = 0; i <= cur->curframe; i++) - if (sl->state.frame[i]->callsite != cur->frame[i]->callsite) - goto next; clean_verifier_state(env, &sl->state); next: sl = sl->next; @@ -15347,8 +15750,11 @@ /* Returns true if (rold safe implies rcur safe) */ static bool regsafe(struct bpf_verifier_env *env, struct bpf_reg_state *rold, - struct bpf_reg_state *rcur, struct bpf_idmap *idmap) + struct bpf_reg_state *rcur, struct bpf_idmap *idmap, bool exact) { + if (exact) + return regs_exact(rold, rcur, idmap); + if (!(rold->live & REG_LIVE_READ)) /* explored state didn't use this */ return true; @@ -15465,7 +15871,7 @@ } static bool stacksafe(struct bpf_verifier_env *env, struct bpf_func_state *old, - struct bpf_func_state *cur, struct bpf_idmap *idmap) + struct bpf_func_state *cur, struct bpf_idmap *idmap, bool exact) { int i, spi; @@ -15478,7 +15884,12 @@ spi = i / BPF_REG_SIZE; - if (!(old->stack[spi].spilled_ptr.live & REG_LIVE_READ)) { + if (exact && + old->stack[spi].slot_type[i % BPF_REG_SIZE] != + cur->stack[spi].slot_type[i % BPF_REG_SIZE]) + return false; + + if (!(old->stack[spi].spilled_ptr.live & REG_LIVE_READ) && !exact) { i += BPF_REG_SIZE - 1; /* explored state didn't use this */ continue; @@ -15528,7 +15939,7 @@ * return false to continue verification of this path */ if (!regsafe(env, &old->stack[spi].spilled_ptr, - &cur->stack[spi].spilled_ptr, idmap)) + &cur->stack[spi].spilled_ptr, idmap, exact)) return false; break; case STACK_DYNPTR: @@ -15610,16 +16021,16 @@ * the current state will reach 'bpf_exit' instruction safely */ static bool func_states_equal(struct bpf_verifier_env *env, struct bpf_func_state *old, - struct bpf_func_state *cur) + struct bpf_func_state *cur, bool exact) { int i; for (i = 0; i < MAX_BPF_REG; i++) if (!regsafe(env, &old->regs[i], &cur->regs[i], - &env->idmap_scratch)) + &env->idmap_scratch, exact)) return false; - if (!stacksafe(env, old, cur, &env->idmap_scratch)) + if (!stacksafe(env, old, cur, &env->idmap_scratch, exact)) return false; if (!refsafe(old, cur, &env->idmap_scratch)) @@ -15628,17 +16039,23 @@ return true; } +static void reset_idmap_scratch(struct bpf_verifier_env *env) +{ + env->idmap_scratch.tmp_id_gen = env->id_gen; + memset(&env->idmap_scratch.map, 0, sizeof(env->idmap_scratch.map)); +} + static bool states_equal(struct bpf_verifier_env *env, struct bpf_verifier_state *old, - struct bpf_verifier_state *cur) + struct bpf_verifier_state *cur, + bool exact) { int i; if (old->curframe != cur->curframe) return false; - env->idmap_scratch.tmp_id_gen = env->id_gen; - memset(&env->idmap_scratch.map, 0, sizeof(env->idmap_scratch.map)); + reset_idmap_scratch(env); /* Verification state from speculative execution simulation * must never prune a non-speculative execution one. @@ -15668,7 +16085,7 @@ for (i = 0; i <= old->curframe; i++) { if (old->frame[i]->callsite != cur->frame[i]->callsite) return false; - if (!func_states_equal(env, old->frame[i], cur->frame[i])) + if (!func_states_equal(env, old->frame[i], cur->frame[i], exact)) return false; } return true; @@ -15922,10 +16339,11 @@ { struct bpf_verifier_state_list *new_sl; struct bpf_verifier_state_list *sl, **pprev; - struct bpf_verifier_state *cur = env->cur_state, *new; - int i, j, err, states_cnt = 0; + struct bpf_verifier_state *cur = env->cur_state, *new, *loop_entry; + int i, j, n, err, states_cnt = 0; bool force_new_state = env->test_state_freq || is_force_checkpoint(env, insn_idx); bool add_new_state = force_new_state; + bool force_exact; /* bpf progs typically have pruning point every 4 instructions * http://vger.kernel.org/bpfconf2019.html#session-1 @@ -15978,9 +16396,33 @@ * It's safe to assume that iterator loop will finish, taking into * account iter_next() contract of eventually returning * sticky NULL result. + * + * Note, that states have to be compared exactly in this case because + * read and precision marks might not be finalized inside the loop. + * E.g. as in the program below: + * + * 1. r7 = -16 + * 2. r6 = bpf_get_prandom_u32() + * 3. while (bpf_iter_num_next(&fp[-8])) { + * 4. if (r6 != 42) { + * 5. r7 = -32 + * 6. r6 = bpf_get_prandom_u32() + * 7. continue + * 8. } + * 9. r0 = r10 + * 10. r0 += r7 + * 11. r8 = *(u64 *)(r0 + 0) + * 12. r6 = bpf_get_prandom_u32() + * 13. } + * + * Here verifier would first visit path 1-3, create a checkpoint at 3 + * with r7=-16, continue to 4-7,3. Existing checkpoint at 3 does + * not have read or precision mark for r7 yet, thus inexact states + * comparison would discard current state with r7=-32 + * => unsafe memory access at 11 would not be caught. */ if (is_iter_next_insn(env, insn_idx)) { - if (states_equal(env, &sl->state, cur)) { + if (states_equal(env, &sl->state, cur, true)) { struct bpf_func_state *cur_frame; struct bpf_reg_state *iter_state, *iter_reg; int spi; @@ -15996,17 +16438,29 @@ */ spi = __get_spi(iter_reg->off + iter_reg->var_off.value); iter_state = &func(env, iter_reg)->stack[spi].spilled_ptr; - if (iter_state->iter.state == BPF_ITER_STATE_ACTIVE) + if (iter_state->iter.state == BPF_ITER_STATE_ACTIVE) { + update_loop_entry(cur, &sl->state); goto hit; + } } goto skip_inf_loop_check; } + if (calls_callback(env, insn_idx)) { + if (states_equal(env, &sl->state, cur, true)) + goto hit; + goto skip_inf_loop_check; + } /* attempt to detect infinite loop to avoid unnecessary doomed work */ if (states_maybe_looping(&sl->state, cur) && - states_equal(env, &sl->state, cur) && - !iter_active_depths_differ(&sl->state, cur)) { + states_equal(env, &sl->state, cur, false) && + !iter_active_depths_differ(&sl->state, cur) && + sl->state.callback_unroll_depth == cur->callback_unroll_depth) { verbose_linfo(env, insn_idx, "; "); verbose(env, "infinite loop detected at insn %d\n", insn_idx); + verbose(env, "cur state:"); + print_verifier_state(env, cur->frame[cur->curframe], true); + verbose(env, "old state:"); + print_verifier_state(env, sl->state.frame[cur->curframe], true); return -EINVAL; } /* if the verifier is processing a loop, avoid adding new state @@ -16028,7 +16482,36 @@ add_new_state = false; goto miss; } - if (states_equal(env, &sl->state, cur)) { + /* If sl->state is a part of a loop and this loop's entry is a part of + * current verification path then states have to be compared exactly. + * 'force_exact' is needed to catch the following case: + * + * initial Here state 'succ' was processed first, + * | it was eventually tracked to produce a + * V state identical to 'hdr'. + * .---------> hdr All branches from 'succ' had been explored + * | | and thus 'succ' has its .branches == 0. + * | V + * | .------... Suppose states 'cur' and 'succ' correspond + * | | | to the same instruction + callsites. + * | V V In such case it is necessary to check + * | ... ... if 'succ' and 'cur' are states_equal(). + * | | | If 'succ' and 'cur' are a part of the + * | V V same loop exact flag has to be set. + * | succ <- cur To check if that is the case, verify + * | | if loop entry of 'succ' is in current + * | V DFS path. + * | ... + * | | + * '----' + * + * Additional details are in the comment before get_loop_entry(). + */ + loop_entry = get_loop_entry(&sl->state); + force_exact = loop_entry && loop_entry->branches > 0; + if (states_equal(env, &sl->state, cur, force_exact)) { + if (force_exact) + update_loop_entry(cur, loop_entry); hit: sl->hit_cnt++; /* reached equivalent register/stack state, @@ -16067,13 +16550,18 @@ * to keep checking from state equivalence point of view. * Higher numbers increase max_states_per_insn and verification time, * but do not meaningfully decrease insn_processed. + * 'n' controls how many times state could miss before eviction. + * Use bigger 'n' for checkpoints because evicting checkpoint states + * too early would hinder iterator convergence. */ - if (sl->miss_cnt > sl->hit_cnt * 3 + 3) { + n = is_force_checkpoint(env, insn_idx) && sl->state.branches > 0 ? 64 : 3; + if (sl->miss_cnt > sl->hit_cnt * n + n) { /* the state is unlikely to be useful. Remove it to * speed up verification */ *pprev = sl->next; - if (sl->state.frame[0]->regs[0].live & REG_LIVE_DONE) { + if (sl->state.frame[0]->regs[0].live & REG_LIVE_DONE && + !sl->state.used_as_loop_entry) { u32 br = sl->state.branches; WARN_ONCE(br, @@ -16142,6 +16630,7 @@ cur->parent = new; cur->first_insn_idx = insn_idx; + cur->dfs_depth = new->dfs_depth + 1; clear_jmp_history(cur); new_sl->next = *explored_state(env, insn_idx); *explored_state(env, insn_idx) = new_sl; diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/events/core.c linux-lowlatency-hwe-6.5-6.5.0/kernel/events/core.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/events/core.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/events/core.c @@ -11429,9 +11429,30 @@ static struct attribute *pmu_dev_attrs[] = { &dev_attr_type.attr, &dev_attr_perf_event_mux_interval_ms.attr, + &dev_attr_nr_addr_filters.attr, + NULL, +}; + +static umode_t pmu_dev_is_visible(struct kobject *kobj, struct attribute *a, int n) +{ + struct device *dev = kobj_to_dev(kobj); + struct pmu *pmu = dev_get_drvdata(dev); + + if (n == 2 && !pmu->nr_addr_filters) + return 0; + + return a->mode; +} + +static struct attribute_group pmu_dev_attr_group = { + .is_visible = pmu_dev_is_visible, + .attrs = pmu_dev_attrs, +}; + +static const struct attribute_group *pmu_dev_groups[] = { + &pmu_dev_attr_group, NULL, }; -ATTRIBUTE_GROUPS(pmu_dev); static int pmu_bus_running; static struct bus_type pmu_bus = { @@ -11468,18 +11489,11 @@ if (ret) goto free_dev; - /* For PMUs with address filters, throw in an extra attribute: */ - if (pmu->nr_addr_filters) - ret = device_create_file(pmu->dev, &dev_attr_nr_addr_filters); - - if (ret) - goto del_dev; - - if (pmu->attr_update) + if (pmu->attr_update) { ret = sysfs_update_groups(&pmu->dev->kobj, pmu->attr_update); - - if (ret) - goto del_dev; + if (ret) + goto del_dev; + } out: return ret; diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/rcu/tree.c linux-lowlatency-hwe-6.5-6.5.0/kernel/rcu/tree.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/rcu/tree.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/rcu/tree.c @@ -1009,6 +1009,38 @@ return needmore; } +static void swake_up_one_online_ipi(void *arg) +{ + struct swait_queue_head *wqh = arg; + + swake_up_one(wqh); +} + +static void swake_up_one_online(struct swait_queue_head *wqh) +{ + int cpu = get_cpu(); + + /* + * If called from rcutree_report_cpu_starting(), wake up + * is dangerous that late in the CPU-down hotplug process. The + * scheduler might queue an ignored hrtimer. Defer the wake up + * to an online CPU instead. + */ + if (unlikely(cpu_is_offline(cpu))) { + int target; + + target = cpumask_any_and(housekeeping_cpumask(HK_TYPE_RCU), + cpu_online_mask); + + smp_call_function_single(target, swake_up_one_online_ipi, + wqh, 0); + put_cpu(); + } else { + put_cpu(); + swake_up_one(wqh); + } +} + /* * Awaken the grace-period kthread. Don't do a self-awaken (unless in an * interrupt or softirq handler, in which case we just might immediately @@ -1033,7 +1065,7 @@ return; WRITE_ONCE(rcu_state.gp_wake_time, jiffies); WRITE_ONCE(rcu_state.gp_wake_seq, READ_ONCE(rcu_state.gp_seq)); - swake_up_one(&rcu_state.gp_wq); + swake_up_one_online(&rcu_state.gp_wq); } /* diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/time/clocksource.c linux-lowlatency-hwe-6.5-6.5.0/kernel/time/clocksource.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/time/clocksource.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/time/clocksource.c @@ -99,6 +99,7 @@ * Interval: 0.5sec. */ #define WATCHDOG_INTERVAL (HZ >> 1) +#define WATCHDOG_INTERVAL_MAX_NS ((2 * WATCHDOG_INTERVAL) * (NSEC_PER_SEC / HZ)) /* * Threshold: 0.0312s, when doubled: 0.0625s. @@ -134,6 +135,7 @@ static DEFINE_SPINLOCK(watchdog_lock); static int watchdog_running; static atomic_t watchdog_reset_pending; +static int64_t watchdog_max_interval; static inline void clocksource_watchdog_lock(unsigned long *flags) { @@ -399,8 +401,8 @@ static void clocksource_watchdog(struct timer_list *unused) { u64 csnow, wdnow, cslast, wdlast, delta; + int64_t wd_nsec, cs_nsec, interval; int next_cpu, reset_pending; - int64_t wd_nsec, cs_nsec; struct clocksource *cs; enum wd_read_status read_ret; unsigned long extra_wait = 0; @@ -470,6 +472,27 @@ if (atomic_read(&watchdog_reset_pending)) continue; + /* + * The processing of timer softirqs can get delayed (usually + * on account of ksoftirqd not getting to run in a timely + * manner), which causes the watchdog interval to stretch. + * Skew detection may fail for longer watchdog intervals + * on account of fixed margins being used. + * Some clocksources, e.g. acpi_pm, cannot tolerate + * watchdog intervals longer than a few seconds. + */ + interval = max(cs_nsec, wd_nsec); + if (unlikely(interval > WATCHDOG_INTERVAL_MAX_NS)) { + if (system_state > SYSTEM_SCHEDULING && + interval > 2 * watchdog_max_interval) { + watchdog_max_interval = interval; + pr_warn("Long readout interval, skipping watchdog check: cs_nsec: %lld wd_nsec: %lld\n", + cs_nsec, wd_nsec); + } + watchdog_timer.expires = jiffies; + continue; + } + /* Check the deviation from the watchdog clocksource. */ md = cs->uncertainty_margin + watchdog->uncertainty_margin; if (abs(cs_nsec - wd_nsec) > md) { diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/time/tick-sched.c linux-lowlatency-hwe-6.5-6.5.0/kernel/time/tick-sched.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/time/tick-sched.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/time/tick-sched.c @@ -1547,13 +1547,23 @@ void tick_cancel_sched_timer(int cpu) { struct tick_sched *ts = &per_cpu(tick_cpu_sched, cpu); + ktime_t idle_sleeptime, iowait_sleeptime; + unsigned long idle_calls, idle_sleeps; # ifdef CONFIG_HIGH_RES_TIMERS if (ts->sched_timer.base) hrtimer_cancel(&ts->sched_timer); # endif + idle_sleeptime = ts->idle_sleeptime; + iowait_sleeptime = ts->iowait_sleeptime; + idle_calls = ts->idle_calls; + idle_sleeps = ts->idle_sleeps; memset(ts, 0, sizeof(*ts)); + ts->idle_sleeptime = idle_sleeptime; + ts->iowait_sleeptime = iowait_sleeptime; + ts->idle_calls = idle_calls; + ts->idle_sleeps = idle_sleeps; } #endif diff -u linux-lowlatency-hwe-6.5-6.5.0/kernel/trace/bpf_trace.c linux-lowlatency-hwe-6.5-6.5.0/kernel/trace/bpf_trace.c --- linux-lowlatency-hwe-6.5-6.5.0/kernel/trace/bpf_trace.c +++ linux-lowlatency-hwe-6.5-6.5.0/kernel/trace/bpf_trace.c @@ -40,6 +40,9 @@ #define bpf_event_rcu_dereference(p) \ rcu_dereference_protected(p, lockdep_is_held(&bpf_event_mutex)) +#define MAX_UPROBE_MULTI_CNT (1U << 20) +#define MAX_KPROBE_MULTI_CNT (1U << 20) + #ifdef CONFIG_MODULES struct bpf_trace_module { struct module *module; @@ -2810,10 +2813,14 @@ usyms = u64_to_user_ptr(attr->link_create.kprobe_multi.syms); if (!!uaddrs == !!usyms) return -EINVAL; + if (cnt > MAX_KPROBE_MULTI_CNT) + return -E2BIG; cnt = attr->link_create.kprobe_multi.cnt; if (!cnt) return -EINVAL; + if (cnt > MAX_UPROBE_MULTI_CNT) + return -E2BIG; size = cnt * sizeof(*addrs); addrs = kvmalloc_array(cnt, sizeof(*addrs), GFP_KERNEL); diff -u linux-lowlatency-hwe-6.5-6.5.0/mm/migrate.c linux-lowlatency-hwe-6.5-6.5.0/mm/migrate.c --- linux-lowlatency-hwe-6.5-6.5.0/mm/migrate.c +++ linux-lowlatency-hwe-6.5-6.5.0/mm/migrate.c @@ -1023,32 +1023,31 @@ } /* - * To record some information during migration, we use some unused - * fields (mapping and private) of struct folio of the newly allocated - * destination folio. This is safe because nobody is using them - * except us. + * To record some information during migration, we use unused private + * field of struct folio of the newly allocated destination folio. + * This is safe because nobody is using it except us. */ -union migration_ptr { - struct anon_vma *anon_vma; - struct address_space *mapping; +enum { + PAGE_WAS_MAPPED = BIT(0), + PAGE_WAS_MLOCKED = BIT(1), + PAGE_OLD_STATES = PAGE_WAS_MAPPED | PAGE_WAS_MLOCKED, }; + static void __migrate_folio_record(struct folio *dst, - unsigned long page_was_mapped, + int old_page_state, struct anon_vma *anon_vma) { - union migration_ptr ptr = { .anon_vma = anon_vma }; - dst->mapping = ptr.mapping; - dst->private = (void *)page_was_mapped; + dst->private = (void *)anon_vma + old_page_state; } static void __migrate_folio_extract(struct folio *dst, - int *page_was_mappedp, + int *old_page_state, struct anon_vma **anon_vmap) { - union migration_ptr ptr = { .mapping = dst->mapping }; - *anon_vmap = ptr.anon_vma; - *page_was_mappedp = (unsigned long)dst->private; - dst->mapping = NULL; + unsigned long private = (unsigned long)dst->private; + + *anon_vmap = (struct anon_vma *)(private & ~PAGE_OLD_STATES); + *old_page_state = private & PAGE_OLD_STATES; dst->private = NULL; } @@ -1108,7 +1107,7 @@ { struct folio *dst; int rc = -EAGAIN; - int page_was_mapped = 0; + int old_page_state = 0; struct anon_vma *anon_vma = NULL; bool is_lru = !__PageMovable(&src->page); bool locked = false; @@ -1162,6 +1161,8 @@ folio_lock(src); } locked = true; + if (folio_test_mlocked(src)) + old_page_state |= PAGE_WAS_MLOCKED; if (folio_test_writeback(src)) { /* @@ -1211,7 +1212,7 @@ dst_locked = true; if (unlikely(!is_lru)) { - __migrate_folio_record(dst, page_was_mapped, anon_vma); + __migrate_folio_record(dst, old_page_state, anon_vma); return MIGRATEPAGE_UNMAP; } @@ -1237,11 +1238,11 @@ VM_BUG_ON_FOLIO(folio_test_anon(src) && !folio_test_ksm(src) && !anon_vma, src); try_to_migrate(src, mode == MIGRATE_ASYNC ? TTU_BATCH_FLUSH : 0); - page_was_mapped = 1; + old_page_state |= PAGE_WAS_MAPPED; } if (!folio_mapped(src)) { - __migrate_folio_record(dst, page_was_mapped, anon_vma); + __migrate_folio_record(dst, old_page_state, anon_vma); return MIGRATEPAGE_UNMAP; } @@ -1253,7 +1254,8 @@ if (rc == -EAGAIN) ret = NULL; - migrate_folio_undo_src(src, page_was_mapped, anon_vma, locked, ret); + migrate_folio_undo_src(src, old_page_state & PAGE_WAS_MAPPED, + anon_vma, locked, ret); migrate_folio_undo_dst(dst, dst_locked, put_new_folio, private); return rc; @@ -1266,12 +1268,12 @@ struct list_head *ret) { int rc; - int page_was_mapped = 0; + int old_page_state = 0; struct anon_vma *anon_vma = NULL; bool is_lru = !__PageMovable(&src->page); struct list_head *prev; - __migrate_folio_extract(dst, &page_was_mapped, &anon_vma); + __migrate_folio_extract(dst, &old_page_state, &anon_vma); prev = dst->lru.prev; list_del(&dst->lru); @@ -1292,10 +1294,10 @@ * isolated from the unevictable LRU: but this case is the easiest. */ folio_add_lru(dst); - if (page_was_mapped) + if (old_page_state & PAGE_WAS_MLOCKED) lru_add_drain(); - if (page_was_mapped) + if (old_page_state & PAGE_WAS_MAPPED) remove_migration_ptes(src, dst, false); out_unlock_both: @@ -1327,11 +1329,12 @@ */ if (rc == -EAGAIN) { list_add(&dst->lru, prev); - __migrate_folio_record(dst, page_was_mapped, anon_vma); + __migrate_folio_record(dst, old_page_state, anon_vma); return rc; } - migrate_folio_undo_src(src, page_was_mapped, anon_vma, true, ret); + migrate_folio_undo_src(src, old_page_state & PAGE_WAS_MAPPED, + anon_vma, true, ret); migrate_folio_undo_dst(dst, true, put_new_folio, private); return rc; @@ -1799,12 +1802,12 @@ dst = list_first_entry(&dst_folios, struct folio, lru); dst2 = list_next_entry(dst, lru); list_for_each_entry_safe(folio, folio2, &unmap_folios, lru) { - int page_was_mapped = 0; + int old_page_state = 0; struct anon_vma *anon_vma = NULL; - __migrate_folio_extract(dst, &page_was_mapped, &anon_vma); - migrate_folio_undo_src(folio, page_was_mapped, anon_vma, - true, ret_folios); + __migrate_folio_extract(dst, &old_page_state, &anon_vma); + migrate_folio_undo_src(folio, old_page_state & PAGE_WAS_MAPPED, + anon_vma, true, ret_folios); list_del(&dst->lru); migrate_folio_undo_dst(dst, true, put_new_folio, private); dst = dst2; diff -u linux-lowlatency-hwe-6.5-6.5.0/mm/page_alloc.c linux-lowlatency-hwe-6.5-6.5.0/mm/page_alloc.c --- linux-lowlatency-hwe-6.5-6.5.0/mm/page_alloc.c +++ linux-lowlatency-hwe-6.5-6.5.0/mm/page_alloc.c @@ -3860,14 +3860,9 @@ else (*no_progress_loops)++; - /* - * Make sure we converge to OOM if we cannot make any progress - * several times in the row. - */ - if (*no_progress_loops > MAX_RECLAIM_RETRIES) { - /* Before OOM, exhaust highatomic_reserve */ - return unreserve_highatomic_pageblock(ac, true); - } + if (*no_progress_loops > MAX_RECLAIM_RETRIES) + goto out; + /* * Keep reclaiming pages while there is a chance this will lead @@ -3910,6 +3905,11 @@ schedule_timeout_uninterruptible(1); else cond_resched(); +out: + /* Before OOM, exhaust highatomic_reserve */ + if (!ret) + return unreserve_highatomic_pageblock(ac, true); + return ret; } diff -u linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_conn.c linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_conn.c --- linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_conn.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_conn.c @@ -2380,12 +2380,10 @@ hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); - /* If we're already encrypted set the REAUTH_PEND flag, - * otherwise set the ENCRYPT_PEND. + /* Set the ENCRYPT_PEND to trigger encryption after + * authentication. */ - if (test_bit(HCI_CONN_ENCRYPT, &conn->flags)) - set_bit(HCI_CONN_REAUTH_PEND, &conn->flags); - else + if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags)) set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); } diff -u linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_event.c linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_event.c --- linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_event.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_event.c @@ -3500,14 +3500,8 @@ if (!ev->status) { clear_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); - - if (!hci_conn_ssp_enabled(conn) && - test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { - bt_dev_info(hdev, "re-auth of legacy device is not possible."); - } else { - set_bit(HCI_CONN_AUTH, &conn->flags); - conn->sec_level = conn->pending_sec_level; - } + set_bit(HCI_CONN_AUTH, &conn->flags); + conn->sec_level = conn->pending_sec_level; } else { if (ev->status == HCI_ERROR_PIN_OR_KEY_MISSING) set_bit(HCI_CONN_AUTH_FAILURE, &conn->flags); @@ -3516,7 +3510,6 @@ } clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); - clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags); if (conn->state == BT_CONFIG) { if (!ev->status && hci_conn_ssp_enabled(conn)) { diff -u linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_sync.c linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_sync.c --- linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_sync.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/hci_sync.c @@ -3819,12 +3819,14 @@ if (lmp_bredr_capable(hdev)) { events[4] |= 0x01; /* Flow Specification Complete */ - /* Don't set Disconnect Complete when suspended as that - * would wakeup the host when disconnecting due to - * suspend. + /* Don't set Disconnect Complete and mode change when + * suspended as that would wakeup the host when disconnecting + * due to suspend. */ - if (hdev->suspended) + if (hdev->suspended) { events[0] &= 0xef; + events[2] &= 0xf7; + } } else { /* Use a different default for LE-only devices */ memset(events, 0, sizeof(events)); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/iso.c linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/iso.c --- linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/iso.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/iso.c @@ -52,6 +52,7 @@ enum { BT_SK_BIG_SYNC, BT_SK_PA_SYNC, + BT_SK_PA_SYNC_TERM, }; struct iso_pinfo { @@ -81,4 +82,9 @@ static void iso_sock_disconn(struct sock *sk); +typedef bool (*iso_sock_match_t)(struct sock *sk, void *data); + +static struct sock *iso_get_sock_listen(bdaddr_t *src, bdaddr_t *dst, + iso_sock_match_t match, void *data); + /* ---- ISO timers ---- */ #define ISO_CONN_TIMEOUT (HZ * 40) @@ -188,10 +194,21 @@ sock_set_flag(sk, SOCK_ZAPPED); } +static bool iso_match_conn_sync_handle(struct sock *sk, void *data) +{ + struct hci_conn *hcon = data; + + if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) + return false; + + return hcon->sync_handle == iso_pi(sk)->sync_handle; +} + static void iso_conn_del(struct hci_conn *hcon, int err) { struct iso_conn *conn = hcon->iso_data; struct sock *sk; + struct sock *parent; if (!conn) return; @@ -207,6 +224,25 @@ if (sk) { lock_sock(sk); + + /* While a PA sync hcon is in the process of closing, + * mark parent socket with a flag, so that any residual + * BIGInfo adv reports that arrive before PA sync is + * terminated are not processed anymore. + */ + if (test_bit(BT_SK_PA_SYNC, &iso_pi(sk)->flags)) { + parent = iso_get_sock_listen(&hcon->src, + &hcon->dst, + iso_match_conn_sync_handle, + hcon); + + if (parent) { + set_bit(BT_SK_PA_SYNC_TERM, + &iso_pi(parent)->flags); + sock_put(parent); + } + } + iso_sock_clear_timer(sk); iso_chan_del(sk, err); release_sock(sk); @@ -543,8 +579,6 @@ return NULL; } -typedef bool (*iso_sock_match_t)(struct sock *sk, void *data); - /* Find socket listening: * source bdaddr (Unicast) * destination bdaddr (Broadcast only) @@ -1743,9 +1777,20 @@ /* Try to get PA sync listening socket, if it exists */ sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr, iso_match_pa_sync_flag, NULL); - if (!sk) + + if (!sk) { sk = iso_get_sock_listen(&hdev->bdaddr, bdaddr, iso_match_sync_handle, ev2); + + /* If PA Sync is in process of terminating, + * do not handle any more BIGInfo adv reports. + */ + + if (sk && test_bit(BT_SK_PA_SYNC_TERM, + &iso_pi(sk)->flags)) + return lm; + } + if (sk) { int err; diff -u linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/l2cap_core.c linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/l2cap_core.c --- linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/l2cap_core.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/bluetooth/l2cap_core.c @@ -6532,7 +6532,8 @@ if (len > skb->len || !cmd->ident) { BT_DBG("corrupted command"); l2cap_sig_send_rej(conn, cmd->ident); - break; + skb_pull(skb, len > skb->len ? skb->len : len); + continue; } err = l2cap_bredr_sig_cmd(conn, cmd, len, skb->data); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/bridge/br_netfilter_hooks.c linux-lowlatency-hwe-6.5-6.5.0/net/bridge/br_netfilter_hooks.c --- linux-lowlatency-hwe-6.5-6.5.0/net/bridge/br_netfilter_hooks.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/bridge/br_netfilter_hooks.c @@ -279,8 +279,17 @@ if ((READ_ONCE(neigh->nud_state) & NUD_CONNECTED) && READ_ONCE(neigh->hh.hh_len)) { + struct net_device *br_indev; + + br_indev = nf_bridge_get_physindev(skb, net); + if (!br_indev) { + neigh_release(neigh); + goto free_skb; + } + neigh_hh_bridge(&neigh->hh, skb); - skb->dev = nf_bridge->physindev; + skb->dev = br_indev; + ret = br_handle_frame_finish(net, sk, skb); } else { /* the neighbour function below overwrites the complete @@ -352,12 +361,18 @@ */ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_buff *skb) { - struct net_device *dev = skb->dev; + struct net_device *dev = skb->dev, *br_indev; struct iphdr *iph = ip_hdr(skb); struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); struct rtable *rt; int err; + br_indev = nf_bridge_get_physindev(skb, net); + if (!br_indev) { + kfree_skb(skb); + return 0; + } + nf_bridge->frag_max_size = IPCB(skb)->frag_max_size; if (nf_bridge->pkt_otherhost) { @@ -397,7 +412,7 @@ } else { if (skb_dst(skb)->dev == dev) { bridged_dnat: - skb->dev = nf_bridge->physindev; + skb->dev = br_indev; nf_bridge_update_protocol(skb); nf_bridge_push_encap_header(skb); br_nf_hook_thresh(NF_BR_PRE_ROUTING, @@ -410,7 +425,7 @@ skb->pkt_type = PACKET_HOST; } } else { - rt = bridge_parent_rtable(nf_bridge->physindev); + rt = bridge_parent_rtable(br_indev); if (!rt) { kfree_skb(skb); return 0; @@ -419,7 +434,7 @@ skb_dst_set_noref(skb, &rt->dst); } - skb->dev = nf_bridge->physindev; + skb->dev = br_indev; nf_bridge_update_protocol(skb); nf_bridge_push_encap_header(skb); br_nf_hook_thresh(NF_BR_PRE_ROUTING, net, sk, skb, skb->dev, NULL, @@ -456,7 +471,7 @@ } nf_bridge->in_prerouting = 1; - nf_bridge->physindev = skb->dev; + nf_bridge->physinif = skb->dev->ifindex; skb->dev = brnf_get_logical_dev(skb, skb->dev, net); if (skb->protocol == htons(ETH_P_8021Q)) @@ -553,7 +568,11 @@ if (skb->protocol == htons(ETH_P_IPV6)) nf_bridge->frag_max_size = IP6CB(skb)->frag_max_size; - in = nf_bridge->physindev; + in = nf_bridge_get_physindev(skb, net); + if (!in) { + kfree_skb(skb); + return 0; + } if (nf_bridge->pkt_otherhost) { skb->pkt_type = PACKET_OTHERHOST; nf_bridge->pkt_otherhost = false; @@ -897,6 +916,13 @@ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb) { struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); + struct net_device *br_indev; + + br_indev = nf_bridge_get_physindev(skb, dev_net(skb->dev)); + if (!br_indev) { + kfree_skb(skb); + return; + } skb_pull(skb, ETH_HLEN); nf_bridge->bridged_dnat = 0; @@ -906,7 +932,7 @@ skb_copy_to_linear_data_offset(skb, -(ETH_HLEN - ETH_ALEN), nf_bridge->neigh_header, ETH_HLEN - ETH_ALEN); - skb->dev = nf_bridge->physindev; + skb->dev = br_indev; nf_bridge->physoutdev = NULL; br_handle_frame_finish(dev_net(skb->dev), NULL, skb); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/core/dev.c linux-lowlatency-hwe-6.5-6.5.0/net/core/dev.c --- linux-lowlatency-hwe-6.5-6.5.0/net/core/dev.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/core/dev.c @@ -11397,6 +11397,7 @@ static void __net_exit default_device_exit_net(struct net *net) { + struct netdev_name_node *name_node, *tmp; struct net_device *dev, *aux; /* * Push all migratable network devices back to the @@ -11419,6 +11420,14 @@ snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex); if (netdev_name_in_use(&init_net, fb_name)) snprintf(fb_name, IFNAMSIZ, "dev%%d"); + + netdev_for_each_altname_safe(dev, name_node, tmp) + if (netdev_name_in_use(&init_net, name_node->name)) { + netdev_name_node_del(name_node); + synchronize_rcu(); + __netdev_name_node_alt_destroy(name_node); + } + err = dev_change_net_namespace(dev, &init_net, fb_name); if (err) { pr_emerg("%s: failed to move %s to init_net: %d\n", diff -u linux-lowlatency-hwe-6.5-6.5.0/net/core/dev.h linux-lowlatency-hwe-6.5-6.5.0/net/core/dev.h --- linux-lowlatency-hwe-6.5-6.5.0/net/core/dev.h +++ linux-lowlatency-hwe-6.5-6.5.0/net/core/dev.h @@ -64,6 +64,9 @@ #define netdev_for_each_altname(dev, namenode) \ list_for_each_entry((namenode), &(dev)->name_node->list, list) +#define netdev_for_each_altname_safe(dev, namenode, next) \ + list_for_each_entry_safe((namenode), (next), &(dev)->name_node->list, \ + list) int netdev_name_node_alt_create(struct net_device *dev, const char *name); int netdev_name_node_alt_destroy(struct net_device *dev, const char *name); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/core/filter.c linux-lowlatency-hwe-6.5-6.5.0/net/core/filter.c --- linux-lowlatency-hwe-6.5-6.5.0/net/core/filter.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/core/filter.c @@ -81,6 +81,7 @@ #include #include #include +#include static const struct bpf_func_proto * bpf_sk_base_func_proto(enum bpf_func_id func_id); @@ -11779,6 +11780,27 @@ return 0; } + +__bpf_kfunc int bpf_sock_addr_set_sun_path(struct bpf_sock_addr_kern *sa_kern, + const u8 *sun_path, u32 sun_path__sz) +{ + struct sockaddr_un *un; + + if (sa_kern->sk->sk_family != AF_UNIX) + return -EINVAL; + + /* We do not allow changing the address to unnamed or larger than the + * maximum allowed address size for a unix sockaddr. + */ + if (sun_path__sz == 0 || sun_path__sz > UNIX_PATH_MAX) + return -EINVAL; + + un = (struct sockaddr_un *)sa_kern->uaddr; + memcpy(un->sun_path, sun_path, sun_path__sz); + sa_kern->uaddrlen = offsetof(struct sockaddr_un, sun_path) + sun_path__sz; + + return 0; +} __diag_pop(); int bpf_dynptr_from_skb_rdonly(struct sk_buff *skb, u64 flags, @@ -11803,6 +11825,10 @@ BTF_ID_FLAGS(func, bpf_dynptr_from_xdp) BTF_SET8_END(bpf_kfunc_check_set_xdp) +BTF_SET8_START(bpf_kfunc_check_set_sock_addr) +BTF_ID_FLAGS(func, bpf_sock_addr_set_sun_path) +BTF_SET8_END(bpf_kfunc_check_set_sock_addr) + static const struct btf_kfunc_id_set bpf_kfunc_set_skb = { .owner = THIS_MODULE, .set = &bpf_kfunc_check_set_skb, @@ -11813,6 +11839,11 @@ .set = &bpf_kfunc_check_set_xdp, }; +static const struct btf_kfunc_id_set bpf_kfunc_set_sock_addr = { + .owner = THIS_MODULE, + .set = &bpf_kfunc_check_set_sock_addr, +}; + static int __init bpf_kfunc_init(void) { int ret; @@ -11827,7 +11858,9 @@ ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_XMIT, &bpf_kfunc_set_skb); ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LWT_SEG6LOCAL, &bpf_kfunc_set_skb); ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_NETFILTER, &bpf_kfunc_set_skb); - return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp); + ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp); + return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, + &bpf_kfunc_set_sock_addr); } late_initcall(bpf_kfunc_init); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/core/rtnetlink.c linux-lowlatency-hwe-6.5-6.5.0/net/core/rtnetlink.c --- linux-lowlatency-hwe-6.5-6.5.0/net/core/rtnetlink.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/core/rtnetlink.c @@ -2870,13 +2870,6 @@ call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); } - if (tb[IFLA_MASTER]) { - err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack); - if (err) - goto errout; - status |= DO_SETLINK_MODIFIED; - } - if (ifm->ifi_flags || ifm->ifi_change) { err = dev_change_flags(dev, rtnl_dev_combine_flags(dev, ifm), extack); @@ -2884,6 +2877,13 @@ goto errout; } + if (tb[IFLA_MASTER]) { + err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack); + if (err) + goto errout; + status |= DO_SETLINK_MODIFIED; + } + if (tb[IFLA_CARRIER]) { err = dev_change_carrier(dev, nla_get_u8(tb[IFLA_CARRIER])); if (err) diff -u linux-lowlatency-hwe-6.5-6.5.0/net/core/sock.c linux-lowlatency-hwe-6.5-6.5.0/net/core/sock.c --- linux-lowlatency-hwe-6.5-6.5.0/net/core/sock.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/core/sock.c @@ -107,6 +107,7 @@ #include #include #include +#include #include #include #include @@ -4145,8 +4146,14 @@ { struct sock *sk = p; - return !skb_queue_empty_lockless(&sk->sk_receive_queue) || - sk_busy_loop_timeout(sk, start_time); + if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) + return true; + + if (sk_is_udp(sk) && + !skb_queue_empty_lockless(&udp_sk(sk)->reader_queue)) + return true; + + return sk_busy_loop_timeout(sk, start_time); } EXPORT_SYMBOL(sk_busy_loop_end); #endif /* CONFIG_NET_RX_BUSY_POLL */ diff -u linux-lowlatency-hwe-6.5-6.5.0/net/devlink/leftover.c linux-lowlatency-hwe-6.5-6.5.0/net/devlink/leftover.c --- linux-lowlatency-hwe-6.5-6.5.0/net/devlink/leftover.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/devlink/leftover.c @@ -1195,7 +1195,7 @@ return -EOPNOTSUPP; } if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) { - NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR], + NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FN_ATTR_STATE], "Function does not support state setting"); return -EOPNOTSUPP; } diff -u linux-lowlatency-hwe-6.5-6.5.0/net/dns_resolver/dns_key.c linux-lowlatency-hwe-6.5-6.5.0/net/dns_resolver/dns_key.c --- linux-lowlatency-hwe-6.5-6.5.0/net/dns_resolver/dns_key.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/dns_resolver/dns_key.c @@ -104,7 +104,7 @@ const struct dns_server_list_v1_header *v1; /* It may be a server list. */ - if (datalen <= sizeof(*v1)) + if (datalen < sizeof(*v1)) return -EINVAL; v1 = (const struct dns_server_list_v1_header *)data; diff -u linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/af_inet.c linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/af_inet.c --- linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/af_inet.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/af_inet.c @@ -324,6 +324,9 @@ if (INET_PROTOSW_REUSE & answer_flags) sk->sk_reuse = SK_CAN_REUSE; + if (INET_PROTOSW_ICSK & answer_flags) + inet_init_csk_locks(sk); + inet = inet_sk(sk); inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0; @@ -447,7 +450,7 @@ /* BPF prog is run before any checks are done so that if the prog * changes context in a wrong way it will be caught. */ - err = BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr, + err = BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr, &addr_len, CGROUP_INET4_BIND, &flags); if (err) return err; @@ -784,6 +787,7 @@ struct sock *sk = sock->sk; struct inet_sock *inet = inet_sk(sk); DECLARE_SOCKADDR(struct sockaddr_in *, sin, uaddr); + int sin_addr_len = sizeof(*sin); sin->sin_family = AF_INET; lock_sock(sk); @@ -796,7 +800,7 @@ } sin->sin_port = inet->inet_dport; sin->sin_addr.s_addr = inet->inet_daddr; - BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, + BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, &sin_addr_len, CGROUP_INET4_GETPEERNAME); } else { __be32 addr = inet->inet_rcv_saddr; @@ -804,12 +808,12 @@ addr = inet->inet_saddr; sin->sin_port = inet->inet_sport; sin->sin_addr.s_addr = addr; - BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, + BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, &sin_addr_len, CGROUP_INET4_GETSOCKNAME); } release_sock(sk); memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); - return sizeof(*sin); + return sin_addr_len; } EXPORT_SYMBOL(inet_getname); @@ -1622,6 +1626,7 @@ #endif return -EINVAL; } +EXPORT_SYMBOL(inet_recv_error); int inet_gro_complete(struct sk_buff *skb, int nhoff) { diff -u linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/inet_connection_sock.c linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/inet_connection_sock.c --- linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/inet_connection_sock.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/inet_connection_sock.c @@ -730,6 +730,10 @@ } if (req) reqsk_put(req); + + if (newsk) + inet_init_csk_locks(newsk); + return newsk; out_err: newsk = NULL; diff -u linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/ip_output.c linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/ip_output.c --- linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/ip_output.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/ip_output.c @@ -1286,6 +1286,12 @@ if (unlikely(!rt)) return -EFAULT; + cork->fragsize = ip_sk_use_pmtu(sk) ? + dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu); + + if (!inetdev_valid_mtu(cork->fragsize)) + return -ENETUNREACH; + /* * setup for corking. */ @@ -1302,12 +1308,6 @@ cork->addr = ipc->addr; } - cork->fragsize = ip_sk_use_pmtu(sk) ? - dst_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu); - - if (!inetdev_valid_mtu(cork->fragsize)) - return -ENETUNREACH; - cork->gso_size = ipc->gso_size; cork->dst = &rt->dst; diff -u linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/ip_sockglue.c linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/ip_sockglue.c --- linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/ip_sockglue.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/ip_sockglue.c @@ -1409,12 +1409,13 @@ * ipv4_pktinfo_prepare - transfer some info from rtable to skb * @sk: socket * @skb: buffer + * @drop_dst: if true, drops skb dst * * To support IP_CMSG_PKTINFO option, we store rt_iif and specific * destination in skb->cb[] before dst drop. * This way, receiver doesn't make cache line misses to read rtable. */ -void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb) +void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb, bool drop_dst) { struct in_pktinfo *pktinfo = PKTINFO_SKB_CB(skb); bool prepare = (inet_sk(sk)->cmsg_flags & IP_CMSG_PKTINFO) || @@ -1443,7 +1444,8 @@ pktinfo->ipi_ifindex = 0; pktinfo->ipi_spec_dst.s_addr = 0; } - skb_dst_drop(skb); + if (drop_dst) + skb_dst_drop(skb); } int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, diff -u linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/tcp.c linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/tcp.c --- linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/tcp.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/tcp.c @@ -720,6 +720,7 @@ if (!test_bit(TSQ_THROTTLED, &sk->sk_tsq_flags)) { NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAUTOCORKING); set_bit(TSQ_THROTTLED, &sk->sk_tsq_flags); + smp_mb__after_atomic(); } /* It is possible TX completion already happened * before we set TSQ_THROTTLED. @@ -1782,7 +1783,17 @@ static bool can_map_frag(const skb_frag_t *frag) { - return skb_frag_size(frag) == PAGE_SIZE && !skb_frag_off(frag); + struct page *page; + + if (skb_frag_size(frag) != PAGE_SIZE || skb_frag_off(frag)) + return false; + + page = skb_frag_page(frag); + + if (PageCompound(page) || page->mapping) + return false; + + return true; } static int find_next_mappable_frag(const skb_frag_t *frag, diff -u linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/tcp_ipv4.c linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/tcp_ipv4.c --- linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/tcp_ipv4.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/tcp_ipv4.c @@ -193,7 +193,7 @@ sock_owned_by_me(sk); - return BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr); + return BPF_CGROUP_RUN_PROG_INET4_CONNECT(sk, uaddr, &addr_len); } /* This will initiate an outgoing connection. */ diff -u linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/udp.c linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/udp.c --- linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/udp.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/ipv4/udp.c @@ -835,7 +835,7 @@ if (up->pending) { up->len = 0; - up->pending = 0; + WRITE_ONCE(up->pending, 0); ip_flush_pending_frames(sk); } } @@ -1022,7 +1022,7 @@ out: up->len = 0; - up->pending = 0; + WRITE_ONCE(up->pending, 0); return err; } EXPORT_SYMBOL(udp_push_pending_frames); @@ -1098,7 +1098,7 @@ getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; fl4 = &inet->cork.fl.u.ip4; - if (up->pending) { + if (READ_ONCE(up->pending)) { /* * There are pending frames. * The socket lock must be held while it's corked. @@ -1172,7 +1172,9 @@ if (cgroup_bpf_enabled(CGROUP_UDP4_SENDMSG) && !connected) { err = BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, - (struct sockaddr *)usin, &ipc.addr); + (struct sockaddr *)usin, + &msg->msg_namelen, + &ipc.addr); if (err) goto out_free; if (usin) { @@ -1294,7 +1296,7 @@ fl4->saddr = saddr; fl4->fl4_dport = dport; fl4->fl4_sport = inet->inet_sport; - up->pending = AF_INET; + WRITE_ONCE(up->pending, AF_INET); do_append_data: up->len += ulen; @@ -1306,7 +1308,7 @@ else if (!corkreq) err = udp_push_pending_frames(sk); else if (unlikely(skb_queue_empty(&sk->sk_write_queue))) - up->pending = 0; + WRITE_ONCE(up->pending, 0); release_sock(sk); out: @@ -1344,7 +1346,7 @@ struct sock *sk = sock->sk; struct udp_sock *up = udp_sk(sk); - if (!up->pending || udp_test_bit(CORK, sk)) + if (!READ_ONCE(up->pending) || udp_test_bit(CORK, sk)) return; lock_sock(sk); @@ -1894,7 +1896,8 @@ *addr_len = sizeof(*sin); BPF_CGROUP_RUN_PROG_UDP4_RECVMSG_LOCK(sk, - (struct sockaddr *)sin); + (struct sockaddr *)sin, + addr_len); } if (udp_test_bit(GRO_ENABLED, sk)) @@ -1933,7 +1936,7 @@ if (addr_len < sizeof(struct sockaddr_in)) return -EINVAL; - return BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr); + return BPF_CGROUP_RUN_PROG_INET4_CONNECT_LOCK(sk, uaddr, &addr_len); } EXPORT_SYMBOL(udp_pre_connect); @@ -2193,7 +2196,7 @@ udp_csum_pull_header(skb); - ipv4_pktinfo_prepare(sk, skb); + ipv4_pktinfo_prepare(sk, skb, true); return __udp_queue_rcv_skb(sk, skb); csum_error: @@ -3141,16 +3144,18 @@ struct bpf_udp_iter_state *iter = seq->private; struct udp_iter_state *state = &iter->state; struct net *net = seq_file_net(seq); + int resume_bucket, resume_offset; struct udp_table *udptable; unsigned int batch_sks = 0; bool resized = false; struct sock *sk; + resume_bucket = state->bucket; + resume_offset = iter->offset; + /* The current batch is done, so advance the bucket. */ - if (iter->st_bucket_done) { + if (iter->st_bucket_done) state->bucket++; - iter->offset = 0; - } udptable = udp_get_table_seq(seq, net); @@ -3170,19 +3175,19 @@ for (; state->bucket <= udptable->mask; state->bucket++) { struct udp_hslot *hslot2 = &udptable->hash2[state->bucket]; - if (hlist_empty(&hslot2->head)) { - iter->offset = 0; + if (hlist_empty(&hslot2->head)) continue; - } + iter->offset = 0; spin_lock_bh(&hslot2->lock); udp_portaddr_for_each_entry(sk, &hslot2->head) { if (seq_sk_match(seq, sk)) { /* Resume from the last iterated socket at the * offset in the bucket before iterator was stopped. */ - if (iter->offset) { - --iter->offset; + if (state->bucket == resume_bucket && + iter->offset < resume_offset) { + ++iter->offset; continue; } if (iter->end_sk < iter->max_sk) { @@ -3196,9 +3201,6 @@ if (iter->end_sk) break; - - /* Reset the current bucket's offset before moving to the next bucket. */ - iter->offset = 0; } /* All done: no batch made. */ @@ -3217,7 +3219,6 @@ /* After allocating a larger batch, retry one more time to grab * the whole bucket. */ - state->bucket--; goto again; } done: diff -u linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/af_inet6.c linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/af_inet6.c --- linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/af_inet6.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/af_inet6.c @@ -199,6 +199,9 @@ if (INET_PROTOSW_REUSE & answer_flags) sk->sk_reuse = SK_CAN_REUSE; + if (INET_PROTOSW_ICSK & answer_flags) + inet_init_csk_locks(sk); + inet = inet_sk(sk); inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0; @@ -455,7 +458,7 @@ /* BPF prog is run before any checks are done so that if the prog * changes context in a wrong way it will be caught. */ - err = BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr, + err = BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr, &addr_len, CGROUP_INET6_BIND, &flags); if (err) return err; @@ -515,6 +518,7 @@ int peer) { struct sockaddr_in6 *sin = (struct sockaddr_in6 *)uaddr; + int sin_addr_len = sizeof(*sin); struct sock *sk = sock->sk; struct inet_sock *inet = inet_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk); @@ -534,7 +538,7 @@ sin->sin6_addr = sk->sk_v6_daddr; if (np->sndflow) sin->sin6_flowinfo = np->flow_label; - BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, + BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, &sin_addr_len, CGROUP_INET6_GETPEERNAME); } else { if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) @@ -542,13 +546,13 @@ else sin->sin6_addr = sk->sk_v6_rcv_saddr; sin->sin6_port = inet->inet_sport; - BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, + BPF_CGROUP_RUN_SA_PROG(sk, (struct sockaddr *)sin, &sin_addr_len, CGROUP_INET6_GETSOCKNAME); } sin->sin6_scope_id = ipv6_iface_scope_id(&sin->sin6_addr, sk->sk_bound_dev_if); release_sock(sk); - return sizeof(*sin); + return sin_addr_len; } EXPORT_SYMBOL(inet6_getname); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/ping.c linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/ping.c --- linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/ping.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/ping.c @@ -56,7 +56,7 @@ if (addr_len < SIN6_LEN_RFC2133) return -EINVAL; - return BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr); + return BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr, &addr_len); } static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) diff -u linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/tcp_ipv6.c linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/tcp_ipv6.c --- linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/tcp_ipv6.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/tcp_ipv6.c @@ -135,7 +135,7 @@ sock_owned_by_me(sk); - return BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr); + return BPF_CGROUP_RUN_PROG_INET6_CONNECT(sk, uaddr, &addr_len); } static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, diff -u linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/udp.c linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/udp.c --- linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/udp.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/ipv6/udp.c @@ -443,7 +443,8 @@ *addr_len = sizeof(*sin6); BPF_CGROUP_RUN_PROG_UDP6_RECVMSG_LOCK(sk, - (struct sockaddr *)sin6); + (struct sockaddr *)sin6, + addr_len); } if (udp_test_bit(GRO_ENABLED, sk)) @@ -1163,7 +1164,7 @@ udp_flush_pending_frames(sk); else if (up->pending) { up->len = 0; - up->pending = 0; + WRITE_ONCE(up->pending, 0); ip6_flush_pending_frames(sk); } } @@ -1186,7 +1187,7 @@ if (addr_len < SIN6_LEN_RFC2133) return -EINVAL; - return BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr); + return BPF_CGROUP_RUN_PROG_INET6_CONNECT_LOCK(sk, uaddr, &addr_len); } /** @@ -1341,7 +1342,7 @@ &inet_sk(sk)->cork.base); out: up->len = 0; - up->pending = 0; + WRITE_ONCE(up->pending, 0); return err; } @@ -1398,7 +1399,7 @@ default: return -EINVAL; } - } else if (!up->pending) { + } else if (!READ_ONCE(up->pending)) { if (sk->sk_state != TCP_ESTABLISHED) return -EDESTADDRREQ; daddr = &sk->sk_v6_daddr; @@ -1429,8 +1430,8 @@ return -EMSGSIZE; getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; - if (up->pending) { - if (up->pending == AF_INET) + if (READ_ONCE(up->pending)) { + if (READ_ONCE(up->pending) == AF_INET) return udp_sendmsg(sk, msg, len); /* * There are pending frames. @@ -1539,6 +1540,7 @@ if (cgroup_bpf_enabled(CGROUP_UDP6_SENDMSG) && !connected) { err = BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, (struct sockaddr *)sin6, + &addr_len, &fl6->saddr); if (err) goto out_no_dst; @@ -1620,7 +1622,7 @@ goto out; } - up->pending = AF_INET6; + WRITE_ONCE(up->pending, AF_INET6); do_append_data: if (ipc6.dontfrag < 0) @@ -1634,7 +1636,7 @@ else if (!corkreq) err = udp_v6_push_pending_frames(sk); else if (unlikely(skb_queue_empty(&sk->sk_write_queue))) - up->pending = 0; + WRITE_ONCE(up->pending, 0); if (err > 0) err = np->recverr ? net_xmit_errno(err) : 0; @@ -1675,7 +1677,7 @@ struct sock *sk = sock->sk; struct udp_sock *up = udp_sk(sk); - if (!up->pending || udp_test_bit(CORK, sk)) + if (!READ_ONCE(up->pending) || udp_test_bit(CORK, sk)) return; lock_sock(sk); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/kcm/kcmsock.c linux-lowlatency-hwe-6.5-6.5.0/net/kcm/kcmsock.c --- linux-lowlatency-hwe-6.5-6.5.0/net/kcm/kcmsock.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/kcm/kcmsock.c @@ -634,7 +634,7 @@ msize = 0; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) - msize += skb_shinfo(skb)->frags[i].bv_len; + msize += skb_frag_size(&skb_shinfo(skb)->frags[i]); iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, skb_shinfo(skb)->frags, skb_shinfo(skb)->nr_frags, diff -u linux-lowlatency-hwe-6.5-6.5.0/net/mac80211/sta_info.c linux-lowlatency-hwe-6.5-6.5.0/net/mac80211/sta_info.c --- linux-lowlatency-hwe-6.5-6.5.0/net/mac80211/sta_info.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/mac80211/sta_info.c @@ -398,7 +398,10 @@ int i; for (i = 0; i < ARRAY_SIZE(sta->link); i++) { - if (!(sta->sta.valid_links & BIT(i))) + struct link_sta_info *link_sta; + + link_sta = rcu_access_pointer(sta->link[i]); + if (!link_sta) continue; sta_remove_link(sta, i, false); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/mptcp/options.c linux-lowlatency-hwe-6.5-6.5.0/net/mptcp/options.c --- linux-lowlatency-hwe-6.5-6.5.0/net/mptcp/options.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/mptcp/options.c @@ -123,8 +123,8 @@ break; case MPTCPOPT_MP_JOIN: - mp_opt->suboptions |= OPTIONS_MPTCP_MPJ; if (opsize == TCPOLEN_MPTCP_MPJ_SYN) { + mp_opt->suboptions |= OPTION_MPTCP_MPJ_SYN; mp_opt->backup = *ptr++ & MPTCPOPT_BACKUP; mp_opt->join_id = *ptr++; mp_opt->token = get_unaligned_be32(ptr); @@ -135,6 +135,7 @@ mp_opt->backup, mp_opt->join_id, mp_opt->token, mp_opt->nonce); } else if (opsize == TCPOLEN_MPTCP_MPJ_SYNACK) { + mp_opt->suboptions |= OPTION_MPTCP_MPJ_SYNACK; mp_opt->backup = *ptr++ & MPTCPOPT_BACKUP; mp_opt->join_id = *ptr++; mp_opt->thmac = get_unaligned_be64(ptr); @@ -145,11 +146,10 @@ mp_opt->backup, mp_opt->join_id, mp_opt->thmac, mp_opt->nonce); } else if (opsize == TCPOLEN_MPTCP_MPJ_ACK) { + mp_opt->suboptions |= OPTION_MPTCP_MPJ_ACK; ptr += 2; memcpy(mp_opt->hmac, ptr, MPTCPOPT_HMAC_LEN); pr_debug("MP_JOIN hmac"); - } else { - mp_opt->suboptions &= ~OPTIONS_MPTCP_MPJ; } break; diff -u linux-lowlatency-hwe-6.5-6.5.0/net/mptcp/subflow.c linux-lowlatency-hwe-6.5-6.5.0/net/mptcp/subflow.c --- linux-lowlatency-hwe-6.5-6.5.0/net/mptcp/subflow.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/mptcp/subflow.c @@ -157,8 +157,8 @@ mptcp_get_options(skb, &mp_opt); - opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC); - opt_mp_join = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ); + opt_mp_capable = !!(mp_opt.suboptions & OPTION_MPTCP_MPC_SYN); + opt_mp_join = !!(mp_opt.suboptions & OPTION_MPTCP_MPJ_SYN); if (opt_mp_capable) { SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_MPCAPABLEPASSIVE); @@ -254,8 +254,8 @@ subflow_init_req(req, sk_listener); mptcp_get_options(skb, &mp_opt); - opt_mp_capable = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPC); - opt_mp_join = !!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ); + opt_mp_capable = !!(mp_opt.suboptions & OPTION_MPTCP_MPC_ACK); + opt_mp_join = !!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK); if (opt_mp_capable && opt_mp_join) return -EINVAL; @@ -486,7 +486,7 @@ mptcp_get_options(skb, &mp_opt); if (subflow->request_mptcp) { - if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC)) { + if (!(mp_opt.suboptions & OPTION_MPTCP_MPC_SYNACK)) { MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPCAPABLEACTIVEFALLBACK); mptcp_do_fallback(sk); @@ -506,7 +506,7 @@ } else if (subflow->request_join) { u8 hmac[SHA256_DIGEST_SIZE]; - if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ)) { + if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_SYNACK)) { subflow->reset_reason = MPTCP_RST_EMPTCP; goto do_reset; } @@ -783,12 +783,13 @@ * options. */ mptcp_get_options(skb, &mp_opt); - if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPC)) + if (!(mp_opt.suboptions & + (OPTION_MPTCP_MPC_SYN | OPTION_MPTCP_MPC_ACK))) fallback = true; } else if (subflow_req->mp_join) { mptcp_get_options(skb, &mp_opt); - if (!(mp_opt.suboptions & OPTIONS_MPTCP_MPJ) || + if (!(mp_opt.suboptions & OPTION_MPTCP_MPJ_ACK) || !subflow_hmac_valid(req, &mp_opt) || !mptcp_can_accept_new_subflow(subflow_req->msk)) { SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nf_tables_api.c linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nf_tables_api.c --- linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nf_tables_api.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nf_tables_api.c @@ -24,6 +24,7 @@ #include #define NFT_MODULE_AUTOLOAD_LIMIT (MODULE_NAME_LEN - sizeof("nft-expr-255-")) +#define NFT_SET_MAX_ANONLEN 16 unsigned int nf_tables_net_id __read_mostly; @@ -2263,7 +2264,16 @@ return -EOPNOTSUPP; } - type = basechain->type; + if (nla[NFTA_CHAIN_TYPE]) { + type = __nf_tables_chain_type_lookup(nla[NFTA_CHAIN_TYPE], + family); + if (!type) { + NL_SET_BAD_ATTR(extack, nla[NFTA_CHAIN_TYPE]); + return -ENOENT; + } + } else { + type = basechain->type; + } } if (!try_module_get(type->owner)) { @@ -4339,6 +4349,9 @@ if (p[1] != 'd' || strchr(p + 2, '%')) return -EINVAL; + if (strnlen(name, NFT_SET_MAX_ANONLEN) >= NFT_SET_MAX_ANONLEN) + return -EINVAL; + inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL); if (inuse == NULL) return -ENOMEM; @@ -4741,8 +4754,8 @@ static int nft_set_desc_concat(struct nft_set_desc *desc, const struct nlattr *nla) { + u32 num_regs = 0, key_num_regs = 0; struct nlattr *attr; - u32 num_regs = 0; int rem, err, i; nla_for_each_nested(attr, nla, rem) { @@ -4757,6 +4770,10 @@ for (i = 0; i < desc->field_count; i++) num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32)); + key_num_regs = DIV_ROUND_UP(desc->klen, sizeof(u32)); + if (key_num_regs != num_regs) + return -EINVAL; + if (num_regs > NFT_REG32_COUNT) return -E2BIG; @@ -4978,16 +4995,28 @@ } desc.policy = NFT_SET_POL_PERFORMANCE; - if (nla[NFTA_SET_POLICY] != NULL) + if (nla[NFTA_SET_POLICY] != NULL) { desc.policy = ntohl(nla_get_be32(nla[NFTA_SET_POLICY])); + switch (desc.policy) { + case NFT_SET_POL_PERFORMANCE: + case NFT_SET_POL_MEMORY: + break; + default: + return -EOPNOTSUPP; + } + } if (nla[NFTA_SET_DESC] != NULL) { err = nf_tables_set_desc_parse(&desc, nla[NFTA_SET_DESC]); if (err < 0) return err; - if (desc.field_count > 1 && !(flags & NFT_SET_CONCAT)) + if (desc.field_count > 1) { + if (!(flags & NFT_SET_CONCAT)) + return -EINVAL; + } else if (flags & NFT_SET_CONCAT) { return -EINVAL; + } } else if (flags & NFT_SET_CONCAT) { return -EINVAL; } @@ -5638,7 +5667,7 @@ const struct nft_set_ext *ext = nft_set_elem_ext(set, elem->priv); struct nft_set_dump_args *args; - if (nft_set_elem_expired(ext)) + if (nft_set_elem_expired(ext) || nft_set_elem_is_dead(ext)) return 0; args = container_of(iter, struct nft_set_dump_args, iter); @@ -7383,11 +7412,15 @@ return -1; } -static const struct nft_object_type *__nft_obj_type_get(u32 objtype) +static const struct nft_object_type *__nft_obj_type_get(u32 objtype, u8 family) { const struct nft_object_type *type; list_for_each_entry(type, &nf_tables_objects, list) { + if (type->family != NFPROTO_UNSPEC && + type->family != family) + continue; + if (objtype == type->type) return type; } @@ -7395,11 +7428,11 @@ } static const struct nft_object_type * -nft_obj_type_get(struct net *net, u32 objtype) +nft_obj_type_get(struct net *net, u32 objtype, u8 family) { const struct nft_object_type *type; - type = __nft_obj_type_get(objtype); + type = __nft_obj_type_get(objtype, family); if (type != NULL && try_module_get(type->owner)) return type; @@ -7492,7 +7525,7 @@ if (info->nlh->nlmsg_flags & NLM_F_REPLACE) return -EOPNOTSUPP; - type = __nft_obj_type_get(objtype); + type = __nft_obj_type_get(objtype, family); if (WARN_ON_ONCE(!type)) return -ENOENT; @@ -7506,7 +7539,7 @@ if (!nft_use_inc(&table->use)) return -EMFILE; - type = nft_obj_type_get(net, objtype); + type = nft_obj_type_get(net, objtype, family); if (IS_ERR(type)) { err = PTR_ERR(type); goto err_type; @@ -10342,6 +10375,7 @@ nft_trans_destroy(trans); break; } + nft_trans_set(trans)->dead = 1; list_del_rcu(&nft_trans_set(trans)->list); break; case NFT_MSG_DELSET: diff -u linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nfnetlink_log.c linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nfnetlink_log.c --- linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nfnetlink_log.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nfnetlink_log.c @@ -509,7 +509,7 @@ htonl(br_port_get_rcu(indev)->br->dev->ifindex))) goto nla_put_failure; } else { - struct net_device *physindev; + int physinif; /* Case 2: indev is bridge group, we need to look for * physical device (when called from ipv4) */ @@ -517,10 +517,10 @@ htonl(indev->ifindex))) goto nla_put_failure; - physindev = nf_bridge_get_physindev(skb); - if (physindev && + physinif = nf_bridge_get_physinif(skb); + if (physinif && nla_put_be32(inst->skb, NFULA_IFINDEX_PHYSINDEV, - htonl(physindev->ifindex))) + htonl(physinif))) goto nla_put_failure; } #endif diff -u linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nft_set_rbtree.c linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nft_set_rbtree.c --- linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nft_set_rbtree.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/netfilter/nft_set_rbtree.c @@ -235,7 +235,7 @@ static const struct nft_rbtree_elem * nft_rbtree_gc_elem(const struct nft_set *__set, struct nft_rbtree *priv, - struct nft_rbtree_elem *rbe, u8 genmask) + struct nft_rbtree_elem *rbe) { struct nft_set *set = (struct nft_set *)__set; struct rb_node *prev = rb_prev(&rbe->node); @@ -254,7 +254,7 @@ while (prev) { rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); if (nft_rbtree_interval_end(rbe_prev) && - nft_set_elem_active(&rbe_prev->ext, genmask)) + nft_set_elem_active(&rbe_prev->ext, NFT_GENMASK_ANY)) break; prev = rb_prev(prev); @@ -365,7 +365,7 @@ nft_set_elem_active(&rbe->ext, cur_genmask)) { const struct nft_rbtree_elem *removed_end; - removed_end = nft_rbtree_gc_elem(set, priv, rbe, genmask); + removed_end = nft_rbtree_gc_elem(set, priv, rbe); if (IS_ERR(removed_end)) return PTR_ERR(removed_end); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/netlink/af_netlink.c linux-lowlatency-hwe-6.5-6.5.0/net/netlink/af_netlink.c --- linux-lowlatency-hwe-6.5-6.5.0/net/netlink/af_netlink.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/netlink/af_netlink.c @@ -374,7 +374,7 @@ if (is_vmalloc_addr(skb->head)) { if (!skb->cloned || !atomic_dec_return(&(skb_shinfo(skb)->dataref))) - vfree(skb->head); + vfree_atomic(skb->head); skb->head = NULL; } diff -u linux-lowlatency-hwe-6.5-6.5.0/net/rxrpc/local_object.c linux-lowlatency-hwe-6.5-6.5.0/net/rxrpc/local_object.c --- linux-lowlatency-hwe-6.5-6.5.0/net/rxrpc/local_object.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/rxrpc/local_object.c @@ -37,6 +37,17 @@ } /* + * Set or clear the Don't Fragment flag on a socket. + */ +void rxrpc_local_dont_fragment(const struct rxrpc_local *local, bool set) +{ + if (set) + ip_sock_set_mtu_discover(local->socket->sk, IP_PMTUDISC_DO); + else + ip_sock_set_mtu_discover(local->socket->sk, IP_PMTUDISC_DONT); +} + +/* * Compare a local to an address. Return -ve, 0 or +ve to indicate less than, * same or greater than. * @@ -203,7 +214,7 @@ ip_sock_set_recverr(usk); /* we want to set the don't fragment bit */ - ip_sock_set_mtu_discover(usk, IP_PMTUDISC_DO); + rxrpc_local_dont_fragment(local, true); /* We want receive timestamps. */ sock_enable_timestamps(usk); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/sched/act_ct.c linux-lowlatency-hwe-6.5-6.5.0/net/sched/act_ct.c --- linux-lowlatency-hwe-6.5-6.5.0/net/sched/act_ct.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/sched/act_ct.c @@ -851,7 +851,6 @@ if (err || !frag) return err; - skb_get(skb); err = nf_ct_handle_fragments(net, skb, zone, family, &proto, &mru); if (err) return err; @@ -995,12 +994,8 @@ nh_ofs = skb_network_offset(skb); skb_pull_rcsum(skb, nh_ofs); err = tcf_ct_handle_fragments(net, skb, family, p->zone, &defrag); - if (err == -EINPROGRESS) { - retval = TC_ACT_STOLEN; - goto out_clear; - } if (err) - goto drop; + goto out_frag; err = nf_ct_skb_network_trim(skb, family); if (err) @@ -1087,6 +1082,11 @@ qdisc_skb_cb(skb)->pkt_len = skb->len; return retval; +out_frag: + if (err != -EINPROGRESS) + tcf_action_inc_drop_qstats(&c->common); + return TC_ACT_CONSUMED; + drop: tcf_action_inc_drop_qstats(&c->common); return TC_ACT_SHOT; diff -u linux-lowlatency-hwe-6.5-6.5.0/net/sctp/socket.c linux-lowlatency-hwe-6.5-6.5.0/net/sctp/socket.c --- linux-lowlatency-hwe-6.5-6.5.0/net/sctp/socket.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/sctp/socket.c @@ -2099,6 +2099,13 @@ pr_debug("%s: sk:%p, msghdr:%p, len:%zd, flags:0x%x, addr_len:%p)\n", __func__, sk, msg, len, flags, addr_len); + if (unlikely(flags & MSG_ERRQUEUE)) + return inet_recv_error(sk, msg, len, addr_len); + + if (sk_can_busy_loop(sk) && + skb_queue_empty_lockless(&sk->sk_receive_queue)) + sk_busy_loop(sk, flags & MSG_DONTWAIT); + lock_sock(sk); if (sctp_style(sk, TCP) && !sctp_sstate(sk, ESTABLISHED) && @@ -9043,12 +9050,6 @@ if (sk->sk_shutdown & RCV_SHUTDOWN) break; - if (sk_can_busy_loop(sk)) { - sk_busy_loop(sk, flags & MSG_DONTWAIT); - - if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) - continue; - } /* User doesn't want to wait. */ error = -EAGAIN; diff -u linux-lowlatency-hwe-6.5-6.5.0/net/smc/smc_clc.c linux-lowlatency-hwe-6.5-6.5.0/net/smc/smc_clc.c --- linux-lowlatency-hwe-6.5-6.5.0/net/smc/smc_clc.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/smc/smc_clc.c @@ -155,10 +155,12 @@ rc = 0; } } +#if IS_ENABLED(CONFIG_S390) if (!rc && !smc_clc_eid_table.ueid_cnt) { smc_clc_eid_table.seid_enabled = 1; rc = -EAGAIN; /* indicate success and enabling of seid */ } +#endif write_unlock(&smc_clc_eid_table.lock); return rc; } @@ -273,22 +275,30 @@ int smc_nl_enable_seid(struct sk_buff *skb, struct genl_info *info) { +#if IS_ENABLED(CONFIG_S390) write_lock(&smc_clc_eid_table.lock); smc_clc_eid_table.seid_enabled = 1; write_unlock(&smc_clc_eid_table.lock); return 0; +#else + return -EOPNOTSUPP; +#endif } int smc_nl_disable_seid(struct sk_buff *skb, struct genl_info *info) { int rc = 0; +#if IS_ENABLED(CONFIG_S390) write_lock(&smc_clc_eid_table.lock); if (!smc_clc_eid_table.ueid_cnt) rc = -ENOENT; else smc_clc_eid_table.seid_enabled = 0; write_unlock(&smc_clc_eid_table.lock); +#else + rc = -EOPNOTSUPP; +#endif return rc; } @@ -1172,7 +1182,11 @@ INIT_LIST_HEAD(&smc_clc_eid_table.list); rwlock_init(&smc_clc_eid_table.lock); smc_clc_eid_table.ueid_cnt = 0; +#if IS_ENABLED(CONFIG_S390) smc_clc_eid_table.seid_enabled = 1; +#else + smc_clc_eid_table.seid_enabled = 0; +#endif } void smc_clc_exit(void) diff -u linux-lowlatency-hwe-6.5-6.5.0/net/smc/smc_diag.c linux-lowlatency-hwe-6.5-6.5.0/net/smc/smc_diag.c --- linux-lowlatency-hwe-6.5-6.5.0/net/smc/smc_diag.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/smc/smc_diag.c @@ -163,7 +163,7 @@ } if (smc_conn_lgr_valid(&smc->conn) && smc->conn.lgr->is_smcd && (req->diag_ext & (1 << (SMC_DIAG_DMBINFO - 1))) && - !list_empty(&smc->conn.lgr->list)) { + !list_empty(&smc->conn.lgr->list) && smc->conn.rmb_desc) { struct smc_connection *conn = &smc->conn; struct smcd_diag_dmbinfo dinfo; struct smcd_dev *smcd = conn->lgr->smcd; diff -u linux-lowlatency-hwe-6.5-6.5.0/net/tls/tls_sw.c linux-lowlatency-hwe-6.5-6.5.0/net/tls/tls_sw.c --- linux-lowlatency-hwe-6.5-6.5.0/net/tls/tls_sw.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/tls/tls_sw.c @@ -63,6 +63,7 @@ u8 iv[MAX_IV_SIZE]; u8 aad[TLS_MAX_AAD_SIZE]; u8 tail; + bool free_sgout; struct scatterlist sg[]; }; @@ -187,7 +188,6 @@ struct aead_request *aead_req = data; struct crypto_aead *aead = crypto_aead_reqtfm(aead_req); struct scatterlist *sgout = aead_req->dst; - struct scatterlist *sgin = aead_req->src; struct tls_sw_context_rx *ctx; struct tls_decrypt_ctx *dctx; struct tls_context *tls_ctx; @@ -196,6 +196,17 @@ struct sock *sk; int aead_size; + /* If requests get too backlogged crypto API returns -EBUSY and calls + * ->complete(-EINPROGRESS) immediately followed by ->complete(0) + * to make waiting for backlog to flush with crypto_wait_req() easier. + * First wait converts -EBUSY -> -EINPROGRESS, and the second one + * -EINPROGRESS -> 0. + * We have a single struct crypto_async_request per direction, this + * scheme doesn't help us, so just ignore the first ->complete(). + */ + if (err == -EINPROGRESS) + return; + aead_size = sizeof(*aead_req) + crypto_aead_reqsize(aead); aead_size = ALIGN(aead_size, __alignof__(*dctx)); dctx = (void *)((u8 *)aead_req + aead_size); @@ -213,7 +224,7 @@ } /* Free the destination pages if skb was not decrypted inplace */ - if (sgout != sgin) { + if (dctx->free_sgout) { /* Skip the first S/G entry as it points to AAD */ for_each_sg(sg_next(sgout), sg, UINT_MAX, pages) { if (!sg) @@ -224,10 +235,17 @@ kfree(aead_req); - spin_lock_bh(&ctx->decrypt_compl_lock); - if (!atomic_dec_return(&ctx->decrypt_pending)) + if (atomic_dec_and_test(&ctx->decrypt_pending)) complete(&ctx->async_wait.completion); - spin_unlock_bh(&ctx->decrypt_compl_lock); +} + +static int tls_decrypt_async_wait(struct tls_sw_context_rx *ctx) +{ + if (!atomic_dec_and_test(&ctx->decrypt_pending)) + crypto_wait_req(-EINPROGRESS, &ctx->async_wait); + atomic_inc(&ctx->decrypt_pending); + + return ctx->async_wait.err; } static int tls_do_decryption(struct sock *sk, @@ -253,6 +271,7 @@ aead_request_set_callback(aead_req, CRYPTO_TFM_REQ_MAY_BACKLOG, tls_decrypt_done, aead_req); + DEBUG_NET_WARN_ON_ONCE(atomic_read(&ctx->decrypt_pending) < 1); atomic_inc(&ctx->decrypt_pending); } else { aead_request_set_callback(aead_req, @@ -261,6 +280,10 @@ } ret = crypto_aead_decrypt(aead_req); + if (ret == -EBUSY) { + ret = tls_decrypt_async_wait(ctx); + ret = ret ?: -EINPROGRESS; + } if (ret == -EINPROGRESS) { if (darg->async) return 0; @@ -439,9 +462,10 @@ struct tls_rec *rec = data; struct scatterlist *sge; struct sk_msg *msg_en; - bool ready = false; struct sock *sk; - int pending; + + if (err == -EINPROGRESS) /* see the comment in tls_decrypt_done() */ + return; msg_en = &rec->msg_encrypted; @@ -476,23 +500,25 @@ /* If received record is at head of tx_list, schedule tx */ first_rec = list_first_entry(&ctx->tx_list, struct tls_rec, list); - if (rec == first_rec) - ready = true; + if (rec == first_rec) { + /* Schedule the transmission */ + if (!test_and_set_bit(BIT_TX_SCHEDULED, + &ctx->tx_bitmask)) + schedule_delayed_work(&ctx->tx_work.work, 1); + } } - spin_lock_bh(&ctx->encrypt_compl_lock); - pending = atomic_dec_return(&ctx->encrypt_pending); - - if (!pending && ctx->async_notify) + if (atomic_dec_and_test(&ctx->encrypt_pending)) complete(&ctx->async_wait.completion); - spin_unlock_bh(&ctx->encrypt_compl_lock); +} - if (!ready) - return; +static int tls_encrypt_async_wait(struct tls_sw_context_tx *ctx) +{ + if (!atomic_dec_and_test(&ctx->encrypt_pending)) + crypto_wait_req(-EINPROGRESS, &ctx->async_wait); + atomic_inc(&ctx->encrypt_pending); - /* Schedule the transmission */ - if (!test_and_set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) - schedule_delayed_work(&ctx->tx_work.work, 1); + return ctx->async_wait.err; } static int tls_do_encryption(struct sock *sk, @@ -541,9 +567,14 @@ /* Add the record in tx_list */ list_add_tail((struct list_head *)&rec->list, &ctx->tx_list); + DEBUG_NET_WARN_ON_ONCE(atomic_read(&ctx->encrypt_pending) < 1); atomic_inc(&ctx->encrypt_pending); rc = crypto_aead_encrypt(aead_req); + if (rc == -EBUSY) { + rc = tls_encrypt_async_wait(ctx); + rc = rc ?: -EINPROGRESS; + } if (!rc || rc != -EINPROGRESS) { atomic_dec(&ctx->encrypt_pending); sge->offset -= prot->prepend_size; @@ -984,7 +1015,6 @@ int num_zc = 0; int orig_size; int ret = 0; - int pending; if (unlikely(msg->msg_controllen)) { ret = tls_process_cmsg(sk, msg, &record_type); @@ -1049,7 +1079,11 @@ if (ret < 0) goto send_end; tls_ctx->pending_open_record_frags = true; - if (full_record || eor || sk_msg_full(msg_pl)) + + if (sk_msg_full(msg_pl)) + full_record = true; + + if (full_record || eor) goto copied; continue; } @@ -1156,24 +1190,12 @@ if (!num_async) { goto send_end; } else if (num_zc) { - /* Wait for pending encryptions to get completed */ - spin_lock_bh(&ctx->encrypt_compl_lock); - ctx->async_notify = true; - - pending = atomic_read(&ctx->encrypt_pending); - spin_unlock_bh(&ctx->encrypt_compl_lock); - if (pending) - crypto_wait_req(-EINPROGRESS, &ctx->async_wait); - else - reinit_completion(&ctx->async_wait.completion); - - /* There can be no concurrent accesses, since we have no - * pending encrypt operations - */ - WRITE_ONCE(ctx->async_notify, false); + int err; - if (ctx->async_wait.err) { - ret = ctx->async_wait.err; + /* Wait for pending encryptions to get completed */ + err = tls_encrypt_async_wait(ctx); + if (err) { + ret = err; copied = 0; } } @@ -1222,7 +1244,6 @@ ssize_t copied = 0; bool retrying = false; int ret = 0; - int pending; if (!ctx->open_rec) return; @@ -1257,22 +1278,7 @@ } /* Wait for pending encryptions to get completed */ - spin_lock_bh(&ctx->encrypt_compl_lock); - ctx->async_notify = true; - - pending = atomic_read(&ctx->encrypt_pending); - spin_unlock_bh(&ctx->encrypt_compl_lock); - if (pending) - crypto_wait_req(-EINPROGRESS, &ctx->async_wait); - else - reinit_completion(&ctx->async_wait.completion); - - /* There can be no concurrent accesses, since we have no pending - * encrypt operations - */ - WRITE_ONCE(ctx->async_notify, false); - - if (ctx->async_wait.err) + if (tls_encrypt_async_wait(ctx)) goto unlock; /* Transmit if any encryptions have completed */ @@ -1574,6 +1580,7 @@ } else if (out_sg) { memcpy(sgout, out_sg, n_sgout * sizeof(*sgout)); } + dctx->free_sgout = !!pages; /* Prepare and submit AEAD request */ err = tls_do_decryption(sk, sgin, sgout, dctx->iv, @@ -2102,16 +2109,10 @@ recv_end: if (async) { - int ret, pending; + int ret; /* Wait for all previously submitted records to be decrypted */ - spin_lock_bh(&ctx->decrypt_compl_lock); - reinit_completion(&ctx->async_wait.completion); - pending = atomic_read(&ctx->decrypt_pending); - spin_unlock_bh(&ctx->decrypt_compl_lock); - ret = 0; - if (pending) - ret = crypto_wait_req(-EINPROGRESS, &ctx->async_wait); + ret = tls_decrypt_async_wait(ctx); __skb_queue_purge(&ctx->async_hold); if (ret) { @@ -2128,7 +2129,6 @@ else err = process_rx_list(ctx, msg, &control, 0, async_copy_bytes, is_peek); - decrypted += max(err, 0); } copied += decrypted; @@ -2332,16 +2332,9 @@ struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); struct tls_rec *rec, *tmp; - int pending; /* Wait for any pending async encryptions to complete */ - spin_lock_bh(&ctx->encrypt_compl_lock); - ctx->async_notify = true; - pending = atomic_read(&ctx->encrypt_pending); - spin_unlock_bh(&ctx->encrypt_compl_lock); - - if (pending) - crypto_wait_req(-EINPROGRESS, &ctx->async_wait); + tls_encrypt_async_wait(ctx); tls_tx_records(sk, -1); @@ -2494,6 +2487,48 @@ tls_ctx->prot_info.version != TLS_1_3_VERSION; } +static struct tls_sw_context_tx *init_ctx_tx(struct tls_context *ctx, struct sock *sk) +{ + struct tls_sw_context_tx *sw_ctx_tx; + + if (!ctx->priv_ctx_tx) { + sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL); + if (!sw_ctx_tx) + return NULL; + } else { + sw_ctx_tx = ctx->priv_ctx_tx; + } + + crypto_init_wait(&sw_ctx_tx->async_wait); + atomic_set(&sw_ctx_tx->encrypt_pending, 1); + INIT_LIST_HEAD(&sw_ctx_tx->tx_list); + INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler); + sw_ctx_tx->tx_work.sk = sk; + + return sw_ctx_tx; +} + +static struct tls_sw_context_rx *init_ctx_rx(struct tls_context *ctx) +{ + struct tls_sw_context_rx *sw_ctx_rx; + + if (!ctx->priv_ctx_rx) { + sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL); + if (!sw_ctx_rx) + return NULL; + } else { + sw_ctx_rx = ctx->priv_ctx_rx; + } + + crypto_init_wait(&sw_ctx_rx->async_wait); + atomic_set(&sw_ctx_rx->decrypt_pending, 1); + init_waitqueue_head(&sw_ctx_rx->wq); + skb_queue_head_init(&sw_ctx_rx->rx_list); + skb_queue_head_init(&sw_ctx_rx->async_hold); + + return sw_ctx_rx; +} + int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx) { struct tls_context *tls_ctx = tls_get_ctx(sk); @@ -2515,48 +2550,22 @@ } if (tx) { - if (!ctx->priv_ctx_tx) { - sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL); - if (!sw_ctx_tx) { - rc = -ENOMEM; - goto out; - } - ctx->priv_ctx_tx = sw_ctx_tx; - } else { - sw_ctx_tx = - (struct tls_sw_context_tx *)ctx->priv_ctx_tx; - } - } else { - if (!ctx->priv_ctx_rx) { - sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL); - if (!sw_ctx_rx) { - rc = -ENOMEM; - goto out; - } - ctx->priv_ctx_rx = sw_ctx_rx; - } else { - sw_ctx_rx = - (struct tls_sw_context_rx *)ctx->priv_ctx_rx; - } - } + ctx->priv_ctx_tx = init_ctx_tx(ctx, sk); + if (!ctx->priv_ctx_tx) + return -ENOMEM; - if (tx) { - crypto_init_wait(&sw_ctx_tx->async_wait); - spin_lock_init(&sw_ctx_tx->encrypt_compl_lock); + sw_ctx_tx = ctx->priv_ctx_tx; crypto_info = &ctx->crypto_send.info; cctx = &ctx->tx; aead = &sw_ctx_tx->aead_send; - INIT_LIST_HEAD(&sw_ctx_tx->tx_list); - INIT_DELAYED_WORK(&sw_ctx_tx->tx_work.work, tx_work_handler); - sw_ctx_tx->tx_work.sk = sk; } else { - crypto_init_wait(&sw_ctx_rx->async_wait); - spin_lock_init(&sw_ctx_rx->decrypt_compl_lock); - init_waitqueue_head(&sw_ctx_rx->wq); + ctx->priv_ctx_rx = init_ctx_rx(ctx); + if (!ctx->priv_ctx_rx) + return -ENOMEM; + + sw_ctx_rx = ctx->priv_ctx_rx; crypto_info = &ctx->crypto_recv.info; cctx = &ctx->rx; - skb_queue_head_init(&sw_ctx_rx->rx_list); - skb_queue_head_init(&sw_ctx_rx->async_hold); aead = &sw_ctx_rx->aead_recv; } diff -u linux-lowlatency-hwe-6.5-6.5.0/net/unix/af_unix.c linux-lowlatency-hwe-6.5-6.5.0/net/unix/af_unix.c --- linux-lowlatency-hwe-6.5-6.5.0/net/unix/af_unix.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/unix/af_unix.c @@ -1343,13 +1343,11 @@ unix_state_lock(sk1); return; } - if (sk1 < sk2) { - unix_state_lock(sk1); - unix_state_lock_nested(sk2); - } else { - unix_state_lock(sk2); - unix_state_lock_nested(sk1); - } + if (sk1 > sk2) + swap(sk1, sk2); + + unix_state_lock(sk1); + unix_state_lock_nested(sk2, U_LOCK_SECOND); } static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2) @@ -1582,7 +1580,7 @@ goto out_unlock; } - unix_state_lock_nested(sk); + unix_state_lock_nested(sk, U_LOCK_SECOND); if (sk->sk_state != st) { unix_state_unlock(sk); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/unix/unix_bpf.c linux-lowlatency-hwe-6.5-6.5.0/net/unix/unix_bpf.c --- linux-lowlatency-hwe-6.5-6.5.0/net/unix/unix_bpf.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/unix/unix_bpf.c @@ -161,15 +161,30 @@ { struct sock *sk_pair; + /* Restore does not decrement the sk_pair reference yet because we must + * keep the a reference to the socket until after an RCU grace period + * and any pending sends have completed. + */ if (restore) { sk->sk_write_space = psock->saved_write_space; sock_replace_proto(sk, psock->sk_proto); return 0; } - sk_pair = unix_peer(sk); - sock_hold(sk_pair); - psock->sk_pair = sk_pair; + /* psock_update_sk_prot can be called multiple times if psock is + * added to multiple maps and/or slots in the same map. There is + * also an edge case where replacing a psock with itself can trigger + * an extra psock_update_sk_prot during the insert process. So it + * must be safe to do multiple calls. Here we need to ensure we don't + * increment the refcnt through sock_hold many times. There will only + * be a single matching destroy operation. + */ + if (!psock->sk_pair) { + sk_pair = unix_peer(sk); + sock_hold(sk_pair); + psock->sk_pair = sk_pair; + } + unix_stream_bpf_check_needs_rebuild(psock->sk_proto); sock_replace_proto(sk, &unix_stream_bpf_prot); return 0; diff -u linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/af_vsock.c linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/af_vsock.c --- linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/af_vsock.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/af_vsock.c @@ -2214,8 +2214,13 @@ transport = vsk->transport; - if (transport && transport->set_rcvlowat) - return transport->set_rcvlowat(vsk, val); + if (transport && transport->notify_set_rcvlowat) { + int err; + + err = transport->notify_set_rcvlowat(vsk, val); + if (err) + return err; + } WRITE_ONCE(sk->sk_rcvlowat, val ? : 1); return 0; diff -u linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/virtio_transport.c linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/virtio_transport.c --- linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/virtio_transport.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/virtio_transport.c @@ -457,6 +457,7 @@ .notify_send_pre_enqueue = virtio_transport_notify_send_pre_enqueue, .notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue, .notify_buffer_size = virtio_transport_notify_buffer_size, + .notify_set_rcvlowat = virtio_transport_notify_set_rcvlowat, .read_skb = virtio_transport_read_skb, }, diff -u linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/virtio_transport_common.c linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/virtio_transport_common.c --- linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/virtio_transport_common.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/vmw_vsock/virtio_transport_common.c @@ -399,6 +399,8 @@ struct virtio_vsock_sock *vvs = vsk->trans; size_t bytes, total = 0; struct sk_buff *skb; + u32 fwd_cnt_delta; + bool low_rx_bytes; int err = -EFAULT; u32 free_space; @@ -440,7 +442,10 @@ } } - free_space = vvs->buf_alloc - (vvs->fwd_cnt - vvs->last_fwd_cnt); + fwd_cnt_delta = vvs->fwd_cnt - vvs->last_fwd_cnt; + free_space = vvs->buf_alloc - fwd_cnt_delta; + low_rx_bytes = (vvs->rx_bytes < + sock_rcvlowat(sk_vsock(vsk), 0, INT_MAX)); spin_unlock_bh(&vvs->rx_lock); @@ -450,9 +455,11 @@ * too high causes extra messages. Too low causes transmitter * stalls. As stalls are in theory more expensive than extra * messages, we set the limit to a high value. TODO: experiment - * with different values. + * with different values. Also send credit update message when + * number of bytes in rx queue is not enough to wake up reader. */ - if (free_space < VIRTIO_VSOCK_MAX_PKT_BUF_SIZE) + if (fwd_cnt_delta && + (free_space < VIRTIO_VSOCK_MAX_PKT_BUF_SIZE || low_rx_bytes)) virtio_transport_send_credit_update(vsk); return total; @@ -1463,6 +1470,36 @@ } EXPORT_SYMBOL_GPL(virtio_transport_read_skb); +int virtio_transport_notify_set_rcvlowat(struct vsock_sock *vsk, int val) +{ + struct virtio_vsock_sock *vvs = vsk->trans; + bool send_update; + + spin_lock_bh(&vvs->rx_lock); + + /* If number of available bytes is less than new SO_RCVLOWAT value, + * kick sender to send more data, because sender may sleep in its + * 'send()' syscall waiting for enough space at our side. Also + * don't send credit update when peer already knows actual value - + * such transmission will be useless. + */ + send_update = (vvs->rx_bytes < val) && + (vvs->fwd_cnt != vvs->last_fwd_cnt); + + spin_unlock_bh(&vvs->rx_lock); + + if (send_update) { + int err; + + err = virtio_transport_send_credit_update(vsk); + if (err < 0) + return err; + } + + return 0; +} +EXPORT_SYMBOL_GPL(virtio_transport_notify_set_rcvlowat); + MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Asias He"); MODULE_DESCRIPTION("common code for virtio vsock"); diff -u linux-lowlatency-hwe-6.5-6.5.0/net/wireless/scan.c linux-lowlatency-hwe-6.5-6.5.0/net/wireless/scan.c --- linux-lowlatency-hwe-6.5-6.5.0/net/wireless/scan.c +++ linux-lowlatency-hwe-6.5-6.5.0/net/wireless/scan.c @@ -1829,8 +1829,12 @@ list_add(&new->hidden_list, &hidden->hidden_list); hidden->refcount++; + + ies = (void *)rcu_access_pointer(new->pub.beacon_ies); rcu_assign_pointer(new->pub.beacon_ies, hidden->pub.beacon_ies); + if (ies) + kfree_rcu(ies, rcu_head); } } else { /* @@ -2569,10 +2573,12 @@ return false; } -static void cfg80211_parse_ml_sta_data(struct wiphy *wiphy, - struct cfg80211_inform_single_bss_data *tx_data, - struct cfg80211_bss *source_bss, - gfp_t gfp) +static void +cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy, + struct cfg80211_inform_single_bss_data *tx_data, + struct cfg80211_bss *source_bss, + const struct element *elem, + gfp_t gfp) { struct cfg80211_inform_single_bss_data data = { .drv_data = tx_data->drv_data, @@ -2581,7 +2587,6 @@ .bss_source = BSS_SOURCE_STA_PROFILE, }; struct ieee80211_multi_link_elem *ml_elem; - const struct element *elem; struct cfg80211_mle *mle; u16 control; u8 *new_ie; @@ -2591,15 +2596,7 @@ const u8 *pos; u8 i; - if (!source_bss) - return; - - if (tx_data->ftype != CFG80211_BSS_FTYPE_PRESP) - return; - - elem = cfg80211_find_ext_elem(WLAN_EID_EXT_EHT_MULTI_LINK, - tx_data->ie, tx_data->ielen); - if (!elem || !ieee80211_mle_size_ok(elem->data + 1, elem->datalen - 1)) + if (!ieee80211_mle_size_ok(elem->data + 1, elem->datalen - 1)) return; ml_elem = (void *)elem->data + 1; @@ -2625,8 +2622,11 @@ /* MLD capabilities and operations */ pos += 2; - /* Not included when the (nontransmitted) AP is responding itself, - * but defined to zero then (Draft P802.11be_D3.0, 9.4.2.170.2) + /* + * The MLD ID of the reporting AP is always zero. It is set if the AP + * is part of an MBSSID set and will be non-zero for ML Elements + * relating to a nontransmitted BSS (matching the Multi-BSSID Index, + * Draft P802.11be_D3.2, 35.3.4.2) */ if (u16_get_bits(control, IEEE80211_MLC_BASIC_PRES_MLD_ID)) { mld_id = *pos; @@ -2731,6 +2731,25 @@ kfree(mle); } +static void cfg80211_parse_ml_sta_data(struct wiphy *wiphy, + struct cfg80211_inform_single_bss_data *tx_data, + struct cfg80211_bss *source_bss, + gfp_t gfp) +{ + const struct element *elem; + + if (!source_bss) + return; + + if (tx_data->ftype != CFG80211_BSS_FTYPE_PRESP) + return; + + for_each_element_extid(elem, WLAN_EID_EXT_EHT_MULTI_LINK, + tx_data->ie, tx_data->ielen) + cfg80211_parse_ml_elem_sta_data(wiphy, tx_data, source_bss, + elem, gfp); +} + struct cfg80211_bss * cfg80211_inform_bss_data(struct wiphy *wiphy, struct cfg80211_inform_bss *data, diff -u linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/af_unix.c linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/af_unix.c --- linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/af_unix.c +++ linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/af_unix.c @@ -623,13 +623,11 @@ unix_state_lock(sk1); return; } - if (sk1 < sk2) { - unix_state_lock(sk1); - unix_state_lock_nested(sk2); - } else { - unix_state_lock(sk2); - unix_state_lock_nested(sk1); - } + if (sk1 > sk2) + swap(sk1, sk2); + + unix_state_lock(sk1); + unix_state_lock_nested(sk2, U_LOCK_SECOND); } static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2) diff -u linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/lib.c linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/lib.c --- linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/lib.c +++ linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/lib.c @@ -133,6 +133,7 @@ kfree_sensitive(t->table[i]); kfree_sensitive(t->table); t->table = NULL; + t->size = 0; } } diff -u linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/lsm.c linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/lsm.c --- linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/lsm.c +++ linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/lsm.c @@ -1203,7 +1203,6 @@ cl = aa_get_newest_cred_label(cred); error = aa_may_signal(cred, cl, tc, tl, sig); aa_put_label(cl); - return error; } else { cl = __begin_current_label_crit_section(); error = aa_may_signal(current_cred(), cl, tc, tl, sig); diff -u linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/policy_unpack.c linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/policy_unpack.c --- linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/policy_unpack.c +++ linux-lowlatency-hwe-6.5-6.5.0/security/apparmor/policy_unpack.c @@ -488,6 +488,8 @@ if (!table) goto fail; + strs->table = table; + strs->size = size; for (i = 0; i < size; i++) { char *str; int c, j, pos, size2 = aa_unpack_strdup(e, &str, NULL); @@ -530,14 +532,11 @@ goto fail; if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) goto fail; - - strs->table = table; - strs->size = size; } return true; fail: - kfree_sensitive(table); + aa_free_str_table(strs); e->pos = saved_pos; return false; } @@ -844,6 +843,10 @@ tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len); if (tmpns) { + if (!tmpname) { + info = "empty profile name"; + goto fail; + } *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL); if (!*ns_name) { info = "out of memory"; diff -u linux-lowlatency-hwe-6.5-6.5.0/security/security.c linux-lowlatency-hwe-6.5-6.5.0/security/security.c --- linux-lowlatency-hwe-6.5-6.5.0/security/security.c +++ linux-lowlatency-hwe-6.5-6.5.0/security/security.c @@ -2769,6 +2769,24 @@ } EXPORT_SYMBOL_GPL(security_file_ioctl); +/** + * security_file_ioctl_compat() - Check if an ioctl is allowed in compat mode + * @file: associated file + * @cmd: ioctl cmd + * @arg: ioctl arguments + * + * Compat version of security_file_ioctl() that correctly handles 32-bit + * processes running on 64-bit kernels. + * + * Return: Returns 0 if permission is granted. + */ +int security_file_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return call_int_hook(file_ioctl_compat, 0, file, cmd, arg); +} +EXPORT_SYMBOL_GPL(security_file_ioctl_compat); + static inline unsigned long mmap_prot(struct file *file, unsigned long prot) { /* diff -u linux-lowlatency-hwe-6.5-6.5.0/security/selinux/hooks.c linux-lowlatency-hwe-6.5-6.5.0/security/selinux/hooks.c --- linux-lowlatency-hwe-6.5-6.5.0/security/selinux/hooks.c +++ linux-lowlatency-hwe-6.5-6.5.0/security/selinux/hooks.c @@ -3702,6 +3702,33 @@ return error; } +static int selinux_file_ioctl_compat(struct file *file, unsigned int cmd, + unsigned long arg) +{ + /* + * If we are in a 64-bit kernel running 32-bit userspace, we need to + * make sure we don't compare 32-bit flags to 64-bit flags. + */ + switch (cmd) { + case FS_IOC32_GETFLAGS: + cmd = FS_IOC_GETFLAGS; + break; + case FS_IOC32_SETFLAGS: + cmd = FS_IOC_SETFLAGS; + break; + case FS_IOC32_GETVERSION: + cmd = FS_IOC_GETVERSION; + break; + case FS_IOC32_SETVERSION: + cmd = FS_IOC_SETVERSION; + break; + default: + break; + } + + return selinux_file_ioctl(file, cmd, arg); +} + static int default_noexec __ro_after_init; static int file_map_prot_check(struct file *file, unsigned long prot, int shared) @@ -4643,6 +4670,13 @@ return -EINVAL; addr4 = (struct sockaddr_in *)address; if (family_sa == AF_UNSPEC) { + if (family == PF_INET6) { + /* Length check from inet6_bind_sk() */ + if (addrlen < SIN6_LEN_RFC2133) + return -EINVAL; + /* Family check from __inet6_bind() */ + goto err_af; + } /* see __inet_bind(), we only want to allow * AF_UNSPEC if the address is INADDR_ANY */ @@ -7064,6 +7098,7 @@ LSM_HOOK_INIT(file_permission, selinux_file_permission), LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), + LSM_HOOK_INIT(file_ioctl_compat, selinux_file_ioctl_compat), LSM_HOOK_INIT(mmap_file, selinux_mmap_file), LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr), LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect), diff -u linux-lowlatency-hwe-6.5-6.5.0/security/smack/smack_lsm.c linux-lowlatency-hwe-6.5-6.5.0/security/smack/smack_lsm.c --- linux-lowlatency-hwe-6.5-6.5.0/security/smack/smack_lsm.c +++ linux-lowlatency-hwe-6.5-6.5.0/security/smack/smack_lsm.c @@ -4964,6 +4964,7 @@ LSM_HOOK_INIT(file_alloc_security, smack_file_alloc_security), LSM_HOOK_INIT(file_ioctl, smack_file_ioctl), + LSM_HOOK_INIT(file_ioctl_compat, smack_file_ioctl), LSM_HOOK_INIT(file_lock, smack_file_lock), LSM_HOOK_INIT(file_fcntl, smack_file_fcntl), LSM_HOOK_INIT(mmap_file, smack_mmap_file), diff -u linux-lowlatency-hwe-6.5-6.5.0/security/tomoyo/tomoyo.c linux-lowlatency-hwe-6.5-6.5.0/security/tomoyo/tomoyo.c --- linux-lowlatency-hwe-6.5-6.5.0/security/tomoyo/tomoyo.c +++ linux-lowlatency-hwe-6.5-6.5.0/security/tomoyo/tomoyo.c @@ -575,6 +575,7 @@ LSM_HOOK_INIT(path_rename, tomoyo_path_rename), LSM_HOOK_INIT(inode_getattr, tomoyo_inode_getattr), LSM_HOOK_INIT(file_ioctl, tomoyo_file_ioctl), + LSM_HOOK_INIT(file_ioctl_compat, tomoyo_file_ioctl), LSM_HOOK_INIT(path_chmod, tomoyo_path_chmod), LSM_HOOK_INIT(path_chown, tomoyo_path_chown), LSM_HOOK_INIT(path_chroot, tomoyo_path_chroot), diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/hda/hdac_stream.c linux-lowlatency-hwe-6.5-6.5.0/sound/hda/hdac_stream.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/hda/hdac_stream.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/hda/hdac_stream.c @@ -660,17 +660,15 @@ struct hdac_stream *s; bool inited = false; u64 cycle_last = 0; - int i = 0; list_for_each_entry(s, &bus->stream_list, list) { - if (streams & (1 << i)) { + if ((streams & (1 << s->index))) { azx_timecounter_init(s, inited, cycle_last); if (!inited) { inited = true; cycle_last = s->tc.cycle_last; } } - i++; } snd_pcm_gettime(runtime, &runtime->trigger_tstamp); @@ -715,14 +713,13 @@ unsigned int streams) { struct hdac_bus *bus = azx_dev->bus; - int i, nwait, timeout; + int nwait, timeout; struct hdac_stream *s; for (timeout = 5000; timeout; timeout--) { nwait = 0; - i = 0; list_for_each_entry(s, &bus->stream_list, list) { - if (!(streams & (1 << i++))) + if (!(streams & (1 << s->index))) continue; if (start) { diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/hda_intel.c linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/hda_intel.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/hda_intel.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/hda_intel.c @@ -2564,6 +2564,8 @@ /* Lunarlake-P */ { PCI_DEVICE(0x8086, 0xa828), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE}, + /* Arrow Lake */ + { PCI_DEVICE_DATA(INTEL, HDA_ARL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) }, /* Broxton-P(Apollolake) */ { PCI_DEVICE(0x8086, 0x5a98), .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON }, diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/patch_hdmi.c linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/patch_hdmi.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/patch_hdmi.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/patch_hdmi.c @@ -2301,6 +2301,7 @@ codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num); for (idx = 0; idx < pcm_num; idx++) { + struct hdmi_spec_per_cvt *per_cvt; struct hda_pcm *info; struct hda_pcm_stream *pstr; @@ -2316,6 +2317,11 @@ pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; pstr->substreams = 1; pstr->ops = generic_ops; + + per_cvt = get_cvt(spec, 0); + pstr->channels_min = per_cvt->channels_min; + pstr->channels_max = per_cvt->channels_max; + /* pcm number is less than pcm_rec array size */ if (spec->pcm_used >= ARRAY_SIZE(spec->pcm_rec)) break; diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/patch_realtek.c linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/patch_realtek.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/patch_realtek.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/pci/hda/patch_realtek.c @@ -6989,6 +6989,25 @@ } } +static void alc256_decrease_headphone_amp_val(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + u32 caps; + u8 nsteps, offs; + + if (action != HDA_FIXUP_ACT_PRE_PROBE) + return; + + caps = query_amp_caps(codec, 0x3, HDA_OUTPUT); + nsteps = ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) - 10; + offs = ((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT) - 10; + caps &= ~AC_AMPCAP_NUM_STEPS & ~AC_AMPCAP_OFFSET; + caps |= (nsteps << AC_AMPCAP_NUM_STEPS_SHIFT) | (offs << AC_AMPCAP_OFFSET_SHIFT); + + if (snd_hda_override_amp_caps(codec, 0x3, HDA_OUTPUT, caps)) + codec_warn(codec, "failed to override amp caps for NID 0x3\n"); +} + static void alc_fixup_dell4_mic_no_presence_quiet(struct hda_codec *codec, const struct hda_fixup *fix, int action) @@ -7399,6 +7418,7 @@ ALC2XX_FIXUP_HEADSET_MIC, ALC289_FIXUP_DELL_CS35L41_SPI_2, ALC294_FIXUP_CS35L41_I2C_2, + ALC256_FIXUP_HEADPHONE_AMP_VOL, }; /* A special fixup for Lenovo C940 and Yoga Duet 7; @@ -9534,6 +9554,10 @@ .type = HDA_FIXUP_FUNC, .v.func = cs35l41_fixup_i2c_two, }, + [ALC256_FIXUP_HEADPHONE_AMP_VOL] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc256_decrease_headphone_amp_val, + }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { @@ -9767,6 +9791,7 @@ SND_PCI_QUIRK(0x103c, 0x87f5, "HP", ALC287_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x87f6, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), SND_PCI_QUIRK(0x103c, 0x87f7, "HP Spectre x360 14", ALC245_FIXUP_HP_X360_AMP), + SND_PCI_QUIRK(0x103c, 0x87fe, "HP Laptop 15s-fq2xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x8805, "HP ProBook 650 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x880d, "HP EliteBook 830 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8811, "HP Spectre x360 15-eb1xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1), @@ -9861,6 +9886,7 @@ SND_PCI_QUIRK(0x103c, 0x8c71, "HP EliteBook 845 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8c72, "HP EliteBook 865 G11", ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8c96, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8c97, "HP ZBook", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8ca4, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8ca7, "HP ZBook Fury", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8cf5, "HP ZBook Studio 16", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), @@ -10174,6 +10200,8 @@ SND_PCI_QUIRK(0x17aa, 0x9e56, "Lenovo ZhaoYang CF4620Z", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1849, 0x1233, "ASRock NUC Box 1100", ALC233_FIXUP_NO_AUDIO_JACK), SND_PCI_QUIRK(0x1849, 0xa233, "Positivo Master C6300", ALC269_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x1854, 0x0440, "LG CQ6", ALC256_FIXUP_HEADPHONE_AMP_VOL), + SND_PCI_QUIRK(0x1854, 0x0441, "LG CQ6 AIO", ALC256_FIXUP_HEADPHONE_AMP_VOL), SND_PCI_QUIRK(0x19e5, 0x3204, "Huawei MACH-WX9", ALC256_FIXUP_HUAWEI_MACH_WX9_PINS), SND_PCI_QUIRK(0x19e5, 0x320f, "Huawei WRT-WX9 ", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1b35, 0x1235, "CZC B20", ALC269_FIXUP_CZC_B20), @@ -11512,8 +11540,7 @@ snd_hda_gen_hp_automute(codec, jack); vref = spec->gen.hp_jack_present ? (PIN_HP | AC_PINCTL_VREF_100) : PIN_HP; - snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - vref); + snd_hda_set_pin_ctl(codec, 0x1b, vref); } static void alc897_fixup_lenovo_headset_mic(struct hda_codec *codec, @@ -11522,6 +11549,10 @@ struct alc_spec *spec = codec->spec; if (action == HDA_FIXUP_ACT_PRE_PROBE) { spec->gen.hp_automute_hook = alc897_hp_automute_hook; + spec->no_shutup_pins = 1; + } + if (action == HDA_FIXUP_ACT_PROBE) { + snd_hda_set_pin_ctl_cache(codec, 0x1a, PIN_IN | AC_PINCTL_VREF_100); } } diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/lpass-wsa-macro.c linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/lpass-wsa-macro.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/lpass-wsa-macro.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/lpass-wsa-macro.c @@ -1584,7 +1584,6 @@ u16 gain_reg; u16 reg; int val; - int offset_val = 0; struct wsa_macro *wsa = snd_soc_component_get_drvdata(component); if (w->shift == WSA_MACRO_COMP1) { @@ -1623,10 +1622,8 @@ CDC_WSA_RX1_RX_PATH_MIX_SEC0, CDC_WSA_RX_PGA_HALF_DB_MASK, CDC_WSA_RX_PGA_HALF_DB_ENABLE); - offset_val = -2; } val = snd_soc_component_read(component, gain_reg); - val += offset_val; snd_soc_component_write(component, gain_reg, val); wsa_macro_config_ear_spkr_gain(component, wsa, event, gain_reg); @@ -1654,10 +1651,6 @@ CDC_WSA_RX1_RX_PATH_MIX_SEC0, CDC_WSA_RX_PGA_HALF_DB_MASK, CDC_WSA_RX_PGA_HALF_DB_DISABLE); - offset_val = 2; - val = snd_soc_component_read(component, gain_reg); - val += offset_val; - snd_soc_component_write(component, gain_reg, val); } wsa_macro_config_ear_spkr_gain(component, wsa, event, gain_reg); diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/rt5645.c linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/rt5645.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/rt5645.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/rt5645.c @@ -3827,14 +3827,6 @@ }, .driver_data = (void *)&ecs_ef20_platform_data, }, - { - .ident = "EF20EA", - .callback = cht_rt5645_ef20_quirk_cb, - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "EF20EA"), - }, - .driver_data = (void *)&ecs_ef20_platform_data, - }, { } }; diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/tas2781-fmwlib.c linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/tas2781-fmwlib.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/tas2781-fmwlib.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/tas2781-fmwlib.c @@ -2012,6 +2012,7 @@ case 0x301: case 0x302: case 0x502: + case 0x503: tas_priv->fw_parse_variable_header = fw_parse_variable_header_kernel; tas_priv->fw_parse_program_data = diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/wcd938x.c linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/wcd938x.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/wcd938x.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/wcd938x.c @@ -210,7 +210,7 @@ }; static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800); -static const DECLARE_TLV_DB_SCALE(line_gain, -3000, 150, -3000); +static const DECLARE_TLV_DB_SCALE(line_gain, -3000, 150, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(analog_gain, 0, 3000); struct wcd938x_mbhc_zdet_param { diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/wsa883x.c linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/wsa883x.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/wsa883x.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/soc/codecs/wsa883x.c @@ -1098,7 +1098,11 @@ return 1; } -static const DECLARE_TLV_DB_SCALE(pa_gain, -300, 150, -300); +static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(pa_gain, + 0, 14, TLV_DB_SCALE_ITEM(-300, 0, 0), + 15, 29, TLV_DB_SCALE_ITEM(-300, 150, 0), + 30, 31, TLV_DB_SCALE_ITEM(1800, 0, 0), +); static int wsa883x_get_swr_port(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/soc/intel/boards/sof_sdw.c linux-lowlatency-hwe-6.5-6.5.0/sound/soc/intel/boards/sof_sdw.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/soc/intel/boards/sof_sdw.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/soc/intel/boards/sof_sdw.c @@ -1185,13 +1185,13 @@ comp_index = i - adr_index + offset; if (is_unique_device(link, sdw_version, mfg_id, part_id, class_id, i)) { - codec_str = "sdw:%01x:%04x:%04x:%02x"; + codec_str = "sdw:0:%01x:%04x:%04x:%02x"; codec[comp_index].name = devm_kasprintf(dev, GFP_KERNEL, codec_str, link_id, mfg_id, part_id, class_id); } else { - codec_str = "sdw:%01x:%04x:%04x:%02x:%01x"; + codec_str = "sdw:0:%01x:%04x:%04x:%02x:%01x"; codec[comp_index].name = devm_kasprintf(dev, GFP_KERNEL, codec_str, link_id, mfg_id, part_id, diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c linux-lowlatency-hwe-6.5-6.5.0/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c @@ -168,6 +168,7 @@ device_remove_software_node(ctx->headset_codec_dev); put_device(ctx->headset_codec_dev); + ctx->headset_codec_dev = NULL; return 0; } diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/soc/qcom/sc8280xp.c linux-lowlatency-hwe-6.5-6.5.0/sound/soc/qcom/sc8280xp.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/soc/qcom/sc8280xp.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/soc/qcom/sc8280xp.c @@ -34,12 +34,14 @@ case WSA_CODEC_DMA_RX_0: case WSA_CODEC_DMA_RX_1: /* - * set limit of 0dB on Digital Volume for Speakers, - * this can prevent damage of speakers to some extent without - * active speaker protection + * Set limit of -3 dB on Digital Volume and 0 dB on PA Volume + * to reduce the risk of speaker damage until we have active + * speaker protection in place. */ - snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 84); - snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 84); + snd_soc_limit_volume(card, "WSA_RX0 Digital Volume", 81); + snd_soc_limit_volume(card, "WSA_RX1 Digital Volume", 81); + snd_soc_limit_volume(card, "SpkrLeft PA Volume", 17); + snd_soc_limit_volume(card, "SpkrRight PA Volume", 17); break; default: break; diff -u linux-lowlatency-hwe-6.5-6.5.0/sound/soc/sof/topology.c linux-lowlatency-hwe-6.5-6.5.0/sound/soc/sof/topology.c --- linux-lowlatency-hwe-6.5-6.5.0/sound/soc/sof/topology.c +++ linux-lowlatency-hwe-6.5-6.5.0/sound/soc/sof/topology.c @@ -1134,7 +1134,7 @@ list_for_each_entry(rtd, &card->rtd_list, list) { /* does stream match DAI link ? */ if (!rtd->dai_link->stream_name || - strcmp(sname, rtd->dai_link->stream_name)) + !strstr(rtd->dai_link->stream_name, sname)) continue; for_each_rtd_cpu_dais(rtd, i, cpu_dai) diff -u linux-lowlatency-hwe-6.5-6.5.0/tools/include/uapi/linux/bpf.h linux-lowlatency-hwe-6.5-6.5.0/tools/include/uapi/linux/bpf.h --- linux-lowlatency-hwe-6.5-6.5.0/tools/include/uapi/linux/bpf.h +++ linux-lowlatency-hwe-6.5-6.5.0/tools/include/uapi/linux/bpf.h @@ -4428,6 +4428,8 @@ * long bpf_get_task_stack(struct task_struct *task, void *buf, u32 size, u64 flags) * Description * Return a user or a kernel stack in bpf program provided buffer. + * Note: the user stack will only be populated if the *task* is + * the current task; all other tasks will return -EOPNOTSUPP. * To achieve this, the helper needs *task*, which is a valid * pointer to **struct task_struct**. To store the stacktrace, the * bpf program provides *buf* with a nonnegative *size*. @@ -4439,6 +4441,7 @@ * * **BPF_F_USER_STACK** * Collect a user space stack instead of a kernel stack. + * The *task* must be the current task. * **BPF_F_USER_BUILD_ID** * Collect buildid+offset instead of ips for user stack, * only valid if **BPF_F_USER_STACK** is also specified. diff -u linux-lowlatency-hwe-6.5-6.5.0/tools/lib/bpf/libbpf.c linux-lowlatency-hwe-6.5-6.5.0/tools/lib/bpf/libbpf.c --- linux-lowlatency-hwe-6.5-6.5.0/tools/lib/bpf/libbpf.c +++ linux-lowlatency-hwe-6.5-6.5.0/tools/lib/bpf/libbpf.c @@ -4234,6 +4234,8 @@ scn = elf_sec_by_idx(obj, sec_idx); scn_data = elf_sec_data(obj, scn); + if (!scn_data) + return -LIBBPF_ERRNO__FORMAT; relo_sec_name = elf_sec_str(obj, shdr->sh_name); sec_name = elf_sec_name(obj, scn); diff -u linux-lowlatency-hwe-6.5-6.5.0/tools/perf/builtin-stat.c linux-lowlatency-hwe-6.5-6.5.0/tools/perf/builtin-stat.c --- linux-lowlatency-hwe-6.5-6.5.0/tools/perf/builtin-stat.c +++ linux-lowlatency-hwe-6.5-6.5.0/tools/perf/builtin-stat.c @@ -2695,15 +2695,19 @@ */ if (metrics) { const char *pmu = parse_events_option_args.pmu_filter ?: "all"; + int ret = metricgroup__parse_groups(evsel_list, pmu, metrics, + stat_config.metric_no_group, + stat_config.metric_no_merge, + stat_config.metric_no_threshold, + stat_config.user_requested_cpu_list, + stat_config.system_wide, + &stat_config.metric_events); - metricgroup__parse_groups(evsel_list, pmu, metrics, - stat_config.metric_no_group, - stat_config.metric_no_merge, - stat_config.metric_no_threshold, - stat_config.user_requested_cpu_list, - stat_config.system_wide, - &stat_config.metric_events); zfree(&metrics); + if (ret) { + status = ret; + goto out; + } } if (add_default_attributes()) diff -u linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/env.c linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/env.c --- linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/env.c +++ linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/env.c @@ -23,12 +23,18 @@ void perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node) { + down_write(&env->bpf_progs.lock); + __perf_env__insert_bpf_prog_info(env, info_node); + up_write(&env->bpf_progs.lock); +} + +void __perf_env__insert_bpf_prog_info(struct perf_env *env, struct bpf_prog_info_node *info_node) +{ __u32 prog_id = info_node->info_linear->info.id; struct bpf_prog_info_node *node; struct rb_node *parent = NULL; struct rb_node **p; - down_write(&env->bpf_progs.lock); p = &env->bpf_progs.infos.rb_node; while (*p != NULL) { @@ -40,15 +46,13 @@ p = &(*p)->rb_right; } else { pr_debug("duplicated bpf prog info %u\n", prog_id); - goto out; + return; } } rb_link_node(&info_node->rb_node, parent, p); rb_insert_color(&info_node->rb_node, &env->bpf_progs.infos); env->bpf_progs.infos_cnt++; -out: - up_write(&env->bpf_progs.lock); } struct bpf_prog_info_node *perf_env__find_bpf_prog_info(struct perf_env *env, @@ -78,13 +82,21 @@ bool perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) { + bool ret; + + down_write(&env->bpf_progs.lock); + ret = __perf_env__insert_btf(env, btf_node); + up_write(&env->bpf_progs.lock); + return ret; +} + +bool __perf_env__insert_btf(struct perf_env *env, struct btf_node *btf_node) +{ struct rb_node *parent = NULL; __u32 btf_id = btf_node->id; struct btf_node *node; struct rb_node **p; - bool ret = true; - down_write(&env->bpf_progs.lock); p = &env->bpf_progs.btfs.rb_node; while (*p != NULL) { @@ -96,25 +108,31 @@ p = &(*p)->rb_right; } else { pr_debug("duplicated btf %u\n", btf_id); - ret = false; - goto out; + return false; } } rb_link_node(&btf_node->rb_node, parent, p); rb_insert_color(&btf_node->rb_node, &env->bpf_progs.btfs); env->bpf_progs.btfs_cnt++; -out: - up_write(&env->bpf_progs.lock); - return ret; + return true; } struct btf_node *perf_env__find_btf(struct perf_env *env, __u32 btf_id) { + struct btf_node *res; + + down_read(&env->bpf_progs.lock); + res = __perf_env__find_btf(env, btf_id); + up_read(&env->bpf_progs.lock); + return res; +} + +struct btf_node *__perf_env__find_btf(struct perf_env *env, __u32 btf_id) +{ struct btf_node *node = NULL; struct rb_node *n; - down_read(&env->bpf_progs.lock); n = env->bpf_progs.btfs.rb_node; while (n) { @@ -124,13 +142,9 @@ else if (btf_id > node->id) n = n->rb_right; else - goto out; + return node; } - node = NULL; - -out: - up_read(&env->bpf_progs.lock); - return node; + return NULL; } /* purge data in bpf_progs.infos tree */ diff -u linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/header.c linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/header.c --- linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/header.c +++ linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/header.c @@ -1442,7 +1442,9 @@ nodes = new_nodes; size += 4; } - ret = memory_node__read(&nodes[cnt++], idx); + ret = memory_node__read(&nodes[cnt], idx); + if (!ret) + cnt += 1; } out: closedir(dir); @@ -1845,8 +1847,8 @@ node = rb_entry(next, struct bpf_prog_info_node, rb_node); next = rb_next(&node->rb_node); - bpf_event__print_bpf_prog_info(&node->info_linear->info, - env, fp); + __bpf_event__print_bpf_prog_info(&node->info_linear->info, + env, fp); } up_read(&env->bpf_progs.lock); @@ -3173,7 +3175,7 @@ /* after reading from file, translate offset to address */ bpil_offs_to_addr(info_linear); info_node->info_linear = info_linear; - perf_env__insert_bpf_prog_info(env, info_node); + __perf_env__insert_bpf_prog_info(env, info_node); } up_write(&env->bpf_progs.lock); @@ -3220,7 +3222,7 @@ if (__do_read(ff, node->data, data_size)) goto out; - perf_env__insert_btf(env, node); + __perf_env__insert_btf(env, node); node = NULL; } @@ -4359,9 +4361,10 @@ ret += fprintf(fp, "... "); map = cpu_map__new_data(&ev->cpus.cpus); - if (map) + if (map) { ret += cpu_map__fprintf(map, fp); - else + perf_cpu_map__put(map); + } else ret += fprintf(fp, "failed to get cpus\n"); break; default: diff -u linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/mem-events.c linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/mem-events.c --- linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/mem-events.c +++ linux-lowlatency-hwe-6.5-6.5.0/tools/perf/util/mem-events.c @@ -100,11 +100,14 @@ return -1; } -static bool perf_mem_event__supported(const char *mnt, char *sysfs_name) +static bool perf_mem_event__supported(const char *mnt, struct perf_pmu *pmu, + struct perf_mem_event *e) { + char sysfs_name[100]; char path[PATH_MAX]; struct stat st; + scnprintf(sysfs_name, sizeof(sysfs_name), e->sysfs_name, pmu->name); scnprintf(path, PATH_MAX, "%s/devices/%s", mnt, sysfs_name); return !stat(path, &st); } @@ -120,7 +123,6 @@ for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) { struct perf_mem_event *e = perf_mem_events__ptr(j); - char sysfs_name[100]; struct perf_pmu *pmu = NULL; /* @@ -136,12 +138,12 @@ * of core PMU. */ while ((pmu = perf_pmus__scan(pmu)) != NULL) { - scnprintf(sysfs_name, sizeof(sysfs_name), e->sysfs_name, pmu->name); - e->supported |= perf_mem_event__supported(mnt, sysfs_name); + e->supported |= perf_mem_event__supported(mnt, pmu, e); + if (e->supported) { + found = true; + break; + } } - - if (e->supported) - found = true; } return found ? 0 : -ENOENT; @@ -167,13 +169,10 @@ int idx) { const char *mnt = sysfs__mount(); - char sysfs_name[100]; struct perf_pmu *pmu = NULL; while ((pmu = perf_pmus__scan(pmu)) != NULL) { - scnprintf(sysfs_name, sizeof(sysfs_name), e->sysfs_name, - pmu->name); - if (!perf_mem_event__supported(mnt, sysfs_name)) { + if (!perf_mem_event__supported(mnt, pmu, e)) { pr_err("failed: event '%s' not supported\n", perf_mem_events__name(idx, pmu->name)); } @@ -183,6 +182,7 @@ int perf_mem_events__record_args(const char **rec_argv, int *argv_nr, char **rec_tmp, int *tmp_nr) { + const char *mnt = sysfs__mount(); int i = *argv_nr, k = 0; struct perf_mem_event *e; @@ -211,6 +211,9 @@ while ((pmu = perf_pmus__scan(pmu)) != NULL) { const char *s = perf_mem_events__name(j, pmu->name); + if (!perf_mem_event__supported(mnt, pmu, e)) + continue; + rec_argv[i++] = "-e"; if (s) { char *copy = strdup(s); diff -u linux-lowlatency-hwe-6.5-6.5.0/tools/testing/selftests/alsa/mixer-test.c linux-lowlatency-hwe-6.5-6.5.0/tools/testing/selftests/alsa/mixer-test.c --- linux-lowlatency-hwe-6.5-6.5.0/tools/testing/selftests/alsa/mixer-test.c +++ linux-lowlatency-hwe-6.5-6.5.0/tools/testing/selftests/alsa/mixer-test.c @@ -166,7 +166,7 @@ err = snd_ctl_poll_descriptors(card_data->handle, &card_data->pollfd, 1); if (err != 1) { - ksft_exit_fail_msg("snd_ctl_poll_descriptors() failed for %d\n", + ksft_exit_fail_msg("snd_ctl_poll_descriptors() failed for card %d: %d\n", card, err); } @@ -319,7 +319,7 @@ } if (int64_val > snd_ctl_elem_info_get_max64(ctl->info)) { - ksft_print_msg("%s.%d value %lld more than maximum %lld\n", + ksft_print_msg("%s.%d value %lld more than maximum %ld\n", ctl->name, index, int64_val, snd_ctl_elem_info_get_max(ctl->info)); return false; diff -u linux-lowlatency-hwe-6.5-6.5.0/tools/testing/selftests/net/pmtu.sh linux-lowlatency-hwe-6.5-6.5.0/tools/testing/selftests/net/pmtu.sh --- linux-lowlatency-hwe-6.5-6.5.0/tools/testing/selftests/net/pmtu.sh +++ linux-lowlatency-hwe-6.5-6.5.0/tools/testing/selftests/net/pmtu.sh @@ -714,23 +714,23 @@ } setup_xfrm4udp() { - setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr} "encap espinudp 4500 4500 0.0.0.0" - setup_nettest_xfrm 4 4500 + setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr} "encap espinudp 4500 4500 0.0.0.0" && \ + setup_nettest_xfrm 4 4500 } setup_xfrm6udp() { - setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr} "encap espinudp 4500 4500 0.0.0.0" - setup_nettest_xfrm 6 4500 + setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr} "encap espinudp 4500 4500 0.0.0.0" && \ + setup_nettest_xfrm 6 4500 } setup_xfrm4udprouted() { - setup_xfrm 4 ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "encap espinudp 4500 4500 0.0.0.0" - setup_nettest_xfrm 4 4500 + setup_xfrm 4 ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "encap espinudp 4500 4500 0.0.0.0" && \ + setup_nettest_xfrm 4 4500 } setup_xfrm6udprouted() { - setup_xfrm 6 ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "encap espinudp 4500 4500 0.0.0.0" - setup_nettest_xfrm 6 4500 + setup_xfrm 6 ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "encap espinudp 4500 4500 0.0.0.0" && \ + setup_nettest_xfrm 6 4500 } setup_routing_old() { @@ -1348,7 +1348,7 @@ sleep 1 - dd if=/dev/zero of=/dev/stdout status=none bs=1M count=1 | ${target} socat -T 3 -u STDIN $TCPDST,connect-timeout=3 + dd if=/dev/zero status=none bs=1M count=1 | ${target} socat -T 3 -u STDIN $TCPDST,connect-timeout=3 size=$(du -sb $tmpoutfile) size=${size%%/tmp/*} only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/ABI/testing/sysfs-class-devfreq +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/ABI/testing/sysfs-class-devfreq @@ -52,6 +52,9 @@ echo 0 > /sys/class/devfreq/.../trans_stat + If the transition table is bigger than PAGE_SIZE, reading + this will return an -EFBIG error. + What: /sys/class/devfreq/.../available_frequencies Date: October 2012 Contact: Nishanth Menon only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/ABI/testing/sysfs-class-net-queues +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/ABI/testing/sysfs-class-net-queues @@ -1,4 +1,4 @@ -What: /sys/class//queues/rx-/rps_cpus +What: /sys/class/net//queues/rx-/rps_cpus Date: March 2010 KernelVersion: 2.6.35 Contact: netdev@vger.kernel.org @@ -8,7 +8,7 @@ network device queue. Possible values depend on the number of available CPU(s) in the system. -What: /sys/class//queues/rx-/rps_flow_cnt +What: /sys/class/net//queues/rx-/rps_flow_cnt Date: April 2010 KernelVersion: 2.6.35 Contact: netdev@vger.kernel.org @@ -16,7 +16,7 @@ Number of Receive Packet Steering flows being currently processed by this particular network device receive queue. -What: /sys/class//queues/tx-/tx_timeout +What: /sys/class/net//queues/tx-/tx_timeout Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org @@ -24,7 +24,7 @@ Indicates the number of transmit timeout events seen by this network interface transmit queue. -What: /sys/class//queues/tx-/tx_maxrate +What: /sys/class/net//queues/tx-/tx_maxrate Date: March 2015 KernelVersion: 4.1 Contact: netdev@vger.kernel.org @@ -32,7 +32,7 @@ A Mbps max-rate set for the queue, a value of zero means disabled, default is disabled. -What: /sys/class//queues/tx-/xps_cpus +What: /sys/class/net//queues/tx-/xps_cpus Date: November 2010 KernelVersion: 2.6.38 Contact: netdev@vger.kernel.org @@ -42,7 +42,7 @@ network device transmit queue. Possible vaules depend on the number of available CPU(s) in the system. -What: /sys/class//queues/tx-/xps_rxqs +What: /sys/class/net//queues/tx-/xps_rxqs Date: June 2018 KernelVersion: 4.18.0 Contact: netdev@vger.kernel.org @@ -53,7 +53,7 @@ number of available receive queue(s) in the network device. Default is disabled. -What: /sys/class//queues/tx-/byte_queue_limits/hold_time +What: /sys/class/net//queues/tx-/byte_queue_limits/hold_time Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org @@ -62,7 +62,7 @@ of this particular network device transmit queue. Default value is 1000. -What: /sys/class//queues/tx-/byte_queue_limits/inflight +What: /sys/class/net//queues/tx-/byte_queue_limits/inflight Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org @@ -70,7 +70,7 @@ Indicates the number of bytes (objects) in flight on this network device transmit queue. -What: /sys/class//queues/tx-/byte_queue_limits/limit +What: /sys/class/net//queues/tx-/byte_queue_limits/limit Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org @@ -79,7 +79,7 @@ on this network device transmit queue. This value is clamped to be within the bounds defined by limit_max and limit_min. -What: /sys/class//queues/tx-/byte_queue_limits/limit_max +What: /sys/class/net//queues/tx-/byte_queue_limits/limit_max Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org @@ -88,7 +88,7 @@ queued on this network device transmit queue. See include/linux/dynamic_queue_limits.h for the default value. -What: /sys/class//queues/tx-/byte_queue_limits/limit_min +What: /sys/class/net//queues/tx-/byte_queue_limits/limit_min Date: November 2011 KernelVersion: 3.3 Contact: netdev@vger.kernel.org only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/admin-guide/abi-obsolete.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/admin-guide/abi-obsolete.rst @@ -7,5 +7,5 @@ The description of the interface will document the reason why it is obsolete and when it can be expected to be removed. -.. kernel-abi:: $srctree/Documentation/ABI/obsolete +.. kernel-abi:: ABI/obsolete :rst: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/admin-guide/abi-removed.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/admin-guide/abi-removed.rst @@ -1,5 +1,5 @@ ABI removed symbols =================== -.. kernel-abi:: $srctree/Documentation/ABI/removed +.. kernel-abi:: ABI/removed :rst: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/admin-guide/abi-stable.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/admin-guide/abi-stable.rst @@ -10,5 +10,5 @@ Most interfaces (like syscalls) are expected to never change and always be available. -.. kernel-abi:: $srctree/Documentation/ABI/stable +.. kernel-abi:: ABI/stable :rst: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/admin-guide/abi-testing.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/admin-guide/abi-testing.rst @@ -16,5 +16,5 @@ name to the description of these interfaces, so that the kernel developers can easily notify them if any changes occur. -.. kernel-abi:: $srctree/Documentation/ABI/testing +.. kernel-abi:: ABI/testing :rst: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/admin-guide/hw-vuln/spectre.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/admin-guide/hw-vuln/spectre.rst @@ -138,11 +138,10 @@ the BHB might be shared across privilege levels even in the presence of Enhanced IBRS. -Currently the only known real-world BHB attack vector is via -unprivileged eBPF. Therefore, it's highly recommended to not enable -unprivileged eBPF, especially when eIBRS is used (without retpolines). -For a full mitigation against BHB attacks, it's recommended to use -retpolines (or eIBRS combined with retpolines). +Previously the only known real-world BHB attack vector was via unprivileged +eBPF. Further research has found attacks that don't require unprivileged eBPF. +For a full mitigation against BHB attacks it is recommended to set BHI_DIS_S or +use the BHB clearing sequence. Attack scenarios ---------------- @@ -430,6 +429,23 @@ 'PBRSB-eIBRS: Not affected' CPU is not affected by PBRSB =========================== ======================================================= + - Branch History Injection (BHI) protection status: + +.. list-table:: + + * - BHI: Not affected + - System is not affected + * - BHI: Retpoline + - System is protected by retpoline + * - BHI: BHI_DIS_S + - System is protected by BHI_DIS_S + * - BHI: SW loop; KVM SW loop + - System is protected by software clearing sequence + * - BHI: Syscall hardening + - Syscalls are hardened against BHI + * - BHI: Syscall hardening; KVM: SW loop + - System is protected from userspace attacks by syscall hardening; KVM is protected by software clearing sequence + Full mitigation might require a microcode update from the CPU vendor. When the necessary microcode is not available, the kernel will report vulnerability. @@ -484,7 +500,11 @@ Systems which support enhanced IBRS (eIBRS) enable IBRS protection once at boot, by setting the IBRS bit, and they're automatically protected against - Spectre v2 variant attacks. + some Spectre v2 variant attacks. The BHB can still influence the choice of + indirect branch predictor entry, and although branch predictor entries are + isolated between modes when eIBRS is enabled, the BHB itself is not isolated + between modes. Systems which support BHI_DIS_S will set it to protect against + BHI attacks. On Intel's enhanced IBRS systems, this includes cross-thread branch target injections on SMT systems (STIBP). In other words, Intel eIBRS enables @@ -638,6 +658,22 @@ spectre_v2=off. Spectre variant 1 mitigations cannot be disabled. + spectre_bhi= + + [X86] Control mitigation of Branch History Injection + (BHI) vulnerability. Syscalls are hardened against BHI + regardless of this setting. This setting affects the deployment + of the HW BHI control and the SW BHB clearing sequence. + + on + unconditionally enable. + off + unconditionally disable. + auto + enable if hardware mitigation + control(BHI_DIS_S) is available, otherwise + enable alternate mitigation in KVM. + For spectre_v2_user see Documentation/admin-guide/kernel-parameters.txt Mitigation selection guide only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/devicetree/bindings/arm/qcom.yaml +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/devicetree/bindings/arm/qcom.yaml @@ -133,7 +133,7 @@ There are many devices in the list below that run the standard ChromeOS bootloader setup and use the open source depthcharge bootloader to boot the OS. These devices do not use the scheme described above. For details, see: - https://docs.kernel.org/arm/google/chromebook-boot-flow.html + https://docs.kernel.org/arch/arm/google/chromebook-boot-flow.html properties: $nodename: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/devicetree/bindings/gpio/xlnx,gpio-xilinx.yaml @@ -126,7 +126,7 @@ - | #include - gpio@e000a000 { + gpio@a0020000 { compatible = "xlnx,xps-gpio-1.00.a"; reg = <0xa0020000 0x10000>; #gpio-cells = <2>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/devicetree/bindings/media/mediatek,mdp3-rdma.yaml @@ -61,6 +61,9 @@ - description: used for 1st data pipe from RDMA - description: used for 2nd data pipe from RDMA + '#dma-cells': + const: 1 + required: - compatible - reg @@ -70,6 +73,7 @@ - clocks - iommus - mboxes + - '#dma-cells' additionalProperties: false @@ -80,16 +84,17 @@ #include #include - mdp3_rdma0: mdp3-rdma0@14001000 { - compatible = "mediatek,mt8183-mdp3-rdma"; - reg = <0x14001000 0x1000>; - mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; - mediatek,gce-events = , - ; - power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; - clocks = <&mmsys CLK_MM_MDP_RDMA0>, - <&mmsys CLK_MM_MDP_RSZ1>; - iommus = <&iommu>; - mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>, - <&gce 21 CMDQ_THR_PRIO_LOWEST>; + dma-controller@14001000 { + compatible = "mediatek,mt8183-mdp3-rdma"; + reg = <0x14001000 0x1000>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x1000 0x1000>; + mediatek,gce-events = , + ; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_MDP_RDMA0>, + <&mmsys CLK_MM_MDP_RSZ1>; + iommus = <&iommu>; + mboxes = <&gce 20 CMDQ_THR_PRIO_LOWEST>, + <&gce 21 CMDQ_THR_PRIO_LOWEST>; + #dma-cells = <1>; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/devicetree/bindings/media/mediatek,mdp3-wrot.yaml @@ -50,6 +50,9 @@ iommus: maxItems: 1 + '#dma-cells': + const: 1 + required: - compatible - reg @@ -58,6 +61,7 @@ - power-domains - clocks - iommus + - '#dma-cells' additionalProperties: false @@ -68,13 +72,14 @@ #include #include - mdp3_wrot0: mdp3-wrot0@14005000 { - compatible = "mediatek,mt8183-mdp3-wrot"; - reg = <0x14005000 0x1000>; - mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; - mediatek,gce-events = , - ; - power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; - clocks = <&mmsys CLK_MM_MDP_WROT0>; - iommus = <&iommu>; + dma-controller@14005000 { + compatible = "mediatek,mt8183-mdp3-wrot"; + reg = <0x14005000 0x1000>; + mediatek,gce-client-reg = <&gce SUBSYS_1400XXXX 0x5000 0x1000>; + mediatek,gce-events = , + ; + power-domains = <&spm MT8183_POWER_DOMAIN_DISP>; + clocks = <&mmsys CLK_MM_MDP_WROT0>; + iommus = <&iommu>; + #dma-cells = <1>; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/devicetree/bindings/media/rockchip-isp1.yaml +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/devicetree/bindings/media/rockchip-isp1.yaml @@ -90,15 +90,16 @@ description: connection point for input on the parallel interface properties: - bus-type: - enum: [5, 6] - endpoint: $ref: video-interfaces.yaml# unevaluatedProperties: false - required: - - bus-type + properties: + bus-type: + enum: [5, 6] + + required: + - bus-type anyOf: - required: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/devicetree/bindings/net/snps,dwmac.yaml +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/devicetree/bindings/net/snps,dwmac.yaml @@ -394,6 +394,11 @@ When a PFC frame is received with priorities matching the bitmask, the queue is blocked from transmitting for the pause time specified in the PFC frame. + + snps,coe-unsupported: + type: boolean + description: TX checksum offload is unsupported by the TX queue. + allOf: - if: required: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml @@ -53,12 +53,12 @@ "#clock-cells": const: 1 description: - See include/dt-bindings/dt-bindings/phy/phy-qcom-qmp.h + See include/dt-bindings/phy/phy-qcom-qmp.h "#phy-cells": const: 1 description: - See include/dt-bindings/dt-bindings/phy/phy-qcom-qmp.h + See include/dt-bindings/phy/phy-qcom-qmp.h orientation-switch: description: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/driver-api/pci/p2pdma.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/driver-api/pci/p2pdma.rst @@ -83,19 +83,9 @@ Client Drivers -------------- -A client driver typically only has to conditionally change its DMA map -routine to use the mapping function :c:func:`pci_p2pdma_map_sg()` instead -of the usual :c:func:`dma_map_sg()` function. Memory mapped in this -way does not need to be unmapped. - -The client may also, optionally, make use of -:c:func:`is_pci_p2pdma_page()` to determine when to use the P2P mapping -functions and when to use the regular mapping functions. In some -situations, it may be more appropriate to use a flag to indicate a -given request is P2P memory and map appropriately. It is important to -ensure that struct pages that back P2P memory stay out of code that -does not have support for them as other code may treat the pages as -regular memory which may not be appropriate. +A client driver only has to use the mapping API :c:func:`dma_map_sg()` +and :c:func:`dma_unmap_sg()` functions as usual, and the implementation +will do the right thing for the P2P capable memory. Orchestrator Drivers only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/filesystems/directory-locking.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/filesystems/directory-locking.rst @@ -22,13 +22,16 @@ 3) object removal. Locking rules: caller locks parent, finds victim, locks victim and calls the method. Locks are exclusive. -4) rename() that is _not_ cross-directory. Locking rules: caller locks the -parent and finds source and target. We lock both (provided they exist). If we -need to lock two inodes of different type (dir vs non-dir), we lock directory -first. If we need to lock two inodes of the same type, lock them in inode -pointer order. Then call the method. All locks are exclusive. -NB: we might get away with locking the source (and target in exchange -case) shared. +4) rename() that is _not_ cross-directory. Locking rules: caller locks +the parent and finds source and target. Then we decide which of the +source and target need to be locked. Source needs to be locked if it's a +non-directory; target - if it's a non-directory or about to be removed. +Take the locks that need to be taken, in inode pointer order if need +to take both (that can happen only when both source and target are +non-directories - the source because it wouldn't be locked otherwise +and the target because mixing directory and non-directory is allowed +only with RENAME_EXCHANGE, and that won't be removing the target). +After the locks had been taken, call the method. All locks are exclusive. 5) link creation. Locking rules: @@ -44,20 +47,17 @@ * lock the filesystem * lock parents in "ancestors first" order. If one is not ancestor of - the other, lock them in inode pointer order. + the other, lock the parent of source first. * find source and target. * if old parent is equal to or is a descendent of target fail with -ENOTEMPTY * if new parent is equal to or is a descendent of source fail with -ELOOP - * Lock both the source and the target provided they exist. If we - need to lock two inodes of different type (dir vs non-dir), we lock - the directory first. If we need to lock two inodes of the same type, - lock them in inode pointer order. + * Lock subdirectories involved (source before target). + * Lock non-directories involved, in inode pointer order. * call the method. -All ->i_rwsem are taken exclusive. Again, we might get away with locking -the source (and target in exchange case) shared. +All ->i_rwsem are taken exclusive. The rules above obviously guarantee that all directories that are going to be read, modified or removed by method will be locked by caller. @@ -67,6 +67,7 @@ Proof: +[XXX: will be updated once we are done massaging the lock_rename()] First of all, at any moment we have a linear ordering of the objects - A < B iff (A is an ancestor of B) or (B is not an ancestor of A and ptr(A) < ptr(B)). only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/filesystems/locking.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/filesystems/locking.rst @@ -100,7 +100,7 @@ mkdir: exclusive unlink: exclusive (both) rmdir: exclusive (both)(see below) -rename: exclusive (all) (see below) +rename: exclusive (both parents, some children) (see below) readlink: no get_link: no setattr: exclusive @@ -121,6 +121,9 @@ Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_rwsem exclusive on victim. cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. + ->unlink() and ->rename() have ->i_rwsem exclusive on all non-directories + involved. + ->rename() has ->i_rwsem exclusive on any subdirectory that changes parent. See Documentation/filesystems/directory-locking.rst for more detailed discussion of the locking scheme for directory operations. only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/filesystems/porting.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/filesystems/porting.rst @@ -938,3 +938,21 @@ changed to simplify callers. The passed file is in a non-open state and on success must be opened before returning (e.g. by calling finish_open_simple()). + +--- + +**mandatory** + +If ->rename() update of .. on cross-directory move needs an exclusion with +directory modifications, do *not* lock the subdirectory in question in your +->rename() - it's done by the caller now [that item should've been added in +28eceeda130f "fs: Lock moved directories"]. + +--- + +**mandatory** + +On same-directory ->rename() the (tautological) update of .. is not protected +by any locks; just don't do it if the old parent is the same as the new one. +We really can't lock two subdirectories in same-directory rename - not without +deadlocks. only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/gpu/drm-kms.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/gpu/drm-kms.rst @@ -546,6 +546,8 @@ .. kernel-doc:: drivers/gpu/drm/drm_blend.c :doc: overview +.. _damage_tracking_properties: + Damage Tracking Properties -------------------------- only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/gpu/todo.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/gpu/todo.rst @@ -342,8 +342,8 @@ Level: Intermediate -Remove load/unload callbacks from all non-DRIVER_LEGACY drivers ---------------------------------------------------------------- +Remove load/unload callbacks +---------------------------- The load/unload callbacks in struct &drm_driver are very much midlayers, plus for historical reasons they get the ordering wrong (and we can't fix that) @@ -352,8 +352,7 @@ - Rework drivers to no longer use the load/unload callbacks, directly coding the load/unload sequence into the driver's probe function. -- Once all non-DRIVER_LEGACY drivers are converted, disallow the load/unload - callbacks for all modern drivers. +- Once all drivers are converted, remove the load/unload callbacks. Contact: Daniel Vetter only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/sound/soc/dapm.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/sound/soc/dapm.rst @@ -234,7 +234,7 @@ a virtual widget - a widget with no control bits e.g. :: - SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), This can be used to merge to signal paths together in software. only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/sphinx/kernel_abi.py +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/sphinx/kernel_abi.py @@ -39,8 +39,6 @@ import re import kernellog -from os import path - from docutils import nodes, statemachine from docutils.statemachine import ViewList from docutils.parsers.rst import directives, Directive @@ -73,60 +71,26 @@ } def run(self): - doc = self.state.document if not doc.settings.file_insertion_enabled: raise self.warning("docutils: file insertion disabled") - env = doc.settings.env - cwd = path.dirname(doc.current_source) - cmd = "get_abi.pl rest --enable-lineno --dir " - cmd += self.arguments[0] - - if 'rst' in self.options: - cmd += " --rst-source" - - srctree = path.abspath(os.environ["srctree"]) + srctree = os.path.abspath(os.environ["srctree"]) - fname = cmd + args = [ + os.path.join(srctree, 'scripts/get_abi.pl'), + 'rest', + '--enable-lineno', + '--dir', os.path.join(srctree, 'Documentation', self.arguments[0]), + ] - # extend PATH with $(srctree)/scripts - path_env = os.pathsep.join([ - srctree + os.sep + "scripts", - os.environ["PATH"] - ]) - shell_env = os.environ.copy() - shell_env["PATH"] = path_env - shell_env["srctree"] = srctree + if 'rst' in self.options: + args.append('--rst-source') - lines = self.runCmd(cmd, shell=True, cwd=cwd, env=shell_env) + lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8') nodeList = self.nestedParse(lines, self.arguments[0]) return nodeList - def runCmd(self, cmd, **kwargs): - u"""Run command ``cmd`` and return its stdout as unicode.""" - - try: - proc = subprocess.Popen( - cmd - , stdout = subprocess.PIPE - , stderr = subprocess.PIPE - , **kwargs - ) - out, err = proc.communicate() - - out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8') - - if proc.returncode != 0: - raise self.severe( - u"command '%s' failed with return code %d" - % (cmd, proc.returncode) - ) - except OSError as exc: - raise self.severe(u"problems with '%s' directive: %s." - % (self.name, ErrorString(exc))) - return out - def nestedParse(self, lines, fname): env = self.state.document.settings.env content = ViewList() @@ -138,7 +102,7 @@ code_block += "\n " + l lines = code_block + "\n\n" - line_regex = re.compile("^\.\. LINENO (\S+)\#([0-9]+)$") + line_regex = re.compile(r"^\.\. LINENO (\S+)\#([0-9]+)$") ln = 0 n = 0 f = fname only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/sphinx/kernel_feat.py +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/sphinx/kernel_feat.py @@ -104,7 +104,7 @@ lines = self.runCmd(cmd, shell=True, cwd=cwd, env=shell_env) - line_regex = re.compile("^\.\. FILE (\S+)$") + line_regex = re.compile(r"^\.\. FILE (\S+)$") out_lines = "" only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/sphinx/kerneldoc.py +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/sphinx/kerneldoc.py @@ -130,7 +130,7 @@ result = ViewList() lineoffset = 0; - line_regex = re.compile("^\.\. LINENO ([0-9]+)$") + line_regex = re.compile(r"^\.\. LINENO ([0-9]+)$") for line in lines: match = line_regex.search(line) if match: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/sphinx/maintainers_include.py +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/sphinx/maintainers_include.py @@ -77,7 +77,7 @@ line = line.rstrip() # Linkify all non-wildcard refs to ReST files in Documentation/. - pat = '(Documentation/([^\s\?\*]*)\.rst)' + pat = r'(Documentation/([^\s\?\*]*)\.rst)' m = re.search(pat, line) if m: # maintainers.rst is in a subdirectory, so include "../". @@ -90,11 +90,11 @@ output = "| %s" % (line.replace("\\", "\\\\")) # Look for and record field letter to field name mappings: # R: Designated *reviewer*: FullName - m = re.search("\s(\S):\s", line) + m = re.search(r"\s(\S):\s", line) if m: field_letter = m.group(1) if field_letter and not field_letter in fields: - m = re.search("\*([^\*]+)\*", line) + m = re.search(r"\*([^\*]+)\*", line) if m: fields[field_letter] = m.group(1) elif subsystems: @@ -112,7 +112,7 @@ field_content = "" # Collapse whitespace in subsystem name. - heading = re.sub("\s+", " ", line) + heading = re.sub(r"\s+", " ", line) output = output + "%s\n%s" % (heading, "~" * len(heading)) field_prev = "" else: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/translations/zh_TW/dev-tools/sparse.txt +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/translations/zh_TW/dev-tools/sparse.txt @@ -0,0 +1,91 @@ +Chinese translated version of Documentation/dev-tools/sparse.rst + +If you have any comment or update to the content, please contact the +original document maintainer directly. However, if you have a problem +communicating in English you can also ask the Chinese maintainer for +help. Contact the Chinese maintainer if this translation is outdated +or if there is a problem with the translation. + +Traditional Chinese maintainer: Hu Haowen +--------------------------------------------------------------------- +Documentation/dev-tools/sparse.rst 的繁體中文翻譯 + +如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文 +交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或 +者翻譯存在問題,請聯繫繁體中文版維護者。 + +繁體中文版維護者: 胡皓文 Hu Haowen +繁體中文版翻譯者: 胡皓文 Hu Haowen + +以下爲正文 +--------------------------------------------------------------------- + +Copyright 2004 Linus Torvalds +Copyright 2004 Pavel Machek +Copyright 2006 Bob Copeland + +使用 sparse 工具做類型檢查 +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +"__bitwise" 是一種類型屬性,所以你應該這樣使用它: + + typedef int __bitwise pm_request_t; + + enum pm_request { + PM_SUSPEND = (__force pm_request_t) 1, + PM_RESUME = (__force pm_request_t) 2 + }; + +這樣會使 PM_SUSPEND 和 PM_RESUME 成爲位方式(bitwise)整數(使用"__force" +是因爲 sparse 會抱怨改變位方式的類型轉換,但是這裡我們確實需要強制進行轉 +換)。而且因爲所有枚舉值都使用了相同的類型,這裡的"enum pm_request"也將 +會使用那個類型做爲底層實現。 + +而且使用 gcc 編譯的時候,所有的 __bitwise/__force 都會消失,最後在 gcc +看來它們只不過是普通的整數。 + +坦白來說,你並不需要使用枚舉類型。上面那些實際都可以濃縮成一個特殊的"int +__bitwise"類型。 + +所以更簡單的辦法只要這樣做: + + typedef int __bitwise pm_request_t; + + #define PM_SUSPEND ((__force pm_request_t) 1) + #define PM_RESUME ((__force pm_request_t) 2) + +現在你就有了嚴格的類型檢查所需要的所有基礎架構。 + +一個小提醒:常數整數"0"是特殊的。你可以直接把常數零當作位方式整數使用而 +不用擔心 sparse 會抱怨。這是因爲"bitwise"(恰如其名)是用來確保不同位方 +式類型不會被弄混(小尾模式,大尾模式,cpu尾模式,或者其他),對他們來說 +常數"0"確實是特殊的。 + +獲取 sparse 工具 +~~~~~~~~~~~~~~~~ + +你可以從 Sparse 的主頁獲取最新的發布版本: + + http://www.kernel.org/pub/linux/kernel/people/josh/sparse/ + +或者,你也可以使用 git 克隆最新的 sparse 開發版本: + + git://git.kernel.org/pub/scm/linux/kernel/git/josh/sparse.git + +一旦你下載了源碼,只要以普通用戶身份運行: + + make + make install + +它將會被自動安裝到你的 ~/bin 目錄下。 + +使用 sparse 工具 +~~~~~~~~~~~~~~~~ + +用"make C=1"命令來編譯內核,會對所有重新編譯的 C 文件使用 sparse 工具。 +或者使用"make C=2"命令,無論文件是否被重新編譯都會對其使用 sparse 工具。 +如果你已經編譯了內核,用後一種方式可以很快地檢查整個源碼樹。 + +make 的可選變量 CHECKFLAGS 可以用來向 sparse 工具傳遞參數。編譯系統會自 +動向 sparse 工具傳遞 -Wbitwise 參數。 + only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/Documentation/translations/zh_TW/index.rst +++ linux-lowlatency-hwe-6.5-6.5.0/Documentation/translations/zh_TW/index.rst @@ -70,10 +70,10 @@ :maxdepth: 2 process/index + dev-tools/index TODOList: -* dev-tools/index * doc-guide/index * kernel-hacking/index * trace/index only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/alpha/kernel/rtc.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/alpha/kernel/rtc.c @@ -80,7 +80,7 @@ static int alpha_rtc_read_time(struct device *dev, struct rtc_time *tm) { - int ret = mc146818_get_time(tm); + int ret = mc146818_get_time(tm, 10); if (ret < 0) { dev_err_ratelimited(dev, "unable to read current time\n"); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx1-ads.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx1-ads.dts @@ -65,7 +65,7 @@ pinctrl-0 = <&pinctrl_weim>; status = "okay"; - nor: nor@0,0 { + nor: flash@0,0 { compatible = "cfi-flash"; reg = <0 0x00000000 0x02000000>; bank-width = <4>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx1-apf9328.dts @@ -45,7 +45,7 @@ pinctrl-0 = <&pinctrl_weim>; status = "okay"; - nor: nor@0,0 { + nor: flash@0,0 { compatible = "cfi-flash"; reg = <0 0x00000000 0x02000000>; bank-width = <2>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx1.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx1.dtsi @@ -268,9 +268,12 @@ status = "disabled"; }; - esram: esram@300000 { + esram: sram@300000 { compatible = "mmio-sram"; reg = <0x00300000 0x20000>; + ranges = <0 0x00300000 0x20000>; + #address-cells = <1>; + #size-cells = <1>; }; }; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx25-eukrea-cpuimx25.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx25-eukrea-cpuimx25.dtsi @@ -27,7 +27,7 @@ pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; - pcf8563@51 { + rtc@51 { compatible = "nxp,pcf8563"; reg = <0x51>; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts @@ -16,7 +16,7 @@ bus-width = <18>; display-timings { native-mode = <&qvga_timings>; - qvga_timings: 320x240 { + qvga_timings: timing0 { clock-frequency = <6500000>; hactive = <320>; vactive = <240>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts @@ -16,7 +16,7 @@ bus-width = <18>; display-timings { native-mode = <&dvi_svga_timings>; - dvi_svga_timings: 800x600 { + dvi_svga_timings: timing0 { clock-frequency = <40000000>; hactive = <800>; vactive = <600>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts @@ -16,7 +16,7 @@ bus-width = <18>; display-timings { native-mode = <&dvi_vga_timings>; - dvi_vga_timings: 640x480 { + dvi_vga_timings: timing0 { clock-frequency = <31250000>; hactive = <640>; vactive = <480>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx25-pdk.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx25-pdk.dts @@ -78,7 +78,7 @@ bus-width = <18>; display-timings { native-mode = <&wvga_timings>; - wvga_timings: 640x480 { + wvga_timings: timing0 { hactive = <640>; vactive = <480>; hback-porch = <45>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx25.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx25.dtsi @@ -543,7 +543,7 @@ }; iim: efuse@53ff0000 { - compatible = "fsl,imx25-iim", "fsl,imx27-iim"; + compatible = "fsl,imx25-iim"; reg = <0x53ff0000 0x4000>; interrupts = <19>; clocks = <&clks 99>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx27-apf27dev.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx27-apf27dev.dts @@ -16,7 +16,7 @@ fsl,pcr = <0xfae80083>; /* non-standard but required */ display-timings { native-mode = <&timing0>; - timing0: 800x480 { + timing0: timing0 { clock-frequency = <33000033>; hactive = <800>; vactive = <480>; @@ -47,7 +47,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio_leds>; - user { + led-user { label = "Heartbeat"; gpios = <&gpio6 14 GPIO_ACTIVE_HIGH>; linux,default-trigger = "heartbeat"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx27-eukrea-cpuimx27.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx27-eukrea-cpuimx27.dtsi @@ -33,7 +33,7 @@ pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; - pcf8563@51 { + rtc@51 { compatible = "nxp,pcf8563"; reg = <0x51>; }; @@ -90,7 +90,7 @@ &weim { status = "okay"; - nor: nor@0,0 { + nor: flash@0,0 { #address-cells = <1>; #size-cells = <1>; compatible = "cfi-flash"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx27-eukrea-mbimxsd27-baseboard.dts @@ -16,7 +16,7 @@ display-timings { native-mode = <&timing0>; - timing0: 320x240 { + timing0: timing0 { clock-frequency = <6500000>; hactive = <320>; vactive = <240>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-rdk.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycard-s-rdk.dts @@ -19,7 +19,7 @@ fsl,pcr = <0xf0c88080>; /* non-standard but required */ display-timings { native-mode = <&timing0>; - timing0: 640x480 { + timing0: timing0 { hactive = <640>; vactive = <480>; hback-porch = <112>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-rdk.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-rdk.dts @@ -19,7 +19,7 @@ display-timings { native-mode = <&timing0>; - timing0: 240x320 { + timing0: timing0 { clock-frequency = <5500000>; hactive = <240>; vactive = <320>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-som.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx27-phytec-phycore-som.dtsi @@ -322,7 +322,7 @@ &weim { status = "okay"; - nor: nor@0,0 { + nor: flash@0,0 { compatible = "cfi-flash"; reg = <0 0x00000000 0x02000000>; bank-width = <2>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx27.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx27.dtsi @@ -588,6 +588,9 @@ iram: sram@ffff4c00 { compatible = "mmio-sram"; reg = <0xffff4c00 0xb400>; + ranges = <0 0xffff4c00 0xb400>; + #address-cells = <1>; + #size-cells = <1>; }; }; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx6q-apalis-ixora-v1.2.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx6q-apalis-ixora-v1.2.dts @@ -76,6 +76,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enable_can1_power>; regulator-name = "can1_supply"; + startup-delay-us = <1000>; }; reg_can2_supply: regulator-can2-supply { @@ -85,6 +86,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enable_can2_power>; regulator-name = "can2_supply"; + startup-delay-us = <1000>; }; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/imx/imx7d.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/imx/imx7d.dtsi @@ -217,9 +217,6 @@ }; &ca_funnel_in_ports { - #address-cells = <1>; - #size-cells = <0>; - port@1 { reg = <1>; ca_funnel_in_port1: endpoint { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/mxs/imx23-sansa.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/mxs/imx23-sansa.dts @@ -175,10 +175,8 @@ #address-cells = <1>; #size-cells = <0>; compatible = "i2c-gpio"; - gpios = < - &gpio1 24 0 /* SDA */ - &gpio1 22 0 /* SCL */ - >; + sda-gpios = <&gpio1 24 0>; + scl-gpios = <&gpio1 22 0>; i2c-gpio,delay-us = <2>; /* ~100 kHz */ }; @@ -186,10 +184,8 @@ #address-cells = <1>; #size-cells = <0>; compatible = "i2c-gpio"; - gpios = < - &gpio0 31 0 /* SDA */ - &gpio0 30 0 /* SCL */ - >; + sda-gpios = <&gpio0 31 0>; + scl-gpios = <&gpio0 30 0>; i2c-gpio,delay-us = <2>; /* ~100 kHz */ touch: touch@20 { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/mxs/imx23.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/mxs/imx23.dtsi @@ -412,7 +412,7 @@ status = "disabled"; }; - dma_apbx: dma-apbx@80024000 { + dma_apbx: dma-controller@80024000 { compatible = "fsl,imx23-dma-apbx"; reg = <0x80024000 0x2000>; interrupts = <7 5 9 26 only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/nxp/mxs/imx28.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/nxp/mxs/imx28.dtsi @@ -990,7 +990,7 @@ status = "disabled"; }; - dma_apbx: dma-apbx@80024000 { + dma_apbx: dma-controller@80024000 { compatible = "fsl,imx28-dma-apbx"; reg = <0x80024000 0x2000>; interrupts = <78 79 66 0 only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/pm8226.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/pm8226.dtsi @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: BSD-3-Clause +#include +#include +#include +#include + +/ { + thermal-zones { + pm8226-thermal { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-sensors = <&pm8226_temp>; + + trips { + trip0 { + temperature = <105000>; + hysteresis = <2000>; + type = "passive"; + }; + + trip1 { + temperature = <125000>; + hysteresis = <2000>; + type = "hot"; + }; + + crit { + temperature = <145000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; +}; + +&spmi_bus { + pm8226_0: pm8226@0 { + compatible = "qcom,pm8226", "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pon@800 { + compatible = "qcom,pm8916-pon"; + reg = <0x800>; + + pwrkey { + compatible = "qcom,pm8941-pwrkey"; + interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; + debounce = <15625>; + bias-pull-up; + linux,code = ; + }; + + pm8226_resin: resin { + compatible = "qcom,pm8941-resin"; + interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>; + debounce = <15625>; + bias-pull-up; + status = "disabled"; + }; + }; + + smbb: charger@1000 { + compatible = "qcom,pm8226-charger"; + reg = <0x1000>; + interrupts = <0x0 0x10 7 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x10 5 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x10 4 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x12 1 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x12 0 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x13 2 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x13 1 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x14 1 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "chg-done", + "chg-fast", + "chg-trkl", + "bat-temp-ok", + "bat-present", + "chg-gone", + "usb-valid", + "dc-valid"; + + chg_otg: otg-vbus { }; + }; + + pm8226_temp: temp-alarm@2400 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0x2400>; + interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; + io-channels = <&pm8226_vadc VADC_DIE_TEMP>; + io-channel-names = "thermal"; + #thermal-sensor-cells = <0>; + }; + + pm8226_vadc: adc@3100 { + compatible = "qcom,spmi-vadc"; + reg = <0x3100>; + interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + + adc-chan@7 { + reg = ; + qcom,pre-scaling = <1 3>; + label = "vph_pwr"; + }; + adc-chan@8 { + reg = ; + label = "die_temp"; + }; + adc-chan@9 { + reg = ; + label = "ref_625mv"; + }; + adc-chan@a { + reg = ; + label = "ref_1250mv"; + }; + adc-chan@e { + reg = ; + }; + adc-chan@f { + reg = ; + }; + }; + + pm8226_iadc: adc@3600 { + compatible = "qcom,pm8226-iadc", "qcom,spmi-iadc"; + reg = <0x3600>; + interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>; + }; + + rtc@6000 { + compatible = "qcom,pm8941-rtc"; + reg = <0x6000>, <0x6100>; + reg-names = "rtc", "alarm"; + interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; + }; + + pm8226_mpps: mpps@a000 { + compatible = "qcom,pm8226-mpp", "qcom,spmi-mpp"; + reg = <0xa000>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pm8226_mpps 0 0 8>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pm8226_gpios: gpio@c000 { + compatible = "qcom,pm8226-gpio", "qcom,spmi-gpio"; + reg = <0xc000>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pm8226_gpios 0 0 8>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + pm8226_1: pm8226@1 { + compatible = "qcom,pm8226", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pm8226_spmi_regulators: regulators { + compatible = "qcom,pm8226-regulators"; + }; + + pm8226_vib: vibrator@c000 { + compatible = "qcom,pm8916-vib"; + reg = <0xc000>; + status = "disabled"; + }; + }; +}; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/pm8841.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/pm8841.dtsi @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + + +/ { + thermal-zones { + pm8841-thermal { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-sensors = <&pm8841_temp>; + + trips { + trip0 { + temperature = <105000>; + hysteresis = <2000>; + type = "passive"; + }; + + trip1 { + temperature = <125000>; + hysteresis = <2000>; + type = "hot"; + }; + + crit { + temperature = <140000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; +}; + +&spmi_bus { + + pm8841_0: pm8841@4 { + compatible = "qcom,pm8841", "qcom,spmi-pmic"; + reg = <0x4 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pm8841_mpps: mpps@a000 { + compatible = "qcom,pm8841-mpp", "qcom,spmi-mpp"; + reg = <0xa000>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pm8841_mpps 0 0 4>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pm8841_temp: temp-alarm@2400 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0x2400>; + interrupts = <4 0x24 0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <0>; + }; + }; + + pm8841_1: pm8841@5 { + compatible = "qcom,pm8841", "qcom,spmi-pmic"; + reg = <0x5 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/pm8941.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/pm8941.dtsi @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + + +/ { + thermal-zones { + pm8941-thermal { + polling-delay-passive = <100>; + polling-delay = <0>; + thermal-sensors = <&pm8941_temp>; + + trips { + trip0 { + temperature = <105000>; + hysteresis = <2000>; + type = "passive"; + }; + + trip1 { + temperature = <125000>; + hysteresis = <2000>; + type = "hot"; + }; + + crit { + temperature = <145000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + }; + }; +}; + +&spmi_bus { + + pm8941_0: pm8941@0 { + compatible = "qcom,pm8941", "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + rtc@6000 { + compatible = "qcom,pm8941-rtc"; + reg = <0x6000>, + <0x6100>; + reg-names = "rtc", "alarm"; + interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; + }; + + pwrkey@800 { + compatible = "qcom,pm8941-pwrkey"; + reg = <0x800>; + interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; + debounce = <15625>; + bias-pull-up; + }; + + usb_id: usb-detect@900 { + compatible = "qcom,pm8941-misc"; + reg = <0x900>; + interrupts = <0x0 0x9 0 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "usb_id"; + }; + + smbb: charger@1000 { + compatible = "qcom,pm8941-charger"; + reg = <0x1000>; + interrupts = <0x0 0x10 7 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x10 5 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x10 4 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x12 1 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x12 0 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x13 2 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x13 1 IRQ_TYPE_EDGE_BOTH>, + <0x0 0x14 1 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "chg-done", + "chg-fast", + "chg-trkl", + "bat-temp-ok", + "bat-present", + "chg-gone", + "usb-valid", + "dc-valid"; + + usb-otg-in-supply = <&pm8941_5vs1>; + + chg_otg: otg-vbus { }; + }; + + pm8941_gpios: gpio@c000 { + compatible = "qcom,pm8941-gpio", "qcom,spmi-gpio"; + reg = <0xc000>; + gpio-controller; + gpio-ranges = <&pm8941_gpios 0 0 36>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + + boost_bypass_n_pin: boost-bypass-state { + pins = "gpio21"; + function = "normal"; + }; + }; + + pm8941_mpps: mpps@a000 { + compatible = "qcom,pm8941-mpp", "qcom,spmi-mpp"; + reg = <0xa000>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pm8941_mpps 0 0 8>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pm8941_temp: temp-alarm@2400 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0x2400>; + interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; + io-channels = <&pm8941_vadc VADC_DIE_TEMP>; + io-channel-names = "thermal"; + #thermal-sensor-cells = <0>; + }; + + pm8941_vadc: adc@3100 { + compatible = "qcom,spmi-vadc"; + reg = <0x3100>; + interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + + + adc-chan@6 { + reg = ; + }; + + adc-chan@8 { + reg = ; + }; + + adc-chan@9 { + reg = ; + }; + + adc-chan@a { + reg = ; + }; + + adc-chan@e { + reg = ; + }; + + adc-chan@f { + reg = ; + }; + + adc-chan@30 { + reg = ; + }; + }; + + pm8941_iadc: adc@3600 { + compatible = "qcom,pm8941-iadc", "qcom,spmi-iadc"; + reg = <0x3600>; + interrupts = <0x0 0x36 0x0 IRQ_TYPE_EDGE_RISING>; + qcom,external-resistor-micro-ohms = <10000>; + }; + + pm8941_coincell: charger@2800 { + compatible = "qcom,pm8941-coincell"; + reg = <0x2800>; + status = "disabled"; + }; + }; + + pm8941_1: pm8941@1 { + compatible = "qcom,pm8941", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pm8941_lpg: pwm { + compatible = "qcom,pm8941-lpg"; + + #address-cells = <1>; + #size-cells = <0>; + #pwm-cells = <2>; + + status = "disabled"; + }; + + pm8941_vib: vibrator@c000 { + compatible = "qcom,pm8916-vib"; + reg = <0xc000>; + status = "disabled"; + }; + + pm8941_wled: wled@d800 { + compatible = "qcom,pm8941-wled"; + reg = <0xd800>; + label = "backlight"; + + status = "disabled"; + }; + + regulators { + compatible = "qcom,pm8941-regulators"; + interrupts = <0x1 0x83 0x2 0>, <0x1 0x84 0x2 0>; + interrupt-names = "ocp-5vs1", "ocp-5vs2"; + vin_5vs-supply = <&pm8941_5v>; + + pm8941_5v: s4 { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-enable-ramp-delay = <500>; + }; + + pm8941_5vs1: 5vs1 { + regulator-enable-ramp-delay = <1000>; + regulator-pull-down; + regulator-over-current-protection; + qcom,ocp-max-retries = <10>; + qcom,ocp-retry-delay = <30>; + qcom,vs-soft-start-strength = <0>; + regulator-initial-mode = <1>; + }; + + pm8941_5vs2: 5vs2 { + regulator-enable-ramp-delay = <1000>; + regulator-pull-down; + regulator-over-current-protection; + qcom,ocp-max-retries = <10>; + qcom,ocp-retry-delay = <30>; + qcom,vs-soft-start-strength = <0>; + regulator-initial-mode = <1>; + }; + }; + }; +}; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/pma8084.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/pma8084.dtsi @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +&spmi_bus { + + pma8084_0: pma8084@0 { + compatible = "qcom,pma8084", "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + rtc@6000 { + compatible = "qcom,pm8941-rtc"; + reg = <0x6000>, + <0x6100>; + reg-names = "rtc", "alarm"; + interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; + }; + + pwrkey@800 { + compatible = "qcom,pm8941-pwrkey"; + reg = <0x800>; + interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>; + debounce = <15625>; + bias-pull-up; + }; + + pma8084_gpios: gpio@c000 { + compatible = "qcom,pma8084-gpio", "qcom,spmi-gpio"; + reg = <0xc000>; + gpio-controller; + gpio-ranges = <&pma8084_gpios 0 0 22>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pma8084_mpps: mpps@a000 { + compatible = "qcom,pma8084-mpp", "qcom,spmi-mpp"; + reg = <0xa000>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pma8084_mpps 0 0 8>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + pma8084_temp: temp-alarm@2400 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0x2400>; + interrupts = <0 0x24 0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <0>; + io-channels = <&pma8084_vadc VADC_DIE_TEMP>; + io-channel-names = "thermal"; + }; + + pma8084_vadc: adc@3100 { + compatible = "qcom,spmi-vadc"; + reg = <0x3100>; + interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + + adc-chan@8 { + reg = ; + }; + + adc-chan@9 { + reg = ; + }; + + adc-chan@a { + reg = ; + }; + + adc-chan@c { + reg = ; + }; + + adc-chan@e { + reg = ; + }; + + adc-chan@f { + reg = ; + }; + }; + }; + + pma8084_1: pma8084@1 { + compatible = "qcom,pma8084", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/pmx55.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/pmx55.dtsi @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: BSD-3-Clause + +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020, Linaro Limited + */ + +#include +#include +#include + +&spmi_bus { + pmic@8 { + compatible = "qcom,pmx55", "qcom,spmi-pmic"; + reg = <0x8 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pon@800 { + compatible = "qcom,pm8916-pon"; + reg = <0x0800>; + + status = "disabled"; + }; + + pmx55_temp: temp-alarm@2400 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0x2400>; + interrupts = <0x8 0x24 0x0 IRQ_TYPE_EDGE_BOTH>; + io-channels = <&pmx55_adc ADC5_DIE_TEMP>; + io-channel-names = "thermal"; + #thermal-sensor-cells = <0>; + }; + + pmx55_adc: adc@3100 { + compatible = "qcom,spmi-adc5"; + reg = <0x3100>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + interrupts = <0x8 0x31 0x0 IRQ_TYPE_EDGE_RISING>; + + ref-gnd@0 { + reg = ; + qcom,pre-scaling = <1 1>; + label = "ref_gnd"; + }; + + vref-1p25@1 { + reg = ; + qcom,pre-scaling = <1 1>; + label = "vref_1p25"; + }; + + die-temp@6 { + reg = ; + qcom,pre-scaling = <1 1>; + label = "die_temp"; + }; + + chg-temp@9 { + reg = ; + qcom,pre-scaling = <1 1>; + label = "chg_temp"; + }; + }; + + pmx55_gpios: gpio@c000 { + compatible = "qcom,pmx55-gpio", "qcom,spmi-gpio"; + reg = <0xc000>; + gpio-controller; + gpio-ranges = <&pmx55_gpios 0 0 11>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + pmic@9 { + compatible = "qcom,pmx55", "qcom,spmi-pmic"; + reg = <0x9 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + }; +}; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/pmx65.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/pmx65.dtsi @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include + +&spmi_bus { + pmic@1 { + compatible = "qcom,pmx65", "qcom,spmi-pmic"; + reg = <1 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmx65_temp: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x1 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmx65_gpios: gpio@8800 { + compatible = "qcom,pmx65-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmx65_gpios 0 0 16>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-apq8026-asus-sparrow.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8026-asus-sparrow.dts @@ -6,7 +6,7 @@ /dts-v1/; #include "qcom-msm8226.dtsi" -#include "qcom-pm8226.dtsi" +#include "pm8226.dtsi" /delete-node/ &adsp_region; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-apq8026-huawei-sturgeon.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8026-huawei-sturgeon.dts @@ -6,7 +6,7 @@ /dts-v1/; #include "qcom-msm8226.dtsi" -#include "qcom-pm8226.dtsi" +#include "pm8226.dtsi" #include /delete-node/ &adsp_region; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-apq8026-lg-lenok.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8026-lg-lenok.dts @@ -6,7 +6,7 @@ /dts-v1/; #include "qcom-msm8226.dtsi" -#include "qcom-pm8226.dtsi" +#include "pm8226.dtsi" /delete-node/ &adsp_region; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-apq8060-dragonboard.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8060-dragonboard.dts @@ -72,7 +72,7 @@ /* Trig on both edges - getting close or far away */ interrupts-extended = <&pm8058_gpio 34 IRQ_TYPE_EDGE_BOTH>; /* MPP05 analog input to the XOADC */ - io-channels = <&xoadc 0x00 0x05>; + io-channels = <&pm8058_xoadc 0x00 0x05>; io-channel-names = "aout"; pinctrl-names = "default"; pinctrl-0 = <&dragon_cm3605_gpios>, <&dragon_cm3605_mpps>; @@ -945,7 +945,7 @@ }; }; -&xoadc { +&pm8058_xoadc { /* Reference voltage 2.2 V */ xoadc-ref-supply = <&pm8058_l18>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8064.dtsi @@ -766,7 +766,7 @@ xoadc: xoadc@197 { compatible = "qcom,pm8921-adc"; - reg = <197>; + reg = <0x197>; interrupts-extended = <&pmicintc 78 IRQ_TYPE_EDGE_RISING>; #address-cells = <2>; #size-cells = <0>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-apq8074-dragonboard.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8074-dragonboard.dts @@ -4,8 +4,8 @@ #include #include #include "qcom-msm8974.dtsi" -#include "qcom-pm8841.dtsi" -#include "qcom-pm8941.dtsi" +#include "pm8841.dtsi" +#include "pm8941.dtsi" /delete-node/ &mpss_region; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-apq8084-ifc6540.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8084-ifc6540.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "qcom-apq8084.dtsi" -#include "qcom-pma8084.dtsi" +#include "pma8084.dtsi" / { model = "Qualcomm APQ8084/IFC6540"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-apq8084-mtp.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-apq8084-mtp.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "qcom-apq8084.dtsi" -#include "qcom-pma8084.dtsi" +#include "pma8084.dtsi" / { model = "Qualcomm APQ 8084-MTP"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-mdm9615-wp8548.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-mdm9615-wp8548.dtsi @@ -76,7 +76,7 @@ }; }; -&pmicgpio { +&pm8018_gpio { usb_vbus_5v_pins: usb-vbus-5v-state { pins = "gpio4"; function = "normal"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-msm8660.dtsi @@ -80,13 +80,13 @@ */ iio-hwmon { compatible = "iio-hwmon"; - io-channels = <&xoadc 0x00 0x01>, /* Battery */ - <&xoadc 0x00 0x02>, /* DC in (charger) */ - <&xoadc 0x00 0x04>, /* VPH the main system voltage */ - <&xoadc 0x00 0x0b>, /* Die temperature */ - <&xoadc 0x00 0x0c>, /* Reference voltage 1.25V */ - <&xoadc 0x00 0x0d>, /* Reference voltage 0.625V */ - <&xoadc 0x00 0x0e>; /* Reference voltage 0.325V */ + io-channels = <&pm8058_xoadc 0x00 0x01>, /* Battery */ + <&pm8058_xoadc 0x00 0x02>, /* DC in (charger) */ + <&pm8058_xoadc 0x00 0x04>, /* VPH the main system voltage */ + <&pm8058_xoadc 0x00 0x0b>, /* Die temperature */ + <&pm8058_xoadc 0x00 0x0c>, /* Reference voltage 1.25V */ + <&pm8058_xoadc 0x00 0x0d>, /* Reference voltage 0.625V */ + <&pm8058_xoadc 0x00 0x0e>; /* Reference voltage 0.325V */ }; soc: soc { @@ -390,7 +390,7 @@ row-hold = <91500>; }; - xoadc: xoadc@197 { + pm8058_xoadc: xoadc@197 { compatible = "qcom,pm8058-adc"; reg = <0x197>; interrupts-extended = <&pm8058 76 IRQ_TYPE_EDGE_RISING>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-msm8974-lge-nexus5-hammerhead.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-msm8974-lge-nexus5-hammerhead.dts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "qcom-msm8974.dtsi" -#include "qcom-pm8841.dtsi" -#include "qcom-pm8941.dtsi" +#include "pm8841.dtsi" +#include "pm8941.dtsi" #include #include #include only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-msm8974-sony-xperia-rhine.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-msm8974-sony-xperia-rhine.dtsi @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "qcom-msm8974.dtsi" -#include "qcom-pm8841.dtsi" -#include "qcom-pm8941.dtsi" +#include "pm8841.dtsi" +#include "pm8941.dtsi" #include #include #include only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-msm8974pro-fairphone-fp2.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-msm8974pro-fairphone-fp2.dts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "qcom-msm8974pro.dtsi" -#include "qcom-pm8841.dtsi" -#include "qcom-pm8941.dtsi" +#include "pm8841.dtsi" +#include "pm8941.dtsi" #include #include #include only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-msm8974pro-oneplus-bacon.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-msm8974pro-oneplus-bacon.dts @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "qcom-msm8974pro.dtsi" -#include "qcom-pm8841.dtsi" -#include "qcom-pm8941.dtsi" +#include "pm8841.dtsi" +#include "pm8941.dtsi" #include #include only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-msm8974pro-samsung-klte.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #include "qcom-msm8974pro.dtsi" -#include "qcom-pma8084.dtsi" +#include "pma8084.dtsi" #include #include #include only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-sdx55-mtp.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-sdx55-mtp.dts @@ -9,7 +9,7 @@ #include "qcom-sdx55.dtsi" #include #include -#include "qcom-pmx55.dtsi" +#include "pmx55.dtsi" / { model = "Qualcomm Technologies, Inc. SDX55 MTP"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-sdx55-t55.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-sdx55-t55.dts @@ -8,7 +8,7 @@ #include #include #include "qcom-sdx55.dtsi" -#include "qcom-pmx55.dtsi" +#include "pmx55.dtsi" / { model = "Thundercomm T55 Development Kit"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-sdx55-telit-fn980-tlb.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-sdx55-telit-fn980-tlb.dts @@ -8,7 +8,7 @@ #include #include #include "qcom-sdx55.dtsi" -#include "qcom-pmx55.dtsi" +#include "pmx55.dtsi" / { model = "Telit FN980 TLB"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-sdx55.dtsi @@ -592,10 +592,10 @@ <&gcc GCC_USB30_MASTER_CLK>; assigned-clock-rates = <19200000>, <200000000>; - interrupts = , - , - , - ; + interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 51 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 11 IRQ_TYPE_EDGE_BOTH>, + <&pdc 10 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq"; @@ -619,7 +619,7 @@ compatible = "qcom,sdx55-pdc", "qcom,pdc"; reg = <0x0b210000 0x30000>; qcom,pdc-ranges = <0 179 52>; - #interrupt-cells = <3>; + #interrupt-cells = <2>; interrupt-parent = <&intc>; interrupt-controller; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/qcom/qcom-sdx65.dtsi @@ -338,7 +338,7 @@ power-domains = <&gcc PCIE_GDSC>; phys = <&pcie_phy>; - phy-names = "pcie-phy"; + phy-names = "pciephy"; max-link-speed = <3>; num-lanes = <2>; @@ -530,7 +530,7 @@ reg = <0x0c264000 0x1000>; }; - spmi_bus: qcom,spmi@c440000 { + spmi_bus: spmi@c440000 { compatible = "qcom,spmi-pmic-arb"; reg = <0xc440000 0xd00>, <0xc600000 0x2000000>, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/rockchip/rk3036.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/rockchip/rk3036.dtsi @@ -402,12 +402,20 @@ pinctrl-0 = <&hdmi_ctl>; status = "disabled"; - hdmi_in: port { + ports { #address-cells = <1>; #size-cells = <0>; - hdmi_in_vop: endpoint@0 { + + hdmi_in: port@0 { reg = <0>; - remote-endpoint = <&vop_out_hdmi>; + + hdmi_in_vop: endpoint { + remote-endpoint = <&vop_out_hdmi>; + }; + }; + + hdmi_out: port@1 { + reg = <1>; }; }; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/samsung/exynos4.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/samsung/exynos4.dtsi @@ -203,16 +203,16 @@ camera: camera@11800000 { compatible = "samsung,fimc"; + ranges = <0x0 0x11800000 0xa0000>; status = "disabled"; #address-cells = <1>; #size-cells = <1>; #clock-cells = <1>; clock-output-names = "cam_a_clkout", "cam_b_clkout"; - ranges; - fimc_0: fimc@11800000 { + fimc_0: fimc@0 { compatible = "samsung,exynos4210-fimc"; - reg = <0x11800000 0x1000>; + reg = <0x0 0x1000>; interrupts = ; clocks = <&clock CLK_FIMC0>, <&clock CLK_SCLK_FIMC0>; @@ -223,9 +223,9 @@ status = "disabled"; }; - fimc_1: fimc@11810000 { + fimc_1: fimc@10000 { compatible = "samsung,exynos4210-fimc"; - reg = <0x11810000 0x1000>; + reg = <0x00010000 0x1000>; interrupts = ; clocks = <&clock CLK_FIMC1>, <&clock CLK_SCLK_FIMC1>; @@ -236,9 +236,9 @@ status = "disabled"; }; - fimc_2: fimc@11820000 { + fimc_2: fimc@20000 { compatible = "samsung,exynos4210-fimc"; - reg = <0x11820000 0x1000>; + reg = <0x00020000 0x1000>; interrupts = ; clocks = <&clock CLK_FIMC2>, <&clock CLK_SCLK_FIMC2>; @@ -249,9 +249,9 @@ status = "disabled"; }; - fimc_3: fimc@11830000 { + fimc_3: fimc@30000 { compatible = "samsung,exynos4210-fimc"; - reg = <0x11830000 0x1000>; + reg = <0x00030000 0x1000>; interrupts = ; clocks = <&clock CLK_FIMC3>, <&clock CLK_SCLK_FIMC3>; @@ -262,9 +262,9 @@ status = "disabled"; }; - csis_0: csis@11880000 { + csis_0: csis@80000 { compatible = "samsung,exynos4210-csis"; - reg = <0x11880000 0x4000>; + reg = <0x00080000 0x4000>; interrupts = ; clocks = <&clock CLK_CSIS0>, <&clock CLK_SCLK_CSIS0>; @@ -278,9 +278,9 @@ #size-cells = <0>; }; - csis_1: csis@11890000 { + csis_1: csis@90000 { compatible = "samsung,exynos4210-csis"; - reg = <0x11890000 0x4000>; + reg = <0x00090000 0x4000>; interrupts = ; clocks = <&clock CLK_CSIS1>, <&clock CLK_SCLK_CSIS1>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/samsung/exynos4x12.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/samsung/exynos4x12.dtsi @@ -451,14 +451,15 @@ }; &camera { + ranges = <0x0 0x11800000 0xba1000>; clocks = <&clock CLK_SCLK_CAM0>, <&clock CLK_SCLK_CAM1>, <&clock CLK_PIXELASYNCM0>, <&clock CLK_PIXELASYNCM1>; clock-names = "sclk_cam0", "sclk_cam1", "pxl_async0", "pxl_async1"; /* fimc_[0-3] are configured outside, under phandles */ - fimc_lite_0: fimc-lite@12390000 { + fimc_lite_0: fimc-lite@b90000 { compatible = "samsung,exynos4212-fimc-lite"; - reg = <0x12390000 0x1000>; + reg = <0x00b90000 0x1000>; interrupts = ; power-domains = <&pd_isp>; clocks = <&isp_clock CLK_ISP_FIMC_LITE0>; @@ -467,9 +468,9 @@ status = "disabled"; }; - fimc_lite_1: fimc-lite@123a0000 { + fimc_lite_1: fimc-lite@ba0000 { compatible = "samsung,exynos4212-fimc-lite"; - reg = <0x123a0000 0x1000>; + reg = <0x00ba0000 0x1000>; interrupts = ; power-domains = <&pd_isp>; clocks = <&isp_clock CLK_ISP_FIMC_LITE1>; @@ -478,9 +479,9 @@ status = "disabled"; }; - fimc_is: fimc-is@12000000 { + fimc_is: fimc-is@800000 { compatible = "samsung,exynos4212-fimc-is"; - reg = <0x12000000 0x260000>; + reg = <0x00800000 0x260000>; interrupts = , ; power-domains = <&pd_isp>; @@ -525,9 +526,9 @@ reg = <0x10020000 0x3000>; }; - i2c1_isp: i2c-isp@12140000 { + i2c1_isp: i2c-isp@940000 { compatible = "samsung,exynos4212-i2c-isp"; - reg = <0x12140000 0x100>; + reg = <0x00940000 0x100>; clocks = <&isp_clock CLK_ISP_I2C1_ISP>; clock-names = "i2c_isp"; #address-cells = <1>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/samsung/s5pv210.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/samsung/s5pv210.dtsi @@ -549,17 +549,17 @@ camera: camera@fa600000 { compatible = "samsung,fimc"; + ranges = <0x0 0xfa600000 0xe01000>; clocks = <&clocks SCLK_CAM0>, <&clocks SCLK_CAM1>; clock-names = "sclk_cam0", "sclk_cam1"; #address-cells = <1>; #size-cells = <1>; #clock-cells = <1>; clock-output-names = "cam_a_clkout", "cam_b_clkout"; - ranges; - csis0: csis@fa600000 { + csis0: csis@0 { compatible = "samsung,s5pv210-csis"; - reg = <0xfa600000 0x4000>; + reg = <0x00000000 0x4000>; interrupt-parent = <&vic2>; interrupts = <29>; clocks = <&clocks CLK_CSIS>, @@ -572,9 +572,9 @@ #size-cells = <0>; }; - fimc0: fimc@fb200000 { + fimc0: fimc@c00000 { compatible = "samsung,s5pv210-fimc"; - reg = <0xfb200000 0x1000>; + reg = <0x00c00000 0x1000>; interrupts = <5>; interrupt-parent = <&vic2>; clocks = <&clocks CLK_FIMC0>, @@ -586,9 +586,9 @@ samsung,cam-if; }; - fimc1: fimc@fb300000 { + fimc1: fimc@d00000 { compatible = "samsung,s5pv210-fimc"; - reg = <0xfb300000 0x1000>; + reg = <0x00d00000 0x1000>; interrupt-parent = <&vic2>; interrupts = <6>; clocks = <&clocks CLK_FIMC1>, @@ -602,9 +602,9 @@ samsung,lcd-wb; }; - fimc2: fimc@fb400000 { + fimc2: fimc@e00000 { compatible = "samsung,s5pv210-fimc"; - reg = <0xfb400000 0x1000>; + reg = <0x00e00000 0x1000>; interrupt-parent = <&vic2>; interrupts = <7>; clocks = <&clocks CLK_FIMC2>, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts @@ -11,7 +11,7 @@ / { model = "STMicroelectronics STM32MP157A-DK1 SCMI Discovery Board"; - compatible = "st,stm32mp157a-dk1-scmi", "st,stm32mp157a-dk1", "st,stm32mp157"; + compatible = "st,stm32mp157a-dk1-scmi", "st,stm32mp157"; reserved-memory { optee@de000000 { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts @@ -11,7 +11,7 @@ / { model = "STMicroelectronics STM32MP157C-DK2 SCMI Discovery Board"; - compatible = "st,stm32mp157c-dk2-scmi", "st,stm32mp157c-dk2", "st,stm32mp157"; + compatible = "st,stm32mp157c-dk2-scmi", "st,stm32mp157"; reserved-memory { optee@de000000 { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts @@ -11,7 +11,7 @@ / { model = "STMicroelectronics STM32MP157C-ED1 SCMI eval daughter"; - compatible = "st,stm32mp157c-ed1-scmi", "st,stm32mp157c-ed1", "st,stm32mp157"; + compatible = "st,stm32mp157c-ed1-scmi", "st,stm32mp157"; reserved-memory { optee@fe000000 { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts @@ -11,8 +11,7 @@ / { model = "STMicroelectronics STM32MP157C-EV1 SCMI eval daughter on eval mother"; - compatible = "st,stm32mp157c-ev1-scmi", "st,stm32mp157c-ev1", "st,stm32mp157c-ed1", - "st,stm32mp157"; + compatible = "st,stm32mp157c-ev1-scmi", "st,stm32mp157c-ed1", "st,stm32mp157"; reserved-memory { optee@fe000000 { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/include/asm/irq_work.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/include/asm/irq_work.h @@ -9,6 +9,4 @@ return is_smp(); } -extern void arch_irq_work_raise(void); - #endif /* _ASM_ARM_IRQ_WORK_H */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm/mach-davinci/Kconfig +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm/mach-davinci/Kconfig @@ -4,12 +4,14 @@ bool "TI DaVinci" depends on ARCH_MULTI_V5 depends on CPU_LITTLE_ENDIAN + select CPU_ARM926T select DAVINCI_TIMER select ZONE_DMA select PM_GENERIC_DOMAINS if PM select PM_GENERIC_DOMAINS_OF if PM && OF select REGMAP_MMIO select RESET_CONTROLLER + select PINCTRL select PINCTRL_SINGLE if ARCH_DAVINCI only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/amlogic/meson-s4-s805x2-aq222.dts @@ -15,7 +15,7 @@ #size-cells = <2>; aliases { - serial0 = &uart_B; + serial0 = &uart_b; }; memory@0 { @@ -25,6 +25,6 @@ }; -&uart_B { +&uart_b { status = "okay"; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/amlogic/meson-s4.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/amlogic/meson-s4.dtsi @@ -118,14 +118,14 @@ <10 11 12 13 14 15 16 17 18 19 20 21>; }; - uart_B: serial@7a000 { + uart_b: serial@7a000 { compatible = "amlogic,meson-s4-uart", "amlogic,meson-ao-uart"; reg = <0x0 0x7a000 0x0 0x18>; interrupts = ; - status = "disabled"; clocks = <&xtal>, <&xtal>, <&xtal>; clock-names = "xtal", "pclk", "baud"; + status = "disabled"; }; reset: reset-controller@2000 { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/hisilicon/hikey970-pmic.dtsi @@ -25,9 +25,6 @@ gpios = <&gpio28 0 0>; regulators { - #address-cells = <1>; - #size-cells = <0>; - ldo3: ldo3 { /* HDMI */ regulator-name = "ldo3"; regulator-min-microvolt = <1500000>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/marvell/armada-3720-turris-mox.dts @@ -130,7 +130,7 @@ compatible = "microchip,mcp7940x"; reg = <0x6f>; interrupt-parent = <&gpiosb>; - interrupts = <5 0>; /* GPIO2_5 */ + interrupts = <5 IRQ_TYPE_EDGE_FALLING>; /* GPIO2_5 */ }; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dts @@ -118,6 +118,7 @@ #size-cells = <0>; vcc-supply = <&pm8916_l16>; + vio-supply = <&pm8916_l5>; led@0 { reg = <0>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8953-xiaomi-mido.dts @@ -111,6 +111,7 @@ reg = <0x45>; vcc-supply = <&pm8953_l10>; + vio-supply = <&pm8953_l5>; #address-cells = <1>; #size-cells = <0>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/msm8953-xiaomi-tissot.dts @@ -104,6 +104,7 @@ reg = <0x45>; vcc-supply = <&pm8953_l10>; + vio-supply = <&pm8953_l5>; #address-cells = <1>; #size-cells = <0>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/qrb4210-rb2.dts @@ -510,7 +510,6 @@ &usb_dwc3 { maximum-speed = "super-speed"; - dr_mode = "peripheral"; }; &usb_hsphy { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/qrb5165-rb5.dts @@ -63,8 +63,8 @@ function = LED_FUNCTION_INDICATOR; color = ; gpios = <&pm8150_gpios 10 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "panic-indicator"; default-state = "off"; + panic-indicator; }; led-wlan { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/sa8775p.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sa8775p.dtsi @@ -1602,8 +1602,8 @@ assigned-clock-rates = <19200000>, <200000000>; interrupts-extended = <&intc GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 14 IRQ_TYPE_EDGE_RISING>, - <&pdc 15 IRQ_TYPE_EDGE_RISING>, + <&pdc 14 IRQ_TYPE_EDGE_BOTH>, + <&pdc 15 IRQ_TYPE_EDGE_BOTH>, <&pdc 12 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "pwr_event", "dp_hs_phy_irq", @@ -1689,8 +1689,8 @@ assigned-clock-rates = <19200000>, <200000000>; interrupts-extended = <&intc GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 8 IRQ_TYPE_EDGE_RISING>, - <&pdc 7 IRQ_TYPE_EDGE_RISING>, + <&pdc 8 IRQ_TYPE_EDGE_BOTH>, + <&pdc 7 IRQ_TYPE_EDGE_BOTH>, <&pdc 13 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "pwr_event", "dp_hs_phy_irq", @@ -1752,8 +1752,8 @@ assigned-clock-rates = <19200000>, <200000000>; interrupts-extended = <&intc GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 10 IRQ_TYPE_EDGE_RISING>, - <&pdc 9 IRQ_TYPE_EDGE_RISING>; + <&pdc 10 IRQ_TYPE_EDGE_BOTH>, + <&pdc 9 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "pwr_event", "dp_hs_phy_irq", "dm_hs_phy_irq"; @@ -2154,7 +2154,7 @@ compatible = "qcom,apss-wdt-sa8775p", "qcom,kpss-wdt"; reg = <0x0 0x17c10000 0x0 0x1000>; clocks = <&sleep_clk>; - interrupts = ; + interrupts = ; }; memtimer: timer@17c20000 { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc7180-acer-aspire1.dts @@ -209,9 +209,22 @@ AVDD-supply = <&vreg_l15a_1p8>; MICVDD-supply = <®_codec_3p3>; VBAT-supply = <®_codec_3p3>; + DBVDD-supply = <&vreg_l15a_1p8>; + LDO1-IN-supply = <&vreg_l15a_1p8>; + + /* + * NOTE: The board has a path from this codec to the + * DMIC microphones in the lid, however some of the option + * resistors are absent and the microphones are connected + * to the SoC instead. + * + * If the resistors were to be changed by the user to + * connect the codec, the following could be used: + * + * realtek,dmic1-data-pin = <1>; + * realtek,dmic1-clk-pin = <1>; + */ - realtek,dmic1-data-pin = <1>; - realtek,dmic1-clk-pin = <1>; realtek,jd-src = <1>; }; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/sc7180.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc7180.dtsi @@ -2827,8 +2827,8 @@ interrupts-extended = <&intc GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>, <&pdc 6 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 8 IRQ_TYPE_LEVEL_HIGH>, - <&pdc 9 IRQ_TYPE_LEVEL_HIGH>; + <&pdc 8 IRQ_TYPE_EDGE_BOTH>, + <&pdc 9 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq"; @@ -3436,7 +3436,7 @@ compatible = "qcom,apss-wdt-sc7180", "qcom,kpss-wdt"; reg = <0 0x17c10000 0 0x1000>; clocks = <&sleep_clk>; - interrupts = ; + interrupts = ; }; timer@17c20000 { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc7280-chrome-common.dtsi @@ -46,6 +46,26 @@ }; }; +&lpass_aon { + status = "okay"; +}; + +&lpass_core { + status = "okay"; +}; + +&lpass_hm { + status = "okay"; +}; + +&lpasscc { + status = "okay"; +}; + +&pdc_reset { + status = "okay"; +}; + /* The PMIC PON code isn't compatible w/ how Chrome EC/BIOS handle things. */ &pmk8350_pon { status = "disabled"; @@ -84,6 +104,10 @@ dma-coherent; }; +&watchdog { + status = "okay"; +}; + &wifi { status = "okay"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/sc8180x-primus.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sc8180x-primus.dts @@ -42,7 +42,7 @@ pinctrl-0 = <&hall_int_active_state>; lid-switch { - gpios = <&tlmm 121 GPIO_ACTIVE_HIGH>; + gpios = <&tlmm 121 GPIO_ACTIVE_LOW>; linux,input-type = ; linux,code = ; wakeup-source; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/sdm670.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sdm670.dtsi @@ -1142,8 +1142,8 @@ interrupts = , , - , - ; + , + ; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", "dp_hs_phy_irq"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/sm6375.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm6375.dtsi @@ -294,6 +294,25 @@ }; }; + mpm: interrupt-controller { + compatible = "qcom,mpm"; + qcom,rpm-msg-ram = <&apss_mpm>; + interrupts = ; + mboxes = <&ipcc IPCC_CLIENT_AOP IPCC_MPROC_SIGNAL_SMP2P>; + interrupt-controller; + #interrupt-cells = <2>; + #power-domain-cells = <0>; + interrupt-parent = <&intc>; + qcom,mpm-pin-count = <96>; + qcom,mpm-pin-map = <5 296>, /* Soundwire wake_irq */ + <12 422>, /* DWC3 ss_phy_irq */ + <86 183>, /* MPM wake, SPMI */ + <89 314>, /* TSENS0 0C */ + <90 315>, /* TSENS1 0C */ + <93 164>, /* DWC3 dm_hs_phy_irq */ + <94 165>; /* DWC3 dp_hs_phy_irq */ + }; + memory@80000000 { device_type = "memory"; /* We expect the bootloader to fill in the size */ @@ -359,6 +378,7 @@ CLUSTER_PD: power-domain-cpu-cluster0 { #power-domain-cells = <0>; + power-domains = <&mpm>; domain-idle-states = <&CLUSTER_SLEEP_0>; }; }; @@ -677,7 +697,7 @@ reg = <0 0x00500000 0 0x800000>; interrupts = ; gpio-ranges = <&tlmm 0 0 157>; - /* TODO: Hook up MPM as wakeup-parent when it's there */ + wakeup-parent = <&mpm>; interrupt-controller; gpio-controller; #interrupt-cells = <2>; @@ -799,7 +819,7 @@ <0 0x01c0a000 0 0x26000>; reg-names = "core", "chnls", "obsrvr", "intr", "cnfg"; interrupt-names = "periph_irq"; - interrupts = ; + interrupts-extended = <&mpm 86 IRQ_TYPE_LEVEL_HIGH>; qcom,ee = <0>; qcom,channel = <0>; #address-cells = <2>; @@ -831,8 +851,15 @@ }; rpm_msg_ram: sram@45f0000 { - compatible = "qcom,rpm-msg-ram"; + compatible = "qcom,rpm-msg-ram", "mmio-sram"; reg = <0 0x045f0000 0 0x7000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x0 0x045f0000 0x7000>; + + apss_mpm: sram@1b8 { + reg = <0x1b8 0x48>; + }; }; sram@4690000 { @@ -1229,10 +1256,10 @@ <&gcc GCC_USB30_PRIM_MASTER_CLK>; assigned-clock-rates = <19200000>, <133333333>; - interrupts = , - , - , - ; + interrupts-extended = <&intc GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH>, + <&mpm 12 IRQ_TYPE_LEVEL_HIGH>, + <&mpm 93 IRQ_TYPE_EDGE_BOTH>, + <&mpm 94 IRQ_TYPE_EDGE_BOTH>; interrupt-names = "hs_phy_irq", "ss_phy_irq", "dm_hs_phy_irq", only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/qcom/sm8150-hdk.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/qcom/sm8150-hdk.dts @@ -126,8 +126,6 @@ vdda_sp_sensor: vdda_ufs_2ln_core_1: vdda_ufs_2ln_core_2: - vdda_usb_ss_dp_core_1: - vdda_usb_ss_dp_core_2: vdda_qlink_lv: vdda_qlink_lv_ck: vreg_l5a_0p875: ldo5 { @@ -209,6 +207,12 @@ regulator-max-microvolt = <3008000>; regulator-initial-mode = ; }; + + vreg_l18a_0p8: ldo18 { + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = ; + }; }; regulators-1 { @@ -444,13 +448,13 @@ &usb_1_qmpphy { status = "okay"; vdda-phy-supply = <&vreg_l3c_1p2>; - vdda-pll-supply = <&vdda_usb_ss_dp_core_1>; + vdda-pll-supply = <&vreg_l18a_0p8>; }; &usb_2_qmpphy { status = "okay"; vdda-phy-supply = <&vreg_l3c_1p2>; - vdda-pll-supply = <&vdda_usb_ss_dp_core_1>; + vdda-pll-supply = <&vreg_l5a_0p875>; }; &usb_1 { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk-cpu.dtsi @@ -187,6 +187,9 @@ }; &hscif0 { + pinctrl-0 = <&hscif0_pins>; + pinctrl-names = "default"; + status = "okay"; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/rockchip/rk3328-orangepi-r1-plus-lts.dts @@ -26,9 +26,11 @@ compatible = "ethernet-phy-ieee802.3-c22"; reg = <0>; + motorcomm,auto-sleep-disabled; motorcomm,clk-out-frequency-hz = <125000000>; motorcomm,keep-pll-enabled; - motorcomm,auto-sleep-disabled; + motorcomm,rx-clk-drv-microamp = <5020>; + motorcomm,rx-data-drv-microamp = <5020>; pinctrl-0 = <ð_phy_reset_pin>; pinctrl-names = "default"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/rockchip/rk3566-lubancat-1.dts +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/rockchip/rk3566-lubancat-1.dts @@ -455,7 +455,7 @@ &pinctrl { leds { sys_led_pin: sys-status-led-pin { - rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; + rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; }; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/rockchip/rk3588s.dtsi @@ -784,6 +784,7 @@ reg = ; clocks = <&cru PCLK_PHP_ROOT>, <&cru ACLK_USB_ROOT>, + <&cru ACLK_USB>, <&cru HCLK_USB_ROOT>, <&cru HCLK_HOST0>, <&cru HCLK_HOST_ARB0>, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/sprd/ums512.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/sprd/ums512.dtsi @@ -96,7 +96,7 @@ CPU6: cpu@600 { device_type = "cpu"; - compatible = "arm,cortex-a55"; + compatible = "arm,cortex-a75"; reg = <0x0 0x600>; enable-method = "psci"; cpu-idle-states = <&CORE_PD>; @@ -104,7 +104,7 @@ CPU7: cpu@700 { device_type = "cpu"; - compatible = "arm,cortex-a55"; + compatible = "arm,cortex-a75"; reg = <0x0 0x700>; enable-method = "psci"; cpu-idle-states = <&CORE_PD>; @@ -113,7 +113,7 @@ idle-states { entry-method = "psci"; - CORE_PD: core-pd { + CORE_PD: cpu-pd { compatible = "arm,idle-state"; entry-latency-us = <4000>; exit-latency-us = <4000>; @@ -291,6 +291,7 @@ pll2: clock-controller@0 { compatible = "sprd,ums512-gc-pll"; reg = <0x0 0x100>; + clocks = <&ext_26m>; clock-names = "ext-26m"; #clock-cells = <1>; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi @@ -462,7 +462,7 @@ <193>, <194>, <195>; interrupt-controller; #interrupt-cells = <2>; - ti,ngpio = <87>; + ti,ngpio = <92>; ti,davinci-gpio-unbanked = <0>; power-domains = <&k3_pds 77 TI_SCI_PD_EXCLUSIVE>; clocks = <&k3_clks 77 0>; @@ -480,7 +480,7 @@ <183>, <184>, <185>; interrupt-controller; #interrupt-cells = <2>; - ti,ngpio = <88>; + ti,ngpio = <52>; ti,davinci-gpio-unbanked = <0>; power-domains = <&k3_pds 78 TI_SCI_PD_EXCLUSIVE>; clocks = <&k3_clks 78 0>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/ti/k3-am65-iot2050-common.dtsi @@ -14,6 +14,16 @@ / { aliases { + serial0 = &wkup_uart0; + serial1 = &mcu_uart0; + serial2 = &main_uart0; + serial3 = &main_uart1; + i2c0 = &wkup_i2c0; + i2c1 = &mcu_i2c0; + i2c2 = &main_i2c0; + i2c3 = &main_i2c1; + i2c4 = &main_i2c2; + i2c5 = &main_i2c3; spi0 = &mcu_spi0; mmc0 = &sdhci1; mmc1 = &sdhci0; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/ti/k3-am65-main.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/ti/k3-am65-main.dtsi @@ -1033,7 +1033,7 @@ assigned-clocks = <&k3_clks 67 2>; assigned-clock-parents = <&k3_clks 67 5>; - interrupts = ; + interrupts = ; dma-coherent; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/xilinx/Makefile +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/xilinx/Makefile @@ -22,11 +22,10 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA.dtb zynqmp-sm-k26-revA-sck-kv-g-revA-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kv-g-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA-sck-kv-g-revA.dtb zynqmp-sm-k26-revA-sck-kv-g-revB-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kv-g-revB.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-sm-k26-revA-sck-kv-g-revB.dtb zynqmp-smk-k26-revA-sck-kv-g-revA-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kv-g-revA.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kv-g-revA.dtb zynqmp-smk-k26-revA-sck-kv-g-revB-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kv-g-revB.dtbo - -zynqmp-sm-k26-revA-sck-kr-g-revA-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kr-g-revA.dtbo -zynqmp-sm-k26-revA-sck-kr-g-revB-dtbs := zynqmp-sm-k26-revA.dtb zynqmp-sck-kr-g-revB.dtbo -zynqmp-smk-k26-revA-sck-kr-g-revA-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kr-g-revA.dtbo -zynqmp-smk-k26-revA-sck-kr-g-revB-dtbs := zynqmp-smk-k26-revA.dtb zynqmp-sck-kr-g-revB.dtbo +dtb-$(CONFIG_ARCH_ZYNQMP) += zynqmp-smk-k26-revA-sck-kv-g-revB.dtb only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revA.dtso @@ -21,57 +21,57 @@ /dts-v1/; /plugin/; -&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */ - #address-cells = <1>; - #size-cells = <0>; - pinctrl-names = "default", "gpio"; - pinctrl-0 = <&pinctrl_i2c1_default>; - pinctrl-1 = <&pinctrl_i2c1_gpio>; - scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; - sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; - - /* u14 - 0x40 - ina260 */ - /* u27 - 0xe0 - STDP4320 DP/HDMI splitter */ -}; - -&amba { - si5332_0: si5332_0 { /* u17 */ +&{/} { + si5332_0: si5332-0 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <125000000>; }; - si5332_1: si5332_1 { /* u17 */ + si5332_1: si5332-1 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <25000000>; }; - si5332_2: si5332_2 { /* u17 */ + si5332_2: si5332-2 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <48000000>; }; - si5332_3: si5332_3 { /* u17 */ + si5332_3: si5332-3 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <24000000>; }; - si5332_4: si5332_4 { /* u17 */ + si5332_4: si5332-4 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <26000000>; }; - si5332_5: si5332_5 { /* u17 */ + si5332_5: si5332-5 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <27000000>; }; }; +&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; + + /* u14 - 0x40 - ina260 */ + /* u27 - 0xe0 - STDP4320 DP/HDMI splitter */ +}; + /* DP/USB 3.0 and SATA */ &psgtr { status = "okay"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/dts/xilinx/zynqmp-sck-kv-g-revB.dtso @@ -16,58 +16,58 @@ /dts-v1/; /plugin/; -&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */ - #address-cells = <1>; - #size-cells = <0>; - pinctrl-names = "default", "gpio"; - pinctrl-0 = <&pinctrl_i2c1_default>; - pinctrl-1 = <&pinctrl_i2c1_gpio>; - scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; - sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; - - /* u14 - 0x40 - ina260 */ - /* u43 - 0x2d - usb5744 */ - /* u27 - 0xe0 - STDP4320 DP/HDMI splitter */ -}; - -&amba { - si5332_0: si5332_0 { /* u17 */ +&{/} { + si5332_0: si5332-0 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <125000000>; }; - si5332_1: si5332_1 { /* u17 */ + si5332_1: si5332-1 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <25000000>; }; - si5332_2: si5332_2 { /* u17 */ + si5332_2: si5332-2 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <48000000>; }; - si5332_3: si5332_3 { /* u17 */ + si5332_3: si5332-3 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <24000000>; }; - si5332_4: si5332_4 { /* u17 */ + si5332_4: si5332-4 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <26000000>; }; - si5332_5: si5332_5 { /* u17 */ + si5332_5: si5332-5 { /* u17 */ compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <27000000>; }; }; +&i2c1 { /* I2C_SCK C23/C24 - MIO from SOM */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1_default>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>; + sda-gpios = <&gpio 25 GPIO_ACTIVE_HIGH>; + + /* u14 - 0x40 - ina260 */ + /* u43 - 0x2d - usb5744 */ + /* u27 - 0xe0 - STDP4320 DP/HDMI splitter */ +}; + /* DP/USB 3.0 */ &psgtr { status = "okay"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/boot/install.sh +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/boot/install.sh @@ -17,7 +17,8 @@ # $3 - kernel map file # $4 - default install path (blank if root directory) -if [ "$(basename $2)" = "Image.gz" ]; then +if [ "$(basename $2)" = "Image.gz" ] || [ "$(basename $2)" = "vmlinuz.efi" ] +then # Compressed install echo "Installing compressed kernel" base=vmlinuz only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/include/asm/irq_work.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/include/asm/irq_work.h @@ -2,8 +2,6 @@ #ifndef __ASM_IRQ_WORK_H #define __ASM_IRQ_WORK_H -extern void arch_irq_work_raise(void); - static inline bool arch_irq_work_has_interrupt(void) { return true; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/kernel/irq.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kernel/irq.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -47,17 +48,17 @@ for_each_possible_cpu(cpu) per_cpu(irq_shadow_call_stack_ptr, cpu) = - scs_alloc(cpu_to_node(cpu)); + scs_alloc(early_cpu_to_node(cpu)); } #ifdef CONFIG_VMAP_STACK -static void init_irq_stacks(void) +static void __init init_irq_stacks(void) { int cpu; unsigned long *p; for_each_possible_cpu(cpu) { - p = arch_alloc_vmap_stack(IRQ_STACK_SIZE, cpu_to_node(cpu)); + p = arch_alloc_vmap_stack(IRQ_STACK_SIZE, early_cpu_to_node(cpu)); per_cpu(irq_stack_ptr, cpu) = p; } } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/arm64/kvm/vgic/vgic-its.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/arm64/kvm/vgic/vgic-its.c @@ -584,7 +584,11 @@ unsigned long flags; raw_spin_lock_irqsave(&dist->lpi_list_lock, flags); + irq = __vgic_its_check_cache(dist, db, devid, eventid); + if (irq) + vgic_get_irq_kref(irq); + raw_spin_unlock_irqrestore(&dist->lpi_list_lock, flags); return irq; @@ -763,6 +767,7 @@ raw_spin_lock_irqsave(&irq->irq_lock, flags); irq->pending_latch = true; vgic_queue_irq_unlock(kvm, irq, flags); + vgic_put_irq(kvm, irq); return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/csky/include/asm/irq_work.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/csky/include/asm/irq_work.h @@ -7,5 +7,5 @@ { return true; } -extern void arch_irq_work_raise(void); + #endif /* __ASM_CSKY_IRQ_WORK_H */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/csky/include/asm/jump_label.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/csky/include/asm/jump_label.h @@ -43,5 +43,10 @@ return true; } +enum jump_label_type; +void arch_jump_label_transform_static(struct jump_entry *entry, + enum jump_label_type type); +#define arch_jump_label_transform_static arch_jump_label_transform_static + #endif /* __ASSEMBLY__ */ #endif /* __ASM_CSKY_JUMP_LABEL_H */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/loongarch/kernel/elf.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/kernel/elf.c @@ -23,8 +23,3 @@ { return 0; } - -void loongarch_set_personality_fcsr(struct arch_elf_state *state) -{ - current->thread.fpu.fcsr = boot_cpu_data.fpu_csr0; -} only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/loongarch/kernel/smp.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/kernel/smp.c @@ -503,7 +503,7 @@ unsigned int cpu; sync_counter(); - cpu = smp_processor_id(); + cpu = raw_smp_processor_id(); set_my_cpu_offset(per_cpu_offset(cpu)); cpu_probe(); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/loongarch/mm/tlb.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/loongarch/mm/tlb.c @@ -284,12 +284,16 @@ set_handler(EXCCODE_TLBNR * VECSIZE, handle_tlb_protect, VECSIZE); set_handler(EXCCODE_TLBNX * VECSIZE, handle_tlb_protect, VECSIZE); set_handler(EXCCODE_TLBPE * VECSIZE, handle_tlb_protect, VECSIZE); - } + } else { + int vec_sz __maybe_unused; + void *addr __maybe_unused; + struct page *page __maybe_unused; + + /* Avoid lockdep warning */ + rcu_cpu_starting(cpu); + #ifdef CONFIG_NUMA - else { - void *addr; - struct page *page; - const int vec_sz = sizeof(exception_handlers); + vec_sz = sizeof(exception_handlers); if (pcpu_handlers[cpu]) return; @@ -305,8 +309,8 @@ csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_EENTRY); csr_write64(pcpu_handlers[cpu], LOONGARCH_CSR_MERRENTRY); csr_write64(pcpu_handlers[cpu] + 80*VECSIZE, LOONGARCH_CSR_TLBRENTRY); - } #endif + } } void tlb_init(int cpu) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/mips/alchemy/devboards/db1550.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/mips/alchemy/devboards/db1550.c @@ -589,7 +589,7 @@ i2c_register_board_info(0, db1550_i2c_devs, ARRAY_SIZE(db1550_i2c_devs)); spi_register_board_info(db1550_spi_devs, - ARRAY_SIZE(db1550_i2c_devs)); + ARRAY_SIZE(db1550_spi_devs)); c = clk_get(NULL, "psc0_intclk"); if (!IS_ERR(c)) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/mips/include/asm/dmi.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/mips/include/asm/dmi.h @@ -5,7 +5,7 @@ #include #include -#define dmi_early_remap(x, l) ioremap_cache(x, l) +#define dmi_early_remap(x, l) ioremap(x, l) #define dmi_early_unmap(x, l) iounmap(x) #define dmi_remap(x, l) ioremap_cache(x, l) #define dmi_unmap(x) iounmap(x) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/mips/kernel/elf.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/mips/kernel/elf.c @@ -11,6 +11,7 @@ #include #include +#include #ifdef CONFIG_MIPS_FP_SUPPORT @@ -309,6 +310,11 @@ struct cpuinfo_mips *c = &boot_cpu_data; struct task_struct *t = current; + /* Do this early so t->thread.fpu.fcr31 won't be clobbered in case + * we are preempted before the lose_fpu(0) in start_thread. + */ + lose_fpu(0); + t->thread.fpu.fcr31 = c->fpu_csr31; switch (state->nan_2008) { case 0: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/mips/kernel/setup.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/mips/kernel/setup.c @@ -326,11 +326,11 @@ panic("Incorrect memory mapping !!!"); if (max_pfn > PFN_DOWN(HIGHMEM_START)) { + max_low_pfn = PFN_DOWN(HIGHMEM_START); #ifdef CONFIG_HIGHMEM - highstart_pfn = PFN_DOWN(HIGHMEM_START); + highstart_pfn = max_low_pfn; highend_pfn = max_pfn; #else - max_low_pfn = PFN_DOWN(HIGHMEM_START); max_pfn = max_low_pfn; #endif } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/mips/kernel/smp.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/mips/kernel/smp.c @@ -351,10 +351,11 @@ */ asmlinkage void start_secondary(void) { - unsigned int cpu; + unsigned int cpu = raw_smp_processor_id(); cpu_probe(); per_cpu_trap_init(false); + rcu_cpu_starting(cpu); mips_clockevent_init(); mp_ops->init_secondary(); cpu_report(); @@ -366,7 +367,6 @@ */ calibrate_delay(); - cpu = smp_processor_id(); cpu_data[cpu].udelay_val = loops_per_jiffy; set_cpu_sibling_map(cpu); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/mips/lantiq/prom.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/mips/lantiq/prom.c @@ -108,10 +108,9 @@ prom_init_cmdline(); #if defined(CONFIG_MIPS_MT_SMP) - if (cpu_has_mipsmt) { - lantiq_smp_ops = vsmp_smp_ops; + lantiq_smp_ops = vsmp_smp_ops; + if (cpu_has_mipsmt) lantiq_smp_ops.init_secondary = lantiq_init_secondary; - register_smp_ops(&lantiq_smp_ops); - } + register_smp_ops(&lantiq_smp_ops); #endif } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/mips/mm/init.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/mips/mm/init.c @@ -417,7 +417,12 @@ (highend_pfn - max_low_pfn) << (PAGE_SHIFT - 10)); max_zone_pfns[ZONE_HIGHMEM] = max_low_pfn; } + + max_mapnr = highend_pfn ? highend_pfn : max_low_pfn; +#else + max_mapnr = max_low_pfn; #endif + high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); free_area_init(max_zone_pfns); } @@ -453,13 +458,6 @@ */ BUILD_BUG_ON(IS_ENABLED(CONFIG_32BIT) && (_PFN_SHIFT > PAGE_SHIFT)); -#ifdef CONFIG_HIGHMEM - max_mapnr = highend_pfn ? highend_pfn : max_low_pfn; -#else - max_mapnr = max_low_pfn; -#endif - high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); - maar_init(); memblock_free_all(); setup_zero_pages(); /* Setup zeroed pages. */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/parisc/kernel/firmware.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/parisc/kernel/firmware.c @@ -123,10 +123,10 @@ #ifdef CONFIG_64BIT if(unlikely(parisc_narrow_firmware)) { if((address & 0xff000000) == 0xf0000000) - return 0xf0f0f0f000000000UL | (u32)address; + return (0xfffffff0UL << 32) | (u32)address; if((address & 0xf0000000) == 0xf0000000) - return 0xffffffff00000000UL | (u32)address; + return (0xffffffffUL << 32) | (u32)address; } #endif return address; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/configs/ps3_defconfig +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/configs/ps3_defconfig @@ -24,6 +24,7 @@ CONFIG_PS3_LPM=m # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set CONFIG_KEXEC=y +# CONFIG_PPC64_BIG_ENDIAN_ELF_ABI_V2 is not set CONFIG_PPC_4K_PAGES=y CONFIG_SCHED_SMT=y CONFIG_PM=y only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/crypto/aes-gcm-p10-glue.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/crypto/aes-gcm-p10-glue.c @@ -37,7 +37,7 @@ void *rkey, u8 *iv, void *Xi); asmlinkage void aes_p10_gcm_decrypt(u8 *in, u8 *out, size_t len, void *rkey, u8 *iv, void *Xi); -asmlinkage void gcm_init_htable(unsigned char htable[256], unsigned char Xi[16]); +asmlinkage void gcm_init_htable(unsigned char htable[], unsigned char Xi[]); asmlinkage void gcm_ghash_p10(unsigned char *Xi, unsigned char *Htable, unsigned char *aad, unsigned int alen); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/include/asm/irq_work.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/include/asm/irq_work.h @@ -6,6 +6,5 @@ { return true; } -extern void arch_irq_work_raise(void); #endif /* _ASM_POWERPC_IRQ_WORK_H */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/include/asm/mmu.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/include/asm/mmu.h @@ -417,5 +417,9 @@ #include #endif +#if defined(CONFIG_FA_DUMP) || defined(CONFIG_PRESERVE_FA_DUMP) +#define __HAVE_ARCH_RESERVED_KERNEL_PAGES +#endif + #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_MMU_H_ */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/include/asm/mmzone.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/include/asm/mmzone.h @@ -42,14 +42,6 @@ #else #define memory_hotplug_max() memblock_end_of_DRAM() #endif /* CONFIG_NUMA */ -#ifdef CONFIG_FA_DUMP -#define __HAVE_ARCH_RESERVED_KERNEL_PAGES -#endif - -#ifdef CONFIG_MEMORY_HOTPLUG -extern int create_section_mapping(unsigned long start, unsigned long end, - int nid, pgprot_t prot); -#endif #endif /* __KERNEL__ */ #endif /* _ASM_MMZONE_H_ */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/kernel/rtas.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/kernel/rtas.c @@ -544,6 +544,21 @@ } arch_initcall(rtas_token_to_function_xarray_init); +/* + * For use by sys_rtas(), where the token value is provided by user + * space and we don't want to warn on failed lookups. + */ +static const struct rtas_function *rtas_token_to_function_untrusted(s32 token) +{ + return xa_load(&rtas_token_to_function_xarray, token); +} + +/* + * Reverse lookup for deriving the function descriptor from a + * known-good token value in contexts where the former is not already + * available. @token must be valid, e.g. derived from the result of a + * prior lookup against the function table. + */ static const struct rtas_function *rtas_token_to_function(s32 token) { const struct rtas_function *func; @@ -551,7 +566,7 @@ if (WARN_ONCE(token < 0, "invalid token %d", token)) return NULL; - func = xa_load(&rtas_token_to_function_xarray, token); + func = rtas_token_to_function_untrusted(token); if (WARN_ONCE(!func, "unexpected failed lookup for token %d", token)) return NULL; @@ -1723,7 +1738,7 @@ * If this token doesn't correspond to a function the kernel * understands, you're not allowed to call it. */ - func = rtas_token_to_function(token); + func = rtas_token_to_function_untrusted(token); if (!func) goto err; /* only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -28,6 +28,7 @@ #include #include "book3s.h" +#include "book3s_hv.h" #include "trace_hv.h" //#define DEBUG_RESIZE_HPT 1 @@ -347,7 +348,7 @@ unsigned long v, orig_v, gr; __be64 *hptep; long int index; - int virtmode = vcpu->arch.shregs.msr & (data ? MSR_DR : MSR_IR); + int virtmode = __kvmppc_get_msr_hv(vcpu) & (data ? MSR_DR : MSR_IR); if (kvm_is_radix(vcpu->kvm)) return kvmppc_mmu_radix_xlate(vcpu, eaddr, gpte, data, iswrite); @@ -385,7 +386,7 @@ /* Get PP bits and key for permission check */ pp = gr & (HPTE_R_PP0 | HPTE_R_PP); - key = (vcpu->arch.shregs.msr & MSR_PR) ? SLB_VSID_KP : SLB_VSID_KS; + key = (__kvmppc_get_msr_hv(vcpu) & MSR_PR) ? SLB_VSID_KP : SLB_VSID_KS; key &= slb_v; /* Calculate permissions */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -15,6 +15,7 @@ #include #include +#include "book3s_hv.h" #include #include #include @@ -294,9 +295,9 @@ } else { if (!(pte & _PAGE_PRIVILEGED)) { /* Check AMR/IAMR to see if strict mode is in force */ - if (vcpu->arch.amr & (1ul << 62)) + if (kvmppc_get_amr_hv(vcpu) & (1ul << 62)) gpte->may_read = 0; - if (vcpu->arch.amr & (1ul << 63)) + if (kvmppc_get_amr_hv(vcpu) & (1ul << 63)) gpte->may_write = 0; if (vcpu->arch.iamr & (1ul << 62)) gpte->may_execute = 0; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/kvm/book3s_hv.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/kvm/book3s_hv.c @@ -868,7 +868,7 @@ /* Guests can't breakpoint the hypervisor */ if ((value1 & CIABR_PRIV) == CIABR_PRIV_HYPER) return H_P3; - vcpu->arch.ciabr = value1; + kvmppc_set_ciabr_hv(vcpu, value1); return H_SUCCESS; case H_SET_MODE_RESOURCE_SET_DAWR0: if (!kvmppc_power8_compatible(vcpu)) @@ -879,8 +879,8 @@ return H_UNSUPPORTED_FLAG_START; if (value2 & DABRX_HYP) return H_P4; - vcpu->arch.dawr0 = value1; - vcpu->arch.dawrx0 = value2; + kvmppc_set_dawr0_hv(vcpu, value1); + kvmppc_set_dawrx0_hv(vcpu, value2); return H_SUCCESS; case H_SET_MODE_RESOURCE_SET_DAWR1: if (!kvmppc_power8_compatible(vcpu)) @@ -895,8 +895,8 @@ return H_UNSUPPORTED_FLAG_START; if (value2 & DABRX_HYP) return H_P4; - vcpu->arch.dawr1 = value1; - vcpu->arch.dawrx1 = value2; + kvmppc_set_dawr1_hv(vcpu, value1); + kvmppc_set_dawrx1_hv(vcpu, value2); return H_SUCCESS; case H_SET_MODE_RESOURCE_ADDR_TRANS_MODE: /* @@ -1370,7 +1370,7 @@ */ static void kvmppc_cede(struct kvm_vcpu *vcpu) { - vcpu->arch.shregs.msr |= MSR_EE; + __kvmppc_set_msr_hv(vcpu, __kvmppc_get_msr_hv(vcpu) | MSR_EE); vcpu->arch.ceded = 1; smp_mb(); if (vcpu->arch.prodded) { @@ -1544,7 +1544,7 @@ if (!(vcpu->arch.hfscr_permitted & HFSCR_PM)) return EMULATE_FAIL; - vcpu->arch.hfscr |= HFSCR_PM; + kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) | HFSCR_PM); return RESUME_GUEST; } @@ -1554,7 +1554,7 @@ if (!(vcpu->arch.hfscr_permitted & HFSCR_EBB)) return EMULATE_FAIL; - vcpu->arch.hfscr |= HFSCR_EBB; + kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) | HFSCR_EBB); return RESUME_GUEST; } @@ -1564,7 +1564,7 @@ if (!(vcpu->arch.hfscr_permitted & HFSCR_TM)) return EMULATE_FAIL; - vcpu->arch.hfscr |= HFSCR_TM; + kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) | HFSCR_TM); return RESUME_GUEST; } @@ -1585,7 +1585,7 @@ * That can happen due to a bug, or due to a machine check * occurring at just the wrong time. */ - if (vcpu->arch.shregs.msr & MSR_HV) { + if (__kvmppc_get_msr_hv(vcpu) & MSR_HV) { printk(KERN_EMERG "KVM trap in HV mode!\n"); printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n", vcpu->arch.trap, kvmppc_get_pc(vcpu), @@ -1636,7 +1636,7 @@ * so that it knows that the machine check occurred. */ if (!vcpu->kvm->arch.fwnmi_enabled) { - ulong flags = (vcpu->arch.shregs.msr & 0x083c0000) | + ulong flags = (__kvmppc_get_msr_hv(vcpu) & 0x083c0000) | (kvmppc_get_msr(vcpu) & SRR1_PREFIXED); kvmppc_core_queue_machine_check(vcpu, flags); r = RESUME_GUEST; @@ -1666,7 +1666,7 @@ * as a result of a hypervisor emulation interrupt * (e40) getting turned into a 700 by BML RTAS. */ - flags = (vcpu->arch.shregs.msr & 0x1f0000ull) | + flags = (__kvmppc_get_msr_hv(vcpu) & 0x1f0000ull) | (kvmppc_get_msr(vcpu) & SRR1_PREFIXED); kvmppc_core_queue_program(vcpu, flags); r = RESUME_GUEST; @@ -1676,7 +1676,7 @@ { int i; - if (unlikely(vcpu->arch.shregs.msr & MSR_PR)) { + if (unlikely(__kvmppc_get_msr_hv(vcpu) & MSR_PR)) { /* * Guest userspace executed sc 1. This can only be * reached by the P9 path because the old path @@ -1754,7 +1754,7 @@ break; } - if (!(vcpu->arch.shregs.msr & MSR_DR)) + if (!(__kvmppc_get_msr_hv(vcpu) & MSR_DR)) vsid = vcpu->kvm->arch.vrma_slb_v; else vsid = vcpu->arch.fault_gpa; @@ -1778,7 +1778,7 @@ long err; vcpu->arch.fault_dar = kvmppc_get_pc(vcpu); - vcpu->arch.fault_dsisr = vcpu->arch.shregs.msr & + vcpu->arch.fault_dsisr = __kvmppc_get_msr_hv(vcpu) & DSISR_SRR1_MATCH_64S; if (kvm_is_radix(vcpu->kvm) || !cpu_has_feature(CPU_FTR_ARCH_300)) { /* @@ -1787,7 +1787,7 @@ * hash fault handling below is v3 only (it uses ASDR * via fault_gpa). */ - if (vcpu->arch.shregs.msr & HSRR1_HISI_WRITE) + if (__kvmppc_get_msr_hv(vcpu) & HSRR1_HISI_WRITE) vcpu->arch.fault_dsisr |= DSISR_ISSTORE; r = RESUME_PAGE_FAULT; break; @@ -1801,7 +1801,7 @@ break; } - if (!(vcpu->arch.shregs.msr & MSR_IR)) + if (!(__kvmppc_get_msr_hv(vcpu) & MSR_IR)) vsid = vcpu->kvm->arch.vrma_slb_v; else vsid = vcpu->arch.fault_gpa; @@ -1863,7 +1863,7 @@ * Otherwise, we just generate a program interrupt to the guest. */ case BOOK3S_INTERRUPT_H_FAC_UNAVAIL: { - u64 cause = vcpu->arch.hfscr >> 56; + u64 cause = kvmppc_get_hfscr_hv(vcpu) >> 56; r = EMULATE_FAIL; if (cpu_has_feature(CPU_FTR_ARCH_300)) { @@ -1891,7 +1891,7 @@ kvmppc_dump_regs(vcpu); printk(KERN_EMERG "trap=0x%x | pc=0x%lx | msr=0x%llx\n", vcpu->arch.trap, kvmppc_get_pc(vcpu), - vcpu->arch.shregs.msr); + __kvmppc_get_msr_hv(vcpu)); run->hw.hardware_exit_reason = vcpu->arch.trap; r = RESUME_HOST; break; @@ -1915,11 +1915,11 @@ * That can happen due to a bug, or due to a machine check * occurring at just the wrong time. */ - if (vcpu->arch.shregs.msr & MSR_HV) { + if (__kvmppc_get_msr_hv(vcpu) & MSR_HV) { pr_emerg("KVM trap in HV mode while nested!\n"); pr_emerg("trap=0x%x | pc=0x%lx | msr=0x%llx\n", vcpu->arch.trap, kvmppc_get_pc(vcpu), - vcpu->arch.shregs.msr); + __kvmppc_get_msr_hv(vcpu)); kvmppc_dump_regs(vcpu); return RESUME_HOST; } @@ -1976,7 +1976,7 @@ vcpu->arch.fault_dar = kvmppc_get_pc(vcpu); vcpu->arch.fault_dsisr = kvmppc_get_msr(vcpu) & DSISR_SRR1_MATCH_64S; - if (vcpu->arch.shregs.msr & HSRR1_HISI_WRITE) + if (__kvmppc_get_msr_hv(vcpu) & HSRR1_HISI_WRITE) vcpu->arch.fault_dsisr |= DSISR_ISSTORE; srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); r = kvmhv_nested_page_fault(vcpu); @@ -2207,64 +2207,64 @@ *val = get_reg_val(id, vcpu->arch.dabrx); break; case KVM_REG_PPC_DSCR: - *val = get_reg_val(id, vcpu->arch.dscr); + *val = get_reg_val(id, kvmppc_get_dscr_hv(vcpu)); break; case KVM_REG_PPC_PURR: - *val = get_reg_val(id, vcpu->arch.purr); + *val = get_reg_val(id, kvmppc_get_purr_hv(vcpu)); break; case KVM_REG_PPC_SPURR: - *val = get_reg_val(id, vcpu->arch.spurr); + *val = get_reg_val(id, kvmppc_get_spurr_hv(vcpu)); break; case KVM_REG_PPC_AMR: - *val = get_reg_val(id, vcpu->arch.amr); + *val = get_reg_val(id, kvmppc_get_amr_hv(vcpu)); break; case KVM_REG_PPC_UAMOR: - *val = get_reg_val(id, vcpu->arch.uamor); + *val = get_reg_val(id, kvmppc_get_uamor_hv(vcpu)); break; case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCR1: i = id - KVM_REG_PPC_MMCR0; - *val = get_reg_val(id, vcpu->arch.mmcr[i]); + *val = get_reg_val(id, kvmppc_get_mmcr_hv(vcpu, i)); break; case KVM_REG_PPC_MMCR2: - *val = get_reg_val(id, vcpu->arch.mmcr[2]); + *val = get_reg_val(id, kvmppc_get_mmcr_hv(vcpu, 2)); break; case KVM_REG_PPC_MMCRA: - *val = get_reg_val(id, vcpu->arch.mmcra); + *val = get_reg_val(id, kvmppc_get_mmcra_hv(vcpu)); break; case KVM_REG_PPC_MMCRS: *val = get_reg_val(id, vcpu->arch.mmcrs); break; case KVM_REG_PPC_MMCR3: - *val = get_reg_val(id, vcpu->arch.mmcr[3]); + *val = get_reg_val(id, kvmppc_get_mmcr_hv(vcpu, 3)); break; case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8: i = id - KVM_REG_PPC_PMC1; - *val = get_reg_val(id, vcpu->arch.pmc[i]); + *val = get_reg_val(id, kvmppc_get_pmc_hv(vcpu, i)); break; case KVM_REG_PPC_SPMC1 ... KVM_REG_PPC_SPMC2: i = id - KVM_REG_PPC_SPMC1; *val = get_reg_val(id, vcpu->arch.spmc[i]); break; case KVM_REG_PPC_SIAR: - *val = get_reg_val(id, vcpu->arch.siar); + *val = get_reg_val(id, kvmppc_get_siar_hv(vcpu)); break; case KVM_REG_PPC_SDAR: - *val = get_reg_val(id, vcpu->arch.sdar); + *val = get_reg_val(id, kvmppc_get_siar_hv(vcpu)); break; case KVM_REG_PPC_SIER: - *val = get_reg_val(id, vcpu->arch.sier[0]); + *val = get_reg_val(id, kvmppc_get_sier_hv(vcpu, 0)); break; case KVM_REG_PPC_SIER2: - *val = get_reg_val(id, vcpu->arch.sier[1]); + *val = get_reg_val(id, kvmppc_get_sier_hv(vcpu, 1)); break; case KVM_REG_PPC_SIER3: - *val = get_reg_val(id, vcpu->arch.sier[2]); + *val = get_reg_val(id, kvmppc_get_sier_hv(vcpu, 2)); break; case KVM_REG_PPC_IAMR: - *val = get_reg_val(id, vcpu->arch.iamr); + *val = get_reg_val(id, kvmppc_get_iamr_hv(vcpu)); break; case KVM_REG_PPC_PSPB: - *val = get_reg_val(id, vcpu->arch.pspb); + *val = get_reg_val(id, kvmppc_get_pspb_hv(vcpu)); break; case KVM_REG_PPC_DPDES: /* @@ -2282,19 +2282,19 @@ *val = get_reg_val(id, vcpu->arch.vcore->vtb); break; case KVM_REG_PPC_DAWR: - *val = get_reg_val(id, vcpu->arch.dawr0); + *val = get_reg_val(id, kvmppc_get_dawr0_hv(vcpu)); break; case KVM_REG_PPC_DAWRX: - *val = get_reg_val(id, vcpu->arch.dawrx0); + *val = get_reg_val(id, kvmppc_get_dawrx0_hv(vcpu)); break; case KVM_REG_PPC_DAWR1: - *val = get_reg_val(id, vcpu->arch.dawr1); + *val = get_reg_val(id, kvmppc_get_dawr1_hv(vcpu)); break; case KVM_REG_PPC_DAWRX1: - *val = get_reg_val(id, vcpu->arch.dawrx1); + *val = get_reg_val(id, kvmppc_get_dawrx1_hv(vcpu)); break; case KVM_REG_PPC_CIABR: - *val = get_reg_val(id, vcpu->arch.ciabr); + *val = get_reg_val(id, kvmppc_get_ciabr_hv(vcpu)); break; case KVM_REG_PPC_CSIGR: *val = get_reg_val(id, vcpu->arch.csigr); @@ -2312,7 +2312,7 @@ *val = get_reg_val(id, vcpu->arch.acop); break; case KVM_REG_PPC_WORT: - *val = get_reg_val(id, vcpu->arch.wort); + *val = get_reg_val(id, kvmppc_get_wort_hv(vcpu)); break; case KVM_REG_PPC_TIDR: *val = get_reg_val(id, vcpu->arch.tid); @@ -2345,7 +2345,7 @@ *val = get_reg_val(id, vcpu->arch.vcore->lpcr); break; case KVM_REG_PPC_PPR: - *val = get_reg_val(id, vcpu->arch.ppr); + *val = get_reg_val(id, kvmppc_get_ppr_hv(vcpu)); break; #ifdef CONFIG_PPC_TRANSACTIONAL_MEM case KVM_REG_PPC_TFHAR: @@ -2425,6 +2425,9 @@ case KVM_REG_PPC_PTCR: *val = get_reg_val(id, vcpu->kvm->arch.l1_ptcr); break; + case KVM_REG_PPC_FSCR: + *val = get_reg_val(id, kvmppc_get_fscr_hv(vcpu)); + break; default: r = -EINVAL; break; @@ -2453,29 +2456,29 @@ vcpu->arch.dabrx = set_reg_val(id, *val) & ~DABRX_HYP; break; case KVM_REG_PPC_DSCR: - vcpu->arch.dscr = set_reg_val(id, *val); + kvmppc_set_dscr_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_PURR: - vcpu->arch.purr = set_reg_val(id, *val); + kvmppc_set_purr_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_SPURR: - vcpu->arch.spurr = set_reg_val(id, *val); + kvmppc_set_spurr_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_AMR: - vcpu->arch.amr = set_reg_val(id, *val); + kvmppc_set_amr_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_UAMOR: - vcpu->arch.uamor = set_reg_val(id, *val); + kvmppc_set_uamor_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_MMCR0 ... KVM_REG_PPC_MMCR1: i = id - KVM_REG_PPC_MMCR0; - vcpu->arch.mmcr[i] = set_reg_val(id, *val); + kvmppc_set_mmcr_hv(vcpu, i, set_reg_val(id, *val)); break; case KVM_REG_PPC_MMCR2: - vcpu->arch.mmcr[2] = set_reg_val(id, *val); + kvmppc_set_mmcr_hv(vcpu, 2, set_reg_val(id, *val)); break; case KVM_REG_PPC_MMCRA: - vcpu->arch.mmcra = set_reg_val(id, *val); + kvmppc_set_mmcra_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_MMCRS: vcpu->arch.mmcrs = set_reg_val(id, *val); @@ -2485,32 +2488,32 @@ break; case KVM_REG_PPC_PMC1 ... KVM_REG_PPC_PMC8: i = id - KVM_REG_PPC_PMC1; - vcpu->arch.pmc[i] = set_reg_val(id, *val); + kvmppc_set_pmc_hv(vcpu, i, set_reg_val(id, *val)); break; case KVM_REG_PPC_SPMC1 ... KVM_REG_PPC_SPMC2: i = id - KVM_REG_PPC_SPMC1; vcpu->arch.spmc[i] = set_reg_val(id, *val); break; case KVM_REG_PPC_SIAR: - vcpu->arch.siar = set_reg_val(id, *val); + kvmppc_set_siar_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_SDAR: - vcpu->arch.sdar = set_reg_val(id, *val); + kvmppc_set_sdar_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_SIER: - vcpu->arch.sier[0] = set_reg_val(id, *val); + kvmppc_set_sier_hv(vcpu, 0, set_reg_val(id, *val)); break; case KVM_REG_PPC_SIER2: - vcpu->arch.sier[1] = set_reg_val(id, *val); + kvmppc_set_sier_hv(vcpu, 1, set_reg_val(id, *val)); break; case KVM_REG_PPC_SIER3: - vcpu->arch.sier[2] = set_reg_val(id, *val); + kvmppc_set_sier_hv(vcpu, 2, set_reg_val(id, *val)); break; case KVM_REG_PPC_IAMR: - vcpu->arch.iamr = set_reg_val(id, *val); + kvmppc_set_iamr_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_PSPB: - vcpu->arch.pspb = set_reg_val(id, *val); + kvmppc_set_pspb_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_DPDES: if (cpu_has_feature(CPU_FTR_ARCH_300)) @@ -2522,22 +2525,22 @@ vcpu->arch.vcore->vtb = set_reg_val(id, *val); break; case KVM_REG_PPC_DAWR: - vcpu->arch.dawr0 = set_reg_val(id, *val); + kvmppc_set_dawr0_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_DAWRX: - vcpu->arch.dawrx0 = set_reg_val(id, *val) & ~DAWRX_HYP; + kvmppc_set_dawrx0_hv(vcpu, set_reg_val(id, *val) & ~DAWRX_HYP); break; case KVM_REG_PPC_DAWR1: - vcpu->arch.dawr1 = set_reg_val(id, *val); + kvmppc_set_dawr1_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_DAWRX1: - vcpu->arch.dawrx1 = set_reg_val(id, *val) & ~DAWRX_HYP; + kvmppc_set_dawrx1_hv(vcpu, set_reg_val(id, *val) & ~DAWRX_HYP); break; case KVM_REG_PPC_CIABR: - vcpu->arch.ciabr = set_reg_val(id, *val); + kvmppc_set_ciabr_hv(vcpu, set_reg_val(id, *val)); /* Don't allow setting breakpoints in hypervisor code */ - if ((vcpu->arch.ciabr & CIABR_PRIV) == CIABR_PRIV_HYPER) - vcpu->arch.ciabr &= ~CIABR_PRIV; /* disable */ + if ((kvmppc_get_ciabr_hv(vcpu) & CIABR_PRIV) == CIABR_PRIV_HYPER) + kvmppc_set_ciabr_hv(vcpu, kvmppc_get_ciabr_hv(vcpu) & ~CIABR_PRIV); break; case KVM_REG_PPC_CSIGR: vcpu->arch.csigr = set_reg_val(id, *val); @@ -2555,7 +2558,7 @@ vcpu->arch.acop = set_reg_val(id, *val); break; case KVM_REG_PPC_WORT: - vcpu->arch.wort = set_reg_val(id, *val); + kvmppc_set_wort_hv(vcpu, set_reg_val(id, *val)); break; case KVM_REG_PPC_TIDR: vcpu->arch.tid = set_reg_val(id, *val); @@ -2615,7 +2618,7 @@ kvmppc_set_lpcr(vcpu, set_reg_val(id, *val), false); break; case KVM_REG_PPC_PPR: - vcpu->arch.ppr = set_reg_val(id, *val); + kvmppc_set_ppr_hv(vcpu, set_reg_val(id, *val)); break; #ifdef CONFIG_PPC_TRANSACTIONAL_MEM case KVM_REG_PPC_TFHAR: @@ -2699,6 +2702,9 @@ case KVM_REG_PPC_PTCR: vcpu->kvm->arch.l1_ptcr = set_reg_val(id, *val); break; + case KVM_REG_PPC_FSCR: + kvmppc_set_fscr_hv(vcpu, set_reg_val(id, *val)); + break; default: r = -EINVAL; break; @@ -2916,19 +2922,20 @@ vcpu->arch.shared_big_endian = false; #endif #endif - vcpu->arch.mmcr[0] = MMCR0_FC; + kvmppc_set_mmcr_hv(vcpu, 0, MMCR0_FC); + if (cpu_has_feature(CPU_FTR_ARCH_31)) { - vcpu->arch.mmcr[0] |= MMCR0_PMCCEXT; - vcpu->arch.mmcra = MMCRA_BHRB_DISABLE; + kvmppc_set_mmcr_hv(vcpu, 0, kvmppc_get_mmcr_hv(vcpu, 0) | MMCR0_PMCCEXT); + kvmppc_set_mmcra_hv(vcpu, MMCRA_BHRB_DISABLE); } - vcpu->arch.ctrl = CTRL_RUNLATCH; + kvmppc_set_ctrl_hv(vcpu, CTRL_RUNLATCH); /* default to host PVR, since we can't spoof it */ kvmppc_set_pvr_hv(vcpu, mfspr(SPRN_PVR)); spin_lock_init(&vcpu->arch.vpa_update_lock); spin_lock_init(&vcpu->arch.tbacct_lock); vcpu->arch.busy_preempt = TB_NIL; - vcpu->arch.shregs.msr = MSR_ME; + __kvmppc_set_msr_hv(vcpu, MSR_ME); vcpu->arch.intr_msr = MSR_SF | MSR_ME; /* @@ -2938,29 +2945,30 @@ * don't set the HFSCR_MSGP bit, and that causes those instructions * to trap and then we emulate them. */ - vcpu->arch.hfscr = HFSCR_TAR | HFSCR_EBB | HFSCR_PM | HFSCR_BHRB | - HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP; + kvmppc_set_hfscr_hv(vcpu, HFSCR_TAR | HFSCR_EBB | HFSCR_PM | HFSCR_BHRB | + HFSCR_DSCR | HFSCR_VECVSX | HFSCR_FP); /* On POWER10 and later, allow prefixed instructions */ if (cpu_has_feature(CPU_FTR_ARCH_31)) - vcpu->arch.hfscr |= HFSCR_PREFIX; + kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) | HFSCR_PREFIX); if (cpu_has_feature(CPU_FTR_HVMODE)) { - vcpu->arch.hfscr &= mfspr(SPRN_HFSCR); + kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) & mfspr(SPRN_HFSCR)); + #ifdef CONFIG_PPC_TRANSACTIONAL_MEM if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) - vcpu->arch.hfscr |= HFSCR_TM; + kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) | HFSCR_TM); #endif } if (cpu_has_feature(CPU_FTR_TM_COMP)) vcpu->arch.hfscr |= HFSCR_TM; - vcpu->arch.hfscr_permitted = vcpu->arch.hfscr; + vcpu->arch.hfscr_permitted = kvmppc_get_hfscr_hv(vcpu); /* * PM, EBB, TM are demand-faulted so start with it clear. */ - vcpu->arch.hfscr &= ~(HFSCR_PM | HFSCR_EBB | HFSCR_TM); + kvmppc_set_hfscr_hv(vcpu, kvmppc_get_hfscr_hv(vcpu) & ~(HFSCR_PM | HFSCR_EBB | HFSCR_TM)); kvmppc_mmu_book3s_hv_init(vcpu); @@ -4176,7 +4184,7 @@ __this_cpu_write(cpu_in_guest, NULL); if (trap == BOOK3S_INTERRUPT_SYSCALL && - !(vcpu->arch.shregs.msr & MSR_PR)) { + !(__kvmppc_get_msr_hv(vcpu) & MSR_PR)) { unsigned long req = kvmppc_get_gpr(vcpu, 3); /* @@ -4655,13 +4663,19 @@ if (!nested) { kvmppc_core_prepare_to_enter(vcpu); - if (vcpu->arch.shregs.msr & MSR_EE) { - if (xive_interrupt_pending(vcpu)) + if (test_bit(BOOK3S_IRQPRIO_EXTERNAL, + &vcpu->arch.pending_exceptions) || + xive_interrupt_pending(vcpu)) { + /* + * For nested HV, don't synthesize but always pass MER, + * the L0 will be able to optimise that more + * effectively than manipulating registers directly. + */ + if (!kvmhv_on_pseries() && (__kvmppc_get_msr_hv(vcpu) & MSR_EE)) kvmppc_inject_interrupt_hv(vcpu, - BOOK3S_INTERRUPT_EXTERNAL, 0); - } else if (test_bit(BOOK3S_IRQPRIO_EXTERNAL, - &vcpu->arch.pending_exceptions)) { - lpcr |= LPCR_MER; + BOOK3S_INTERRUPT_EXTERNAL, 0); + else + lpcr |= LPCR_MER; } } else if (vcpu->arch.pending_exceptions || vcpu->arch.doorbell_request || @@ -4844,7 +4858,7 @@ msr |= MSR_VSX; if ((cpu_has_feature(CPU_FTR_TM) || cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST)) && - (vcpu->arch.hfscr & HFSCR_TM)) + (kvmppc_get_hfscr_hv(vcpu) & HFSCR_TM)) msr |= MSR_TM; msr = msr_check_and_set(msr); @@ -4868,7 +4882,7 @@ if (run->exit_reason == KVM_EXIT_PAPR_HCALL) { accumulate_time(vcpu, &vcpu->arch.hcall); - if (WARN_ON_ONCE(vcpu->arch.shregs.msr & MSR_PR)) { + if (WARN_ON_ONCE(__kvmppc_get_msr_hv(vcpu) & MSR_PR)) { /* * These should have been caught reflected * into the guest by now. Final sanity check: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/kvm/book3s_hv.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/kvm/book3s_hv.h @@ -50,3 +50,71 @@ #define start_timing(vcpu, next) do {} while (0) #define end_timing(vcpu) do {} while (0) #endif + +static inline void __kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 val) +{ + vcpu->arch.shregs.msr = val; +} + +static inline u64 __kvmppc_get_msr_hv(struct kvm_vcpu *vcpu) +{ + return vcpu->arch.shregs.msr; +} + +#define KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_SET(reg, size) \ +static inline void kvmppc_set_##reg ##_hv(struct kvm_vcpu *vcpu, u##size val) \ +{ \ + vcpu->arch.reg = val; \ +} + +#define KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_GET(reg, size) \ +static inline u##size kvmppc_get_##reg ##_hv(struct kvm_vcpu *vcpu) \ +{ \ + return vcpu->arch.reg; \ +} + +#define KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(reg, size) \ + KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_SET(reg, size) \ + KVMPPC_BOOK3S_HV_VCPU_ACCESSOR_GET(reg, size) \ + +#define KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_SET(reg, size) \ +static inline void kvmppc_set_##reg ##_hv(struct kvm_vcpu *vcpu, int i, u##size val) \ +{ \ + vcpu->arch.reg[i] = val; \ +} + +#define KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_GET(reg, size) \ +static inline u##size kvmppc_get_##reg ##_hv(struct kvm_vcpu *vcpu, int i) \ +{ \ + return vcpu->arch.reg[i]; \ +} + +#define KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(reg, size) \ + KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_SET(reg, size) \ + KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR_GET(reg, size) \ + +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(mmcra, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(hfscr, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(fscr, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dscr, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(purr, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(spurr, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(amr, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(uamor, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(siar, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(sdar, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(iamr, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawr0, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawr1, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx0, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(dawrx1, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ciabr, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(wort, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ppr, 64) +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(ctrl, 64) + +KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(mmcr, 64) +KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(sier, 64) +KVMPPC_BOOK3S_HV_VCPU_ARRAY_ACCESSOR(pmc, 32) + +KVMPPC_BOOK3S_HV_VCPU_ACCESSOR(pspb, 32) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/kvm/book3s_hv_builtin.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/kvm/book3s_hv_builtin.c @@ -32,6 +32,7 @@ #include "book3s_xics.h" #include "book3s_xive.h" +#include "book3s_hv.h" /* * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206) @@ -510,7 +511,7 @@ */ if ((msr & MSR_TS_MASK) == MSR_TS_MASK) msr &= ~MSR_TS_MASK; - vcpu->arch.shregs.msr = msr; + __kvmppc_set_msr_hv(vcpu, msr); kvmppc_end_cede(vcpu); } EXPORT_SYMBOL_GPL(kvmppc_set_msr_hv); @@ -548,7 +549,7 @@ kvmppc_set_srr0(vcpu, pc); kvmppc_set_srr1(vcpu, (msr & SRR1_MSR_BITS) | srr1_flags); kvmppc_set_pc(vcpu, new_pc); - vcpu->arch.shregs.msr = new_msr; + __kvmppc_set_msr_hv(vcpu, new_msr); } void kvmppc_inject_interrupt_hv(struct kvm_vcpu *vcpu, int vec, u64 srr1_flags) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/lib/Makefile +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/lib/Makefile @@ -45,7 +45,7 @@ # so it is only needed for modules, and only for older linkers which # do not support --save-restore-funcs ifndef CONFIG_LD_IS_BFD -extra-$(CONFIG_PPC64) += crtsavres.o +always-$(CONFIG_PPC64) += crtsavres.o endif obj-$(CONFIG_PPC_BOOK3S_64) += copyuser_power7.o copypage_power7.o \ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/mm/book3s64/pgtable.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/mm/book3s64/pgtable.c @@ -463,6 +463,7 @@ set_pte_at(vma->vm_mm, addr, ptep, pte); } +#ifdef CONFIG_TRANSPARENT_HUGEPAGE /* * For hash translation mode, we use the deposited table to store hash slot * information and they are stored at PTRS_PER_PMD offset from related pmd @@ -484,6 +485,7 @@ return true; } +#endif /* * Does the CPU support tlbie? only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/mm/init-common.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/mm/init-common.c @@ -126,7 +126,7 @@ * as to leave enough 0 bits in the address to contain it. */ unsigned long minalign = max(MAX_PGTABLE_INDEX_SIZE + 1, HUGEPD_SHIFT_MASK + 1); - struct kmem_cache *new; + struct kmem_cache *new = NULL; /* It would be nice if this was a BUILD_BUG_ON(), but at the * moment, gcc doesn't seem to recognize is_power_of_2 as a @@ -139,7 +139,8 @@ align = max_t(unsigned long, align, minalign); name = kasprintf(GFP_KERNEL, "pgtable-2^%d", shift); - new = kmem_cache_create(name, table_size, align, 0, ctor(shift)); + if (name) + new = kmem_cache_create(name, table_size, align, 0, ctor(shift)); if (!new) panic("Could not allocate pgtable cache for order %d", shift); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/mm/mmu_decl.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/mm/mmu_decl.h @@ -180,3 +180,8 @@ { return IS_ENABLED(CONFIG_KFENCE) || debug_pagealloc_enabled(); } + +#ifdef CONFIG_MEMORY_HOTPLUG +int create_section_mapping(unsigned long start, unsigned long end, + int nid, pgprot_t prot); +#endif only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/platforms/44x/Kconfig +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/platforms/44x/Kconfig @@ -173,6 +173,7 @@ config CURRITUCK bool "IBM Currituck (476fpe) Support" depends on PPC_47x + select I2C select SWIOTLB select 476FPE select FORCE_PCI only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/platforms/powernv/opal-irqchip.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/platforms/powernv/opal-irqchip.c @@ -275,6 +275,8 @@ else name = kasprintf(GFP_KERNEL, "opal"); + if (!name) + continue; /* Install interrupt handler */ rc = request_irq(r->start, opal_interrupt, r->flags & IRQD_TRIGGER_MASK, name, NULL); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/platforms/powernv/opal-powercap.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/platforms/powernv/opal-powercap.c @@ -196,6 +196,12 @@ j = 0; pcaps[i].pg.name = kasprintf(GFP_KERNEL, "%pOFn", node); + if (!pcaps[i].pg.name) { + kfree(pcaps[i].pattrs); + kfree(pcaps[i].pg.attrs); + goto out_pcaps_pattrs; + } + if (has_min) { powercap_add_attr(min, "powercap-min", &pcaps[i].pattrs[j]); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/platforms/powernv/opal-xscom.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/platforms/powernv/opal-xscom.c @@ -165,6 +165,11 @@ ent->chip = chip; snprintf(ent->name, 16, "%08x", chip); ent->path.data = (void *)kasprintf(GFP_KERNEL, "%pOF", dn); + if (!ent->path.data) { + kfree(ent); + return -ENOMEM; + } + ent->path.size = strlen((char *)ent->path.data); dir = debugfs_create_dir(ent->name, root); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/powerpc/platforms/pseries/hotplug-memory.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -487,14 +487,15 @@ } } - if (!lmb_found) + if (!lmb_found) { + pr_debug("Failed to look up LMB for drc index %x\n", drc_index); rc = -EINVAL; - - if (rc) + } else if (rc) { pr_debug("Failed to hot-remove memory at %llx\n", lmb->base_addr); - else + } else { pr_debug("Memory at %llx was hot-removed\n", lmb->base_addr); + } return rc; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/riscv/include/asm/irq_work.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/include/asm/irq_work.h @@ -6,5 +6,5 @@ { return IS_ENABLED(CONFIG_SMP); } -extern void arch_irq_work_raise(void); + #endif /* _ASM_RISCV_IRQ_WORK_H */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/riscv/include/asm/pgtable.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/include/asm/pgtable.h @@ -846,7 +846,7 @@ #define TASK_SIZE_MIN (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2) #ifdef CONFIG_COMPAT -#define TASK_SIZE_32 (_AC(0x80000000, UL) - PAGE_SIZE) +#define TASK_SIZE_32 (_AC(0x80000000, UL)) #define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \ TASK_SIZE_32 : TASK_SIZE_64) #else only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/riscv/include/asm/sections.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/include/asm/sections.h @@ -13,6 +13,7 @@ extern char __init_data_begin[], __init_data_end[]; extern char __init_text_begin[], __init_text_end[]; extern char __alt_start[], __alt_end[]; +extern char __exittext_begin[], __exittext_end[]; static inline bool is_va_kernel_text(uintptr_t va) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/riscv/include/asm/xip_fixup.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/include/asm/xip_fixup.h @@ -13,7 +13,7 @@ add \reg, \reg, t0 .endm .macro XIP_FIXUP_FLASH_OFFSET reg - la t1, __data_loc + la t0, __data_loc REG_L t1, _xip_phys_offset sub \reg, \reg, t1 add \reg, \reg, t0 only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/riscv/kernel/head.S +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/kernel/head.S @@ -88,6 +88,7 @@ /* Compute satp for kernel page tables, but don't load it yet */ srl a2, a0, PAGE_SHIFT la a1, satp_mode + XIP_FIXUP_OFFSET a1 REG_L a1, 0(a1) or a2, a2, a1 only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/riscv/kernel/module.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/kernel/module.c @@ -440,7 +440,8 @@ { return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, GFP_KERNEL, - PAGE_KERNEL, 0, NUMA_NO_NODE, + PAGE_KERNEL, VM_FLUSH_RESET_PERMS, + NUMA_NO_NODE, __builtin_return_address(0)); } #endif only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/riscv/kernel/patch.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/kernel/patch.c @@ -13,6 +13,7 @@ #include #include #include +#include struct patch_insn { void *addr; @@ -24,6 +25,14 @@ int riscv_patch_in_stop_machine = false; #ifdef CONFIG_MMU + +static inline bool is_kernel_exittext(uintptr_t addr) +{ + return system_state < SYSTEM_RUNNING && + addr >= (uintptr_t)__exittext_begin && + addr < (uintptr_t)__exittext_end; +} + /* * The fix_to_virt(, idx) needs a const value (not a dynamic variable of * reg-a0) or BUILD_BUG_ON failed with "idx >= __end_of_fixed_addresses". @@ -34,7 +43,7 @@ uintptr_t uintaddr = (uintptr_t) addr; struct page *page; - if (core_kernel_text(uintaddr)) + if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) page = phys_to_page(__pa_symbol(addr)); else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) page = vmalloc_to_page(addr); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/riscv/kernel/pi/cmdline_early.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/kernel/pi/cmdline_early.c @@ -37,8 +37,7 @@ if (IS_ENABLED(CONFIG_CMDLINE_EXTEND) || IS_ENABLED(CONFIG_CMDLINE_FORCE) || fdt_cmdline_size == 0 /* CONFIG_CMDLINE_FALLBACK */) { - strncat(early_cmdline, CONFIG_CMDLINE, - COMMAND_LINE_SIZE - fdt_cmdline_size); + strlcat(early_cmdline, CONFIG_CMDLINE, COMMAND_LINE_SIZE); } return early_cmdline; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/riscv/kernel/vmlinux-xip.lds.S +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/kernel/vmlinux-xip.lds.S @@ -29,10 +29,12 @@ HEAD_TEXT_SECTION INIT_TEXT_SECTION(PAGE_SIZE) /* we have to discard exit text and such at runtime, not link time */ + __exittext_begin = .; .exit.text : { EXIT_TEXT } + __exittext_end = .; .text : { _text = .; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/riscv/kernel/vmlinux.lds.S +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/kernel/vmlinux.lds.S @@ -69,10 +69,12 @@ __soc_builtin_dtb_table_end = .; } /* we have to discard exit text and such at runtime, not link time */ + __exittext_begin = .; .exit.text : { EXIT_TEXT } + __exittext_end = .; __init_text_end = .; . = ALIGN(SECTION_ALIGN); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/riscv/mm/pageattr.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/riscv/mm/pageattr.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -25,19 +26,6 @@ return new_val; } -static int pageattr_pgd_entry(pgd_t *pgd, unsigned long addr, - unsigned long next, struct mm_walk *walk) -{ - pgd_t val = READ_ONCE(*pgd); - - if (pgd_leaf(val)) { - val = __pgd(set_pageattr_masks(pgd_val(val), walk)); - set_pgd(pgd, val); - } - - return 0; -} - static int pageattr_p4d_entry(p4d_t *p4d, unsigned long addr, unsigned long next, struct mm_walk *walk) { @@ -96,7 +84,6 @@ } static const struct mm_walk_ops pageattr_ops = { - .pgd_entry = pageattr_pgd_entry, .p4d_entry = pageattr_p4d_entry, .pud_entry = pageattr_pud_entry, .pmd_entry = pageattr_pmd_entry, @@ -105,12 +92,181 @@ .walk_lock = PGWALK_RDLOCK, }; +#ifdef CONFIG_64BIT +static int __split_linear_mapping_pmd(pud_t *pudp, + unsigned long vaddr, unsigned long end) +{ + pmd_t *pmdp; + unsigned long next; + + pmdp = pmd_offset(pudp, vaddr); + + do { + next = pmd_addr_end(vaddr, end); + + if (next - vaddr >= PMD_SIZE && + vaddr <= (vaddr & PMD_MASK) && end >= next) + continue; + + if (pmd_leaf(*pmdp)) { + struct page *pte_page; + unsigned long pfn = _pmd_pfn(*pmdp); + pgprot_t prot = __pgprot(pmd_val(*pmdp) & ~_PAGE_PFN_MASK); + pte_t *ptep_new; + int i; + + pte_page = alloc_page(GFP_KERNEL); + if (!pte_page) + return -ENOMEM; + + ptep_new = (pte_t *)page_address(pte_page); + for (i = 0; i < PTRS_PER_PTE; ++i, ++ptep_new) + set_pte(ptep_new, pfn_pte(pfn + i, prot)); + + smp_wmb(); + + set_pmd(pmdp, pfn_pmd(page_to_pfn(pte_page), PAGE_TABLE)); + } + } while (pmdp++, vaddr = next, vaddr != end); + + return 0; +} + +static int __split_linear_mapping_pud(p4d_t *p4dp, + unsigned long vaddr, unsigned long end) +{ + pud_t *pudp; + unsigned long next; + int ret; + + pudp = pud_offset(p4dp, vaddr); + + do { + next = pud_addr_end(vaddr, end); + + if (next - vaddr >= PUD_SIZE && + vaddr <= (vaddr & PUD_MASK) && end >= next) + continue; + + if (pud_leaf(*pudp)) { + struct page *pmd_page; + unsigned long pfn = _pud_pfn(*pudp); + pgprot_t prot = __pgprot(pud_val(*pudp) & ~_PAGE_PFN_MASK); + pmd_t *pmdp_new; + int i; + + pmd_page = alloc_page(GFP_KERNEL); + if (!pmd_page) + return -ENOMEM; + + pmdp_new = (pmd_t *)page_address(pmd_page); + for (i = 0; i < PTRS_PER_PMD; ++i, ++pmdp_new) + set_pmd(pmdp_new, + pfn_pmd(pfn + ((i * PMD_SIZE) >> PAGE_SHIFT), prot)); + + smp_wmb(); + + set_pud(pudp, pfn_pud(page_to_pfn(pmd_page), PAGE_TABLE)); + } + + ret = __split_linear_mapping_pmd(pudp, vaddr, next); + if (ret) + return ret; + } while (pudp++, vaddr = next, vaddr != end); + + return 0; +} + +static int __split_linear_mapping_p4d(pgd_t *pgdp, + unsigned long vaddr, unsigned long end) +{ + p4d_t *p4dp; + unsigned long next; + int ret; + + p4dp = p4d_offset(pgdp, vaddr); + + do { + next = p4d_addr_end(vaddr, end); + + /* + * If [vaddr; end] contains [vaddr & P4D_MASK; next], we don't + * need to split, we'll change the protections on the whole P4D. + */ + if (next - vaddr >= P4D_SIZE && + vaddr <= (vaddr & P4D_MASK) && end >= next) + continue; + + if (p4d_leaf(*p4dp)) { + struct page *pud_page; + unsigned long pfn = _p4d_pfn(*p4dp); + pgprot_t prot = __pgprot(p4d_val(*p4dp) & ~_PAGE_PFN_MASK); + pud_t *pudp_new; + int i; + + pud_page = alloc_page(GFP_KERNEL); + if (!pud_page) + return -ENOMEM; + + /* + * Fill the pud level with leaf puds that have the same + * protections as the leaf p4d. + */ + pudp_new = (pud_t *)page_address(pud_page); + for (i = 0; i < PTRS_PER_PUD; ++i, ++pudp_new) + set_pud(pudp_new, + pfn_pud(pfn + ((i * PUD_SIZE) >> PAGE_SHIFT), prot)); + + /* + * Make sure the pud filling is not reordered with the + * p4d store which could result in seeing a partially + * filled pud level. + */ + smp_wmb(); + + set_p4d(p4dp, pfn_p4d(page_to_pfn(pud_page), PAGE_TABLE)); + } + + ret = __split_linear_mapping_pud(p4dp, vaddr, next); + if (ret) + return ret; + } while (p4dp++, vaddr = next, vaddr != end); + + return 0; +} + +static int __split_linear_mapping_pgd(pgd_t *pgdp, + unsigned long vaddr, + unsigned long end) +{ + unsigned long next; + int ret; + + do { + next = pgd_addr_end(vaddr, end); + /* We never use PGD mappings for the linear mapping */ + ret = __split_linear_mapping_p4d(pgdp, vaddr, next); + if (ret) + return ret; + } while (pgdp++, vaddr = next, vaddr != end); + + return 0; +} + +static int split_linear_mapping(unsigned long start, unsigned long end) +{ + return __split_linear_mapping_pgd(pgd_offset_k(start), start, end); +} +#endif /* CONFIG_64BIT */ + static int __set_memory(unsigned long addr, int numpages, pgprot_t set_mask, pgprot_t clear_mask) { int ret; unsigned long start = addr; unsigned long end = start + PAGE_SIZE * numpages; + unsigned long __maybe_unused lm_start; + unsigned long __maybe_unused lm_end; struct pageattr_masks masks = { .set_mask = set_mask, .clear_mask = clear_mask @@ -120,11 +276,72 @@ return 0; mmap_write_lock(&init_mm); + +#ifdef CONFIG_64BIT + /* + * We are about to change the permissions of a kernel mapping, we must + * apply the same changes to its linear mapping alias, which may imply + * splitting a huge mapping. + */ + + if (is_vmalloc_or_module_addr((void *)start)) { + struct vm_struct *area = NULL; + int i, page_start; + + area = find_vm_area((void *)start); + page_start = (start - (unsigned long)area->addr) >> PAGE_SHIFT; + + for (i = page_start; i < page_start + numpages; ++i) { + lm_start = (unsigned long)page_address(area->pages[i]); + lm_end = lm_start + PAGE_SIZE; + + ret = split_linear_mapping(lm_start, lm_end); + if (ret) + goto unlock; + + ret = walk_page_range_novma(&init_mm, lm_start, lm_end, + &pageattr_ops, NULL, &masks); + if (ret) + goto unlock; + } + } else if (is_kernel_mapping(start) || is_linear_mapping(start)) { + if (is_kernel_mapping(start)) { + lm_start = (unsigned long)lm_alias(start); + lm_end = (unsigned long)lm_alias(end); + } else { + lm_start = start; + lm_end = end; + } + + ret = split_linear_mapping(lm_start, lm_end); + if (ret) + goto unlock; + + ret = walk_page_range_novma(&init_mm, lm_start, lm_end, + &pageattr_ops, NULL, &masks); + if (ret) + goto unlock; + } + + ret = walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL, + &masks); + +unlock: + mmap_write_unlock(&init_mm); + + /* + * We can't use flush_tlb_kernel_range() here as we may have split a + * hugepage that is larger than that, so let's flush everything. + */ + flush_tlb_all(); +#else ret = walk_page_range_novma(&init_mm, start, end, &pageattr_ops, NULL, &masks); + mmap_write_unlock(&init_mm); flush_tlb_kernel_range(start, end); +#endif return ret; } @@ -159,36 +376,14 @@ int set_direct_map_invalid_noflush(struct page *page) { - int ret; - unsigned long start = (unsigned long)page_address(page); - unsigned long end = start + PAGE_SIZE; - struct pageattr_masks masks = { - .set_mask = __pgprot(0), - .clear_mask = __pgprot(_PAGE_PRESENT) - }; - - mmap_read_lock(&init_mm); - ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); - mmap_read_unlock(&init_mm); - - return ret; + return __set_memory((unsigned long)page_address(page), 1, + __pgprot(0), __pgprot(_PAGE_PRESENT)); } int set_direct_map_default_noflush(struct page *page) { - int ret; - unsigned long start = (unsigned long)page_address(page); - unsigned long end = start + PAGE_SIZE; - struct pageattr_masks masks = { - .set_mask = PAGE_KERNEL, - .clear_mask = __pgprot(0) - }; - - mmap_read_lock(&init_mm); - ret = walk_page_range(&init_mm, start, end, &pageattr_ops, &masks); - mmap_read_unlock(&init_mm); - - return ret; + return __set_memory((unsigned long)page_address(page), 1, + PAGE_KERNEL, __pgprot(_PAGE_EXEC)); } #ifdef CONFIG_DEBUG_PAGEALLOC only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/s390/boot/ipl_parm.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/s390/boot/ipl_parm.c @@ -273,7 +273,7 @@ memory_limit = round_down(memparse(val, NULL), PAGE_SIZE); if (!strcmp(param, "vmalloc") && val) { - vmalloc_size = round_up(memparse(val, NULL), PAGE_SIZE); + vmalloc_size = round_up(memparse(val, NULL), _SEGMENT_SIZE); vmalloc_size_set = 1; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/s390/crypto/aes_s390.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/s390/crypto/aes_s390.c @@ -597,7 +597,9 @@ * final block may be < AES_BLOCK_SIZE, copy only nbytes */ if (nbytes) { - cpacf_kmctr(sctx->fc, sctx->key, buf, walk.src.virt.addr, + memset(buf, 0, AES_BLOCK_SIZE); + memcpy(buf, walk.src.virt.addr, nbytes); + cpacf_kmctr(sctx->fc, sctx->key, buf, buf, AES_BLOCK_SIZE, walk.iv); memcpy(walk.dst.virt.addr, buf, nbytes); crypto_inc(walk.iv, AES_BLOCK_SIZE); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/s390/include/asm/irq_work.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/s390/include/asm/irq_work.h @@ -7,6 +7,4 @@ return true; } -void arch_irq_work_raise(void); - #endif /* _ASM_S390_IRQ_WORK_H */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/s390/include/asm/pci_io.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/s390/include/asm/pci_io.h @@ -11,6 +11,8 @@ /* I/O size constraints */ #define ZPCI_MAX_READ_SIZE 8 #define ZPCI_MAX_WRITE_SIZE 128 +#define ZPCI_BOUNDARY_SIZE (1 << 12) +#define ZPCI_BOUNDARY_MASK (ZPCI_BOUNDARY_SIZE - 1) /* I/O Map */ #define ZPCI_IOMAP_SHIFT 48 @@ -125,16 +127,18 @@ int zpci_write_block(volatile void __iomem *dst, const void *src, unsigned long len); -static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max) +static inline int zpci_get_max_io_size(u64 src, u64 dst, int len, int max) { - int count = len > max ? max : len, size = 1; + int offset = dst & ZPCI_BOUNDARY_MASK; + int size; - while (!(src & 0x1) && !(dst & 0x1) && ((size << 1) <= count)) { - dst = dst >> 1; - src = src >> 1; - size = size << 1; - } - return size; + size = min3(len, ZPCI_BOUNDARY_SIZE - offset, max); + if (IS_ALIGNED(src, 8) && IS_ALIGNED(dst, 8) && IS_ALIGNED(size, 8)) + return size; + + if (size >= 8) + return 8; + return rounddown_pow_of_two(size); } static inline int zpci_memcpy_fromio(void *dst, @@ -144,9 +148,9 @@ int size, rc = 0; while (n > 0) { - size = zpci_get_max_write_size((u64 __force) src, - (u64) dst, n, - ZPCI_MAX_READ_SIZE); + size = zpci_get_max_io_size((u64 __force) src, + (u64) dst, n, + ZPCI_MAX_READ_SIZE); rc = zpci_read_single(dst, src, size); if (rc) break; @@ -166,9 +170,9 @@ return -EINVAL; while (n > 0) { - size = zpci_get_max_write_size((u64 __force) dst, - (u64) src, n, - ZPCI_MAX_WRITE_SIZE); + size = zpci_get_max_io_size((u64 __force) dst, + (u64) src, n, + ZPCI_MAX_WRITE_SIZE); if (size > 8) /* main path */ rc = zpci_write_block(dst, src, size); else only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/s390/kernel/ptrace.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/s390/kernel/ptrace.c @@ -385,6 +385,7 @@ /* * floating point control reg. is in the thread structure */ + save_fpu_regs(); if ((unsigned int) data != 0 || test_fp_ctl(data >> (BITS_PER_LONG - 32))) return -EINVAL; @@ -741,6 +742,7 @@ /* * floating point control reg. is in the thread structure */ + save_fpu_regs(); if (test_fp_ctl(tmp)) return -EINVAL; child->thread.fpu.fpc = data; @@ -904,9 +906,7 @@ int rc = 0; freg_t fprs[__NUM_FPRS]; - if (target == current) - save_fpu_regs(); - + save_fpu_regs(); if (MACHINE_HAS_VX) convert_vx_to_fp(fprs, target->thread.fpu.vxrs); else only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/s390/pci/pci_mmio.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/s390/pci/pci_mmio.c @@ -97,9 +97,9 @@ return -EINVAL; while (n > 0) { - size = zpci_get_max_write_size((u64 __force) dst, - (u64 __force) src, n, - ZPCI_MAX_WRITE_SIZE); + size = zpci_get_max_io_size((u64 __force) dst, + (u64 __force) src, n, + ZPCI_MAX_WRITE_SIZE); if (size > 8) /* main path */ rc = __pcistb_mio_inuser(dst, src, size, &status); else @@ -242,9 +242,9 @@ u8 status; while (n > 0) { - size = zpci_get_max_write_size((u64 __force) src, - (u64 __force) dst, n, - ZPCI_MAX_READ_SIZE); + size = zpci_get_max_io_size((u64 __force) src, + (u64 __force) dst, n, + ZPCI_MAX_READ_SIZE); rc = __pcilg_mio_inuser(dst, src, size, &status); if (rc) break; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/um/drivers/net_kern.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/um/drivers/net_kern.c @@ -204,7 +204,7 @@ return 0; } -static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) +static netdev_tx_t uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct uml_net_private *lp = netdev_priv(dev); unsigned long flags; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/um/include/shared/kern_util.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/um/include/shared/kern_util.h @@ -50,7 +50,7 @@ * Are we disallowed to sleep? Used to choose between GFP_KERNEL and * GFP_ATOMIC. */ -extern int __cant_sleep(void); +extern int __uml_cant_sleep(void); extern int get_current_pid(void); extern int copy_from_user_proc(void *to, void *from, int size); extern char *uml_strdup(const char *string); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/um/kernel/process.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/um/kernel/process.c @@ -220,7 +220,7 @@ um_idle_sleep(); } -int __cant_sleep(void) { +int __uml_cant_sleep(void) { return in_atomic() || irqs_disabled() || in_interrupt(); /* Is in_interrupt() really needed? */ } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/um/kernel/time.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/um/kernel/time.c @@ -432,9 +432,29 @@ time_travel_del_event(&ne); } +static void time_travel_update_time_rel(unsigned long long offs) +{ + unsigned long flags; + + /* + * Disable interrupts before calculating the new time so + * that a real timer interrupt (signal) can't happen at + * a bad time e.g. after we read time_travel_time but + * before we've completed updating the time. + */ + local_irq_save(flags); + time_travel_update_time(time_travel_time + offs, false); + local_irq_restore(flags); +} + void time_travel_ndelay(unsigned long nsec) { - time_travel_update_time(time_travel_time + nsec, false); + /* + * Not strictly needed to use _rel() version since this is + * only used in INFCPU/EXT modes, but it doesn't hurt and + * is more readable too. + */ + time_travel_update_time_rel(nsec); } EXPORT_SYMBOL(time_travel_ndelay); @@ -568,7 +588,11 @@ #define time_travel_time 0 #define time_travel_ext_waiting 0 -static inline void time_travel_update_time(unsigned long long ns, bool retearly) +static inline void time_travel_update_time(unsigned long long ns, bool idle) +{ +} + +static inline void time_travel_update_time_rel(unsigned long long offs) { } @@ -720,9 +744,7 @@ */ if (!irqs_disabled() && !in_interrupt() && !in_softirq() && !time_travel_ext_waiting) - time_travel_update_time(time_travel_time + - TIMER_MULTIPLIER, - false); + time_travel_update_time_rel(TIMER_MULTIPLIER); return time_travel_time / TIMER_MULTIPLIER; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/um/os-Linux/helper.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/um/os-Linux/helper.c @@ -46,7 +46,7 @@ unsigned long stack, sp; int pid, fds[2], ret, n; - stack = alloc_stack(0, __cant_sleep()); + stack = alloc_stack(0, __uml_cant_sleep()); if (stack == 0) return -ENOMEM; @@ -70,7 +70,7 @@ data.pre_data = pre_data; data.argv = argv; data.fd = fds[1]; - data.buf = __cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) : + data.buf = __uml_cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) : uml_kmalloc(PATH_MAX, UM_GFP_KERNEL); pid = clone(helper_child, (void *) sp, CLONE_VM, &data); if (pid < 0) { @@ -121,7 +121,7 @@ unsigned long stack, sp; int pid, status, err; - stack = alloc_stack(0, __cant_sleep()); + stack = alloc_stack(0, __uml_cant_sleep()); if (stack == 0) return -ENOMEM; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/um/os-Linux/util.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/um/os-Linux/util.c @@ -173,23 +173,38 @@ "quiet\n" " Turns off information messages during boot.\n\n"); +/* + * The os_info/os_warn functions will be called by helper threads. These + * have a very limited stack size and using the libc formatting functions + * may overflow the stack. + * So pull in the kernel vscnprintf and use that instead with a fixed + * on-stack buffer. + */ +int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); + void os_info(const char *fmt, ...) { + char buf[256]; va_list list; + int len; if (quiet_info) return; va_start(list, fmt); - vfprintf(stderr, fmt, list); + len = vscnprintf(buf, sizeof(buf), fmt, list); + fwrite(buf, len, 1, stderr); va_end(list); } void os_warn(const char *fmt, ...) { + char buf[256]; va_list list; + int len; va_start(list, fmt); - vfprintf(stderr, fmt, list); + len = vscnprintf(buf, sizeof(buf), fmt, list); + fwrite(buf, len, 1, stderr); va_end(list); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/boot/compressed/idt_64.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/boot/compressed/idt_64.c @@ -61,6 +61,7 @@ boot_idt_desc.address = (unsigned long)boot_idt; set_idt_entry(X86_TRAP_PF, boot_page_fault); + set_idt_entry(X86_TRAP_NMI, boot_nmi_trap); #ifdef CONFIG_AMD_MEM_ENCRYPT /* only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/boot/compressed/idt_handlers_64.S +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/boot/compressed/idt_handlers_64.S @@ -70,6 +70,7 @@ .code64 EXCEPTION_HANDLER boot_page_fault do_boot_page_fault error_code=1 +EXCEPTION_HANDLER boot_nmi_trap do_boot_nmi_trap error_code=0 #ifdef CONFIG_AMD_MEM_ENCRYPT EXCEPTION_HANDLER boot_stage1_vc do_vc_no_ghcb error_code=1 only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/boot/compressed/misc.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/boot/compressed/misc.h @@ -199,6 +199,7 @@ /* IDT Entry Points */ void boot_page_fault(void); +void boot_nmi_trap(void); void boot_stage1_vc(void); void boot_stage2_vc(void); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/entry/entry_64.S +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/entry_64.S @@ -116,6 +116,7 @@ /* clobbers %rax, make sure it is after saving the syscall nr */ IBRS_ENTER UNTRAIN_RET + CLEAR_BRANCH_HISTORY call do_syscall_64 /* returns with IRQs disabled */ @@ -1538,3 +1539,63 @@ call make_task_dead SYM_CODE_END(rewind_stack_and_make_dead) .popsection + +/* + * This sequence executes branches in order to remove user branch information + * from the branch history tracker in the Branch Predictor, therefore removing + * user influence on subsequent BTB lookups. + * + * It should be used on parts prior to Alder Lake. Newer parts should use the + * BHI_DIS_S hardware control instead. If a pre-Alder Lake part is being + * virtualized on newer hardware the VMM should protect against BHI attacks by + * setting BHI_DIS_S for the guests. + * + * CALLs/RETs are necessary to prevent Loop Stream Detector(LSD) from engaging + * and not clearing the branch history. The call tree looks like: + * + * call 1 + * call 2 + * call 2 + * call 2 + * call 2 + * call 2 + * ret + * ret + * ret + * ret + * ret + * ret + * + * This means that the stack is non-constant and ORC can't unwind it with %rsp + * alone. Therefore we unconditionally set up the frame pointer, which allows + * ORC to unwind properly. + * + * The alignment is for performance and not for safety, and may be safely + * refactored in the future if needed. + */ +SYM_FUNC_START(clear_bhb_loop) + push %rbp + mov %rsp, %rbp + movl $5, %ecx + ANNOTATE_INTRA_FUNCTION_CALL + call 1f + jmp 5f + .align 64, 0xcc + ANNOTATE_INTRA_FUNCTION_CALL +1: call 2f + RET + .align 64, 0xcc +2: movl $5, %eax +3: jmp 4f + nop +4: sub $1, %eax + jnz 3b + sub $1, %ecx + jnz 1b + RET +5: lfence + pop %rbp + RET +SYM_FUNC_END(clear_bhb_loop) +EXPORT_SYMBOL_GPL(clear_bhb_loop) +STACK_FRAME_NON_STANDARD(clear_bhb_loop) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/entry/syscall_32.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/syscall_32.c @@ -18,8 +18,25 @@ #include #undef __SYSCALL +/* + * The sys_call_table[] is no longer used for system calls, but + * kernel/trace/trace_syscalls.c still wants to know the system + * call address. + */ +#ifdef CONFIG_X86_32 #define __SYSCALL(nr, sym) __ia32_##sym, - -__visible const sys_call_ptr_t ia32_sys_call_table[] = { +const sys_call_ptr_t sys_call_table[] = { #include }; +#undef __SYSCALL +#endif + +#define __SYSCALL(nr, sym) case nr: return __ia32_##sym(regs); + +long ia32_sys_call(const struct pt_regs *regs, unsigned int nr) +{ + switch (nr) { + #include + default: return __ia32_sys_ni_syscall(regs); + } +}; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/entry/syscall_64.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/syscall_64.c @@ -11,8 +11,23 @@ #include #undef __SYSCALL +/* + * The sys_call_table[] is no longer used for system calls, but + * kernel/trace/trace_syscalls.c still wants to know the system + * call address. + */ #define __SYSCALL(nr, sym) __x64_##sym, - -asmlinkage const sys_call_ptr_t sys_call_table[] = { +const sys_call_ptr_t sys_call_table[] = { #include }; +#undef __SYSCALL + +#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs); + +long x64_sys_call(const struct pt_regs *regs, unsigned int nr) +{ + switch (nr) { + #include + default: return __x64_sys_ni_syscall(regs); + } +}; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/entry/syscall_x32.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/entry/syscall_x32.c @@ -11,8 +11,12 @@ #include #undef __SYSCALL -#define __SYSCALL(nr, sym) __x64_##sym, +#define __SYSCALL(nr, sym) case nr: return __x64_##sym(regs); -asmlinkage const sys_call_ptr_t x32_sys_call_table[] = { -#include +long x32_sys_call(const struct pt_regs *regs, unsigned int nr) +{ + switch (nr) { + #include + default: return __x64_sys_ni_syscall(regs); + } }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/include/asm/cpufeatures.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/cpufeatures.h @@ -451,6 +451,17 @@ #define X86_FEATURE_SRSO_NO (20*32+29) /* "" CPU is not affected by SRSO */ /* + * Extended auxiliary flags: Linux defined - for features scattered in various + * CPUID levels like 0x80000022, etc and Linux defined features. + * + * Reuse free bits when adding new feature flags! + */ +#define X86_FEATURE_CLEAR_BHB_LOOP (21*32+ 1) /* "" Clear branch history at syscall entry using SW loop */ +#define X86_FEATURE_BHI_CTRL (21*32+ 2) /* "" BHI_DIS_S HW control available */ +#define X86_FEATURE_CLEAR_BHB_HW (21*32+ 3) /* "" BHI_DIS_S HW control enabled */ +#define X86_FEATURE_CLEAR_BHB_LOOP_ON_VMEXIT (21*32+ 4) /* "" Clear branch history at vmexit using SW loop */ + +/* * BUG word(s) */ #define X86_BUG(x) (NCAPINTS*32 + (x)) @@ -496,4 +507,5 @@ /* BUG word 2 */ #define X86_BUG_SRSO X86_BUG(1*32 + 0) /* AMD SRSO bug */ #define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* AMD DIV0 speculation bug */ +#define X86_BUG_BHI X86_BUG(1*32 + 3) /* CPU is affected by Branch History Injection */ #endif /* _ASM_X86_CPUFEATURES_H */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/include/asm/irq_work.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/irq_work.h @@ -9,7 +9,6 @@ { return boot_cpu_has(X86_FEATURE_APIC); } -extern void arch_irq_work_raise(void); #else static inline bool arch_irq_work_has_interrupt(void) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/include/asm/kmsan.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/kmsan.h @@ -64,6 +64,7 @@ { unsigned long x = (unsigned long)addr; unsigned long y = x - __START_KERNEL_map; + bool ret; /* use the carry flag to determine if x was < __START_KERNEL_map */ if (unlikely(x > y)) { @@ -79,7 +80,21 @@ return false; } - return pfn_valid(x >> PAGE_SHIFT); + /* + * pfn_valid() relies on RCU, and may call into the scheduler on exiting + * the critical section. However, this would result in recursion with + * KMSAN. Therefore, disable preemption here, and re-enable preemption + * below while suppressing reschedules to avoid recursion. + * + * Note, this sacrifices occasionally breaking scheduling guarantees. + * Although, a kernel compiled with KMSAN has already given up on any + * performance guarantees due to being heavily instrumented. + */ + preempt_disable(); + ret = pfn_valid(x >> PAGE_SHIFT); + preempt_enable_no_resched(); + + return ret; } #endif /* !MODULE */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/include/asm/kvm-x86-pmu-ops.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/kvm-x86-pmu-ops.h @@ -22,7 +22,7 @@ KVM_X86_PMU_OP(set_msr) KVM_X86_PMU_OP(refresh) KVM_X86_PMU_OP(init) -KVM_X86_PMU_OP(reset) +KVM_X86_PMU_OP_OPTIONAL(reset) KVM_X86_PMU_OP_OPTIONAL(deliver_pmi) KVM_X86_PMU_OP_OPTIONAL(cleanup) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/include/asm/mwait.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/mwait.h @@ -115,8 +115,15 @@ } __monitor((void *)¤t_thread_info()->flags, 0, 0); - if (!need_resched()) - __mwait(eax, ecx); + + if (!need_resched()) { + if (ecx & 1) { + __mwait(eax, ecx); + } else { + __sti_mwait(eax, ecx); + raw_local_irq_disable(); + } + } } current_clr_polling(); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/include/asm/syscall.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/include/asm/syscall.h @@ -16,19 +16,17 @@ #include /* for TS_COMPAT */ #include +/* This is used purely for kernel/trace/trace_syscalls.c */ typedef long (*sys_call_ptr_t)(const struct pt_regs *); extern const sys_call_ptr_t sys_call_table[]; -#if defined(CONFIG_X86_32) -#define ia32_sys_call_table sys_call_table -#else /* * These may not exist, but still put the prototypes in so we * can use IS_ENABLED(). */ -extern const sys_call_ptr_t ia32_sys_call_table[]; -extern const sys_call_ptr_t x32_sys_call_table[]; -#endif +extern long ia32_sys_call(const struct pt_regs *, unsigned int nr); +extern long x32_sys_call(const struct pt_regs *, unsigned int nr); +extern long x64_sys_call(const struct pt_regs *, unsigned int nr); /* * Only the low 32 bits of orig_ax are meaningful, so we return int. @@ -127,6 +125,7 @@ } void do_syscall_64(struct pt_regs *regs, int nr); +void do_int80_emulation(struct pt_regs *regs); #endif /* CONFIG_X86_32 */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/kernel/cpu/mce/inject.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/mce/inject.c @@ -747,6 +747,7 @@ wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), status); rdmsrl_safe(mca_msr_reg(bank, MCA_STATUS), &status); + wrmsrl_safe(mca_msr_reg(bank, MCA_STATUS), 0); if (!status) { hw_injection_possible = false; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/kernel/cpu/scattered.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/cpu/scattered.c @@ -28,6 +28,7 @@ { X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 }, { X86_FEATURE_INTEL_PPIN, CPUID_EBX, 0, 0x00000007, 1 }, { X86_FEATURE_RRSBA_CTRL, CPUID_EDX, 2, 0x00000007, 2 }, + { X86_FEATURE_BHI_CTRL, CPUID_EDX, 4, 0x00000007, 2 }, { X86_FEATURE_CQM_LLC, CPUID_EDX, 1, 0x0000000f, 0 }, { X86_FEATURE_CQM_OCCUP_LLC, CPUID_EDX, 0, 0x0000000f, 1 }, { X86_FEATURE_CQM_MBM_TOTAL, CPUID_EDX, 1, 0x0000000f, 1 }, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/kernel/hpet.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/hpet.c @@ -1438,7 +1438,7 @@ memset(&curr_time, 0, sizeof(struct rtc_time)); if (hpet_rtc_flags & (RTC_UIE | RTC_AIE)) { - if (unlikely(mc146818_get_time(&curr_time) < 0)) { + if (unlikely(mc146818_get_time(&curr_time, 10) < 0)) { pr_err_ratelimited("unable to read current time from RTC\n"); return IRQ_HANDLED; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/kernel/kvmclock.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/kvmclock.c @@ -24,8 +24,8 @@ static int kvmclock __initdata = 1; static int kvmclock_vsyscall __initdata = 1; -static int msr_kvm_system_time __ro_after_init = MSR_KVM_SYSTEM_TIME; -static int msr_kvm_wall_clock __ro_after_init = MSR_KVM_WALL_CLOCK; +static int msr_kvm_system_time __ro_after_init; +static int msr_kvm_wall_clock __ro_after_init; static u64 kvm_sched_clock_offset __ro_after_init; static int __init parse_no_kvmclock(char *arg) @@ -195,7 +195,8 @@ void kvmclock_disable(void) { - native_write_msr(msr_kvm_system_time, 0, 0); + if (msr_kvm_system_time) + native_write_msr(msr_kvm_system_time, 0, 0); } static void __init kvmclock_init_mem(void) @@ -294,7 +295,10 @@ if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE2)) { msr_kvm_system_time = MSR_KVM_SYSTEM_TIME_NEW; msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK_NEW; - } else if (!kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { + } else if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) { + msr_kvm_system_time = MSR_KVM_SYSTEM_TIME; + msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK; + } else { return; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/kernel/rtc.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kernel/rtc.c @@ -67,7 +67,7 @@ return; } - if (mc146818_get_time(&tm)) { + if (mc146818_get_time(&tm, 1000)) { pr_err("Unable to read current time from RTC\n"); now->tv_sec = now->tv_nsec = 0; return; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/kvm/pmu.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/pmu.c @@ -271,6 +271,24 @@ return true; } +static void pmc_release_perf_event(struct kvm_pmc *pmc) +{ + if (pmc->perf_event) { + perf_event_release_kernel(pmc->perf_event); + pmc->perf_event = NULL; + pmc->current_config = 0; + pmc_to_pmu(pmc)->event_count--; + } +} + +static void pmc_stop_counter(struct kvm_pmc *pmc) +{ + if (pmc->perf_event) { + pmc->counter = pmc_read_counter(pmc); + pmc_release_perf_event(pmc); + } +} + static int filter_cmp(const void *pa, const void *pb, u64 mask) { u64 a = *(u64 *)pa & mask; @@ -662,27 +680,55 @@ return 0; } -/* refresh PMU settings. This function generally is called when underlying - * settings are changed (such as changes of PMU CPUID by guest VMs), which - * should rarely happen. +void kvm_pmu_reset(struct kvm_vcpu *vcpu) +{ + struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); + struct kvm_pmc *pmc; + int i; + + irq_work_sync(&pmu->irq_work); + + pmu->need_cleanup = false; + + bitmap_zero(pmu->reprogram_pmi, X86_PMC_IDX_MAX); + + for_each_set_bit(i, pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX) { + pmc = static_call(kvm_x86_pmu_pmc_idx_to_pmc)(pmu, i); + if (!pmc) + continue; + + pmc_stop_counter(pmc); + pmc->counter = 0; + + if (pmc_is_gp(pmc)) + pmc->eventsel = 0; + } + + pmu->fixed_ctr_ctrl = pmu->global_ctrl = pmu->global_status = 0; + + static_call_cond(kvm_x86_pmu_reset)(vcpu); +} + + +/* + * Refresh the PMU configuration for the vCPU, e.g. if userspace changes CPUID + * and/or PERF_CAPABILITIES. */ void kvm_pmu_refresh(struct kvm_vcpu *vcpu) { if (KVM_BUG_ON(kvm_vcpu_has_run(vcpu), vcpu->kvm)) return; + /* + * Stop/release all existing counters/events before realizing the new + * vPMU model. + */ + kvm_pmu_reset(vcpu); + bitmap_zero(vcpu_to_pmu(vcpu)->all_valid_pmc_idx, X86_PMC_IDX_MAX); static_call(kvm_x86_pmu_refresh)(vcpu); } -void kvm_pmu_reset(struct kvm_vcpu *vcpu) -{ - struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); - - irq_work_sync(&pmu->irq_work); - static_call(kvm_x86_pmu_reset)(vcpu); -} - void kvm_pmu_init(struct kvm_vcpu *vcpu) { struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/kvm/reverse_cpuid.h +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/reverse_cpuid.h @@ -45,6 +45,9 @@ #define X86_FEATURE_AVX_NE_CONVERT KVM_X86_FEATURE(CPUID_7_1_EDX, 5) #define X86_FEATURE_PREFETCHITI KVM_X86_FEATURE(CPUID_7_1_EDX, 14) +/* Intel-defined sub-features, CPUID level 0x00000007:2 (EDX) */ +#define KVM_X86_FEATURE_BHI_CTRL KVM_X86_FEATURE(CPUID_7_2_EDX, 4) + /* CPUID level 0x80000007 (EDX). */ #define KVM_X86_FEATURE_CONSTANT_TSC KVM_X86_FEATURE(CPUID_8000_0007_EDX, 8) @@ -115,6 +118,8 @@ return KVM_X86_FEATURE_CONSTANT_TSC; else if (x86_feature == X86_FEATURE_PERFMON_V2) return KVM_X86_FEATURE_PERFMON_V2; + else if (x86_feature == X86_FEATURE_BHI_CTRL) + return X86_FEATURE_BHI_CTRL; return x86_feature; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/kvm/vmx/vmenter.S +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/kvm/vmx/vmenter.S @@ -272,6 +272,8 @@ call vmx_spec_ctrl_restore_host + CLEAR_BRANCH_HISTORY_VMEXIT + /* Put return value in AX */ mov %_ASM_BX, %_ASM_AX only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/lib/misc.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/lib/misc.c @@ -8,7 +8,7 @@ */ int num_digits(int val) { - int m = 10; + long long m = 10; int d = 1; if (val < 0) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/arch/x86/pci/mmconfig-shared.c +++ linux-lowlatency-hwe-6.5-6.5.0/arch/x86/pci/mmconfig-shared.c @@ -525,6 +525,8 @@ static bool __ref pci_mmcfg_check_reserved(struct device *dev, struct pci_mmcfg_region *cfg, int early) { + struct resource *conflict; + if (!early && !acpi_disabled) { if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, "ACPI motherboard resource")) @@ -542,8 +544,17 @@ &cfg->res); if (is_mmconf_reserved(is_efi_mmio, cfg, dev, - "EfiMemoryMappedIO")) + "EfiMemoryMappedIO")) { + conflict = insert_resource_conflict(&iomem_resource, + &cfg->res); + if (conflict) + pr_warn("MMCONFIG %pR conflicts with %s %pR\n", + &cfg->res, conflict->name, conflict); + else + pr_info("MMCONFIG %pR reserved to work around lack of ACPI motherboard _CRS\n", + &cfg->res); return true; + } } /* only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/block/genhd.c +++ linux-lowlatency-hwe-6.5-6.5.0/block/genhd.c @@ -432,7 +432,9 @@ DISK_MAX_PARTS); disk->minors = DISK_MAX_PARTS; } - if (disk->first_minor + disk->minors > MINORMASK + 1) + if (disk->first_minor > MINORMASK || + disk->minors > MINORMASK + 1 || + disk->first_minor + disk->minors > MINORMASK + 1) goto out_exit_elevator; } else { if (WARN_ON(disk->minors)) @@ -542,6 +544,7 @@ kobject_put(disk->part0->bd_holder_dir); out_del_block_link: sysfs_remove_link(block_depr, dev_name(ddev)); + pm_runtime_set_memalloc_noio(ddev, false); out_device_del: device_del(ddev); out_free_ext_minor: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/block/ioctl.c +++ linux-lowlatency-hwe-6.5-6.5.0/block/ioctl.c @@ -18,7 +18,7 @@ { struct gendisk *disk = bdev->bd_disk; struct blkpg_partition p; - long long start, length; + sector_t start, length; if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -33,14 +33,17 @@ if (op == BLKPG_DEL_PARTITION) return bdev_del_partition(disk, p.pno); + if (p.start < 0 || p.length <= 0 || p.start + p.length < 0) + return -EINVAL; + /* Check that the partition is aligned to the block size */ + if (!IS_ALIGNED(p.start | p.length, bdev_logical_block_size(bdev))) + return -EINVAL; + start = p.start >> SECTOR_SHIFT; length = p.length >> SECTOR_SHIFT; switch (op) { case BLKPG_ADD_PARTITION: - /* check if partition is aligned to blocksize */ - if (p.start & (bdev_logical_block_size(bdev) - 1)) - return -EINVAL; return bdev_add_partition(disk, p.pno, start, length); case BLKPG_RESIZE_PARTITION: return bdev_resize_partition(disk, p.pno, start, length); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/crypto/rsa.c +++ linux-lowlatency-hwe-6.5-6.5.0/crypto/rsa.c @@ -220,6 +220,8 @@ } e_max = mpi_alloc(0); + if (!e_max) + return -ENOMEM; mpi_set_bit(e_max, 256); if (mpi_cmp(e, e_max) >= 0) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/crypto/scompress.c +++ linux-lowlatency-hwe-6.5-6.5.0/crypto/scompress.c @@ -117,6 +117,7 @@ struct crypto_scomp *scomp = *tfm_ctx; void **ctx = acomp_request_ctx(req); struct scomp_scratch *scratch; + unsigned int dlen; int ret; if (!req->src || !req->slen || req->slen > SCOMP_SCRATCH_SIZE) @@ -128,6 +129,8 @@ if (!req->dlen || req->dlen > SCOMP_SCRATCH_SIZE) req->dlen = SCOMP_SCRATCH_SIZE; + dlen = req->dlen; + scratch = raw_cpu_ptr(&scomp_scratch); spin_lock(&scratch->lock); @@ -145,6 +148,9 @@ ret = -ENOMEM; goto out; } + } else if (req->dlen > dlen) { + ret = -ENOSPC; + goto out; } scatterwalk_map_and_copy(scratch->dst, req->dst, 0, req->dlen, 1); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/accel/habanalabs/common/device.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/accel/habanalabs/common/device.c @@ -808,6 +808,9 @@ gaudi2_set_asic_funcs(hdev); strscpy(hdev->asic_name, "GAUDI2B", sizeof(hdev->asic_name)); break; + case ASIC_GAUDI2C: + gaudi2_set_asic_funcs(hdev); + strscpy(hdev->asic_name, "GAUDI2C", sizeof(hdev->asic_name)); break; default: dev_err(hdev->dev, "Unrecognized ASIC type %d\n", only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/accel/habanalabs/common/habanalabs.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/accel/habanalabs/common/habanalabs.h @@ -1220,6 +1220,7 @@ * @ASIC_GAUDI_SEC: Gaudi secured device (HL-2000). * @ASIC_GAUDI2: Gaudi2 device. * @ASIC_GAUDI2B: Gaudi2B device. + * @ASIC_GAUDI2C: Gaudi2C device. */ enum hl_asic_type { ASIC_INVALID, @@ -1228,6 +1229,7 @@ ASIC_GAUDI_SEC, ASIC_GAUDI2, ASIC_GAUDI2B, + ASIC_GAUDI2C, }; struct hl_cs_parser; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/accel/habanalabs/common/habanalabs_drv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/accel/habanalabs/common/habanalabs_drv.c @@ -101,6 +101,9 @@ case REV_ID_B: asic_type = ASIC_GAUDI2B; break; + case REV_ID_C: + asic_type = ASIC_GAUDI2C; + break; default: break; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/accel/habanalabs/common/mmu/mmu.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/accel/habanalabs/common/mmu/mmu.c @@ -596,6 +596,7 @@ break; case ASIC_GAUDI2: case ASIC_GAUDI2B: + case ASIC_GAUDI2C: /* MMUs in Gaudi2 are always host resident */ hl_mmu_v2_hr_set_funcs(hdev, &hdev->mmu_func[MMU_HR_PGT]); break; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/accel/habanalabs/common/sysfs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/accel/habanalabs/common/sysfs.c @@ -251,6 +251,9 @@ case ASIC_GAUDI2B: str = "GAUDI2B"; break; + case ASIC_GAUDI2C: + str = "GAUDI2C"; + break; default: dev_err(hdev->dev, "Unrecognized ASIC type %d\n", hdev->asic_type); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/accel/habanalabs/include/hw_ip/pci/pci_general.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/accel/habanalabs/include/hw_ip/pci/pci_general.h @@ -25,6 +25,7 @@ REV_ID_INVALID = 0x00, REV_ID_A = 0x01, REV_ID_B = 0x02, + REV_ID_C = 0x03 }; #endif /* INCLUDE_PCI_GENERAL_H_ */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/acpi/acpi_extlog.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/acpi_extlog.c @@ -145,9 +145,14 @@ static u32 err_seq; estatus = extlog_elog_entry_check(cpu, bank); - if (estatus == NULL || (mce->kflags & MCE_HANDLED_CEC)) + if (!estatus) return NOTIFY_DONE; + if (mce->kflags & MCE_HANDLED_CEC) { + estatus->block_status = 0; + return NOTIFY_DONE; + } + memcpy(elog_buf, (void *)estatus, ELOG_ENTRY_LEN); /* clear record status to enable BIOS to update it again */ estatus->block_status = 0; @@ -303,9 +308,10 @@ static void __exit extlog_exit(void) { mce_unregister_decode_chain(&extlog_mce_dec); - ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; - if (extlog_l1_addr) + if (extlog_l1_addr) { + ((struct extlog_l1_head *)extlog_l1_addr)->flags &= ~FLAG_OS_OPTIN; acpi_os_unmap_iomem(extlog_l1_addr, l1_size); + } if (elog_addr) acpi_os_unmap_iomem(elog_addr, elog_size); release_mem_region(elog_base, elog_size); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/acpi/acpi_lpit.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/acpi_lpit.c @@ -105,7 +105,7 @@ return; info->frequency = lpit_native->counter_frequency ? - lpit_native->counter_frequency : tsc_khz * 1000; + lpit_native->counter_frequency : mul_u32_u32(tsc_khz, 1000U); if (!info->frequency) info->frequency = 1; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/acpi/acpi_lpss.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/acpi_lpss.c @@ -465,8 +465,9 @@ if (!clk_name) return -ENOMEM; clk = clk_register_fractional_divider(NULL, clk_name, parent, + 0, prv_base, 1, 15, 16, 15, CLK_FRAC_DIVIDER_POWER_OF_TWO_PS, - prv_base, 1, 15, 16, 15, 0, NULL); + NULL); parent = clk_name; clk_name = kasprintf(GFP_KERNEL, "%s-update", devname); @@ -578,6 +579,7 @@ { struct acpi_handle_list dep_devices; acpi_status status; + bool ret = false; int i; if (!acpi_has_method(adev->handle, "_DEP")) @@ -591,11 +593,14 @@ } for (i = 0; i < dep_devices.count; i++) { - if (dep_devices.handles[i] == handle) - return true; + if (dep_devices.handles[i] == handle) { + ret = true; + break; + } } - return false; + acpi_handle_list_free(&dep_devices); + return ret; } static void acpi_lpss_link_consumer(struct device *dev1, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/acpi/utils.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/acpi/utils.c @@ -370,7 +370,8 @@ goto end; } - if (package->package.count > ACPI_MAX_HANDLES) { + list->handles = kcalloc(package->package.count, sizeof(*list->handles), GFP_KERNEL); + if (!list->handles) { kfree(package); return AE_NO_MEMORY; } @@ -399,12 +400,13 @@ acpi_handle_debug(list->handles[i], "Found in reference list\n"); } - end: if (ACPI_FAILURE(status)) { list->count = 0; - //kfree(list->handles); + kfree(list->handles); + list->handles = NULL; } +end: kfree(buffer.pointer); return status; @@ -412,6 +414,61 @@ EXPORT_SYMBOL(acpi_evaluate_reference); +/** + * acpi_handle_list_equal - Check if two ACPI handle lists are the same + * @list1: First list to compare. + * @list2: Second list to compare. + * + * Return true if the given ACPI handle lists are of the same size and + * contain the same ACPI handles in the same order. Otherwise, return false. + */ +bool acpi_handle_list_equal(struct acpi_handle_list *list1, + struct acpi_handle_list *list2) +{ + return list1->count == list2->count && + !memcmp(list1->handles, list2->handles, + list1->count * sizeof(acpi_handle)); +} +EXPORT_SYMBOL_GPL(acpi_handle_list_equal); + +/** + * acpi_handle_list_replace - Replace one ACPI handle list with another + * @dst: ACPI handle list to replace. + * @src: Source ACPI handle list. + * + * Free the handles table in @dst, move the handles table from @src to @dst, + * copy count from @src to @dst and clear @src. + */ +void acpi_handle_list_replace(struct acpi_handle_list *dst, + struct acpi_handle_list *src) +{ + if (dst->count) + kfree(dst->handles); + + dst->count = src->count; + dst->handles = src->handles; + + src->handles = NULL; + src->count = 0; +} +EXPORT_SYMBOL_GPL(acpi_handle_list_replace); + +/** + * acpi_handle_list_free - Free the handles table in an ACPI handle list + * @list: ACPI handle list to free. + * + * Free the handles table in @list and clear its count field. + */ +void acpi_handle_list_free(struct acpi_handle_list *list) +{ + if (!list->count) + return; + + kfree(list->handles); + list->count = 0; +} +EXPORT_SYMBOL_GPL(acpi_handle_list_free); + acpi_status acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/base/arch_numa.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/base/arch_numa.c @@ -144,7 +144,7 @@ unsigned long __per_cpu_offset[NR_CPUS] __read_mostly; EXPORT_SYMBOL(__per_cpu_offset); -static int __init early_cpu_to_node(int cpu) +int __init early_cpu_to_node(int cpu) { return cpu_to_node_map[cpu]; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/base/class.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/base/class.c @@ -215,6 +215,7 @@ return 0; err_out: + lockdep_unregister_key(key); kfree(cp); return error; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/base/node.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/base/node.c @@ -869,11 +869,15 @@ { int error; int cpu; + struct node *node; - node_devices[nid] = kzalloc(sizeof(struct node), GFP_KERNEL); - if (!node_devices[nid]) + node = kzalloc(sizeof(struct node), GFP_KERNEL); + if (!node) return -ENOMEM; + INIT_LIST_HEAD(&node->access_list); + node_devices[nid] = node; + error = register_node(node_devices[nid], nid); /* link cpu under this node */ @@ -882,7 +886,6 @@ register_cpu_under_node(cpu, nid); } - INIT_LIST_HEAD(&node_devices[nid]->access_list); node_init_caches(nid); return error; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/base/power/main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/base/power/main.c @@ -579,7 +579,7 @@ } /** - * device_resume_noirq - Execute a "noirq resume" callback for given device. + * __device_resume_noirq - Execute a "noirq resume" callback for given device. * @dev: Device to handle. * @state: PM transition of the system being carried out. * @async: If true, the device is being resumed asynchronously. @@ -587,7 +587,7 @@ * The driver of @dev will not receive interrupts while this function is being * executed. */ -static int device_resume_noirq(struct device *dev, pm_message_t state, bool async) +static void __device_resume_noirq(struct device *dev, pm_message_t state, bool async) { pm_callback_t callback = NULL; const char *info = NULL; @@ -655,7 +655,13 @@ Out: complete_all(&dev->power.completion); TRACE_RESUME(error); - return error; + + if (error) { + suspend_stats.failed_resume_noirq++; + dpm_save_failed_step(SUSPEND_RESUME_NOIRQ); + dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, state, async ? " async noirq" : " noirq", error); + } } static bool is_async(struct device *dev) @@ -668,11 +674,15 @@ { reinit_completion(&dev->power.completion); - if (is_async(dev)) { - get_device(dev); - async_schedule_dev(func, dev); + if (!is_async(dev)) + return false; + + get_device(dev); + + if (async_schedule_dev_nocall(func, dev)) return true; - } + + put_device(dev); return false; } @@ -680,15 +690,19 @@ static void async_resume_noirq(void *data, async_cookie_t cookie) { struct device *dev = data; - int error; - - error = device_resume_noirq(dev, pm_transition, true); - if (error) - pm_dev_err(dev, pm_transition, " async", error); + __device_resume_noirq(dev, pm_transition, true); put_device(dev); } +static void device_resume_noirq(struct device *dev) +{ + if (dpm_async_fn(dev, async_resume_noirq)) + return; + + __device_resume_noirq(dev, pm_transition, false); +} + static void dpm_noirq_resume_devices(pm_message_t state) { struct device *dev; @@ -698,14 +712,6 @@ mutex_lock(&dpm_list_mtx); pm_transition = state; - /* - * Advanced the async threads upfront, - * in case the starting of async threads is - * delayed by non-async resuming devices. - */ - list_for_each_entry(dev, &dpm_noirq_list, power.entry) - dpm_async_fn(dev, async_resume_noirq); - while (!list_empty(&dpm_noirq_list)) { dev = to_device(dpm_noirq_list.next); get_device(dev); @@ -713,17 +719,7 @@ mutex_unlock(&dpm_list_mtx); - if (!is_async(dev)) { - int error; - - error = device_resume_noirq(dev, state, false); - if (error) { - suspend_stats.failed_resume_noirq++; - dpm_save_failed_step(SUSPEND_RESUME_NOIRQ); - dpm_save_failed_dev(dev_name(dev)); - pm_dev_err(dev, state, " noirq", error); - } - } + device_resume_noirq(dev); put_device(dev); @@ -751,14 +747,14 @@ } /** - * device_resume_early - Execute an "early resume" callback for given device. + * __device_resume_early - Execute an "early resume" callback for given device. * @dev: Device to handle. * @state: PM transition of the system being carried out. * @async: If true, the device is being resumed asynchronously. * * Runtime PM is disabled for @dev while this function is being executed. */ -static int device_resume_early(struct device *dev, pm_message_t state, bool async) +static void __device_resume_early(struct device *dev, pm_message_t state, bool async) { pm_callback_t callback = NULL; const char *info = NULL; @@ -811,21 +807,31 @@ pm_runtime_enable(dev); complete_all(&dev->power.completion); - return error; + + if (error) { + suspend_stats.failed_resume_early++; + dpm_save_failed_step(SUSPEND_RESUME_EARLY); + dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, state, async ? " async early" : " early", error); + } } static void async_resume_early(void *data, async_cookie_t cookie) { struct device *dev = data; - int error; - - error = device_resume_early(dev, pm_transition, true); - if (error) - pm_dev_err(dev, pm_transition, " async", error); + __device_resume_early(dev, pm_transition, true); put_device(dev); } +static void device_resume_early(struct device *dev) +{ + if (dpm_async_fn(dev, async_resume_early)) + return; + + __device_resume_early(dev, pm_transition, false); +} + /** * dpm_resume_early - Execute "early resume" callbacks for all devices. * @state: PM transition of the system being carried out. @@ -839,14 +845,6 @@ mutex_lock(&dpm_list_mtx); pm_transition = state; - /* - * Advanced the async threads upfront, - * in case the starting of async threads is - * delayed by non-async resuming devices. - */ - list_for_each_entry(dev, &dpm_late_early_list, power.entry) - dpm_async_fn(dev, async_resume_early); - while (!list_empty(&dpm_late_early_list)) { dev = to_device(dpm_late_early_list.next); get_device(dev); @@ -854,17 +852,7 @@ mutex_unlock(&dpm_list_mtx); - if (!is_async(dev)) { - int error; - - error = device_resume_early(dev, state, false); - if (error) { - suspend_stats.failed_resume_early++; - dpm_save_failed_step(SUSPEND_RESUME_EARLY); - dpm_save_failed_dev(dev_name(dev)); - pm_dev_err(dev, state, " early", error); - } - } + device_resume_early(dev); put_device(dev); @@ -888,12 +876,12 @@ EXPORT_SYMBOL_GPL(dpm_resume_start); /** - * device_resume - Execute "resume" callbacks for given device. + * __device_resume - Execute "resume" callbacks for given device. * @dev: Device to handle. * @state: PM transition of the system being carried out. * @async: If true, the device is being resumed asynchronously. */ -static int device_resume(struct device *dev, pm_message_t state, bool async) +static void __device_resume(struct device *dev, pm_message_t state, bool async) { pm_callback_t callback = NULL; const char *info = NULL; @@ -975,20 +963,30 @@ TRACE_RESUME(error); - return error; + if (error) { + suspend_stats.failed_resume++; + dpm_save_failed_step(SUSPEND_RESUME); + dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, state, async ? " async" : "", error); + } } static void async_resume(void *data, async_cookie_t cookie) { struct device *dev = data; - int error; - error = device_resume(dev, pm_transition, true); - if (error) - pm_dev_err(dev, pm_transition, " async", error); + __device_resume(dev, pm_transition, true); put_device(dev); } +static void device_resume(struct device *dev) +{ + if (dpm_async_fn(dev, async_resume)) + return; + + __device_resume(dev, pm_transition, false); +} + /** * dpm_resume - Execute "resume" callbacks for non-sysdev devices. * @state: PM transition of the system being carried out. @@ -1008,27 +1006,17 @@ pm_transition = state; async_error = 0; - list_for_each_entry(dev, &dpm_suspended_list, power.entry) - dpm_async_fn(dev, async_resume); - while (!list_empty(&dpm_suspended_list)) { dev = to_device(dpm_suspended_list.next); + get_device(dev); - if (!is_async(dev)) { - int error; - mutex_unlock(&dpm_list_mtx); + mutex_unlock(&dpm_list_mtx); - error = device_resume(dev, state, false); - if (error) { - suspend_stats.failed_resume++; - dpm_save_failed_step(SUSPEND_RESUME); - dpm_save_failed_dev(dev_name(dev)); - pm_dev_err(dev, state, "", error); - } + device_resume(dev); + + mutex_lock(&dpm_list_mtx); - mutex_lock(&dpm_list_mtx); - } if (!list_empty(&dev->power.entry)) list_move_tail(&dev->power.entry, &dpm_prepared_list); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/base/power/trace.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/base/power/trace.c @@ -120,7 +120,7 @@ struct rtc_time time; unsigned int val; - if (mc146818_get_time(&time) < 0) { + if (mc146818_get_time(&time, 1000) < 0) { pr_err("Unable to read current time from RTC\n"); return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/base/swnode.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/base/swnode.c @@ -541,6 +541,9 @@ if (nargs > NR_FWNODE_REFERENCE_ARGS) return -EINVAL; + if (!args) + return 0; + args->fwnode = software_node_get(refnode); args->nargs = nargs; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/block/loop.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/block/loop.c @@ -165,39 +165,37 @@ return get_size(lo->lo_offset, lo->lo_sizelimit, file); } +/* + * We support direct I/O only if lo_offset is aligned with the logical I/O size + * of backing device, and the logical block size of loop is bigger than that of + * the backing device. + */ +static bool lo_bdev_can_use_dio(struct loop_device *lo, + struct block_device *backing_bdev) +{ + unsigned short sb_bsize = bdev_logical_block_size(backing_bdev); + + if (queue_logical_block_size(lo->lo_queue) < sb_bsize) + return false; + if (lo->lo_offset & (sb_bsize - 1)) + return false; + return true; +} + static void __loop_update_dio(struct loop_device *lo, bool dio) { struct file *file = lo->lo_backing_file; - struct address_space *mapping = file->f_mapping; - struct inode *inode = mapping->host; - unsigned short sb_bsize = 0; - unsigned dio_align = 0; + struct inode *inode = file->f_mapping->host; + struct block_device *backing_bdev = NULL; bool use_dio; - if (inode->i_sb->s_bdev) { - sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev); - dio_align = sb_bsize - 1; - } - - /* - * We support direct I/O only if lo_offset is aligned with the - * logical I/O size of backing device, and the logical block - * size of loop is bigger than the backing device's. - * - * TODO: the above condition may be loosed in the future, and - * direct I/O may be switched runtime at that time because most - * of requests in sane applications should be PAGE_SIZE aligned - */ - if (dio) { - if (queue_logical_block_size(lo->lo_queue) >= sb_bsize && - !(lo->lo_offset & dio_align) && - (file->f_mode & FMODE_CAN_ODIRECT)) - use_dio = true; - else - use_dio = false; - } else { - use_dio = false; - } + if (S_ISBLK(inode->i_mode)) + backing_bdev = I_BDEV(inode); + else if (inode->i_sb->s_bdev) + backing_bdev = inode->i_sb->s_bdev; + + use_dio = dio && (file->f_mode & FMODE_CAN_ODIRECT) && + (!backing_bdev || lo_bdev_can_use_dio(lo, backing_bdev)); if (lo->use_dio == use_dio) return; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/block/rnbd/rnbd-srv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/block/rnbd/rnbd-srv.c @@ -585,6 +585,7 @@ { char *full_path; char *a, *b; + int len; full_path = kmalloc(PATH_MAX, GFP_KERNEL); if (!full_path) @@ -596,19 +597,19 @@ */ a = strnstr(dev_search_path, "%SESSNAME%", sizeof(dev_search_path)); if (a) { - int len = a - dev_search_path; + len = a - dev_search_path; len = snprintf(full_path, PATH_MAX, "%.*s/%s/%s", len, dev_search_path, srv_sess->sessname, dev_name); - if (len >= PATH_MAX) { - pr_err("Too long path: %s, %s, %s\n", - dev_search_path, srv_sess->sessname, dev_name); - kfree(full_path); - return ERR_PTR(-EINVAL); - } } else { - snprintf(full_path, PATH_MAX, "%s/%s", - dev_search_path, dev_name); + len = snprintf(full_path, PATH_MAX, "%s/%s", + dev_search_path, dev_name); + } + if (len >= PATH_MAX) { + pr_err("Too long path: %s, %s, %s\n", + dev_search_path, srv_sess->sessname, dev_name); + kfree(full_path); + return ERR_PTR(-EINVAL); } /* eliminitate duplicated slashes */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/bluetooth/btmtkuart.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/bluetooth/btmtkuart.c @@ -337,7 +337,7 @@ return data; } -static int btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) +static void btmtkuart_recv(struct hci_dev *hdev, const u8 *data, size_t count) { struct btmtkuart_dev *bdev = hci_get_drvdata(hdev); const unsigned char *p_left = data, *p_h4; @@ -376,25 +376,20 @@ bt_dev_err(bdev->hdev, "Frame reassembly failed (%d)", err); bdev->rx_skb = NULL; - return err; + return; } sz_left -= sz_h4; p_left += sz_h4; } - - return 0; } static int btmtkuart_receive_buf(struct serdev_device *serdev, const u8 *data, size_t count) { struct btmtkuart_dev *bdev = serdev_device_get_drvdata(serdev); - int err; - err = btmtkuart_recv(bdev->hdev, data, count); - if (err < 0) - return err; + btmtkuart_recv(bdev->hdev, data, count); bdev->hdev->stat.byte_rx += count; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/bluetooth/btnxpuart.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/bluetooth/btnxpuart.c @@ -1227,11 +1227,10 @@ if (IS_ERR(nxpdev->rx_skb)) { int err = PTR_ERR(nxpdev->rx_skb); /* Safe to ignore out-of-sync bootloader signatures */ - if (is_fw_downloading(nxpdev)) - return count; - bt_dev_err(nxpdev->hdev, "Frame reassembly failed (%d)", err); + if (!is_fw_downloading(nxpdev)) + bt_dev_err(nxpdev->hdev, "Frame reassembly failed (%d)", err); nxpdev->rx_skb = NULL; - return err; + return count; } nxpdev->hdev->stat.byte_rx += count; return count; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/bluetooth/hci_qca.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/bluetooth/hci_qca.c @@ -1876,6 +1876,7 @@ static const struct qca_device_data qca_soc_data_qca6390 __maybe_unused = { .soc_type = QCA_QCA6390, .num_vregs = 0, + .capabilities = QCA_CAP_WIDEBAND_SPEECH | QCA_CAP_VALID_LE_STATES, }; static const struct qca_device_data qca_soc_data_wcn6750 __maybe_unused = { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/bus/mhi/ep/main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/bus/mhi/ep/main.c @@ -71,45 +71,77 @@ static int mhi_ep_send_completion_event(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring, struct mhi_ring_element *tre, u32 len, enum mhi_ev_ccs code) { - struct mhi_ring_element event = {}; + struct mhi_ring_element *event; + int ret; + + event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA); + if (!event) + return -ENOMEM; - event.ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(*tre)); - event.dword[0] = MHI_TRE_EV_DWORD0(code, len); - event.dword[1] = MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT); + event->ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(*tre)); + event->dword[0] = MHI_TRE_EV_DWORD0(code, len); + event->dword[1] = MHI_TRE_EV_DWORD1(ring->ch_id, MHI_PKT_TYPE_TX_EVENT); - return mhi_ep_send_event(mhi_cntrl, ring->er_index, &event, MHI_TRE_DATA_GET_BEI(tre)); + ret = mhi_ep_send_event(mhi_cntrl, ring->er_index, event, MHI_TRE_DATA_GET_BEI(tre)); + kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event); + + return ret; } int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state) { - struct mhi_ring_element event = {}; + struct mhi_ring_element *event; + int ret; + + event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA); + if (!event) + return -ENOMEM; + + event->dword[0] = MHI_SC_EV_DWORD0(state); + event->dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT); - event.dword[0] = MHI_SC_EV_DWORD0(state); - event.dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_STATE_CHANGE_EVENT); + ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0); + kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event); - return mhi_ep_send_event(mhi_cntrl, 0, &event, 0); + return ret; } int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type exec_env) { - struct mhi_ring_element event = {}; + struct mhi_ring_element *event; + int ret; + + event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA); + if (!event) + return -ENOMEM; + + event->dword[0] = MHI_EE_EV_DWORD0(exec_env); + event->dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT); - event.dword[0] = MHI_EE_EV_DWORD0(exec_env); - event.dword[1] = MHI_SC_EV_DWORD1(MHI_PKT_TYPE_EE_EVENT); + ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0); + kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event); - return mhi_ep_send_event(mhi_cntrl, 0, &event, 0); + return ret; } static int mhi_ep_send_cmd_comp_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ev_ccs code) { struct mhi_ep_ring *ring = &mhi_cntrl->mhi_cmd->ring; - struct mhi_ring_element event = {}; + struct mhi_ring_element *event; + int ret; + + event = kmem_cache_zalloc(mhi_cntrl->ev_ring_el_cache, GFP_KERNEL | GFP_DMA); + if (!event) + return -ENOMEM; - event.ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(struct mhi_ring_element)); - event.dword[0] = MHI_CC_EV_DWORD0(code); - event.dword[1] = MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT); + event->ptr = cpu_to_le64(ring->rbase + ring->rd_offset * sizeof(struct mhi_ring_element)); + event->dword[0] = MHI_CC_EV_DWORD0(code); + event->dword[1] = MHI_CC_EV_DWORD1(MHI_PKT_TYPE_CMD_COMPLETION_EVENT); - return mhi_ep_send_event(mhi_cntrl, 0, &event, 0); + ret = mhi_ep_send_event(mhi_cntrl, 0, event, 0); + kmem_cache_free(mhi_cntrl->ev_ring_el_cache, event); + + return ret; } static int mhi_ep_process_cmd_ring(struct mhi_ep_ring *ring, struct mhi_ring_element *el) @@ -419,7 +451,7 @@ mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); } else { /* UL channel */ - result.buf_addr = kzalloc(len, GFP_KERNEL); + result.buf_addr = kmem_cache_zalloc(mhi_cntrl->tre_buf_cache, GFP_KERNEL | GFP_DMA); if (!result.buf_addr) return -ENOMEM; @@ -427,7 +459,7 @@ ret = mhi_ep_read_channel(mhi_cntrl, ring, &result, len); if (ret < 0) { dev_err(&mhi_chan->mhi_dev->dev, "Failed to read channel\n"); - kfree(result.buf_addr); + kmem_cache_free(mhi_cntrl->tre_buf_cache, result.buf_addr); return ret; } @@ -439,7 +471,7 @@ /* Read until the ring becomes empty */ } while (!mhi_ep_queue_is_empty(mhi_chan->mhi_dev, DMA_TO_DEVICE)); - kfree(result.buf_addr); + kmem_cache_free(mhi_cntrl->tre_buf_cache, result.buf_addr); } return 0; @@ -748,14 +780,14 @@ if (ret) { dev_err(dev, "Error updating write offset for ring\n"); mutex_unlock(&chan->lock); - kfree(itr); + kmem_cache_free(mhi_cntrl->ring_item_cache, itr); continue; } /* Sanity check to make sure there are elements in the ring */ if (ring->rd_offset == ring->wr_offset) { mutex_unlock(&chan->lock); - kfree(itr); + kmem_cache_free(mhi_cntrl->ring_item_cache, itr); continue; } @@ -767,12 +799,12 @@ dev_err(dev, "Error processing ring for channel (%u): %d\n", ring->ch_id, ret); mutex_unlock(&chan->lock); - kfree(itr); + kmem_cache_free(mhi_cntrl->ring_item_cache, itr); continue; } mutex_unlock(&chan->lock); - kfree(itr); + kmem_cache_free(mhi_cntrl->ring_item_cache, itr); } } @@ -828,7 +860,7 @@ u32 ch_id = ch_idx + i; ring = &mhi_cntrl->mhi_chan[ch_id].ring; - item = kzalloc(sizeof(*item), GFP_ATOMIC); + item = kmem_cache_zalloc(mhi_cntrl->ring_item_cache, GFP_ATOMIC); if (!item) return; @@ -1375,6 +1407,29 @@ goto err_free_ch; } + mhi_cntrl->ev_ring_el_cache = kmem_cache_create("mhi_ep_event_ring_el", + sizeof(struct mhi_ring_element), 0, + SLAB_CACHE_DMA, NULL); + if (!mhi_cntrl->ev_ring_el_cache) { + ret = -ENOMEM; + goto err_free_cmd; + } + + mhi_cntrl->tre_buf_cache = kmem_cache_create("mhi_ep_tre_buf", MHI_EP_DEFAULT_MTU, 0, + SLAB_CACHE_DMA, NULL); + if (!mhi_cntrl->tre_buf_cache) { + ret = -ENOMEM; + goto err_destroy_ev_ring_el_cache; + } + + mhi_cntrl->ring_item_cache = kmem_cache_create("mhi_ep_ring_item", + sizeof(struct mhi_ep_ring_item), 0, + 0, NULL); + if (!mhi_cntrl->ev_ring_el_cache) { + ret = -ENOMEM; + goto err_destroy_tre_buf_cache; + } + INIT_WORK(&mhi_cntrl->state_work, mhi_ep_state_worker); INIT_WORK(&mhi_cntrl->reset_work, mhi_ep_reset_worker); INIT_WORK(&mhi_cntrl->cmd_ring_work, mhi_ep_cmd_ring_worker); @@ -1383,7 +1438,7 @@ mhi_cntrl->wq = alloc_workqueue("mhi_ep_wq", 0, 0); if (!mhi_cntrl->wq) { ret = -ENOMEM; - goto err_free_cmd; + goto err_destroy_ring_item_cache; } INIT_LIST_HEAD(&mhi_cntrl->st_transition_list); @@ -1442,6 +1497,12 @@ ida_free(&mhi_ep_cntrl_ida, mhi_cntrl->index); err_destroy_wq: destroy_workqueue(mhi_cntrl->wq); +err_destroy_ring_item_cache: + kmem_cache_destroy(mhi_cntrl->ring_item_cache); +err_destroy_ev_ring_el_cache: + kmem_cache_destroy(mhi_cntrl->ev_ring_el_cache); +err_destroy_tre_buf_cache: + kmem_cache_destroy(mhi_cntrl->tre_buf_cache); err_free_cmd: kfree(mhi_cntrl->mhi_cmd); err_free_ch: @@ -1463,6 +1524,9 @@ free_irq(mhi_cntrl->irq, mhi_cntrl); + kmem_cache_destroy(mhi_cntrl->tre_buf_cache); + kmem_cache_destroy(mhi_cntrl->ev_ring_el_cache); + kmem_cache_destroy(mhi_cntrl->ring_item_cache); kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_chan); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/bus/mhi/host/main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/bus/mhi/host/main.c @@ -268,7 +268,8 @@ static bool is_valid_ring_ptr(struct mhi_ring *ring, dma_addr_t addr) { - return addr >= ring->iommu_base && addr < ring->iommu_base + ring->len; + return addr >= ring->iommu_base && addr < ring->iommu_base + ring->len && + !(addr & (sizeof(struct mhi_ring_element) - 1)); } int mhi_destroy_device(struct device *dev, void *data) @@ -642,6 +643,8 @@ mhi_del_ring_element(mhi_cntrl, tre_ring); local_rp = tre_ring->rp; + read_unlock_bh(&mhi_chan->lock); + /* notify client */ mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); @@ -667,6 +670,8 @@ kfree(buf_info->cb_buf); } } + + read_lock_bh(&mhi_chan->lock); } break; } /* CC_EOT */ @@ -1123,17 +1128,15 @@ if (unlikely(MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state))) return -EIO; - read_lock_irqsave(&mhi_cntrl->pm_lock, flags); - ret = mhi_is_ring_full(mhi_cntrl, tre_ring); - if (unlikely(ret)) { - ret = -EAGAIN; - goto exit_unlock; - } + if (unlikely(ret)) + return -EAGAIN; ret = mhi_gen_tre(mhi_cntrl, mhi_chan, buf_info, mflags); if (unlikely(ret)) - goto exit_unlock; + return ret; + + read_lock_irqsave(&mhi_cntrl->pm_lock, flags); /* Packet is queued, take a usage ref to exit M3 if necessary * for host->device buffer, balanced put is done on buffer completion @@ -1153,7 +1156,6 @@ if (dir == DMA_FROM_DEVICE) mhi_cntrl->runtime_put(mhi_cntrl); -exit_unlock: read_unlock_irqrestore(&mhi_cntrl->pm_lock, flags); return ret; @@ -1205,6 +1207,9 @@ int eot, eob, chain, bei; int ret; + /* Protect accesses for reading and incrementing WP */ + write_lock_bh(&mhi_chan->lock); + buf_ring = &mhi_chan->buf_ring; tre_ring = &mhi_chan->tre_ring; @@ -1222,8 +1227,10 @@ if (!info->pre_mapped) { ret = mhi_cntrl->map_single(mhi_cntrl, buf_info); - if (ret) + if (ret) { + write_unlock_bh(&mhi_chan->lock); return ret; + } } eob = !!(flags & MHI_EOB); @@ -1240,6 +1247,8 @@ mhi_add_ring_element(mhi_cntrl, tre_ring); mhi_add_ring_element(mhi_cntrl, buf_ring); + write_unlock_bh(&mhi_chan->lock); + return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/char/hw_random/jh7110-trng.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/char/hw_random/jh7110-trng.c @@ -300,7 +300,7 @@ ret = devm_request_irq(&pdev->dev, irq, starfive_trng_irq, 0, pdev->name, (void *)trng); if (ret) - return dev_err_probe(&pdev->dev, irq, + return dev_err_probe(&pdev->dev, ret, "Failed to register interrupt handler\n"); trng->hclk = devm_clk_get(&pdev->dev, "hclk"); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/clk/clk-renesas-pcie.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/clk-renesas-pcie.c @@ -163,7 +163,7 @@ enum rs9_model model = rs9->chip_info->model; if (model == RENESAS_9FGV0241) - return BIT(idx) + 1; + return BIT(idx + 1); else if (model == RENESAS_9FGV0441) return BIT(idx); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/clk/clk-si5341.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/clk-si5341.c @@ -895,10 +895,8 @@ r[0] = r_div ? (r_div & 0xff) : 1; r[1] = (r_div >> 8) & 0xff; r[2] = (r_div >> 16) & 0xff; - err = regmap_bulk_write(output->data->regmap, + return regmap_bulk_write(output->data->regmap, SI5341_OUT_R_REG(output), r, 3); - - return 0; } static int si5341_output_reparent(struct clk_si5341_output *output, u8 index) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/clk/clk-sp7021.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/clk-sp7021.c @@ -604,14 +604,14 @@ int i; clk_base = devm_platform_ioremap_resource(pdev, 0); - if (!clk_base) - return -ENXIO; + if (IS_ERR(clk_base)) + return PTR_ERR(clk_base); pll_base = devm_platform_ioremap_resource(pdev, 1); - if (!pll_base) - return -ENXIO; + if (IS_ERR(pll_base)) + return PTR_ERR(pll_base); sys_base = devm_platform_ioremap_resource(pdev, 2); - if (!sys_base) - return -ENXIO; + if (IS_ERR(sys_base)) + return PTR_ERR(sys_base); /* enable default clks */ for (i = 0; i < ARRAY_SIZE(sp_clken); i++) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/clk/hisilicon/clk-hi3620.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/hisilicon/clk-hi3620.c @@ -467,8 +467,10 @@ return; clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL); - if (!clk_data->clks) + if (!clk_data->clks) { + kfree(clk_data); return; + } for (i = 0; i < num; i++) { struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i]; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/clk/mmp/clk-of-pxa168.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/mmp/clk-of-pxa168.c @@ -306,18 +306,21 @@ pxa_unit->mpmu_base = of_iomap(np, 0); if (!pxa_unit->mpmu_base) { pr_err("failed to map mpmu registers\n"); + kfree(pxa_unit); return; } pxa_unit->apmu_base = of_iomap(np, 1); if (!pxa_unit->apmu_base) { pr_err("failed to map apmu registers\n"); + kfree(pxa_unit); return; } pxa_unit->apbc_base = of_iomap(np, 2); if (!pxa_unit->apbc_base) { pr_err("failed to map apbc registers\n"); + kfree(pxa_unit); return; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/clk/qcom/gcc-sm8550.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/qcom/gcc-sm8550.c @@ -400,7 +400,7 @@ .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -415,7 +415,7 @@ .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -430,7 +430,7 @@ .parent_data = gcc_parent_data_1, .num_parents = ARRAY_SIZE(gcc_parent_data_1), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -450,7 +450,7 @@ .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -470,7 +470,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -485,7 +485,7 @@ .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -500,7 +500,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -520,7 +520,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -535,7 +535,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -550,7 +550,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -565,7 +565,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -580,7 +580,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -595,7 +595,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -610,7 +610,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -625,7 +625,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -640,7 +640,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -655,7 +655,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -670,7 +670,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -699,7 +699,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { @@ -716,7 +716,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { @@ -749,7 +749,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = { @@ -766,7 +766,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { @@ -783,7 +783,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { @@ -800,7 +800,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { @@ -817,7 +817,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { @@ -834,7 +834,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { @@ -851,7 +851,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = { @@ -868,7 +868,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = { @@ -885,7 +885,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = { @@ -902,7 +902,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = { @@ -919,7 +919,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = { @@ -936,7 +936,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap2_s5_clk_src = { @@ -974,7 +974,7 @@ .parent_data = gcc_parent_data_8, .num_parents = ARRAY_SIZE(gcc_parent_data_8), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap2_s6_clk_src = { @@ -991,7 +991,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }; static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = { @@ -1024,7 +1024,7 @@ .parent_data = gcc_parent_data_9, .num_parents = ARRAY_SIZE(gcc_parent_data_9), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -1047,7 +1047,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -1070,7 +1070,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -1092,7 +1092,7 @@ .parent_data = gcc_parent_data_3, .num_parents = ARRAY_SIZE(gcc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -1113,7 +1113,7 @@ .parent_data = gcc_parent_data_4, .num_parents = ARRAY_SIZE(gcc_parent_data_4), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -1135,7 +1135,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -1158,7 +1158,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -1173,7 +1173,7 @@ .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -1188,7 +1188,7 @@ .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_shared_ops, }, }; @@ -2997,38 +2997,46 @@ static struct gdsc pcie_0_gdsc = { .gdscr = 0x6b004, + .collapse_ctrl = 0x52020, + .collapse_mask = BIT(0), .pd = { .name = "pcie_0_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = POLL_CFG_GDSCR, + .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; static struct gdsc pcie_0_phy_gdsc = { .gdscr = 0x6c000, + .collapse_ctrl = 0x52020, + .collapse_mask = BIT(3), .pd = { .name = "pcie_0_phy_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = POLL_CFG_GDSCR, + .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; static struct gdsc pcie_1_gdsc = { .gdscr = 0x8d004, + .collapse_ctrl = 0x52020, + .collapse_mask = BIT(1), .pd = { .name = "pcie_1_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = POLL_CFG_GDSCR, + .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; static struct gdsc pcie_1_phy_gdsc = { .gdscr = 0x8e000, + .collapse_ctrl = 0x52020, + .collapse_mask = BIT(4), .pd = { .name = "pcie_1_phy_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = POLL_CFG_GDSCR, + .flags = VOTABLE | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; static struct gdsc ufs_phy_gdsc = { @@ -3037,7 +3045,7 @@ .name = "ufs_phy_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = POLL_CFG_GDSCR, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; static struct gdsc ufs_mem_phy_gdsc = { @@ -3046,7 +3054,7 @@ .name = "ufs_mem_phy_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = POLL_CFG_GDSCR, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; static struct gdsc usb30_prim_gdsc = { @@ -3055,7 +3063,7 @@ .name = "usb30_prim_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = POLL_CFG_GDSCR, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; static struct gdsc usb3_phy_gdsc = { @@ -3064,7 +3072,7 @@ .name = "usb3_phy_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = POLL_CFG_GDSCR, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, }; static struct clk_regmap *gcc_sm8550_clocks[] = { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/clk/qcom/gpucc-sm8150.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/qcom/gpucc-sm8150.c @@ -37,8 +37,8 @@ .config_ctl_hi_val = 0x00002267, .config_ctl_hi1_val = 0x00000024, .test_ctl_val = 0x00000000, - .test_ctl_hi_val = 0x00000002, - .test_ctl_hi1_val = 0x00000000, + .test_ctl_hi_val = 0x00000000, + .test_ctl_hi1_val = 0x00000020, .user_ctl_val = 0x00000000, .user_ctl_hi_val = 0x00000805, .user_ctl_hi1_val = 0x000000d0, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/clk/qcom/videocc-sm8150.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/qcom/videocc-sm8150.c @@ -33,6 +33,7 @@ .config_ctl_val = 0x20485699, .config_ctl_hi_val = 0x00002267, .config_ctl_hi1_val = 0x00000024, + .test_ctl_hi1_val = 0x00000020, .user_ctl_val = 0x00000000, .user_ctl_hi_val = 0x00000805, .user_ctl_hi1_val = 0x000000D0, @@ -214,6 +215,10 @@ static const struct qcom_reset_map video_cc_sm8150_resets[] = { [VIDEO_CC_MVSC_CORE_CLK_BCR] = { 0x850, 2 }, + [VIDEO_CC_INTERFACE_BCR] = { 0x8f0 }, + [VIDEO_CC_MVS0_BCR] = { 0x870 }, + [VIDEO_CC_MVS1_BCR] = { 0x8b0 }, + [VIDEO_CC_MVSC_BCR] = { 0x810 }, }; static const struct qcom_cc_desc video_cc_sm8150_desc = { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/clk/zynqmp/clk-mux-zynqmp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/zynqmp/clk-mux-zynqmp.c @@ -89,7 +89,7 @@ static const struct clk_ops zynqmp_clk_mux_ops = { .get_parent = zynqmp_clk_mux_get_parent, .set_parent = zynqmp_clk_mux_set_parent, - .determine_rate = __clk_mux_determine_rate, + .determine_rate = __clk_mux_determine_rate_closest, }; static const struct clk_ops zynqmp_clk_mux_ro_ops = { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/clk/zynqmp/divider.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/clk/zynqmp/divider.c @@ -110,52 +110,6 @@ return DIV_ROUND_UP_ULL(parent_rate, value); } -static void zynqmp_get_divider2_val(struct clk_hw *hw, - unsigned long rate, - struct zynqmp_clk_divider *divider, - u32 *bestdiv) -{ - int div1; - int div2; - long error = LONG_MAX; - unsigned long div1_prate; - struct clk_hw *div1_parent_hw; - struct zynqmp_clk_divider *pdivider; - struct clk_hw *div2_parent_hw = clk_hw_get_parent(hw); - - if (!div2_parent_hw) - return; - - pdivider = to_zynqmp_clk_divider(div2_parent_hw); - if (!pdivider) - return; - - div1_parent_hw = clk_hw_get_parent(div2_parent_hw); - if (!div1_parent_hw) - return; - - div1_prate = clk_hw_get_rate(div1_parent_hw); - *bestdiv = 1; - for (div1 = 1; div1 <= pdivider->max_div;) { - for (div2 = 1; div2 <= divider->max_div;) { - long new_error = ((div1_prate / div1) / div2) - rate; - - if (abs(new_error) < abs(error)) { - *bestdiv = div2; - error = new_error; - } - if (divider->flags & CLK_DIVIDER_POWER_OF_TWO) - div2 = div2 << 1; - else - div2++; - } - if (pdivider->flags & CLK_DIVIDER_POWER_OF_TWO) - div1 = div1 << 1; - else - div1++; - } -} - /** * zynqmp_clk_divider_round_rate() - Round rate of divider clock * @hw: handle between common and hardware-specific interfaces @@ -174,6 +128,7 @@ u32 div_type = divider->div_type; u32 bestdiv; int ret; + u8 width; /* if read only, just return current value */ if (divider->flags & CLK_DIVIDER_READ_ONLY) { @@ -193,23 +148,12 @@ return DIV_ROUND_UP_ULL((u64)*prate, bestdiv); } - bestdiv = zynqmp_divider_get_val(*prate, rate, divider->flags); - - /* - * In case of two divisors, compute best divider values and return - * divider2 value based on compute value. div1 will be automatically - * set to optimum based on required total divider value. - */ - if (div_type == TYPE_DIV2 && - (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) { - zynqmp_get_divider2_val(hw, rate, divider, &bestdiv); - } + width = fls(divider->max_div); - if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac) - bestdiv = rate % *prate ? 1 : bestdiv; + rate = divider_round_rate(hw, rate, prate, NULL, width, divider->flags); - bestdiv = min_t(u32, bestdiv, divider->max_div); - *prate = rate * bestdiv; + if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && (rate % *prate)) + *prate = rate; return rate; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/cpufreq/scmi-cpufreq.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/cpufreq/scmi-cpufreq.c @@ -310,8 +310,11 @@ #ifdef CONFIG_COMMON_CLK /* dummy clock provider as needed by OPP if clocks property is used */ - if (of_property_present(dev->of_node, "#clock-cells")) - devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); + if (of_property_present(dev->of_node, "#clock-cells")) { + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, NULL); + if (ret) + return dev_err_probe(dev, ret, "%s: registering clock provider failed\n", __func__); + } #endif ret = cpufreq_register_driver(&scmi_cpufreq_driver); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/cpuidle/cpuidle-haltpoll.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/cpuidle/cpuidle-haltpoll.c @@ -25,13 +25,12 @@ static struct cpuidle_device __percpu *haltpoll_cpuidle_devices; static enum cpuhp_state haltpoll_hp_state; -static int default_enter_idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index) +static __cpuidle int default_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) { - if (current_clr_polling_and_test()) { - local_irq_enable(); + if (current_clr_polling_and_test()) return index; - } + arch_cpu_idle(); return index; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/crypto/ccp/ccp-ops.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/ccp/ccp-ops.c @@ -179,8 +179,11 @@ wa->dma.address = dma_map_single(wa->dev, wa->address, len, dir); - if (dma_mapping_error(wa->dev, wa->dma.address)) + if (dma_mapping_error(wa->dev, wa->dma.address)) { + kfree(wa->address); + wa->address = NULL; return -ENOMEM; + } wa->dma.length = len; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/crypto/hisilicon/sec2/sec.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/sec2/sec.h @@ -220,6 +220,13 @@ SEC_CORE4_ALG_BITMAP_HIGH, }; +enum sec_cap_reg_record_idx { + SEC_DRV_ALG_BITMAP_LOW_IDX = 0x0, + SEC_DRV_ALG_BITMAP_HIGH_IDX, + SEC_DEV_ALG_BITMAP_LOW_IDX, + SEC_DEV_ALG_BITMAP_HIGH_IDX, +}; + void sec_destroy_qps(struct hisi_qp **qps, int qp_num); struct hisi_qp **sec_create_qps(void); int sec_register_to_crypto(struct hisi_qm *qm); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -2543,8 +2543,12 @@ int sec_register_to_crypto(struct hisi_qm *qm) { - u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW); - int ret; + u64 alg_mask; + int ret = 0; + + alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX, + SEC_DRV_ALG_BITMAP_LOW_IDX); + ret = sec_register_skcipher(alg_mask); if (ret) @@ -2559,7 +2563,10 @@ void sec_unregister_from_crypto(struct hisi_qm *qm) { - u64 alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH, SEC_DRV_ALG_BITMAP_LOW); + u64 alg_mask; + + alg_mask = sec_get_alg_bitmap(qm, SEC_DRV_ALG_BITMAP_HIGH_IDX, + SEC_DRV_ALG_BITMAP_LOW_IDX); sec_unregister_aead(alg_mask, ARRAY_SIZE(sec_aeads)); sec_unregister_skcipher(alg_mask, ARRAY_SIZE(sec_skciphers)); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/crypto/inside-secure/safexcel_cipher.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/inside-secure/safexcel_cipher.c @@ -742,9 +742,9 @@ max(totlen_src, totlen_dst)); return -EINVAL; } - if (sreq->nr_src > 0) - dma_map_sg(priv->dev, src, sreq->nr_src, - DMA_BIDIRECTIONAL); + if (sreq->nr_src > 0 && + !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL)) + return -EIO; } else { if (unlikely(totlen_src && (sreq->nr_src <= 0))) { dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!", @@ -752,8 +752,9 @@ return -EINVAL; } - if (sreq->nr_src > 0) - dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE); + if (sreq->nr_src > 0 && + !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE)) + return -EIO; if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) { dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!", @@ -762,9 +763,11 @@ goto unmap; } - if (sreq->nr_dst > 0) - dma_map_sg(priv->dev, dst, sreq->nr_dst, - DMA_FROM_DEVICE); + if (sreq->nr_dst > 0 && + !dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE)) { + ret = -EIO; + goto unmap; + } } memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/crypto/marvell/octeontx2/otx2_cptlf.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/marvell/octeontx2/otx2_cptlf.c @@ -419,8 +419,8 @@ return 0; free_iq: - otx2_cpt_free_instruction_queues(lfs); cptlf_hw_cleanup(lfs); + otx2_cpt_free_instruction_queues(lfs); detach_rsrcs: otx2_cpt_detach_rsrcs_msg(lfs); clear_lfs_num: @@ -431,11 +431,13 @@ void otx2_cptlf_shutdown(struct otx2_cptlfs_info *lfs) { - lfs->lfs_num = 0; /* Cleanup LFs hardware side */ cptlf_hw_cleanup(lfs); + /* Free instruction queues */ + otx2_cpt_free_instruction_queues(lfs); /* Send request to detach LFs */ otx2_cpt_detach_rsrcs_msg(lfs); + lfs->lfs_num = 0; } EXPORT_SYMBOL_NS_GPL(otx2_cptlf_shutdown, CRYPTO_DEV_OCTEONTX2_CPT); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c @@ -249,8 +249,11 @@ otx2_cptlf_unregister_interrupts(lfs); /* Cleanup LFs software side */ lf_sw_cleanup(lfs); + /* Free instruction queues */ + otx2_cpt_free_instruction_queues(lfs); /* Send request to detach LFs */ otx2_cpt_detach_rsrcs_msg(lfs); + lfs->lfs_num = 0; } static int cptvf_lf_init(struct otx2_cptvf_dev *cptvf) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/crypto/sa2ul.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/sa2ul.c @@ -1868,9 +1868,8 @@ crypto_aead_set_flags(ctx->fallback.aead, crypto_aead_get_flags(authenc) & CRYPTO_TFM_REQ_MASK); - crypto_aead_setkey(ctx->fallback.aead, key, keylen); - return 0; + return crypto_aead_setkey(ctx->fallback.aead, key, keylen); } static int sa_aead_setauthsize(struct crypto_aead *tfm, unsigned int authsize) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/crypto/sahara.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/sahara.c @@ -44,7 +44,6 @@ #define FLAGS_MODE_MASK 0x000f #define FLAGS_ENCRYPT BIT(0) #define FLAGS_CBC BIT(1) -#define FLAGS_NEW_KEY BIT(3) #define SAHARA_HDR_BASE 0x00800000 #define SAHARA_HDR_SKHA_ALG_AES 0 @@ -142,8 +141,6 @@ }; struct sahara_ctx { - unsigned long flags; - /* AES-specific context */ int keylen; u8 key[AES_KEYSIZE_128]; @@ -152,6 +149,7 @@ struct sahara_aes_reqctx { unsigned long mode; + u8 iv_out[AES_BLOCK_SIZE]; struct skcipher_request fallback_req; // keep at the end }; @@ -447,27 +445,24 @@ int ret; int i, j; int idx = 0; + u32 len; - /* Copy new key if necessary */ - if (ctx->flags & FLAGS_NEW_KEY) { - memcpy(dev->key_base, ctx->key, ctx->keylen); - ctx->flags &= ~FLAGS_NEW_KEY; - - if (dev->flags & FLAGS_CBC) { - dev->hw_desc[idx]->len1 = AES_BLOCK_SIZE; - dev->hw_desc[idx]->p1 = dev->iv_phys_base; - } else { - dev->hw_desc[idx]->len1 = 0; - dev->hw_desc[idx]->p1 = 0; - } - dev->hw_desc[idx]->len2 = ctx->keylen; - dev->hw_desc[idx]->p2 = dev->key_phys_base; - dev->hw_desc[idx]->next = dev->hw_phys_desc[1]; - - dev->hw_desc[idx]->hdr = sahara_aes_key_hdr(dev); + memcpy(dev->key_base, ctx->key, ctx->keylen); - idx++; + if (dev->flags & FLAGS_CBC) { + dev->hw_desc[idx]->len1 = AES_BLOCK_SIZE; + dev->hw_desc[idx]->p1 = dev->iv_phys_base; + } else { + dev->hw_desc[idx]->len1 = 0; + dev->hw_desc[idx]->p1 = 0; } + dev->hw_desc[idx]->len2 = ctx->keylen; + dev->hw_desc[idx]->p2 = dev->key_phys_base; + dev->hw_desc[idx]->next = dev->hw_phys_desc[1]; + dev->hw_desc[idx]->hdr = sahara_aes_key_hdr(dev); + + idx++; + dev->nb_in_sg = sg_nents_for_len(dev->in_sg, dev->total); if (dev->nb_in_sg < 0) { @@ -489,24 +484,27 @@ DMA_TO_DEVICE); if (!ret) { dev_err(dev->device, "couldn't map in sg\n"); - goto unmap_in; + return -EINVAL; } + ret = dma_map_sg(dev->device, dev->out_sg, dev->nb_out_sg, DMA_FROM_DEVICE); if (!ret) { dev_err(dev->device, "couldn't map out sg\n"); - goto unmap_out; + goto unmap_in; } /* Create input links */ dev->hw_desc[idx]->p1 = dev->hw_phys_link[0]; sg = dev->in_sg; + len = dev->total; for (i = 0; i < dev->nb_in_sg; i++) { - dev->hw_link[i]->len = sg->length; + dev->hw_link[i]->len = min(len, sg->length); dev->hw_link[i]->p = sg->dma_address; if (i == (dev->nb_in_sg - 1)) { dev->hw_link[i]->next = 0; } else { + len -= min(len, sg->length); dev->hw_link[i]->next = dev->hw_phys_link[i + 1]; sg = sg_next(sg); } @@ -515,12 +513,14 @@ /* Create output links */ dev->hw_desc[idx]->p2 = dev->hw_phys_link[i]; sg = dev->out_sg; + len = dev->total; for (j = i; j < dev->nb_out_sg + i; j++) { - dev->hw_link[j]->len = sg->length; + dev->hw_link[j]->len = min(len, sg->length); dev->hw_link[j]->p = sg->dma_address; if (j == (dev->nb_out_sg + i - 1)) { dev->hw_link[j]->next = 0; } else { + len -= min(len, sg->length); dev->hw_link[j]->next = dev->hw_phys_link[j + 1]; sg = sg_next(sg); } @@ -539,9 +539,6 @@ return 0; -unmap_out: - dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, - DMA_FROM_DEVICE); unmap_in: dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, DMA_TO_DEVICE); @@ -549,8 +546,24 @@ return -EINVAL; } +static void sahara_aes_cbc_update_iv(struct skcipher_request *req) +{ + struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); + struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); + unsigned int ivsize = crypto_skcipher_ivsize(skcipher); + + /* Update IV buffer to contain the last ciphertext block */ + if (rctx->mode & FLAGS_ENCRYPT) { + sg_pcopy_to_buffer(req->dst, sg_nents(req->dst), req->iv, + ivsize, req->cryptlen - ivsize); + } else { + memcpy(req->iv, rctx->iv_out, ivsize); + } +} + static int sahara_aes_process(struct skcipher_request *req) { + struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); struct sahara_dev *dev = dev_ptr; struct sahara_ctx *ctx; struct sahara_aes_reqctx *rctx; @@ -572,8 +585,17 @@ rctx->mode &= FLAGS_MODE_MASK; dev->flags = (dev->flags & ~FLAGS_MODE_MASK) | rctx->mode; - if ((dev->flags & FLAGS_CBC) && req->iv) - memcpy(dev->iv_base, req->iv, AES_KEYSIZE_128); + if ((dev->flags & FLAGS_CBC) && req->iv) { + unsigned int ivsize = crypto_skcipher_ivsize(skcipher); + + memcpy(dev->iv_base, req->iv, ivsize); + + if (!(dev->flags & FLAGS_ENCRYPT)) { + sg_pcopy_to_buffer(req->src, sg_nents(req->src), + rctx->iv_out, ivsize, + req->cryptlen - ivsize); + } + } /* assign new context to device */ dev->ctx = ctx; @@ -586,16 +608,20 @@ timeout = wait_for_completion_timeout(&dev->dma_completion, msecs_to_jiffies(SAHARA_TIMEOUT_MS)); - if (!timeout) { - dev_err(dev->device, "AES timeout\n"); - return -ETIMEDOUT; - } dma_unmap_sg(dev->device, dev->out_sg, dev->nb_out_sg, DMA_FROM_DEVICE); dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, DMA_TO_DEVICE); + if (!timeout) { + dev_err(dev->device, "AES timeout\n"); + return -ETIMEDOUT; + } + + if ((dev->flags & FLAGS_CBC) && req->iv) + sahara_aes_cbc_update_iv(req); + return 0; } @@ -609,7 +635,6 @@ /* SAHARA only supports 128bit keys */ if (keylen == AES_KEYSIZE_128) { memcpy(ctx->key, key, keylen); - ctx->flags |= FLAGS_NEW_KEY; return 0; } @@ -625,12 +650,40 @@ return crypto_skcipher_setkey(ctx->fallback, key, keylen); } +static int sahara_aes_fallback(struct skcipher_request *req, unsigned long mode) +{ + struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); + struct sahara_ctx *ctx = crypto_skcipher_ctx( + crypto_skcipher_reqtfm(req)); + + skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); + skcipher_request_set_callback(&rctx->fallback_req, + req->base.flags, + req->base.complete, + req->base.data); + skcipher_request_set_crypt(&rctx->fallback_req, req->src, + req->dst, req->cryptlen, req->iv); + + if (mode & FLAGS_ENCRYPT) + return crypto_skcipher_encrypt(&rctx->fallback_req); + + return crypto_skcipher_decrypt(&rctx->fallback_req); +} + static int sahara_aes_crypt(struct skcipher_request *req, unsigned long mode) { struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); + struct sahara_ctx *ctx = crypto_skcipher_ctx( + crypto_skcipher_reqtfm(req)); struct sahara_dev *dev = dev_ptr; int err = 0; + if (!req->cryptlen) + return 0; + + if (unlikely(ctx->keylen != AES_KEYSIZE_128)) + return sahara_aes_fallback(req, mode); + dev_dbg(dev->device, "nbytes: %d, enc: %d, cbc: %d\n", req->cryptlen, !!(mode & FLAGS_ENCRYPT), !!(mode & FLAGS_CBC)); @@ -653,81 +706,21 @@ static int sahara_aes_ecb_encrypt(struct skcipher_request *req) { - struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); - struct sahara_ctx *ctx = crypto_skcipher_ctx( - crypto_skcipher_reqtfm(req)); - - if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { - skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); - skcipher_request_set_callback(&rctx->fallback_req, - req->base.flags, - req->base.complete, - req->base.data); - skcipher_request_set_crypt(&rctx->fallback_req, req->src, - req->dst, req->cryptlen, req->iv); - return crypto_skcipher_encrypt(&rctx->fallback_req); - } - return sahara_aes_crypt(req, FLAGS_ENCRYPT); } static int sahara_aes_ecb_decrypt(struct skcipher_request *req) { - struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); - struct sahara_ctx *ctx = crypto_skcipher_ctx( - crypto_skcipher_reqtfm(req)); - - if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { - skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); - skcipher_request_set_callback(&rctx->fallback_req, - req->base.flags, - req->base.complete, - req->base.data); - skcipher_request_set_crypt(&rctx->fallback_req, req->src, - req->dst, req->cryptlen, req->iv); - return crypto_skcipher_decrypt(&rctx->fallback_req); - } - return sahara_aes_crypt(req, 0); } static int sahara_aes_cbc_encrypt(struct skcipher_request *req) { - struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); - struct sahara_ctx *ctx = crypto_skcipher_ctx( - crypto_skcipher_reqtfm(req)); - - if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { - skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); - skcipher_request_set_callback(&rctx->fallback_req, - req->base.flags, - req->base.complete, - req->base.data); - skcipher_request_set_crypt(&rctx->fallback_req, req->src, - req->dst, req->cryptlen, req->iv); - return crypto_skcipher_encrypt(&rctx->fallback_req); - } - return sahara_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC); } static int sahara_aes_cbc_decrypt(struct skcipher_request *req) { - struct sahara_aes_reqctx *rctx = skcipher_request_ctx(req); - struct sahara_ctx *ctx = crypto_skcipher_ctx( - crypto_skcipher_reqtfm(req)); - - if (unlikely(ctx->keylen != AES_KEYSIZE_128)) { - skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback); - skcipher_request_set_callback(&rctx->fallback_req, - req->base.flags, - req->base.complete, - req->base.data); - skcipher_request_set_crypt(&rctx->fallback_req, req->src, - req->dst, req->cryptlen, req->iv); - return crypto_skcipher_decrypt(&rctx->fallback_req); - } - return sahara_aes_crypt(req, FLAGS_CBC); } @@ -784,6 +777,7 @@ int start) { struct scatterlist *sg; + unsigned int len; unsigned int i; int ret; @@ -805,12 +799,14 @@ if (!ret) return -EFAULT; + len = rctx->total; for (i = start; i < dev->nb_in_sg + start; i++) { - dev->hw_link[i]->len = sg->length; + dev->hw_link[i]->len = min(len, sg->length); dev->hw_link[i]->p = sg->dma_address; if (i == (dev->nb_in_sg + start - 1)) { dev->hw_link[i]->next = 0; } else { + len -= min(len, sg->length); dev->hw_link[i]->next = dev->hw_phys_link[i + 1]; sg = sg_next(sg); } @@ -891,24 +887,6 @@ return 0; } -static int sahara_walk_and_recalc(struct scatterlist *sg, unsigned int nbytes) -{ - if (!sg || !sg->length) - return nbytes; - - while (nbytes && sg) { - if (nbytes <= sg->length) { - sg->length = nbytes; - sg_mark_end(sg); - break; - } - nbytes -= sg->length; - sg = sg_next(sg); - } - - return nbytes; -} - static int sahara_sha_prepare_request(struct ahash_request *req) { struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); @@ -945,36 +923,20 @@ hash_later, 0); } - /* nbytes should now be multiple of blocksize */ - req->nbytes = req->nbytes - hash_later; - - sahara_walk_and_recalc(req->src, req->nbytes); - + rctx->total = len - hash_later; /* have data from previous operation and current */ if (rctx->buf_cnt && req->nbytes) { sg_init_table(rctx->in_sg_chain, 2); sg_set_buf(rctx->in_sg_chain, rctx->rembuf, rctx->buf_cnt); - sg_chain(rctx->in_sg_chain, 2, req->src); - - rctx->total = req->nbytes + rctx->buf_cnt; rctx->in_sg = rctx->in_sg_chain; - - req->src = rctx->in_sg_chain; /* only data from previous operation */ } else if (rctx->buf_cnt) { - if (req->src) - rctx->in_sg = req->src; - else - rctx->in_sg = rctx->in_sg_chain; - /* buf was copied into rembuf above */ + rctx->in_sg = rctx->in_sg_chain; sg_init_one(rctx->in_sg, rctx->rembuf, rctx->buf_cnt); - rctx->total = rctx->buf_cnt; /* no data from previous operation */ } else { rctx->in_sg = req->src; - rctx->total = req->nbytes; - req->src = rctx->in_sg; } /* on next call, we only have the remaining data in the buffer */ @@ -995,7 +957,10 @@ return ret; if (rctx->first) { - sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0); + ret = sahara_sha_hw_data_descriptor_create(dev, rctx, req, 0); + if (ret) + return ret; + dev->hw_desc[0]->next = 0; rctx->first = 0; } else { @@ -1003,7 +968,10 @@ sahara_sha_hw_context_descriptor_create(dev, rctx, req, 0); dev->hw_desc[0]->next = dev->hw_phys_desc[1]; - sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1); + ret = sahara_sha_hw_data_descriptor_create(dev, rctx, req, 1); + if (ret) + return ret; + dev->hw_desc[1]->next = 0; } @@ -1016,18 +984,19 @@ timeout = wait_for_completion_timeout(&dev->dma_completion, msecs_to_jiffies(SAHARA_TIMEOUT_MS)); - if (!timeout) { - dev_err(dev->device, "SHA timeout\n"); - return -ETIMEDOUT; - } if (rctx->sg_in_idx) dma_unmap_sg(dev->device, dev->in_sg, dev->nb_in_sg, DMA_TO_DEVICE); + if (!timeout) { + dev_err(dev->device, "SHA timeout\n"); + return -ETIMEDOUT; + } + memcpy(rctx->context, dev->context_base, rctx->context_size); - if (req->result) + if (req->result && rctx->last) memcpy(req->result, rctx->context, rctx->digest_size); return 0; @@ -1171,8 +1140,7 @@ static int sahara_sha_cra_init(struct crypto_tfm *tfm) { crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), - sizeof(struct sahara_sha_reqctx) + - SHA_BUFFER_LEN + SHA256_BLOCK_SIZE); + sizeof(struct sahara_sha_reqctx)); return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/crypto/starfive/jh7110-cryp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/starfive/jh7110-cryp.c @@ -150,7 +150,7 @@ ret = devm_request_irq(&pdev->dev, irq, starfive_cryp_irq, 0, pdev->name, (void *)cryp); if (ret) - return dev_err_probe(&pdev->dev, irq, + return dev_err_probe(&pdev->dev, ret, "Failed to register interrupt handler\n"); clk_prepare_enable(cryp->hclk); @@ -162,12 +162,8 @@ spin_unlock(&dev_list.lock); ret = starfive_dma_init(cryp); - if (ret) { - if (ret == -EPROBE_DEFER) - goto err_probe_defer; - else - goto err_dma_init; - } + if (ret) + goto err_dma_init; /* Initialize crypto engine */ cryp->engine = crypto_engine_alloc_init(&pdev->dev, 1); @@ -208,7 +204,7 @@ reset_control_assert(cryp->rst); tasklet_kill(&cryp->hash_done); -err_probe_defer: + return ret; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/crypto/stm32/stm32-crc32.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/crypto/stm32/stm32-crc32.c @@ -104,7 +104,7 @@ struct stm32_crc *crc; spin_lock_bh(&crc_list.lock); - crc = list_first_entry(&crc_list.dev_list, struct stm32_crc, list); + crc = list_first_entry_or_null(&crc_list.dev_list, struct stm32_crc, list); if (crc) list_move_tail(&crc->list, &crc_list.dev_list); spin_unlock_bh(&crc_list.lock); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/dma/dmaengine.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/dma/dmaengine.c @@ -1103,6 +1103,9 @@ static void __dma_async_device_channel_unregister(struct dma_device *device, struct dma_chan *chan) { + if (chan->local == NULL) + return; + WARN_ONCE(!device->device_release && chan->client_count, "%s called while %d clients hold a reference\n", __func__, chan->client_count); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/edac/thunderx_edac.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/edac/thunderx_edac.c @@ -1133,7 +1133,7 @@ decode_register(other, OCX_OTHER_SIZE, ocx_com_errors, ctx->reg_com_int); - strncat(msg, other, OCX_MESSAGE_SIZE); + strlcat(msg, other, OCX_MESSAGE_SIZE); for (lane = 0; lane < OCX_RX_LANES; lane++) if (ctx->reg_com_int & BIT(lane)) { @@ -1142,12 +1142,12 @@ lane, ctx->reg_lane_int[lane], lane, ctx->reg_lane_stat11[lane]); - strncat(msg, other, OCX_MESSAGE_SIZE); + strlcat(msg, other, OCX_MESSAGE_SIZE); decode_register(other, OCX_OTHER_SIZE, ocx_lane_errors, ctx->reg_lane_int[lane]); - strncat(msg, other, OCX_MESSAGE_SIZE); + strlcat(msg, other, OCX_MESSAGE_SIZE); } if (ctx->reg_com_int & OCX_COM_INT_CE) @@ -1217,7 +1217,7 @@ decode_register(other, OCX_OTHER_SIZE, ocx_com_link_errors, ctx->reg_com_link_int); - strncat(msg, other, OCX_MESSAGE_SIZE); + strlcat(msg, other, OCX_MESSAGE_SIZE); if (ctx->reg_com_link_int & OCX_COM_LINK_INT_UE) edac_device_handle_ue(ocx->edac_dev, 0, 0, msg); @@ -1896,7 +1896,7 @@ decode_register(other, L2C_OTHER_SIZE, l2_errors, ctx->reg_int); - strncat(msg, other, L2C_MESSAGE_SIZE); + strlcat(msg, other, L2C_MESSAGE_SIZE); if (ctx->reg_int & mask_ue) edac_device_handle_ue(l2c->edac_dev, 0, 0, msg); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/extcon/extcon.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/extcon/extcon.c @@ -1280,8 +1280,6 @@ edev->id = ret; - dev_set_name(&edev->dev, "extcon%d", edev->id); - ret = extcon_alloc_cables(edev); if (ret < 0) goto err_alloc_cables; @@ -1310,6 +1308,7 @@ RAW_INIT_NOTIFIER_HEAD(&edev->nh_all); dev_set_drvdata(&edev->dev, edev); + dev_set_name(&edev->dev, "extcon%d", edev->id); edev->state = 0; ret = device_register(&edev->dev); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/firmware/arm_scmi/common.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/firmware/arm_scmi/common.h @@ -314,6 +314,7 @@ void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem); bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, struct scmi_xfer *xfer); +bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem); /* declarations for message passing transports */ struct scmi_msg_payld; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/firmware/arm_scmi/mailbox.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/firmware/arm_scmi/mailbox.c @@ -45,6 +45,20 @@ { struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl); + /* + * An A2P IRQ is NOT valid when received while the platform still has + * the ownership of the channel, because the platform at first releases + * the SMT channel and then sends the completion interrupt. + * + * This addresses a possible race condition in which a spurious IRQ from + * a previous timed-out reply which arrived late could be wrongly + * associated with the next pending transaction. + */ + if (cl->knows_txdone && !shmem_channel_free(smbox->shmem)) { + dev_warn(smbox->cinfo->dev, "Ignoring spurious A2P IRQ !\n"); + return; + } + scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem), NULL); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/firmware/arm_scmi/raw_mode.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/firmware/arm_scmi/raw_mode.c @@ -1111,7 +1111,6 @@ int i; for (i = 0; i < num_chans; i++) { - void *xret; struct scmi_raw_queue *q; q = scmi_raw_queue_init(raw); @@ -1120,13 +1119,12 @@ goto err_xa; } - xret = xa_store(&raw->chans_q, channels[i], q, + ret = xa_insert(&raw->chans_q, channels[i], q, GFP_KERNEL); - if (xa_err(xret)) { + if (ret) { dev_err(dev, "Fail to allocate Raw queue 0x%02X\n", channels[i]); - ret = xa_err(xret); goto err_xa; } } @@ -1322,6 +1320,12 @@ dev = raw->handle->dev; q = scmi_raw_queue_select(raw, idx, SCMI_XFER_IS_CHAN_SET(xfer) ? chan_id : 0); + if (!q) { + dev_warn(dev, + "RAW[%d] - NO queue for chan 0x%X. Dropping report.\n", + idx, chan_id); + return; + } /* * Grab the msg_q_lock upfront to avoid a possible race between only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/firmware/arm_scmi/shmem.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/firmware/arm_scmi/shmem.c @@ -122,3 +122,9 @@ (SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR | SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); } + +bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem) +{ + return (ioread32(&shmem->channel_status) & + SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); +} only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/firmware/sysfb.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/firmware/sysfb.c @@ -128,4 +128,4 @@ } /* must execute after PCI subsystem for EFI quirks */ -subsys_initcall_sync(sysfb_init); +device_initcall(sysfb_init); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpio/gpio-eic-sprd.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpio-eic-sprd.c @@ -321,20 +321,27 @@ switch (flow_type) { case IRQ_TYPE_LEVEL_HIGH: sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 1); + sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IC, 1); break; case IRQ_TYPE_LEVEL_LOW: sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 0); + sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IC, 1); break; case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_EDGE_BOTH: state = sprd_eic_get(chip, offset); - if (state) + if (state) { sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 0); - else + sprd_eic_update(chip, offset, + SPRD_EIC_DBNC_IC, 1); + } else { sprd_eic_update(chip, offset, SPRD_EIC_DBNC_IEV, 1); + sprd_eic_update(chip, offset, + SPRD_EIC_DBNC_IC, 1); + } break; default: return -ENOTSUPP; @@ -346,20 +353,27 @@ switch (flow_type) { case IRQ_TYPE_LEVEL_HIGH: sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 0); + sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTCLR, 1); break; case IRQ_TYPE_LEVEL_LOW: sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 1); + sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTCLR, 1); break; case IRQ_TYPE_EDGE_RISING: case IRQ_TYPE_EDGE_FALLING: case IRQ_TYPE_EDGE_BOTH: state = sprd_eic_get(chip, offset); - if (state) + if (state) { sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 0); - else + sprd_eic_update(chip, offset, + SPRD_EIC_LATCH_INTCLR, 1); + } else { sprd_eic_update(chip, offset, SPRD_EIC_LATCH_INTPOL, 1); + sprd_eic_update(chip, offset, + SPRD_EIC_LATCH_INTCLR, 1); + } break; default: return -ENOTSUPP; @@ -373,29 +387,34 @@ sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1); + sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_EDGE_FALLING: sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0); + sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_EDGE_BOTH: sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 1); + sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_LEVEL_HIGH: sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 1); + sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); irq_set_handler_locked(data, handle_level_irq); break; case IRQ_TYPE_LEVEL_LOW: sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTMODE, 1); sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTPOL, 0); + sprd_eic_update(chip, offset, SPRD_EIC_ASYNC_INTCLR, 1); irq_set_handler_locked(data, handle_level_irq); break; default: @@ -408,29 +427,34 @@ sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1); + sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_EDGE_FALLING: sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0); + sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_EDGE_BOTH: sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 1); + sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); irq_set_handler_locked(data, handle_edge_irq); break; case IRQ_TYPE_LEVEL_HIGH: sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 1); + sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); irq_set_handler_locked(data, handle_level_irq); break; case IRQ_TYPE_LEVEL_LOW: sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTBOTH, 0); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTMODE, 1); sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTPOL, 0); + sprd_eic_update(chip, offset, SPRD_EIC_SYNC_INTCLR, 1); irq_set_handler_locked(data, handle_level_irq); break; default: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpio/gpio-mlxbf3.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpio-mlxbf3.c @@ -193,6 +193,8 @@ gs->gpio_clr_io + MLXBF_GPIO_FW_DATA_OUT_CLEAR, gs->gpio_set_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_SET, gs->gpio_clr_io + MLXBF_GPIO_FW_OUTPUT_ENABLE_CLEAR, 0); + if (ret) + return dev_err_probe(dev, ret, "%s: bgpio_init() failed", __func__); gc->request = gpiochip_generic_request; gc->free = gpiochip_generic_free; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpio/gpiolib.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpiolib.c @@ -1007,16 +1007,10 @@ } EXPORT_SYMBOL_GPL(gpiochip_remove); -/** - * gpiochip_find() - iterator for locating a specific gpio_chip - * @data: data to pass to match function - * @match: Callback function to check gpio_chip +/* + * FIXME: This will be removed soon. * - * Similar to bus_find_device. It returns a reference to a gpio_chip as - * determined by a user supplied @match callback. The callback should return - * 0 if the device doesn't match and non-zero if it does. If the callback is - * non-zero, this function will return to the caller and not iterate over any - * more gpio_chips. + * This function is depracated, don't use. */ struct gpio_chip *gpiochip_find(void *data, int (*match)(struct gpio_chip *gc, @@ -1024,21 +1018,62 @@ { struct gpio_device *gdev; struct gpio_chip *gc = NULL; - unsigned long flags; - - spin_lock_irqsave(&gpio_lock, flags); - list_for_each_entry(gdev, &gpio_devices, list) - if (gdev->chip && match(gdev->chip, data)) { - gc = gdev->chip; - break; - } - spin_unlock_irqrestore(&gpio_lock, flags); + gdev = gpio_device_find(data, match); + if (gdev) { + gc = gdev->chip; + gpio_device_put(gdev); + } return gc; } EXPORT_SYMBOL_GPL(gpiochip_find); +/** + * gpio_device_find() - find a specific GPIO device + * @data: data to pass to match function + * @match: Callback function to check gpio_chip + * + * Returns: + * New reference to struct gpio_device. + * + * Similar to bus_find_device(). It returns a reference to a gpio_device as + * determined by a user supplied @match callback. The callback should return + * 0 if the device doesn't match and non-zero if it does. If the callback + * returns non-zero, this function will return to the caller and not iterate + * over any more gpio_devices. + * + * The callback takes the GPIO chip structure as argument. During the execution + * of the callback function the chip is protected from being freed. TODO: This + * actually has yet to be implemented. + * + * If the function returns non-NULL, the returned reference must be freed by + * the caller using gpio_device_put(). + */ +struct gpio_device *gpio_device_find(void *data, + int (*match)(struct gpio_chip *gc, + void *data)) +{ + struct gpio_device *gdev; + + /* + * Not yet but in the future the spinlock below will become a mutex. + * Annotate this function before anyone tries to use it in interrupt + * context like it happened with gpiochip_find(). + */ + might_sleep(); + + guard(spinlock_irqsave)(&gpio_lock); + + list_for_each_entry(gdev, &gpio_devices, list) { + if (gdev->chip && match(gdev->chip, data)) + return gpio_device_get(gdev); + } + + return NULL; +} +EXPORT_SYMBOL_GPL(gpio_device_find); + static int gpiochip_match_name(struct gpio_chip *gc, void *data) { const char *name = data; @@ -1051,6 +1086,30 @@ return gpiochip_find((void *)name, gpiochip_match_name); } +/** + * gpio_device_get() - Increase the reference count of this GPIO device + * @gdev: GPIO device to increase the refcount for + * + * Returns: + * Pointer to @gdev. + */ +struct gpio_device *gpio_device_get(struct gpio_device *gdev) +{ + return to_gpio_device(get_device(&gdev->dev)); +} +EXPORT_SYMBOL_GPL(gpio_device_get); + +/** + * gpio_device_put() - Decrease the reference count of this GPIO device and + * possibly free all resources associated with it. + * @gdev: GPIO device to decrease the reference count for + */ +void gpio_device_put(struct gpio_device *gdev) +{ + put_device(&gdev->dev); +} +EXPORT_SYMBOL_GPL(gpio_device_put); + #ifdef CONFIG_GPIOLIB_IRQCHIP /* only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpio/gpiolib.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpio/gpiolib.h @@ -82,16 +82,6 @@ return container_of(dev, struct gpio_device, dev); } -static inline struct gpio_device *gpio_device_get(struct gpio_device *gdev) -{ - return to_gpio_device(get_device(&gdev->dev)); -} - -static inline void gpio_device_put(struct gpio_device *gdev) -{ - put_device(&gdev->dev); -} - /* gpio suffixes used for ACPI and device tree lookup */ static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/aldebaran.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/aldebaran.c @@ -333,6 +333,7 @@ { struct list_head *reset_device_list = reset_context->reset_device_list; struct amdgpu_device *tmp_adev = NULL; + struct amdgpu_ras *con; int r; if (reset_device_list == NULL) @@ -358,7 +359,30 @@ */ amdgpu_register_gpu_instance(tmp_adev); - /* Resume RAS */ + /* Resume RAS, ecc_irq */ + con = amdgpu_ras_get_context(tmp_adev); + if (!amdgpu_sriov_vf(tmp_adev) && con) { + if (tmp_adev->sdma.ras && + tmp_adev->sdma.ras->ras_block.ras_late_init) { + r = tmp_adev->sdma.ras->ras_block.ras_late_init(tmp_adev, + &tmp_adev->sdma.ras->ras_block.ras_comm); + if (r) { + dev_err(tmp_adev->dev, "SDMA failed to execute ras_late_init! ret:%d\n", r); + goto end; + } + } + + if (tmp_adev->gfx.ras && + tmp_adev->gfx.ras->ras_block.ras_late_init) { + r = tmp_adev->gfx.ras->ras_block.ras_late_init(tmp_adev, + &tmp_adev->gfx.ras->ras_block.ras_comm); + if (r) { + dev_err(tmp_adev->dev, "GFX failed to execute ras_late_init! ret:%d\n", r); + goto end; + } + } + } + amdgpu_ras_resume(tmp_adev); /* Update PSP FW topology after reset */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c @@ -90,7 +90,7 @@ return NULL; fence = container_of(f, struct amdgpu_amdkfd_fence, base); - if (fence && f->ops == &amdkfd_fence_ops) + if (f->ops == &amdkfd_fence_ops) return fence; return NULL; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -876,21 +876,28 @@ * seconds, so here, we just pick up three parts for emulation. */ ret = memcmp(vram_ptr, cptr, 10); - if (ret) - return ret; + if (ret) { + ret = -EIO; + goto release_buffer; + } ret = memcmp(vram_ptr + (size / 2), cptr, 10); - if (ret) - return ret; + if (ret) { + ret = -EIO; + goto release_buffer; + } ret = memcmp(vram_ptr + size - 10, cptr, 10); - if (ret) - return ret; + if (ret) { + ret = -EIO; + goto release_buffer; + } +release_buffer: amdgpu_bo_free_kernel(&vram_bo, &vram_gpu, &vram_ptr); - return 0; + return ret; } static ssize_t current_memory_partition_show( only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.h @@ -286,9 +286,10 @@ uint64_t process_context_addr; union { struct { - uint64_t single_memop : 1; - uint64_t single_alu_op : 1; - uint64_t reserved: 30; + uint32_t single_memop : 1; + uint32_t single_alu_op : 1; + uint32_t reserved: 29; + uint32_t process_ctx_flush: 1; }; uint32_t u32all; } flags; @@ -364,7 +365,8 @@ const uint32_t *tcp_watch_cntl, uint32_t flags, bool trap_en); - +int amdgpu_mes_flush_shader_debugger(struct amdgpu_device *adev, + uint64_t process_context_addr); int amdgpu_mes_add_ring(struct amdgpu_device *adev, int gang_id, int queue_type, int idx, struct amdgpu_mes_ctx_data *ctx_data, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c @@ -1241,19 +1241,15 @@ * amdgpu_bo_move_notify - notification about a memory move * @bo: pointer to a buffer object * @evict: if this move is evicting the buffer from the graphics address space - * @new_mem: new information of the bufer object * * Marks the corresponding &amdgpu_bo buffer object as invalid, also performs * bookkeeping. * TTM driver callback which is called when ttm moves a buffer. */ -void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, - bool evict, - struct ttm_resource *new_mem) +void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict) { struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev); struct amdgpu_bo *abo; - struct ttm_resource *old_mem = bo->resource; if (!amdgpu_bo_is_amdgpu_bo(bo)) return; @@ -1270,13 +1266,6 @@ /* remember the eviction */ if (evict) atomic64_inc(&adev->num_evictions); - - /* update statistics */ - if (!new_mem) - return; - - /* move_notify is called before move happens */ - trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type); } void amdgpu_bo_get_memory(struct amdgpu_bo *bo, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c @@ -191,7 +191,8 @@ /* Never sync to VM updates either. */ if (fence_owner == AMDGPU_FENCE_OWNER_VM && - owner != AMDGPU_FENCE_OWNER_UNDEFINED) + owner != AMDGPU_FENCE_OWNER_UNDEFINED && + owner != AMDGPU_FENCE_OWNER_KFD) return false; /* Ignore fences depending on the sync mode */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -543,10 +543,11 @@ return r; } + trace_amdgpu_bo_move(abo, new_mem->mem_type, old_mem->mem_type); out: /* update statistics */ atomic64_add(bo->base.size, &adev->num_bytes_moved); - amdgpu_bo_move_notify(bo, evict, new_mem); + amdgpu_bo_move_notify(bo, evict); return 0; } @@ -1542,7 +1543,7 @@ static void amdgpu_bo_delete_mem_notify(struct ttm_buffer_object *bo) { - amdgpu_bo_move_notify(bo, false, NULL); + amdgpu_bo_move_notify(bo, false); } static struct ttm_device_funcs amdgpu_bo_driver = { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -1323,9 +1323,13 @@ if (err) return -ENODEV; + err = amdgpu_ucode_validate(*fw); - if (err) + if (err) { dev_dbg(adev->dev, "\"%s\" failed to validate\n", fw_name); + release_firmware(*fw); + *fw = NULL; + } return err; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_0.c @@ -102,7 +102,9 @@ WREG32_SOC15_RLC(GC, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); - if (adev->apu_flags & AMD_APU_IS_RAVEN2) + if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | + AMD_APU_IS_RENOIR | + AMD_APU_IS_GREEN_SARDINE)) /* * Raven2 has a HW issue that it is unable to use the * vram which is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c @@ -139,7 +139,9 @@ WREG32_SOC15_RLC(GC, GET_INST(GC, i), regMC_VM_SYSTEM_APERTURE_LOW_ADDR, min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); - if (adev->apu_flags & AMD_APU_IS_RAVEN2) + if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | + AMD_APU_IS_RENOIR | + AMD_APU_IS_GREEN_SARDINE)) /* * Raven2 has a HW issue that it is unable to use the * vram which is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -913,8 +913,8 @@ if (amdgpu_emu_mode == 1) return amdgpu_gmc_vram_checking(adev); - else - return r; + + return 0; } static int gmc_v6_0_hw_fini(void *handle) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -1101,8 +1101,8 @@ if (amdgpu_emu_mode == 1) return amdgpu_gmc_vram_checking(adev); - else - return r; + + return 0; } static int gmc_v7_0_hw_fini(void *handle) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -1231,8 +1231,8 @@ if (amdgpu_emu_mode == 1) return amdgpu_gmc_vram_checking(adev); - else - return r; + + return 0; } static int gmc_v8_0_hw_fini(void *handle) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c @@ -96,7 +96,9 @@ WREG32_SOC15(MMHUB, 0, mmMC_VM_SYSTEM_APERTURE_LOW_ADDR, min(adev->gmc.fb_start, adev->gmc.agp_start) >> 18); - if (adev->apu_flags & AMD_APU_IS_RAVEN2) + if (adev->apu_flags & (AMD_APU_IS_RAVEN2 | + AMD_APU_IS_RENOIR | + AMD_APU_IS_GREEN_SARDINE)) /* * Raven2 has a HW issue that it is unable to use the vram which * is out of MC_VM_SYSTEM_APERTURE_HIGH_ADDR. So here is the only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/amdkfd/kfd_migrate.c @@ -1020,7 +1020,7 @@ } else { res = devm_request_free_mem_region(adev->dev, &iomem_resource, size); if (IS_ERR(res)) - return -ENOMEM; + return PTR_ERR(res); pgmap->range.start = res->start; pgmap->range.end = res->end; pgmap->type = MEMORY_DEVICE_PRIVATE; @@ -1036,10 +1036,10 @@ r = devm_memremap_pages(adev->dev, pgmap); if (IS_ERR(r)) { pr_err("failed to register HMM device memory\n"); - /* Disable SVM support capability */ - pgmap->type = 0; if (pgmap->type == MEMORY_DEVICE_PRIVATE) devm_release_mem_region(adev->dev, res->start, resource_size(res)); + /* Disable SVM support capability */ + pgmap->type = 0; return PTR_ERR(r); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -63,6 +63,14 @@ DRM_DEBUG_DRIVER("Disabling FAMS on monitor with panel id %X\n", panel_id); edid_caps->panel_patch.disable_fams = true; break; + /* Workaround for some monitors that do not clear DPCD 0x317 if FreeSync is unsupported */ + case drm_edid_encode_panel_id('A', 'U', 'O', 0xA7AB): + case drm_edid_encode_panel_id('A', 'U', 'O', 0xE69B): + case drm_edid_encode_panel_id('B', 'O', 'E', 0x092A): + case drm_edid_encode_panel_id('L', 'G', 'D', 0x06D1): + DRM_DEBUG_DRIVER("Clearing DPCD 0x317 on monitor with panel id %X\n", panel_id); + edid_caps->panel_patch.remove_sink_ext_caps = true; + break; default: return; } @@ -113,6 +121,8 @@ edid_caps->edid_hdmi = connector->display_info.is_hdmi; + apply_edid_quirks(edid_buf, edid_caps); + sad_count = drm_edid_to_sad((struct edid *) edid->raw_edid, &sads); if (sad_count <= 0) return result; @@ -139,8 +149,6 @@ else edid_caps->speaker_flags = DEFAULT_SPEAKER_LOCATION; - apply_edid_quirks(edid_buf, edid_caps); - kfree(sads); kfree(sadb); @@ -948,6 +956,11 @@ struct aux_payload *payload, enum aux_return_code_type *operation_result) { + if (!link->hpd_status) { + *operation_result = AUX_RET_ERROR_HPD_DISCON; + return -1; + } + return amdgpu_dm_process_dmub_aux_transfer_sync(ctx, link->link_index, payload, operation_result); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn314/dcn314_clk_mgr.c @@ -131,30 +131,27 @@ return display_count; } -static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool disable) +static void dcn314_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, + bool safe_to_lower, bool disable) { struct dc *dc = clk_mgr_base->ctx->dc; int i; for (i = 0; i < dc->res_pool->pipe_count; ++i) { - struct pipe_ctx *pipe = &dc->current_state->res_ctx.pipe_ctx[i]; + struct pipe_ctx *pipe = safe_to_lower + ? &context->res_ctx.pipe_ctx[i] + : &dc->current_state->res_ctx.pipe_ctx[i]; if (pipe->top_pipe || pipe->prev_odm_pipe) continue; if (pipe->stream && (pipe->stream->dpms_off || dc_is_virtual_signal(pipe->stream->signal))) { - struct stream_encoder *stream_enc = pipe->stream_res.stream_enc; - if (disable) { - if (stream_enc && stream_enc->funcs->disable_fifo) - pipe->stream_res.stream_enc->funcs->disable_fifo(stream_enc); + if (pipe->stream_res.tg && pipe->stream_res.tg->funcs->immediate_disable_crtc) + pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg); - pipe->stream_res.tg->funcs->immediate_disable_crtc(pipe->stream_res.tg); reset_sync_context_for_pipe(dc, context, i); } else { pipe->stream_res.tg->funcs->enable_crtc(pipe->stream_res.tg); - - if (stream_enc && stream_enc->funcs->enable_fifo) - pipe->stream_res.stream_enc->funcs->enable_fifo(stream_enc); } } } @@ -252,11 +249,11 @@ } if (should_set_clock(safe_to_lower, new_clocks->dispclk_khz, clk_mgr_base->clks.dispclk_khz)) { - dcn314_disable_otg_wa(clk_mgr_base, context, true); + dcn314_disable_otg_wa(clk_mgr_base, context, safe_to_lower, true); clk_mgr_base->clks.dispclk_khz = new_clocks->dispclk_khz; dcn314_smu_set_dispclk(clk_mgr, clk_mgr_base->clks.dispclk_khz); - dcn314_disable_otg_wa(clk_mgr_base, context, false); + dcn314_disable_otg_wa(clk_mgr_base, context, safe_to_lower, false); update_dispclk = true; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/dc/dc_types.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -189,7 +189,7 @@ unsigned int disable_fams; unsigned int skip_avmute; unsigned int mst_start_top_delay; - unsigned int delay_disable_aux_intercept_ms; + unsigned int remove_sink_ext_caps; }; struct dc_edid_caps { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_hwseq.c @@ -523,7 +523,8 @@ if (pipe_ctx->stream_res.tg->funcs->set_odm_bypass) pipe_ctx->stream_res.tg->funcs->set_odm_bypass( pipe_ctx->stream_res.tg, &pipe_ctx->stream->timing); - pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; + if (dc_is_hdmi_tmds_signal(pipe_ctx->stream->signal)) + pipe_ctx->stream->link->phy_state.symclk_ref_cnts.otg = 0; if (pipe_ctx->stream_res.tg->funcs->set_drr) pipe_ctx->stream_res.tg->funcs->set_drr( only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_32.c @@ -813,6 +813,8 @@ (v->DRAMSpeedPerState[mode_lib->vba.VoltageLevel] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKPerState[mode_lib->vba.VoltageLevel] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, + mode_lib->vba.PrefetchModePerState[mode_lib->vba.VoltageLevel][mode_lib->vba.maxMpcComb] > 0 || mode_lib->vba.DRAMClockChangeRequirementFinal == false, + /* Output */ &v->DSTXAfterScaler[k], &v->DSTYAfterScaler[k], @@ -3317,6 +3319,7 @@ v->SwathHeightCThisState[k], v->TWait, (v->DRAMSpeedPerState[i] <= MEM_STROBE_FREQ_MHZ || v->DCFCLKState[i][j] <= DCFCLK_FREQ_EXTRA_PREFETCH_REQ_MHZ) ? mode_lib->vba.ip.min_prefetch_in_strobe_us : 0, + mode_lib->vba.PrefetchModePerState[i][j] > 0 || mode_lib->vba.DRAMClockChangeRequirementFinal == false, /* Output */ &v->dummy_vars.dml32_ModeSupportAndSystemConfigurationFull.DSTXAfterScaler[k], only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.h @@ -747,6 +747,7 @@ unsigned int SwathHeightC, double TWait, double TPreReq, + bool ExtendPrefetchIfPossible, /* Output */ double *DSTXAfterScaler, double *DSTYAfterScaler, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.c @@ -50,6 +50,7 @@ && tmp->hpd_status && tmp->dpia_bw_alloc_config.bw_alloc_enabled); } + static void reset_bw_alloc_struct(struct dc_link *link) { link->dpia_bw_alloc_config.bw_alloc_enabled = false; @@ -59,6 +60,11 @@ link->dpia_bw_alloc_config.bw_granularity = 0; link->dpia_bw_alloc_config.response_ready = false; } + +#define BW_GRANULARITY_0 4 // 0.25 Gbps +#define BW_GRANULARITY_1 2 // 0.5 Gbps +#define BW_GRANULARITY_2 1 // 1 Gbps + static uint8_t get_bw_granularity(struct dc_link *link) { uint8_t bw_granularity = 0; @@ -71,16 +77,20 @@ switch (bw_granularity & 0x3) { case 0: - bw_granularity = 4; + bw_granularity = BW_GRANULARITY_0; break; case 1: + bw_granularity = BW_GRANULARITY_1; + break; + case 2: default: - bw_granularity = 2; + bw_granularity = BW_GRANULARITY_2; break; } return bw_granularity; } + static int get_estimated_bw(struct dc_link *link) { uint8_t bw_estimated_bw = 0; @@ -93,31 +103,7 @@ return bw_estimated_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); } -static bool allocate_usb4_bw(int *stream_allocated_bw, int bw_needed, struct dc_link *link) -{ - if (bw_needed > 0) - *stream_allocated_bw += bw_needed; - return true; -} -static bool deallocate_usb4_bw(int *stream_allocated_bw, int bw_to_dealloc, struct dc_link *link) -{ - bool ret = false; - - if (*stream_allocated_bw > 0) { - *stream_allocated_bw -= bw_to_dealloc; - ret = true; - } else { - //Do nothing for now - ret = true; - } - - // Unplug so reset values - if (!link->hpd_status) - reset_bw_alloc_struct(link); - - return ret; -} /* * Read all New BW alloc configuration ex: estimated_bw, allocated_bw, * granuality, Driver_ID, CM_Group, & populate the BW allocation structs @@ -128,7 +114,12 @@ // Init the known values link->dpia_bw_alloc_config.bw_granularity = get_bw_granularity(link); link->dpia_bw_alloc_config.estimated_bw = get_estimated_bw(link); + + DC_LOG_DEBUG("%s: bw_granularity(%d), estimated_bw(%d)\n", + __func__, link->dpia_bw_alloc_config.bw_granularity, + link->dpia_bw_alloc_config.estimated_bw); } + static uint8_t get_lowest_dpia_index(struct dc_link *link) { const struct dc *dc_struct = link->dc; @@ -141,12 +132,15 @@ dc_struct->links[i]->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) continue; - if (idx > dc_struct->links[i]->link_index) + if (idx > dc_struct->links[i]->link_index) { idx = dc_struct->links[i]->link_index; + break; + } } return idx; } + /* * Get the Max Available BW or Max Estimated BW for each Host Router * @@ -186,6 +180,7 @@ return total_bw; } + /* * Cleanup function for when the dpia is unplugged to reset struct * and perform any required clean up @@ -194,42 +189,50 @@ * * return: none */ -static bool dpia_bw_alloc_unplug(struct dc_link *link) +static void dpia_bw_alloc_unplug(struct dc_link *link) { - if (!link) - return true; - - return deallocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, - link->dpia_bw_alloc_config.sink_allocated_bw, link); + if (link) { + DC_LOG_DEBUG("%s: resetting bw alloc config for link(%d)\n", + __func__, link->link_index); + link->dpia_bw_alloc_config.sink_allocated_bw = 0; + reset_bw_alloc_struct(link); + } } + static void set_usb4_req_bw_req(struct dc_link *link, int req_bw) { uint8_t requested_bw; uint32_t temp; - // 1. Add check for this corner case #1 - if (req_bw > link->dpia_bw_alloc_config.estimated_bw) + /* Error check whether request bw greater than allocated */ + if (req_bw > link->dpia_bw_alloc_config.estimated_bw) { + DC_LOG_ERROR("%s: Request bw greater than estimated bw for link(%d)\n", + __func__, link->link_index); req_bw = link->dpia_bw_alloc_config.estimated_bw; + } temp = req_bw * link->dpia_bw_alloc_config.bw_granularity; requested_bw = temp / Kbps_TO_Gbps; - // Always make sure to add more to account for floating points + /* Always make sure to add more to account for floating points */ if (temp % Kbps_TO_Gbps) ++requested_bw; - // 2. Add check for this corner case #2 + /* Error check whether requested and allocated are equal */ req_bw = requested_bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); - if (req_bw == link->dpia_bw_alloc_config.sink_allocated_bw) - return; + if (req_bw == link->dpia_bw_alloc_config.sink_allocated_bw) { + DC_LOG_ERROR("%s: Request bw equals to allocated bw for link(%d)\n", + __func__, link->link_index); + } - if (core_link_write_dpcd( + link->dpia_bw_alloc_config.response_ready = false; // Reset flag + core_link_write_dpcd( link, REQUESTED_BW, &requested_bw, - sizeof(uint8_t)) == DC_OK) - link->dpia_bw_alloc_config.response_ready = false; // Reset flag + sizeof(uint8_t)); } + /* * Return the response_ready flag from dc_link struct * @@ -241,6 +244,7 @@ { return link->dpia_bw_alloc_config.response_ready; } + // ------------------------------------------------------------------ // PUBLIC FUNCTIONS // ------------------------------------------------------------------ @@ -277,27 +281,27 @@ DPTX_BW_ALLOCATION_MODE_CONTROL, &response, sizeof(uint8_t)) != DC_OK) { - DC_LOG_DEBUG("%s: **** FAILURE Enabling DPtx BW Allocation Mode Support ***\n", - __func__); + DC_LOG_DEBUG("%s: FAILURE Enabling DPtx BW Allocation Mode Support for link(%d)\n", + __func__, link->link_index); } else { // SUCCESS Enabled DPtx BW Allocation Mode Support - link->dpia_bw_alloc_config.bw_alloc_enabled = true; - DC_LOG_DEBUG("%s: **** SUCCESS Enabling DPtx BW Allocation Mode Support ***\n", - __func__); + DC_LOG_DEBUG("%s: SUCCESS Enabling DPtx BW Allocation Mode Support for link(%d)\n", + __func__, link->link_index); ret = true; init_usb4_bw_struct(link); + link->dpia_bw_alloc_config.bw_alloc_enabled = true; } } out: return ret; } + void dpia_handle_bw_alloc_response(struct dc_link *link, uint8_t bw, uint8_t result) { int bw_needed = 0; int estimated = 0; - int host_router_total_estimated_bw = 0; if (!get_bw_alloc_proceed_flag((link))) return; @@ -306,14 +310,22 @@ case DPIA_BW_REQ_FAILED: - DC_LOG_DEBUG("%s: *** *** BW REQ FAILURE for DP-TX Request *** ***\n", __func__); + /* + * Ideally, we shouldn't run into this case as we always validate available + * bandwidth and request within that limit + */ + estimated = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); - // Update the new Estimated BW value updated by CM - link->dpia_bw_alloc_config.estimated_bw = - bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); + DC_LOG_ERROR("%s: BW REQ FAILURE for DP-TX Request for link(%d)\n", + __func__, link->link_index); + DC_LOG_ERROR("%s: current estimated_bw(%d), new estimated_bw(%d)\n", + __func__, link->dpia_bw_alloc_config.estimated_bw, estimated); + /* Update the new Estimated BW value updated by CM */ + link->dpia_bw_alloc_config.estimated_bw = estimated; + + /* Allocate the previously requested bandwidth */ set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.estimated_bw); - link->dpia_bw_alloc_config.response_ready = false; /* * If FAIL then it is either: @@ -326,68 +338,34 @@ case DPIA_BW_REQ_SUCCESS: - DC_LOG_DEBUG("%s: *** BW REQ SUCCESS for DP-TX Request ***\n", __func__); - - // 1. SUCCESS 1st time before any Pruning is done - // 2. SUCCESS after prev. FAIL before any Pruning is done - // 3. SUCCESS after Pruning is done but before enabling link - bw_needed = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); - // 1. - if (!link->dpia_bw_alloc_config.sink_allocated_bw) { + DC_LOG_DEBUG("%s: BW REQ SUCCESS for DP-TX Request for link(%d)\n", + __func__, link->link_index); + DC_LOG_DEBUG("%s: current allocated_bw(%d), new allocated_bw(%d)\n", + __func__, link->dpia_bw_alloc_config.sink_allocated_bw, bw_needed); - allocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, bw_needed, link); - link->dpia_bw_alloc_config.sink_verified_bw = - link->dpia_bw_alloc_config.sink_allocated_bw; - - // SUCCESS from first attempt - if (link->dpia_bw_alloc_config.sink_allocated_bw > - link->dpia_bw_alloc_config.sink_max_bw) - link->dpia_bw_alloc_config.sink_verified_bw = - link->dpia_bw_alloc_config.sink_max_bw; - } - // 3. - else if (link->dpia_bw_alloc_config.sink_allocated_bw) { - - // Find out how much do we need to de-alloc - if (link->dpia_bw_alloc_config.sink_allocated_bw > bw_needed) - deallocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, - link->dpia_bw_alloc_config.sink_allocated_bw - bw_needed, link); - else - allocate_usb4_bw(&link->dpia_bw_alloc_config.sink_allocated_bw, - bw_needed - link->dpia_bw_alloc_config.sink_allocated_bw, link); - } - - // 4. If this is the 2nd sink then any unused bw will be reallocated to master DPIA - // => check if estimated_bw changed + link->dpia_bw_alloc_config.sink_allocated_bw = bw_needed; link->dpia_bw_alloc_config.response_ready = true; break; case DPIA_EST_BW_CHANGED: - DC_LOG_DEBUG("%s: *** ESTIMATED BW CHANGED for DP-TX Request ***\n", __func__); - estimated = bw * (Kbps_TO_Gbps / link->dpia_bw_alloc_config.bw_granularity); - host_router_total_estimated_bw = get_host_router_total_bw(link, HOST_ROUTER_BW_ESTIMATED); - // 1. If due to unplug of other sink - if (estimated == host_router_total_estimated_bw) { - // First update the estimated & max_bw fields - if (link->dpia_bw_alloc_config.estimated_bw < estimated) - link->dpia_bw_alloc_config.estimated_bw = estimated; - } - // 2. If due to realloc bw btw 2 dpia due to plug OR realloc unused Bw - else { - // We lost estimated bw usually due to plug event of other dpia - link->dpia_bw_alloc_config.estimated_bw = estimated; - } + DC_LOG_DEBUG("%s: ESTIMATED BW CHANGED for link(%d)\n", + __func__, link->link_index); + DC_LOG_DEBUG("%s: current estimated_bw(%d), new estimated_bw(%d)\n", + __func__, link->dpia_bw_alloc_config.estimated_bw, estimated); + + link->dpia_bw_alloc_config.estimated_bw = estimated; break; case DPIA_BW_ALLOC_CAPS_CHANGED: - DC_LOG_DEBUG("%s: *** BW ALLOC CAPABILITY CHANGED for DP-TX Request ***\n", __func__); + DC_LOG_ERROR("%s: BW ALLOC CAPABILITY CHANGED to Disabled for link(%d)\n", + __func__, link->link_index); link->dpia_bw_alloc_config.bw_alloc_enabled = false; break; } @@ -409,11 +387,11 @@ set_usb4_req_bw_req(link, link->dpia_bw_alloc_config.sink_max_bw); do { - if (!(timeout > 0)) + if (timeout > 0) timeout--; else break; - fsleep(10 * 1000); + msleep(10); } while (!get_cm_response_ready_flag(link)); if (!timeout) @@ -428,37 +406,36 @@ out: return ret; } -int link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw) + +bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw) { - int ret = 0; + bool ret = false; uint8_t timeout = 10; + DC_LOG_DEBUG("%s: ENTER: link(%d), hpd_status(%d), current allocated_bw(%d), req_bw(%d)\n", + __func__, link->link_index, link->hpd_status, + link->dpia_bw_alloc_config.sink_allocated_bw, req_bw); + if (!get_bw_alloc_proceed_flag(link)) goto out; - /* - * Sometimes stream uses same timing parameters as the already - * allocated max sink bw so no need to re-alloc - */ - if (req_bw != link->dpia_bw_alloc_config.sink_allocated_bw) { - set_usb4_req_bw_req(link, req_bw); - do { - if (!(timeout > 0)) - timeout--; - else - break; - udelay(10 * 1000); - } while (!get_cm_response_ready_flag(link)); + set_usb4_req_bw_req(link, req_bw); + do { + if (timeout > 0) + timeout--; + else + break; + msleep(10); + } while (!get_cm_response_ready_flag(link)); - if (!timeout) - ret = 0;// ERROR TIMEOUT waiting for response for allocating bw - else if (link->dpia_bw_alloc_config.sink_allocated_bw > 0) - ret = get_host_router_total_bw(link, HOST_ROUTER_BW_ALLOCATED); - } + if (timeout) + ret = true; out: + DC_LOG_DEBUG("%s: EXIT: timeout(%d), ret(%d)\n", __func__, timeout, ret); return ret; } + bool dpia_validate_usb4_bw(struct dc_link **link, int *bw_needed_per_dpia, const unsigned int num_dpias) { bool ret = true; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_dpia_bw.h @@ -59,9 +59,9 @@ * @link: pointer to the dc_link struct instance * @req_bw: Bw requested by the stream * - * return: allocated bw else return 0 + * return: true if allocated successfully */ -int link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw); +bool link_dp_dpia_allocate_usb4_bandwidth_for_stream(struct dc_link *link, int req_bw); /* * Handle the USB4 BW Allocation related functionality here: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -807,7 +807,7 @@ const struct link_training_settings *lt_settings, const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX], struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], - union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]) + union dpcd_training_lane *dpcd_lane_settings) { uint32_t lane; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.h @@ -111,7 +111,7 @@ const struct link_training_settings *lt_settings, const union lane_adjust ln_adjust[LANE_COUNT_DP_MAX], struct dc_lane_settings hw_lane_settings[LANE_COUNT_DP_MAX], - union dpcd_training_lane dpcd_lane_settings[LANE_COUNT_DP_MAX]); + union dpcd_training_lane *dpcd_lane_settings); enum dc_dp_training_pattern decide_cr_training_pattern( const struct dc_link_settings *link_settings); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/display/dc/link/protocols/link_dpcd.c @@ -205,7 +205,7 @@ uint32_t extended_size; /* size of the remaining partitioned address space */ uint32_t size_left_to_read; - enum dc_status status; + enum dc_status status = DC_ERROR_UNEXPECTED; /* size of the next partition to be read from */ uint32_t partition_size; uint32_t data_index = 0; @@ -234,7 +234,7 @@ { uint32_t partition_size; uint32_t data_index = 0; - enum dc_status status; + enum dc_status status = DC_ERROR_UNEXPECTED; while (size) { partition_size = dpcd_get_next_partition_size(address, size); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/include/mes_v11_api_def.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/include/mes_v11_api_def.h @@ -569,7 +569,8 @@ struct { uint32_t single_memop : 1; /* SQ_DEBUG.single_memop */ uint32_t single_alu_op : 1; /* SQ_DEBUG.single_alu_op */ - uint32_t reserved : 30; + uint32_t reserved : 29; + uint32_t process_ctx_flush : 1; }; uint32_t u32all; } flags; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c @@ -2748,10 +2748,8 @@ non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL); - if (ps == NULL) { - kfree(adev->pm.dpm.ps); + if (ps == NULL) return -ENOMEM; - } adev->pm.dpm.ps[i].ps_priv = ps; k = 0; idx = (u8 *)&power_state->v2.clockInfoIndex[0]; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c @@ -272,10 +272,8 @@ le16_to_cpu(power_info->pplib4.usVddcDependencyOnSCLKOffset)); ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_sclk, dep_table); - if (ret) { - amdgpu_free_extended_power_table(adev); + if (ret) return ret; - } } if (power_info->pplib4.usVddciDependencyOnMCLKOffset) { dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) @@ -283,10 +281,8 @@ le16_to_cpu(power_info->pplib4.usVddciDependencyOnMCLKOffset)); ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddci_dependency_on_mclk, dep_table); - if (ret) { - amdgpu_free_extended_power_table(adev); + if (ret) return ret; - } } if (power_info->pplib4.usVddcDependencyOnMCLKOffset) { dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) @@ -294,10 +290,8 @@ le16_to_cpu(power_info->pplib4.usVddcDependencyOnMCLKOffset)); ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.vddc_dependency_on_mclk, dep_table); - if (ret) { - amdgpu_free_extended_power_table(adev); + if (ret) return ret; - } } if (power_info->pplib4.usMvddDependencyOnMCLKOffset) { dep_table = (ATOM_PPLIB_Clock_Voltage_Dependency_Table *) @@ -305,10 +299,8 @@ le16_to_cpu(power_info->pplib4.usMvddDependencyOnMCLKOffset)); ret = amdgpu_parse_clk_voltage_dep_table(&adev->pm.dpm.dyn_state.mvdd_dependency_on_mclk, dep_table); - if (ret) { - amdgpu_free_extended_power_table(adev); + if (ret) return ret; - } } if (power_info->pplib4.usMaxClockVoltageOnDCOffset) { ATOM_PPLIB_Clock_Voltage_Limit_Table *clk_v = @@ -339,10 +331,8 @@ kcalloc(psl->ucNumEntries, sizeof(struct amdgpu_phase_shedding_limits_entry), GFP_KERNEL); - if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) { - amdgpu_free_extended_power_table(adev); + if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) return -ENOMEM; - } entry = &psl->entries[0]; for (i = 0; i < psl->ucNumEntries; i++) { @@ -383,10 +373,8 @@ ATOM_PPLIB_CAC_Leakage_Record *entry; u32 size = cac_table->ucNumEntries * sizeof(struct amdgpu_cac_leakage_table); adev->pm.dpm.dyn_state.cac_leakage_table.entries = kzalloc(size, GFP_KERNEL); - if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) { - amdgpu_free_extended_power_table(adev); + if (!adev->pm.dpm.dyn_state.cac_leakage_table.entries) return -ENOMEM; - } entry = &cac_table->entries[0]; for (i = 0; i < cac_table->ucNumEntries; i++) { if (adev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_EVV) { @@ -438,10 +426,8 @@ sizeof(struct amdgpu_vce_clock_voltage_dependency_entry); adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries = kzalloc(size, GFP_KERNEL); - if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) { - amdgpu_free_extended_power_table(adev); + if (!adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.entries) return -ENOMEM; - } adev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table.count = limits->numEntries; entry = &limits->entries[0]; @@ -493,10 +479,8 @@ sizeof(struct amdgpu_uvd_clock_voltage_dependency_entry); adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries = kzalloc(size, GFP_KERNEL); - if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) { - amdgpu_free_extended_power_table(adev); + if (!adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.entries) return -ENOMEM; - } adev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table.count = limits->numEntries; entry = &limits->entries[0]; @@ -525,10 +509,8 @@ sizeof(struct amdgpu_clock_voltage_dependency_entry); adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries = kzalloc(size, GFP_KERNEL); - if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) { - amdgpu_free_extended_power_table(adev); + if (!adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.entries) return -ENOMEM; - } adev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table.count = limits->numEntries; entry = &limits->entries[0]; @@ -548,10 +530,8 @@ le16_to_cpu(ext_hdr->usPPMTableOffset)); adev->pm.dpm.dyn_state.ppm_table = kzalloc(sizeof(struct amdgpu_ppm_table), GFP_KERNEL); - if (!adev->pm.dpm.dyn_state.ppm_table) { - amdgpu_free_extended_power_table(adev); + if (!adev->pm.dpm.dyn_state.ppm_table) return -ENOMEM; - } adev->pm.dpm.dyn_state.ppm_table->ppm_design = ppm->ucPpmDesign; adev->pm.dpm.dyn_state.ppm_table->cpu_core_number = le16_to_cpu(ppm->usCpuCoreNumber); @@ -583,10 +563,8 @@ sizeof(struct amdgpu_clock_voltage_dependency_entry); adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries = kzalloc(size, GFP_KERNEL); - if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) { - amdgpu_free_extended_power_table(adev); + if (!adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.entries) return -ENOMEM; - } adev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table.count = limits->numEntries; entry = &limits->entries[0]; @@ -606,10 +584,8 @@ ATOM_PowerTune_Table *pt; adev->pm.dpm.dyn_state.cac_tdp_table = kzalloc(sizeof(struct amdgpu_cac_tdp_table), GFP_KERNEL); - if (!adev->pm.dpm.dyn_state.cac_tdp_table) { - amdgpu_free_extended_power_table(adev); + if (!adev->pm.dpm.dyn_state.cac_tdp_table) return -ENOMEM; - } if (rev > 0) { ATOM_PPLIB_POWERTUNE_Table_V1 *ppt = (ATOM_PPLIB_POWERTUNE_Table_V1 *) (mode_info->atom_context->bios + data_offset + @@ -645,10 +621,8 @@ ret = amdgpu_parse_clk_voltage_dep_table( &adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk, dep_table); - if (ret) { - kfree(adev->pm.dpm.dyn_state.vddgfx_dependency_on_sclk.entries); + if (ret) return ret; - } } } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c @@ -7379,10 +7379,9 @@ kcalloc(4, sizeof(struct amdgpu_clock_voltage_dependency_entry), GFP_KERNEL); - if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { - amdgpu_free_extended_power_table(adev); + if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) return -ENOMEM; - } + adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4; adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0; adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c @@ -200,7 +200,7 @@ struct pp_hwmgr *hwmgr, ATOM_Tonga_PPM_Table *atom_ppm_table) { - struct phm_ppm_table *ptr = kzalloc(sizeof(ATOM_Tonga_PPM_Table), GFP_KERNEL); + struct phm_ppm_table *ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); struct phm_ppt_v1_information *pp_table_information = (struct phm_ppt_v1_information *)(hwmgr->pptable); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -1441,10 +1441,12 @@ case 0x3: dev_dbg(adev->dev, "Switched to AC mode!\n"); schedule_work(&smu->interrupt_work); + adev->pm.ac_power = true; break; case 0x4: dev_dbg(adev->dev, "Switched to DC mode!\n"); schedule_work(&smu->interrupt_work); + adev->pm.ac_power = false; break; case 0x7: /* only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/bridge/analogix/anx7625.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/analogix/anx7625.h @@ -259,6 +259,10 @@ #define AP_MIPI_RX_EN BIT(5) /* 1: MIPI RX input in 0: no RX in */ #define AP_DISABLE_PD BIT(6) #define AP_DISABLE_DISPLAY BIT(7) + +#define GPIO_CTRL_2 0x49 +#define HPD_SOURCE BIT(6) + /***************************************************************/ /* Register definition of device address 0x84 */ #define MIPI_PHY_CONTROL_3 0x03 @@ -471,6 +475,8 @@ struct workqueue_struct *hdcp_workqueue; /* Lock for hdcp work queue */ struct mutex hdcp_wq_lock; + /* Lock for aux transfer and disable */ + struct mutex aux_lock; char edid_block; struct display_timing dt; u8 display_timing_valid; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-hdcp.c @@ -403,7 +403,8 @@ static int _cdns_mhdp_hdcp_enable(struct cdns_mhdp_device *mhdp, u8 content_type) { - int ret, tries = 3; + int ret = -EINVAL; + int tries = 3; u32 i; for (i = 0; i < tries; i++) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/bridge/nxp-ptn3460.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/nxp-ptn3460.c @@ -54,13 +54,13 @@ int ret; ret = i2c_master_send(ptn_bridge->client, &addr, 1); - if (ret <= 0) { + if (ret < 0) { DRM_ERROR("Failed to send i2c command, ret=%d\n", ret); return ret; } ret = i2c_master_recv(ptn_bridge->client, buf, len); - if (ret <= 0) { + if (ret < 0) { DRM_ERROR("Failed to recv i2c data, ret=%d\n", ret); return ret; } @@ -78,7 +78,7 @@ buf[1] = val; ret = i2c_master_send(ptn_bridge->client, buf, ARRAY_SIZE(buf)); - if (ret <= 0) { + if (ret < 0) { DRM_ERROR("Failed to send i2c command, ret=%d\n", ret); return ret; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/bridge/sii902x.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/sii902x.c @@ -1040,6 +1040,26 @@ return ret; } + ret = sii902x_audio_codec_init(sii902x, dev); + if (ret) + return ret; + + i2c_set_clientdata(sii902x->i2c, sii902x); + + sii902x->i2cmux = i2c_mux_alloc(sii902x->i2c->adapter, dev, + 1, 0, I2C_MUX_GATE, + sii902x_i2c_bypass_select, + sii902x_i2c_bypass_deselect); + if (!sii902x->i2cmux) { + ret = -ENOMEM; + goto err_unreg_audio; + } + + sii902x->i2cmux->priv = sii902x; + ret = i2c_mux_add_adapter(sii902x->i2cmux, 0, 0, 0); + if (ret) + goto err_unreg_audio; + sii902x->bridge.funcs = &sii902x_bridge_funcs; sii902x->bridge.of_node = dev->of_node; sii902x->bridge.timings = &default_sii902x_timings; @@ -1050,19 +1070,13 @@ drm_bridge_add(&sii902x->bridge); - sii902x_audio_codec_init(sii902x, dev); + return 0; - i2c_set_clientdata(sii902x->i2c, sii902x); +err_unreg_audio: + if (!PTR_ERR_OR_ZERO(sii902x->audio.pdev)) + platform_device_unregister(sii902x->audio.pdev); - sii902x->i2cmux = i2c_mux_alloc(sii902x->i2c->adapter, dev, - 1, 0, I2C_MUX_GATE, - sii902x_i2c_bypass_select, - sii902x_i2c_bypass_deselect); - if (!sii902x->i2cmux) - return -ENOMEM; - - sii902x->i2cmux->priv = sii902x; - return i2c_mux_add_adapter(sii902x->i2cmux, 0, 0, 0); + return ret; } static int sii902x_probe(struct i2c_client *client) @@ -1130,12 +1144,14 @@ } static void sii902x_remove(struct i2c_client *client) - { struct sii902x *sii902x = i2c_get_clientdata(client); - i2c_mux_del_adapters(sii902x->i2cmux); drm_bridge_remove(&sii902x->bridge); + i2c_mux_del_adapters(sii902x->i2cmux); + + if (!PTR_ERR_OR_ZERO(sii902x->audio.pdev)) + platform_device_unregister(sii902x->audio.pdev); } static const struct of_device_id sii902x_dt_ids[] = { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/bridge/tc358767.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/tc358767.c @@ -2290,7 +2290,7 @@ } else { if (tc->hpd_pin < 0 || tc->hpd_pin > 1) { dev_err(dev, "failed to parse HPD number\n"); - return ret; + return -EINVAL; } } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/bridge/ti-tpd12s015.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/bridge/ti-tpd12s015.c @@ -179,7 +179,7 @@ return 0; } -static int __exit tpd12s015_remove(struct platform_device *pdev) +static int tpd12s015_remove(struct platform_device *pdev) { struct tpd12s015_device *tpd = platform_get_drvdata(pdev); @@ -197,7 +197,7 @@ static struct platform_driver tpd12s015_driver = { .probe = tpd12s015_probe, - .remove = __exit_p(tpd12s015_remove), + .remove = tpd12s015_remove, .driver = { .name = "tpd12s015", .of_match_table = tpd12s015_of_match, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/drm_damage_helper.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/drm_damage_helper.c @@ -241,7 +241,8 @@ iter->plane_src.x2 = (src.x2 >> 16) + !!(src.x2 & 0xFFFF); iter->plane_src.y2 = (src.y2 >> 16) + !!(src.y2 & 0xFFFF); - if (!iter->clips || !drm_rect_equals(&state->src, &old_state->src)) { + if (!iter->clips || state->ignore_damage_clips || + !drm_rect_equals(&state->src, &old_state->src)) { iter->clips = NULL; iter->num_clips = 0; iter->full_update = true; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/drm_drv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/drm_drv.c @@ -940,8 +940,11 @@ goto err_minors; } - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_modeset_register_all(dev); + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = drm_modeset_register_all(dev); + if (ret) + goto err_unload; + } DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", driver->name, driver->major, driver->minor, @@ -951,6 +954,9 @@ goto out_unlock; +err_unload: + if (dev->driver->unload) + dev->driver->unload(dev); err_minors: remove_compat_control_link(dev); drm_minor_unregister(dev, DRM_MINOR_ACCEL); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/drm_framebuffer.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/drm_framebuffer.c @@ -570,7 +570,7 @@ struct drm_mode_fb_cmd2 *r = data; struct drm_framebuffer *fb; unsigned int i; - int ret; + int ret = 0; if (!drm_core_check_feature(dev, DRIVER_MODESET)) return -EINVAL; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/drm_mipi_dsi.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/drm_mipi_dsi.c @@ -346,7 +346,8 @@ { struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev); - mipi_dsi_detach(dsi); + if (dsi->attached) + mipi_dsi_detach(dsi); mipi_dsi_device_unregister(dsi); return 0; @@ -369,11 +370,18 @@ int mipi_dsi_attach(struct mipi_dsi_device *dsi) { const struct mipi_dsi_host_ops *ops = dsi->host->ops; + int ret; if (!ops || !ops->attach) return -ENOSYS; - return ops->attach(dsi->host, dsi); + ret = ops->attach(dsi->host, dsi); + if (ret) + return ret; + + dsi->attached = true; + + return 0; } EXPORT_SYMBOL(mipi_dsi_attach); @@ -385,9 +393,14 @@ { const struct mipi_dsi_host_ops *ops = dsi->host->ops; + if (WARN_ON(!dsi->attached)) + return -EINVAL; + if (!ops || !ops->detach) return -ENOSYS; + dsi->attached = false; + return ops->detach(dsi->host, dsi); } EXPORT_SYMBOL(mipi_dsi_detach); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/drm_plane.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/drm_plane.c @@ -678,6 +678,19 @@ !file_priv->universal_planes) continue; + /* + * If we're running on a virtualized driver then, + * unless userspace advertizes support for the + * virtualized cursor plane, disable cursor planes + * because they'll be broken due to missing cursor + * hotspot info. + */ + if (plane->type == DRM_PLANE_TYPE_CURSOR && + drm_core_check_feature(dev, DRIVER_CURSOR_HOTSPOT) && + file_priv->atomic && + !file_priv->supports_virtualized_cursor_plane) + continue; + if (drm_lease_held(file_priv, plane->base.id)) { if (count < plane_resp->count_planes && put_user(plane->base.id, plane_ptr + count)) @@ -1387,6 +1400,7 @@ out: if (fb) drm_framebuffer_put(fb); + fb = NULL; if (plane->old_fb) drm_framebuffer_put(plane->old_fb); plane->old_fb = NULL; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/exynos/exynos5433_drm_decon.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/exynos/exynos5433_drm_decon.c @@ -319,9 +319,9 @@ static void decon_win_set_pixfmt(struct decon_context *ctx, unsigned int win, struct drm_framebuffer *fb) { - struct exynos_drm_plane plane = ctx->planes[win]; + struct exynos_drm_plane *plane = &ctx->planes[win]; struct exynos_drm_plane_state *state = - to_exynos_plane_state(plane.base.state); + to_exynos_plane_state(plane->base.state); unsigned int alpha = state->base.alpha; unsigned int pixel_alpha; unsigned long val; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -303,6 +303,7 @@ drm_mode_config_cleanup(drm); exynos_drm_cleanup_dma(drm); kfree(private); + dev_set_drvdata(dev, NULL); err_free_drm: drm_dev_put(drm); @@ -316,6 +317,7 @@ drm_dev_unregister(drm); drm_kms_helper_poll_fini(drm); + drm_atomic_helper_shutdown(drm); component_unbind_all(drm->dev, drm); drm_mode_config_cleanup(drm); @@ -353,9 +355,18 @@ return 0; } +static void exynos_drm_platform_shutdown(struct platform_device *pdev) +{ + struct drm_device *drm = platform_get_drvdata(pdev); + + if (drm) + drm_atomic_helper_shutdown(drm); +} + static struct platform_driver exynos_drm_platform_driver = { .probe = exynos_drm_platform_probe, .remove = exynos_drm_platform_remove, + .shutdown = exynos_drm_platform_shutdown, .driver = { .name = "exynos-drm", .pm = &exynos_drm_pm_ops, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -662,9 +662,9 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win, struct drm_framebuffer *fb, int width) { - struct exynos_drm_plane plane = ctx->planes[win]; + struct exynos_drm_plane *plane = &ctx->planes[win]; struct exynos_drm_plane_state *state = - to_exynos_plane_state(plane.base.state); + to_exynos_plane_state(plane->base.state); uint32_t pixel_format = fb->format->format; unsigned int alpha = state->base.alpha; u32 val = WINCONx_ENWIN; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/exynos/exynos_drm_gsc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/exynos/exynos_drm_gsc.c @@ -1342,7 +1342,7 @@ for (i = 0; i < ctx->num_clocks; i++) { ret = clk_prepare_enable(ctx->clocks[i]); if (ret) { - while (--i > 0) + while (--i >= 0) clk_disable_unprepare(ctx->clocks[i]); return ret; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/i915/display/intel_psr.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/i915/display/intel_psr.c @@ -565,7 +565,9 @@ val |= EDP_PSR_IDLE_FRAMES(psr_compute_idle_frames(intel_dp)); - val |= EDP_PSR_MAX_SLEEP_TIME(max_sleep_time); + if (DISPLAY_VER(dev_priv) < 20) + val |= EDP_PSR_MAX_SLEEP_TIME(max_sleep_time); + if (IS_HASWELL(dev_priv)) val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES; @@ -1278,9 +1280,21 @@ * can rely on frontbuffer tracking. */ mask = EDP_PSR_DEBUG_MASK_MEMUP | - EDP_PSR_DEBUG_MASK_HPD | - EDP_PSR_DEBUG_MASK_LPSP | - EDP_PSR_DEBUG_MASK_MAX_SLEEP; + EDP_PSR_DEBUG_MASK_HPD; + + /* + * For some unknown reason on HSW non-ULT (or at least on + * Dell Latitude E6540) external displays start to flicker + * when PSR is enabled on the eDP. SR/PC6 residency is much + * higher than should be possible with an external display. + * As a workaround leave LPSP unmasked to prevent PSR entry + * when external displays are active. + */ + if (DISPLAY_VER(dev_priv) >= 8 || IS_HSW_ULT(dev_priv)) + mask |= EDP_PSR_DEBUG_MASK_LPSP; + + if (DISPLAY_VER(dev_priv) < 20) + mask |= EDP_PSR_DEBUG_MASK_MAX_SLEEP; if (DISPLAY_VER(dev_priv) < 11) mask |= EDP_PSR_DEBUG_MASK_DISP_REG_WRITE; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/imx/lcdc/imx-lcdc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/imx/lcdc/imx-lcdc.c @@ -342,21 +342,12 @@ .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, }; -static void imx_lcdc_release(struct drm_device *drm) -{ - struct imx_lcdc *lcdc = imx_lcdc_from_drmdev(drm); - - drm_kms_helper_poll_fini(drm); - kfree(lcdc); -} - DEFINE_DRM_GEM_DMA_FOPS(imx_lcdc_drm_fops); static struct drm_driver imx_lcdc_drm_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &imx_lcdc_drm_fops, DRM_GEM_DMA_DRIVER_OPS_VMAP, - .release = imx_lcdc_release, .name = "imx-lcdc", .desc = "i.MX LCDC driver", .date = "20200716", only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/mediatek/mtk_disp_merge.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/mediatek/mtk_disp_merge.c @@ -104,7 +104,7 @@ mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, DISP_REG_MERGE_CTRL); - if (priv->async_clk) + if (!cmdq_pkt && priv->async_clk) reset_control_reset(priv->reset_ctl); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/mediatek/mtk_mdp_rdma.c @@ -247,8 +247,7 @@ { struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev); - clk_prepare_enable(rdma->clk); - return 0; + return clk_prepare_enable(rdma->clk); } void mtk_mdp_rdma_clk_disable(struct device *dev) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -125,7 +125,7 @@ continue; /* Calculate MISR over 1 frame */ - m->hw_lm->ops.setup_misr(m->hw_lm, true, 1); + m->hw_lm->ops.setup_misr(m->hw_lm); } } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -2,7 +2,7 @@ /* * Copyright (C) 2013 Red Hat * Copyright (c) 2014-2018, 2020-2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * * Author: Rob Clark */ @@ -39,6 +39,9 @@ #define DPU_ERROR_ENC(e, fmt, ...) DPU_ERROR("enc%d " fmt,\ (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) +#define DPU_ERROR_ENC_RATELIMITED(e, fmt, ...) DPU_ERROR_RATELIMITED("enc%d " fmt,\ + (e) ? (e)->base.base.id : -1, ##__VA_ARGS__) + /* * Two to anticipate panels that can do cmd/vid dynamic switching * plan is to create all possible physical encoder types, and switch between @@ -259,7 +262,7 @@ if (!phys->hw_intf || !phys->hw_intf->ops.setup_misr) continue; - phys->hw_intf->ops.setup_misr(phys->hw_intf, true, 1); + phys->hw_intf->ops.setup_misr(phys->hw_intf); } } @@ -2367,7 +2370,7 @@ return; } - DPU_ERROR_ENC(dpu_enc, "frame done timeout\n"); + DPU_ERROR_ENC_RATELIMITED(dpu_enc, "frame done timeout\n"); event = DPU_ENCODER_FRAME_EVENT_ERROR; trace_dpu_enc_frame_done_timeout(DRMID(drm_enc), event); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ @@ -318,9 +318,9 @@ return DPU_REG_READ(c, INTF_LINE_COUNT); } -static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf, bool enable, u32 frame_count) +static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf) { - dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, enable, frame_count); + dpu_hw_setup_misr(&intf->hw, INTF_MISR_CTRL, 0x1); } static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ @@ -90,7 +90,7 @@ void (*bind_pingpong_blk)(struct dpu_hw_intf *intf, const enum dpu_pingpong pp); - void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count); + void (*setup_misr)(struct dpu_hw_intf *intf); int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value); // Tearcheck on INTF since DPU 5.0.0 only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -81,9 +81,9 @@ } } -static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count) +static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx) { - dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, enable, frame_count); + dpu_hw_setup_misr(&ctx->hw, LM_MISR_CTRL, 0x0); } static int dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx, u32 *misr_value) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -57,7 +58,7 @@ /** * setup_misr: Enable/disable MISR */ - void (*setup_misr)(struct dpu_hw_mixer *ctx, bool enable, u32 frame_count); + void (*setup_misr)(struct dpu_hw_mixer *ctx); /** * collect_misr: Read MISR signature only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -481,9 +481,11 @@ cfg->danger_safe_en ? QOS_QOS_CTRL_DANGER_SAFE_EN : 0); } +/* + * note: Aside from encoders, input_sel should be set to 0x0 by default + */ void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, - u32 misr_ctrl_offset, - bool enable, u32 frame_count) + u32 misr_ctrl_offset, u8 input_sel) { u32 config = 0; @@ -492,15 +494,9 @@ /* Clear old MISR value (in case it's read before a new value is calculated)*/ wmb(); - if (enable) { - config = (frame_count & MISR_FRAME_COUNT_MASK) | - MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK; - - DPU_REG_WRITE(c, misr_ctrl_offset, config); - } else { - DPU_REG_WRITE(c, misr_ctrl_offset, 0); - } - + config = MISR_FRAME_COUNT | MISR_CTRL_ENABLE | MISR_CTRL_FREE_RUN_MASK | + ((input_sel & 0xF) << 24); + DPU_REG_WRITE(c, misr_ctrl_offset, config); } int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -13,7 +13,7 @@ #include "dpu_hw_catalog.h" #define REG_MASK(n) ((BIT(n)) - 1) -#define MISR_FRAME_COUNT_MASK 0xFF +#define MISR_FRAME_COUNT 0x1 #define MISR_CTRL_ENABLE BIT(8) #define MISR_CTRL_STATUS BIT(9) #define MISR_CTRL_STATUS_CLEAR BIT(10) @@ -358,9 +358,7 @@ const struct dpu_hw_qos_cfg *cfg); void dpu_hw_setup_misr(struct dpu_hw_blk_reg_map *c, - u32 misr_ctrl_offset, - bool enable, - u32 frame_count); + u32 misr_ctrl_offset, u8 input_sel); int dpu_hw_collect_misr(struct dpu_hw_blk_reg_map *c, u32 misr_ctrl_offset, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_wb.c @@ -86,6 +86,9 @@ dst_format |= BIT(14); /* DST_ALPHA_X */ } + if (DPU_FORMAT_IS_YUV(fmt)) + dst_format |= BIT(15); + pattern = (fmt->element[3] << 24) | (fmt->element[2] << 16) | (fmt->element[1] << 8) | only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h @@ -51,6 +51,7 @@ } while (0) #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__) +#define DPU_ERROR_RATELIMITED(fmt, ...) pr_err_ratelimited("[dpu error]" fmt, ##__VA_ARGS__) /** * ktime_compare_safe - compare two ktime structures only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/disp/mdp4/mdp4_crtc.c @@ -269,6 +269,7 @@ { struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); struct mdp4_kms *mdp4_kms = get_kms(crtc); + unsigned long flags; DBG("%s", mdp4_crtc->name); @@ -281,6 +282,14 @@ mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); mdp4_disable(mdp4_kms); + if (crtc->state->event && !crtc->state->active) { + WARN_ON(mdp4_crtc->event); + spin_lock_irqsave(&mdp4_kms->dev->event_lock, flags); + drm_crtc_send_vblank_event(crtc, crtc->state->event); + crtc->state->event = NULL; + spin_unlock_irqrestore(&mdp4_kms->dev->event_lock, flags); + } + mdp4_crtc->enabled = false; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/dp/dp_display.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/dp/dp_display.c @@ -171,6 +171,11 @@ {} }; +static const struct msm_dp_desc sm8650_dp_descs[] = { + { .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .connector_type = DRM_MODE_CONNECTOR_DisplayPort }, + {} +}; + static const struct of_device_id dp_dt_match[] = { { .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs }, { .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs }, @@ -181,6 +186,7 @@ { .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_edp_descs }, { .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs }, { .compatible = "qcom,sm8350-dp", .data = &sm8350_dp_descs }, + { .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs }, {} }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -516,7 +516,9 @@ struct device *dev = &phy->pdev->dev; int ret; - pm_runtime_get_sync(dev); + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; ret = clk_prepare_enable(phy->ahb_clk); if (ret) { @@ -687,6 +689,10 @@ return dev_err_probe(dev, PTR_ERR(phy->ahb_clk), "Unable to get ahb clk\n"); + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; + /* PLL init will call into clk_register which requires * register access, so we need to enable power and ahb clock. */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/nouveau/nouveau_vmm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/nouveau/nouveau_vmm.c @@ -108,6 +108,9 @@ } else { ret = nvif_vmm_get(&vmm->vmm, PTES, false, mem->mem.page, 0, mem->mem.size, &tmp); + if (ret) + goto done; + vma->addr = tmp.addr; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/nouveau/nv04_fence.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/nouveau/nv04_fence.c @@ -39,7 +39,7 @@ static int nv04_fence_emit(struct nouveau_fence *fence) { - struct nvif_push *push = fence->channel->chan.push; + struct nvif_push *push = unrcu_pointer(fence->channel)->chan.push; int ret = PUSH_WAIT(push, 2); if (ret == 0) { PUSH_NVSQ(push, NV_SW, 0x0150, fence->base.seqno); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/omapdrm/omap_drv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/omapdrm/omap_drv.c @@ -69,7 +69,6 @@ { struct drm_device *dev = old_state->dev; struct omap_drm_private *priv = dev->dev_private; - bool fence_cookie = dma_fence_begin_signalling(); dispc_runtime_get(priv->dispc); @@ -92,6 +91,8 @@ omap_atomic_wait_for_completion(dev, old_state); drm_atomic_helper_commit_planes(dev, old_state, 0); + + drm_atomic_helper_commit_hw_done(old_state); } else { /* * OMAP3 DSS seems to have issues with the work-around above, @@ -101,11 +102,9 @@ drm_atomic_helper_commit_planes(dev, old_state, 0); drm_atomic_helper_commit_modeset_enables(dev, old_state); - } - drm_atomic_helper_commit_hw_done(old_state); - - dma_fence_end_signalling(fence_cookie); + drm_atomic_helper_commit_hw_done(old_state); + } /* * Wait for completion of the page flips to ensure that old buffers only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/panel/panel-edp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/panel/panel-edp.c @@ -203,6 +203,9 @@ /** @name: Name of this panel (for printing to logs). */ const char *name; + + /** @override_edid_mode: Override the mode obtained by edid. */ + const struct drm_display_mode *override_edid_mode; }; struct panel_edp { @@ -301,6 +304,24 @@ return num; } +static int panel_edp_override_edid_mode(struct panel_edp *panel, + struct drm_connector *connector, + const struct drm_display_mode *override_mode) +{ + struct drm_display_mode *mode; + + mode = drm_mode_duplicate(connector->dev, override_mode); + if (!mode) { + dev_err(panel->base.dev, "failed to add additional mode\n"); + return 0; + } + + mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; + drm_mode_set_name(mode); + drm_mode_probed_add(connector, mode); + return 1; +} + static int panel_edp_get_non_edid_modes(struct panel_edp *panel, struct drm_connector *connector) { @@ -568,6 +589,9 @@ { struct panel_edp *p = to_panel_edp(panel); int num = 0; + bool has_override_edid_mode = p->detected_panel && + p->detected_panel != ERR_PTR(-EINVAL) && + p->detected_panel->override_edid_mode; /* probe EDID if a DDC bus is available */ if (p->ddc) { @@ -575,9 +599,18 @@ if (!p->edid) p->edid = drm_get_edid(connector, p->ddc); - - if (p->edid) - num += drm_add_edid_modes(connector, p->edid); + if (p->edid) { + if (has_override_edid_mode) { + /* + * override_edid_mode is specified. Use + * override_edid_mode instead of from edid. + */ + num += panel_edp_override_edid_mode(p, connector, + p->detected_panel->override_edid_mode); + } else { + num += drm_add_edid_modes(connector, p->edid); + } + } pm_runtime_mark_last_busy(panel->dev); pm_runtime_put_autosuspend(panel->dev); @@ -973,6 +1006,8 @@ }, .delay = { .hpd_absent = 200, + .unprepare = 500, + .enable = 50, }, }; @@ -1857,6 +1892,15 @@ .delay = _delay \ } +#define EDP_PANEL_ENTRY2(vend_chr_0, vend_chr_1, vend_chr_2, product_id, _delay, _name, _mode) \ +{ \ + .name = _name, \ + .panel_id = drm_edid_encode_panel_id(vend_chr_0, vend_chr_1, vend_chr_2, \ + product_id), \ + .delay = _delay, \ + .override_edid_mode = _mode \ +} + /* * This table is used to figure out power sequencing delays for panels that * are detected by EDID. Entries here may point to entries in the @@ -1868,7 +1912,8 @@ EDP_PANEL_ENTRY('A', 'U', 'O', 0x1062, &delay_200_500_e50, "B120XAN01.0"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x1e9b, &delay_200_500_e50, "B133UAN02.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x1ea5, &delay_200_500_e50, "B116XAK01.6"), - EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAK01"), + EDP_PANEL_ENTRY('A', 'U', 'O', 0x235c, &delay_200_500_e50, "B116XTN02.3"), + EDP_PANEL_ENTRY('A', 'U', 'O', 0x405c, &auo_b116xak01.delay, "B116XAK01.0"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x582d, &delay_200_500_e50, "B133UAN01.0"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x615c, &delay_200_500_e50, "B116XAN06.1"), EDP_PANEL_ENTRY('A', 'U', 'O', 0x8594, &delay_200_500_e50, "B133UAN01.0"), @@ -1876,8 +1921,10 @@ EDP_PANEL_ENTRY('B', 'O', 'E', 0x0786, &delay_200_500_p2e80, "NV116WHM-T01"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x07d1, &boe_nv133fhm_n61.delay, "NV133FHM-N61"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x082d, &boe_nv133fhm_n61.delay, "NV133FHM-N62"), + EDP_PANEL_ENTRY('B', 'O', 'E', 0x09c3, &delay_200_500_e50, "NT116WHM-N21,836X2"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x094b, &delay_200_500_e50, "NT116WHM-N21"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x095f, &delay_200_500_e50, "NE135FBM-N41 v8.1"), + EDP_PANEL_ENTRY('B', 'O', 'E', 0x0979, &delay_200_500_e50, "NV116WHM-N49 V8.0"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x098d, &boe_nv110wtm_n61.delay, "NV110WTM-N61"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x09dd, &delay_200_500_e50, "NT116WHM-N21"), EDP_PANEL_ENTRY('B', 'O', 'E', 0x0a5d, &delay_200_500_e50, "NV116WHM-N45"), only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/panel/panel-elida-kd35t133.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/panel/panel-elida-kd35t133.c @@ -104,6 +104,8 @@ return ret; } + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_disable(ctx->iovcc); regulator_disable(ctx->vdd); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/panel/panel-newvision-nv3051d.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/panel/panel-newvision-nv3051d.c @@ -261,6 +261,8 @@ usleep_range(10000, 15000); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + regulator_disable(ctx->vdd); return 0; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/panel/panel-samsung-s6d7aa0.c @@ -311,7 +311,7 @@ .off_func = s6d7aa0_lsl080al02_off, .drm_mode = &s6d7aa0_lsl080al02_mode, .mode_flags = MIPI_DSI_MODE_VSYNC_FLUSH | MIPI_DSI_MODE_VIDEO_NO_HFP, - .bus_flags = DRM_BUS_FLAG_DE_HIGH, + .bus_flags = 0, .has_backlight = false, .use_passwd3 = false, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/panel/panel-sitronix-st7701.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/panel/panel-sitronix-st7701.c @@ -288,7 +288,7 @@ FIELD_PREP(DSI_CMD2_BK1_PWRCTRL2_AVDD_MASK, DIV_ROUND_CLOSEST(desc->avdd_mv - 6200, 200)) | FIELD_PREP(DSI_CMD2_BK1_PWRCTRL2_AVCL_MASK, - DIV_ROUND_CLOSEST(-4400 + desc->avcl_mv, 200))); + DIV_ROUND_CLOSEST(-4400 - desc->avcl_mv, 200))); /* T2D = 0.2us * T2D[3:0] */ ST7701_DSI(st7701, DSI_CMD2_BK1_SPD1, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/panfrost/panfrost_gpu.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/panfrost/panfrost_gpu.c @@ -71,7 +71,12 @@ } gpu_write(pfdev, GPU_INT_CLEAR, GPU_IRQ_MASK_ALL); - gpu_write(pfdev, GPU_INT_MASK, GPU_IRQ_MASK_ALL); + + /* Only enable the interrupts we care about */ + gpu_write(pfdev, GPU_INT_MASK, + GPU_IRQ_MASK_ERROR | + GPU_IRQ_PERFCNT_SAMPLE_COMPLETED | + GPU_IRQ_CLEAN_CACHES_COMPLETED); return 0; } @@ -321,28 +326,38 @@ pfdev->features.shader_present, pfdev->features.l2_present); } +static u64 panfrost_get_core_mask(struct panfrost_device *pfdev) +{ + u64 core_mask; + + if (pfdev->features.l2_present == 1) + return U64_MAX; + + /* + * Only support one core group now. + * ~(l2_present - 1) unsets all bits in l2_present except + * the bottom bit. (l2_present - 2) has all the bits in + * the first core group set. AND them together to generate + * a mask of cores in the first core group. + */ + core_mask = ~(pfdev->features.l2_present - 1) & + (pfdev->features.l2_present - 2); + dev_info_once(pfdev->dev, "using only 1st core group (%lu cores from %lu)\n", + hweight64(core_mask), + hweight64(pfdev->features.shader_present)); + + return core_mask; +} + void panfrost_gpu_power_on(struct panfrost_device *pfdev) { int ret; u32 val; - u64 core_mask = U64_MAX; + u64 core_mask; panfrost_gpu_init_quirks(pfdev); + core_mask = panfrost_get_core_mask(pfdev); - if (pfdev->features.l2_present != 1) { - /* - * Only support one core group now. - * ~(l2_present - 1) unsets all bits in l2_present except - * the bottom bit. (l2_present - 2) has all the bits in - * the first core group set. AND them together to generate - * a mask of cores in the first core group. - */ - core_mask = ~(pfdev->features.l2_present - 1) & - (pfdev->features.l2_present - 2); - dev_info_once(pfdev->dev, "using only 1st core group (%lu cores from %lu)\n", - hweight64(core_mask), - hweight64(pfdev->features.shader_present)); - } gpu_write(pfdev, L2_PWRON_LO, pfdev->features.l2_present & core_mask); ret = readl_relaxed_poll_timeout(pfdev->iomem + L2_READY_LO, val, val == (pfdev->features.l2_present & core_mask), @@ -367,9 +382,26 @@ void panfrost_gpu_power_off(struct panfrost_device *pfdev) { - gpu_write(pfdev, TILER_PWROFF_LO, 0); - gpu_write(pfdev, SHADER_PWROFF_LO, 0); - gpu_write(pfdev, L2_PWROFF_LO, 0); + int ret; + u32 val; + + gpu_write(pfdev, SHADER_PWROFF_LO, pfdev->features.shader_present); + ret = readl_relaxed_poll_timeout(pfdev->iomem + SHADER_PWRTRANS_LO, + val, !val, 1, 1000); + if (ret) + dev_err(pfdev->dev, "shader power transition timeout"); + + gpu_write(pfdev, TILER_PWROFF_LO, pfdev->features.tiler_present); + ret = readl_relaxed_poll_timeout(pfdev->iomem + TILER_PWRTRANS_LO, + val, !val, 1, 1000); + if (ret) + dev_err(pfdev->dev, "tiler power transition timeout"); + + gpu_write(pfdev, L2_PWROFF_LO, pfdev->features.l2_present); + ret = readl_poll_timeout(pfdev->iomem + L2_PWRTRANS_LO, + val, !val, 0, 1000); + if (ret) + dev_err(pfdev->dev, "l2 power transition timeout"); } int panfrost_gpu_init(struct panfrost_device *pfdev) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/qxl/qxl_drv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/qxl/qxl_drv.c @@ -283,7 +283,7 @@ }; static struct drm_driver qxl_driver = { - .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, + .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC | DRIVER_CURSOR_HOTSPOT, .dumb_create = qxl_mode_dumb_create, .dumb_map_offset = drm_gem_ttm_dumb_map_offset, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/radeon/r100.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/radeon/r100.c @@ -2321,7 +2321,7 @@ switch (prim_walk) { case 1: for (i = 0; i < track->num_arrays; i++) { - size = track->arrays[i].esize * track->max_indx * 4; + size = track->arrays[i].esize * track->max_indx * 4UL; if (track->arrays[i].robj == NULL) { DRM_ERROR("(PW %u) Vertex array %u no buffer " "bound\n", prim_walk, i); @@ -2340,7 +2340,7 @@ break; case 2: for (i = 0; i < track->num_arrays; i++) { - size = track->arrays[i].esize * (nverts - 1) * 4; + size = track->arrays[i].esize * (nverts - 1) * 4UL; if (track->arrays[i].robj == NULL) { DRM_ERROR("(PW %u) Vertex array %u no buffer " "bound\n", prim_walk, i); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/radeon/r600_cs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/radeon/r600_cs.c @@ -1275,7 +1275,7 @@ return -EINVAL; } tmp = (reg - CB_COLOR0_BASE) / 4; - track->cb_color_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; + track->cb_color_bo_offset[tmp] = (u64)radeon_get_ib_value(p, idx) << 8; ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); track->cb_color_base_last[tmp] = ib[idx]; track->cb_color_bo[tmp] = reloc->robj; @@ -1302,7 +1302,7 @@ "0x%04X\n", reg); return -EINVAL; } - track->htile_offset = radeon_get_ib_value(p, idx) << 8; + track->htile_offset = (u64)radeon_get_ib_value(p, idx) << 8; ib[idx] += (u32)((reloc->gpu_offset >> 8) & 0xffffffff); track->htile_bo = reloc->robj; track->db_dirty = true; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/radeon/radeon_display.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/radeon/radeon_display.c @@ -687,11 +687,16 @@ if (radeon_crtc == NULL) return; + radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); + if (!radeon_crtc->flip_queue) { + kfree(radeon_crtc); + return; + } + drm_crtc_init(dev, &radeon_crtc->base, &radeon_crtc_funcs); drm_mode_crtc_set_gamma_size(&radeon_crtc->base, 256); radeon_crtc->crtc_id = index; - radeon_crtc->flip_queue = alloc_workqueue("radeon-crtc", WQ_HIGHPRI, 0); rdev->mode_info.crtcs[index] = radeon_crtc; if (rdev->family >= CHIP_BONAIRE) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/radeon/radeon_vm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/radeon/radeon_vm.c @@ -1204,13 +1204,17 @@ r = radeon_bo_create(rdev, pd_size, align, true, RADEON_GEM_DOMAIN_VRAM, 0, NULL, NULL, &vm->page_directory); - if (r) + if (r) { + kfree(vm->page_tables); + vm->page_tables = NULL; return r; - + } r = radeon_vm_clear_bo(rdev, vm->page_directory); if (r) { radeon_bo_unref(&vm->page_directory); vm->page_directory = NULL; + kfree(vm->page_tables); + vm->page_tables = NULL; return r; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/radeon/sumo_dpm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/radeon/sumo_dpm.c @@ -1493,8 +1493,10 @@ non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; - if (!rdev->pm.power_state[i].clock_info) + if (!rdev->pm.power_state[i].clock_info) { + kfree(rdev->pm.dpm.ps); return -EINVAL; + } ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); if (ps == NULL) { kfree(rdev->pm.dpm.ps); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/radeon/trinity_dpm.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/radeon/trinity_dpm.c @@ -1726,8 +1726,10 @@ non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; - if (!rdev->pm.power_state[i].clock_info) + if (!rdev->pm.power_state[i].clock_info) { + kfree(rdev->pm.dpm.ps); return -EINVAL; + } ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); if (ps == NULL) { kfree(rdev->pm.dpm.ps); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/tests/drm_dp_mst_helper_test.c @@ -42,13 +42,13 @@ .clock = 332880, .bpp = 24, .dsc = true, - .expected = 50 + .expected = 1191 }, { .clock = 324540, .bpp = 24, .dsc = true, - .expected = 49 + .expected = 1161 }, }; @@ -56,7 +56,7 @@ { const struct drm_dp_mst_calc_pbn_mode_test *params = test->param_value; - KUNIT_EXPECT_EQ(test, drm_dp_calc_pbn_mode(params->clock, params->bpp, params->dsc), + KUNIT_EXPECT_EQ(test, drm_dp_calc_pbn_mode(params->clock, params->bpp << 4), params->expected); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/tidss/tidss_crtc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/tidss/tidss_crtc.c @@ -169,13 +169,13 @@ struct tidss_device *tidss = to_tidss(ddev); unsigned long flags; - dev_dbg(ddev->dev, - "%s: %s enabled %d, needs modeset %d, event %p\n", __func__, - crtc->name, drm_atomic_crtc_needs_modeset(crtc->state), - crtc->state->enable, crtc->state->event); + dev_dbg(ddev->dev, "%s: %s is %sactive, %s modeset, event %p\n", + __func__, crtc->name, crtc->state->active ? "" : "not ", + drm_atomic_crtc_needs_modeset(crtc->state) ? "needs" : "doesn't need", + crtc->state->event); /* There is nothing to do if CRTC is not going to be enabled. */ - if (!crtc->state->enable) + if (!crtc->state->active) return; /* only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/tidss/tidss_dispc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/tidss/tidss_dispc.c @@ -2649,18 +2649,69 @@ } } -static void dispc_softreset(struct dispc_device *dispc) +static int dispc_softreset(struct dispc_device *dispc) { u32 val; int ret = 0; + /* K2G display controller does not support soft reset */ + if (dispc->feat->subrev == DISPC_K2G) + return 0; + /* Soft reset */ REG_FLD_MOD(dispc, DSS_SYSCONFIG, 1, 1, 1); /* Wait for reset to complete */ ret = readl_poll_timeout(dispc->base_common + DSS_SYSSTATUS, val, val & 1, 100, 5000); + if (ret) { + dev_err(dispc->dev, "failed to reset dispc\n"); + return ret; + } + + return 0; +} + +static int dispc_init_hw(struct dispc_device *dispc) +{ + struct device *dev = dispc->dev; + int ret; + + ret = pm_runtime_set_active(dev); + if (ret) { + dev_err(dev, "Failed to set DSS PM to active\n"); + return ret; + } + + ret = clk_prepare_enable(dispc->fclk); + if (ret) { + dev_err(dev, "Failed to enable DSS fclk\n"); + goto err_runtime_suspend; + } + + ret = dispc_softreset(dispc); if (ret) - dev_warn(dispc->dev, "failed to reset dispc\n"); + goto err_clk_disable; + + clk_disable_unprepare(dispc->fclk); + ret = pm_runtime_set_suspended(dev); + if (ret) { + dev_err(dev, "Failed to set DSS PM to suspended\n"); + return ret; + } + + return 0; + +err_clk_disable: + clk_disable_unprepare(dispc->fclk); + +err_runtime_suspend: + ret = pm_runtime_set_suspended(dev); + if (ret) { + dev_err(dev, "Failed to set DSS PM to suspended\n"); + return ret; + } + + return ret; } int dispc_init(struct tidss_device *tidss) @@ -2724,10 +2775,6 @@ return r; } - /* K2G display controller does not support soft reset */ - if (feat->subrev != DISPC_K2G) - dispc_softreset(dispc); - for (i = 0; i < dispc->feat->num_vps; i++) { u32 gamma_size = dispc->feat->vp_feat.color.gamma_size; u32 *gamma_table; @@ -2776,6 +2823,10 @@ of_property_read_u32(dispc->dev->of_node, "max-memory-bandwidth", &dispc->memory_bandwidth_limit); + r = dispc_init_hw(dispc); + if (r) + return r; + tidss->dispc = dispc; return 0; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/tidss/tidss_kms.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/tidss/tidss_kms.c @@ -4,8 +4,6 @@ * Author: Tomi Valkeinen */ -#include - #include #include #include @@ -25,7 +23,6 @@ { struct drm_device *ddev = old_state->dev; struct tidss_device *tidss = to_tidss(ddev); - bool fence_cookie = dma_fence_begin_signalling(); dev_dbg(ddev->dev, "%s\n", __func__); @@ -36,7 +33,6 @@ drm_atomic_helper_commit_modeset_enables(ddev, old_state); drm_atomic_helper_commit_hw_done(old_state); - dma_fence_end_signalling(fence_cookie); drm_atomic_helper_wait_for_flip_done(ddev, old_state); drm_atomic_helper_cleanup_planes(ddev, old_state); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/virtio/virtgpu_drv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/virtio/virtgpu_drv.c @@ -176,7 +176,8 @@ * If KMS is disabled DRIVER_MODESET and DRIVER_ATOMIC are masked * out via drm_device::driver_features: */ - .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC, + .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_RENDER | DRIVER_ATOMIC | + DRIVER_CURSOR_HOTSPOT, .open = virtio_gpu_driver_open, .postclose = virtio_gpu_driver_postclose, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/virtio/virtgpu_plane.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -79,6 +79,8 @@ { struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, + plane); bool is_cursor = plane->type == DRM_PLANE_TYPE_CURSOR; struct drm_crtc_state *crtc_state; int ret; @@ -86,6 +88,14 @@ if (!new_plane_state->fb || WARN_ON(!new_plane_state->crtc)) return 0; + /* + * Ignore damage clips if the framebuffer attached to the plane's state + * has changed since the last plane update (page-flip). In this case, a + * full plane update should happen because uploads are done per-buffer. + */ + if (old_plane_state->fb != new_plane_state->fb) + new_plane_state->ignore_damage_clips = true; + crtc_state = drm_atomic_get_crtc_state(state, new_plane_state->crtc); if (IS_ERR(crtc_state)) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1611,7 +1611,7 @@ static const struct drm_driver driver = { .driver_features = - DRIVER_MODESET | DRIVER_RENDER | DRIVER_ATOMIC | DRIVER_GEM, + DRIVER_MODESET | DRIVER_RENDER | DRIVER_ATOMIC | DRIVER_GEM | DRIVER_CURSOR_HOTSPOT, .ioctls = vmw_ioctls, .num_ioctls = ARRAY_SIZE(vmw_ioctls), .master_set = vmw_master_set, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/hid/hidraw.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/hid/hidraw.c @@ -355,8 +355,11 @@ down_write(&minors_rwsem); spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags); - for (int i = list->tail; i < list->head; i++) - kfree(list->buffer[i].value); + while (list->tail != list->head) { + kfree(list->buffer[list->tail].value); + list->buffer[list->tail].value = NULL; + list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1); + } list_del(&list->node); spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags); kfree(list); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/hwmon/hp-wmi-sensors.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/hwmon/hp-wmi-sensors.c @@ -17,6 +17,8 @@ * Available: https://github.com/linuxhw/ACPI * [4] P. Rohár, "bmfdec - Decompile binary MOF file (BMF) from WMI buffer", * 2017. [Online]. Available: https://github.com/pali/bmfdec + * [5] Microsoft Corporation, "Driver-Defined WMI Data Items", 2017. [Online]. + * Available: https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/driver-defined-wmi-data-items */ #include @@ -24,6 +26,7 @@ #include #include #include +#include #include #include @@ -395,6 +398,50 @@ struct mutex lock; /* Lock polling WMI and driver state changes. */ }; +static bool is_raw_wmi_string(const u8 *pointer, u32 length) +{ + const u16 *ptr; + u16 len; + + /* WMI strings are length-prefixed UTF-16 [5]. */ + if (length <= sizeof(*ptr)) + return false; + + length -= sizeof(*ptr); + ptr = (const u16 *)pointer; + len = *ptr; + + return len <= length && !(len & 1); +} + +static char *convert_raw_wmi_string(const u8 *buf) +{ + const wchar_t *src; + unsigned int cps; + unsigned int len; + char *dst; + int i; + + src = (const wchar_t *)buf; + + /* Count UTF-16 code points. Exclude trailing null padding. */ + cps = *src / sizeof(*src); + while (cps && !src[cps]) + cps--; + + /* Each code point becomes up to 3 UTF-8 characters. */ + len = min(cps * 3, HP_WMI_MAX_STR_SIZE - 1); + + dst = kmalloc((len + 1) * sizeof(*dst), GFP_KERNEL); + if (!dst) + return NULL; + + i = utf16s_to_utf8s(++src, cps, UTF16_LITTLE_ENDIAN, dst, len); + dst[i] = '\0'; + + return dst; +} + /* hp_wmi_strdup - devm_kstrdup, but length-limited */ static char *hp_wmi_strdup(struct device *dev, const char *src) { @@ -412,6 +459,23 @@ return dst; } +/* hp_wmi_wstrdup - hp_wmi_strdup, but for a raw WMI string */ +static char *hp_wmi_wstrdup(struct device *dev, const u8 *buf) +{ + char *src; + char *dst; + + src = convert_raw_wmi_string(buf); + if (!src) + return NULL; + + dst = hp_wmi_strdup(dev, strim(src)); /* Note: Copy is trimmed. */ + + kfree(src); + + return dst; +} + /* * hp_wmi_get_wobj - poll WMI for a WMI object instance * @guid: WMI object GUID @@ -476,8 +540,14 @@ for (prop = 0; prop <= last_prop; prop++) { type = elements[prop].type; valid_type = property_map[prop]; - if (type != valid_type) + if (type != valid_type) { + if (type == ACPI_TYPE_BUFFER && + valid_type == ACPI_TYPE_STRING && + is_raw_wmi_string(elements[prop].buffer.pointer, + elements[prop].buffer.length)) + continue; return -EINVAL; + } } return 0; @@ -494,7 +564,9 @@ break; case ACPI_TYPE_STRING: - *out_string = hp_wmi_strdup(dev, strim(element->string.pointer)); + *out_string = element->type == ACPI_TYPE_BUFFER ? + hp_wmi_wstrdup(dev, element->buffer.pointer) : + hp_wmi_strdup(dev, strim(element->string.pointer)); if (!*out_string) return -ENOMEM; break; @@ -875,7 +947,9 @@ { const union acpi_object *elements; const union acpi_object *element; - const char *string; + const char *new_string; + char *trimmed; + char *string; bool is_new; int offset; u8 size; @@ -899,11 +973,21 @@ offset = is_new ? size - 1 : -2; element = &elements[HP_WMI_PROPERTY_CURRENT_STATE + offset]; - string = strim(element->string.pointer); - - if (strcmp(string, nsensor->current_state)) { - devm_kfree(dev, nsensor->current_state); - nsensor->current_state = hp_wmi_strdup(dev, string); + string = element->type == ACPI_TYPE_BUFFER ? + convert_raw_wmi_string(element->buffer.pointer) : + element->string.pointer; + + if (string) { + trimmed = strim(string); + if (strcmp(trimmed, nsensor->current_state)) { + new_string = hp_wmi_strdup(dev, trimmed); + if (new_string) { + devm_kfree(dev, nsensor->current_state); + nsensor->current_state = new_string; + } + } + if (element->type == ACPI_TYPE_BUFFER) + kfree(string); } /* Old variant: -2 (not -1) because it lacks the Size property. */ @@ -1010,11 +1094,15 @@ HP_WMI_EVENT_PROPERTY_STATUS); } -static int populate_event_from_wobj(struct hp_wmi_event *event, +static int populate_event_from_wobj(struct device *dev, + struct hp_wmi_event *event, union acpi_object *wobj) { int prop = HP_WMI_EVENT_PROPERTY_NAME; union acpi_object *element; + acpi_object_type type; + char *string; + u32 value; int err; err = check_event_wobj(wobj); @@ -1023,20 +1111,24 @@ element = wobj->package.elements; - /* Extracted strings are NOT device-managed copies. */ - for (; prop <= HP_WMI_EVENT_PROPERTY_CATEGORY; prop++, element++) { + type = hp_wmi_event_property_map[prop]; + + err = extract_acpi_value(dev, element, type, &value, &string); + if (err) + return err; + switch (prop) { case HP_WMI_EVENT_PROPERTY_NAME: - event->name = strim(element->string.pointer); + event->name = string; break; case HP_WMI_EVENT_PROPERTY_DESCRIPTION: - event->description = strim(element->string.pointer); + event->description = string; break; case HP_WMI_EVENT_PROPERTY_CATEGORY: - event->category = element->integer.value; + event->category = value; break; default: @@ -1525,8 +1617,8 @@ struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; struct hp_wmi_sensors *state = context; struct device *dev = &state->wdev->dev; + struct hp_wmi_event event = {}; struct hp_wmi_info *fan_info; - struct hp_wmi_event event; union acpi_object *wobj; acpi_status err; int event_type; @@ -1560,7 +1652,7 @@ wobj = out.pointer; - err = populate_event_from_wobj(&event, wobj); + err = populate_event_from_wobj(dev, &event, wobj); if (err) { dev_warn(dev, "Bad event data (ACPI type %d)\n", wobj->type); goto out_free_wobj; @@ -1591,6 +1683,9 @@ out_free_wobj: kfree(wobj); + devm_kfree(dev, event.name); + devm_kfree(dev, event.description); + out_unlock: mutex_unlock(&state->lock); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/i2c/busses/i2c-s3c2410.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/i2c/busses/i2c-s3c2410.c @@ -217,8 +217,17 @@ int tries; for (tries = 50; tries; --tries) { - if (readl(i2c->regs + S3C2410_IICCON) - & S3C2410_IICCON_IRQPEND) { + unsigned long tmp = readl(i2c->regs + S3C2410_IICCON); + + if (!(tmp & S3C2410_IICCON_ACKEN)) { + /* + * Wait a bit for the bus to stabilize, + * delay estimated experimentally. + */ + usleep_range(100, 200); + return true; + } + if (tmp & S3C2410_IICCON_IRQPEND) { if (!(readl(i2c->regs + S3C2410_IICSTAT) & S3C2410_IICSTAT_LASTBIT)) return true; @@ -271,16 +280,6 @@ stat |= S3C2410_IICSTAT_START; writel(stat, i2c->regs + S3C2410_IICSTAT); - - if (i2c->quirks & QUIRK_POLL) { - while ((i2c->msg_num != 0) && is_ack(i2c)) { - i2c_s3c_irq_nextbyte(i2c, stat); - stat = readl(i2c->regs + S3C2410_IICSTAT); - - if (stat & S3C2410_IICSTAT_ARBITR) - dev_err(i2c->dev, "deal with arbitration loss\n"); - } - } } static inline void s3c24xx_i2c_stop(struct s3c24xx_i2c *i2c, int ret) @@ -687,7 +686,7 @@ static int s3c24xx_i2c_doxfer(struct s3c24xx_i2c *i2c, struct i2c_msg *msgs, int num) { - unsigned long timeout; + unsigned long timeout = 0; int ret; ret = s3c24xx_i2c_set_master(i2c); @@ -707,16 +706,19 @@ s3c24xx_i2c_message_start(i2c, msgs); if (i2c->quirks & QUIRK_POLL) { - ret = i2c->msg_idx; + while ((i2c->msg_num != 0) && is_ack(i2c)) { + unsigned long stat = readl(i2c->regs + S3C2410_IICSTAT); - if (ret != num) - dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret); + i2c_s3c_irq_nextbyte(i2c, stat); - goto out; + stat = readl(i2c->regs + S3C2410_IICSTAT); + if (stat & S3C2410_IICSTAT_ARBITR) + dev_err(i2c->dev, "deal with arbitration loss\n"); + } + } else { + timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); } - timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5); - ret = i2c->msg_idx; /* only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/idle/intel_idle.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/idle/intel_idle.c @@ -131,11 +131,12 @@ #define MWAIT2flg(eax) ((eax & 0xFF) << 24) static __always_inline int __intel_idle(struct cpuidle_device *dev, - struct cpuidle_driver *drv, int index) + struct cpuidle_driver *drv, + int index, bool irqoff) { struct cpuidle_state *state = &drv->states[index]; unsigned long eax = flg2MWAIT(state->flags); - unsigned long ecx = 1; /* break on interrupt flag */ + unsigned long ecx = 1*irqoff; /* break on interrupt flag */ mwait_idle_with_hints(eax, ecx); @@ -159,19 +160,13 @@ static __cpuidle int intel_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - return __intel_idle(dev, drv, index); + return __intel_idle(dev, drv, index, true); } static __cpuidle int intel_idle_irq(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - int ret; - - raw_local_irq_enable(); - ret = __intel_idle(dev, drv, index); - raw_local_irq_disable(); - - return ret; + return __intel_idle(dev, drv, index, false); } static __cpuidle int intel_idle_ibrs(struct cpuidle_device *dev, @@ -184,7 +179,7 @@ if (smt_active) native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); - ret = __intel_idle(dev, drv, index); + ret = __intel_idle(dev, drv, index, true); if (smt_active) native_wrmsrl(MSR_IA32_SPEC_CTRL, spec_ctrl); @@ -196,7 +191,7 @@ struct cpuidle_driver *drv, int index) { fpu_idle_fpregs(); - return __intel_idle(dev, drv, index); + return __intel_idle(dev, drv, index, true); } /** only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/iio/adc/ad7091r-base.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/iio/adc/ad7091r-base.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -28,6 +29,7 @@ #define AD7091R_REG_RESULT_CONV_RESULT(x) ((x) & 0xfff) /* AD7091R_REG_CONF */ +#define AD7091R_REG_CONF_ALERT_EN BIT(4) #define AD7091R_REG_CONF_AUTO BIT(8) #define AD7091R_REG_CONF_CMD BIT(10) @@ -49,6 +51,27 @@ struct mutex lock; /*lock to prevent concurent reads */ }; +const struct iio_event_spec ad7091r_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS), + }, +}; +EXPORT_SYMBOL_NS_GPL(ad7091r_events, IIO_AD7091R); + static int ad7091r_set_mode(struct ad7091r_state *st, enum ad7091r_mode mode) { int ret, conf; @@ -168,14 +191,148 @@ return ret; } +static int ad7091r_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct ad7091r_state *st = iio_priv(indio_dev); + int val, ret; + + switch (dir) { + case IIO_EV_DIR_RISING: + ret = regmap_read(st->map, + AD7091R_REG_CH_HIGH_LIMIT(chan->channel), + &val); + if (ret) + return ret; + return val != AD7091R_HIGH_LIMIT; + case IIO_EV_DIR_FALLING: + ret = regmap_read(st->map, + AD7091R_REG_CH_LOW_LIMIT(chan->channel), + &val); + if (ret) + return ret; + return val != AD7091R_LOW_LIMIT; + default: + return -EINVAL; + } +} + +static int ad7091r_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, int state) +{ + struct ad7091r_state *st = iio_priv(indio_dev); + + if (state) { + return regmap_set_bits(st->map, AD7091R_REG_CONF, + AD7091R_REG_CONF_ALERT_EN); + } else { + /* + * Set thresholds either to 0 or to 2^12 - 1 as appropriate to + * prevent alerts and thus disable event generation. + */ + switch (dir) { + case IIO_EV_DIR_RISING: + return regmap_write(st->map, + AD7091R_REG_CH_HIGH_LIMIT(chan->channel), + AD7091R_HIGH_LIMIT); + case IIO_EV_DIR_FALLING: + return regmap_write(st->map, + AD7091R_REG_CH_LOW_LIMIT(chan->channel), + AD7091R_LOW_LIMIT); + default: + return -EINVAL; + } + } +} + +static int ad7091r_read_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int *val, int *val2) +{ + struct ad7091r_state *st = iio_priv(indio_dev); + int ret; + + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + ret = regmap_read(st->map, + AD7091R_REG_CH_HIGH_LIMIT(chan->channel), + val); + if (ret) + return ret; + return IIO_VAL_INT; + case IIO_EV_DIR_FALLING: + ret = regmap_read(st->map, + AD7091R_REG_CH_LOW_LIMIT(chan->channel), + val); + if (ret) + return ret; + return IIO_VAL_INT; + default: + return -EINVAL; + } + case IIO_EV_INFO_HYSTERESIS: + ret = regmap_read(st->map, + AD7091R_REG_CH_HYSTERESIS(chan->channel), + val); + if (ret) + return ret; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int ad7091r_write_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int val, int val2) +{ + struct ad7091r_state *st = iio_priv(indio_dev); + + switch (info) { + case IIO_EV_INFO_VALUE: + switch (dir) { + case IIO_EV_DIR_RISING: + return regmap_write(st->map, + AD7091R_REG_CH_HIGH_LIMIT(chan->channel), + val); + case IIO_EV_DIR_FALLING: + return regmap_write(st->map, + AD7091R_REG_CH_LOW_LIMIT(chan->channel), + val); + default: + return -EINVAL; + } + case IIO_EV_INFO_HYSTERESIS: + return regmap_write(st->map, + AD7091R_REG_CH_HYSTERESIS(chan->channel), + val); + default: + return -EINVAL; + } +} + static const struct iio_info ad7091r_info = { .read_raw = ad7091r_read_raw, + .read_event_config = &ad7091r_read_event_config, + .write_event_config = &ad7091r_write_event_config, + .read_event_value = &ad7091r_read_event_value, + .write_event_value = &ad7091r_write_event_value, }; static irqreturn_t ad7091r_event_handler(int irq, void *private) { - struct ad7091r_state *st = (struct ad7091r_state *) private; - struct iio_dev *iio_dev = dev_get_drvdata(st->dev); + struct iio_dev *iio_dev = private; + struct ad7091r_state *st = iio_priv(iio_dev); unsigned int i, read_val; int ret; s64 timestamp = iio_get_time_ns(iio_dev); @@ -232,9 +389,14 @@ iio_dev->channels = chip_info->channels; if (irq) { + ret = regmap_update_bits(st->map, AD7091R_REG_CONF, + AD7091R_REG_CONF_ALERT_EN, BIT(4)); + if (ret) + return ret; + ret = devm_request_threaded_irq(dev, irq, NULL, ad7091r_event_handler, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, st); + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, name, iio_dev); if (ret) return ret; } @@ -243,7 +405,14 @@ if (IS_ERR(st->vref)) { if (PTR_ERR(st->vref) == -EPROBE_DEFER) return -EPROBE_DEFER; + st->vref = NULL; + /* Enable internal vref */ + ret = regmap_set_bits(st->map, AD7091R_REG_CONF, + AD7091R_REG_CONF_INT_VREF); + if (ret) + return dev_err_probe(st->dev, ret, + "Error on enable internal reference\n"); } else { ret = regulator_enable(st->vref); if (ret) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/iio/adc/ad7091r-base.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/iio/adc/ad7091r-base.h @@ -8,6 +8,12 @@ #ifndef __DRIVERS_IIO_ADC_AD7091R_BASE_H__ #define __DRIVERS_IIO_ADC_AD7091R_BASE_H__ +#define AD7091R_REG_CONF_INT_VREF BIT(0) + +/* AD7091R_REG_CH_LIMIT */ +#define AD7091R_HIGH_LIMIT 0xFFF +#define AD7091R_LOW_LIMIT 0x0 + struct device; struct ad7091r_state; @@ -17,6 +23,8 @@ unsigned int vref_mV; }; +extern const struct iio_event_spec ad7091r_events[3]; + extern const struct regmap_config ad7091r_regmap_config; int ad7091r_probe(struct device *dev, const char *name, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/iio/adc/ad7091r5.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/iio/adc/ad7091r5.c @@ -12,26 +12,6 @@ #include "ad7091r-base.h" -static const struct iio_event_spec ad7091r5_events[] = { - { - .type = IIO_EV_TYPE_THRESH, - .dir = IIO_EV_DIR_RISING, - .mask_separate = BIT(IIO_EV_INFO_VALUE) | - BIT(IIO_EV_INFO_ENABLE), - }, - { - .type = IIO_EV_TYPE_THRESH, - .dir = IIO_EV_DIR_FALLING, - .mask_separate = BIT(IIO_EV_INFO_VALUE) | - BIT(IIO_EV_INFO_ENABLE), - }, - { - .type = IIO_EV_TYPE_THRESH, - .dir = IIO_EV_DIR_EITHER, - .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS), - }, -}; - #define AD7091R_CHANNEL(idx, bits, ev, num_ev) { \ .type = IIO_VOLTAGE, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ @@ -44,10 +24,10 @@ .scan_type.realbits = bits, \ } static const struct iio_chan_spec ad7091r5_channels_irq[] = { - AD7091R_CHANNEL(0, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)), - AD7091R_CHANNEL(1, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)), - AD7091R_CHANNEL(2, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)), - AD7091R_CHANNEL(3, 12, ad7091r5_events, ARRAY_SIZE(ad7091r5_events)), + AD7091R_CHANNEL(0, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), + AD7091R_CHANNEL(1, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), + AD7091R_CHANNEL(2, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), + AD7091R_CHANNEL(3, 12, ad7091r_events, ARRAY_SIZE(ad7091r_events)), }; static const struct iio_chan_spec ad7091r5_channels_noirq[] = { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/iio/adc/ad9467.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/iio/adc/ad9467.c @@ -4,8 +4,9 @@ * * Copyright 2012-2020 Analog Devices Inc. */ - +#include #include +#include #include #include #include @@ -119,9 +120,11 @@ struct spi_device *spi; struct clk *clk; unsigned int output_mode; + unsigned int (*scales)[2]; struct gpio_desc *pwrdown_gpio; - struct gpio_desc *reset_gpio; + /* ensure consistent state obtained on multiple related accesses */ + struct mutex lock; }; static int ad9467_spi_read(struct spi_device *spi, unsigned int reg) @@ -162,10 +165,12 @@ int ret; if (readval == NULL) { + guard(mutex)(&st->lock); ret = ad9467_spi_write(spi, reg, writeval); - ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, - AN877_ADC_TRANSFER_SYNC); - return ret; + if (ret) + return ret; + return ad9467_spi_write(spi, AN877_ADC_REG_TRANSFER, + AN877_ADC_TRANSFER_SYNC); } ret = ad9467_spi_read(spi, reg); @@ -212,6 +217,7 @@ .channel = _chan, \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \ .scan_index = _si, \ .scan_type = { \ .sign = _sign, \ @@ -273,10 +279,13 @@ const struct ad9467_chip_info *info1 = to_ad9467_chip_info(info); struct ad9467_state *st = adi_axi_adc_conv_priv(conv); unsigned int i, vref_val; + int ret; - vref_val = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); + ret = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); + if (ret < 0) + return ret; - vref_val &= info1->vref_mask; + vref_val = ret & info1->vref_mask; for (i = 0; i < info->num_scales; i++) { if (vref_val == info->scale_table[i][1]) @@ -297,6 +306,7 @@ struct ad9467_state *st = adi_axi_adc_conv_priv(conv); unsigned int scale_val[2]; unsigned int i; + int ret; if (val != 0) return -EINVAL; @@ -306,11 +316,14 @@ if (scale_val[0] != val || scale_val[1] != val2) continue; - ad9467_spi_write(st->spi, AN877_ADC_REG_VREF, - info->scale_table[i][1]); - ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, - AN877_ADC_TRANSFER_SYNC); - return 0; + guard(mutex)(&st->lock); + ret = ad9467_spi_write(st->spi, AN877_ADC_REG_VREF, + info->scale_table[i][1]); + if (ret < 0) + return ret; + + return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, + AN877_ADC_TRANSFER_SYNC); } return -EINVAL; @@ -359,6 +372,26 @@ } } +static int ad9467_read_avail(struct adi_axi_adc_conv *conv, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + const struct adi_axi_adc_chip_info *info = conv->chip_info; + struct ad9467_state *st = adi_axi_adc_conv_priv(conv); + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + *vals = (const int *)st->scales; + *type = IIO_VAL_INT_PLUS_MICRO; + /* Values are stored in a 2D matrix */ + *length = info->num_scales * 2; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + static int ad9467_outputmode_set(struct spi_device *spi, unsigned int mode) { int ret; @@ -371,6 +404,26 @@ AN877_ADC_TRANSFER_SYNC); } +static int ad9467_scale_fill(struct adi_axi_adc_conv *conv) +{ + const struct adi_axi_adc_chip_info *info = conv->chip_info; + struct ad9467_state *st = adi_axi_adc_conv_priv(conv); + unsigned int i, val1, val2; + + st->scales = devm_kmalloc_array(&st->spi->dev, info->num_scales, + sizeof(*st->scales), GFP_KERNEL); + if (!st->scales) + return -ENOMEM; + + for (i = 0; i < info->num_scales; i++) { + __ad9467_get_scale(conv, i, &val1, &val2); + st->scales[i][0] = val1; + st->scales[i][1] = val2; + } + + return 0; +} + static int ad9467_preenable_setup(struct adi_axi_adc_conv *conv) { struct ad9467_state *st = adi_axi_adc_conv_priv(conv); @@ -378,6 +431,21 @@ return ad9467_outputmode_set(st->spi, st->output_mode); } +static int ad9467_reset(struct device *dev) +{ + struct gpio_desc *gpio; + + gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR_OR_NULL(gpio)) + return PTR_ERR_OR_ZERO(gpio); + + fsleep(1); + gpiod_set_value_cansleep(gpio, 0); + fsleep(10 * USEC_PER_MSEC); + + return 0; +} + static int ad9467_probe(struct spi_device *spi) { const struct ad9467_chip_info *info; @@ -408,21 +476,16 @@ if (IS_ERR(st->pwrdown_gpio)) return PTR_ERR(st->pwrdown_gpio); - st->reset_gpio = devm_gpiod_get_optional(&spi->dev, "reset", - GPIOD_OUT_LOW); - if (IS_ERR(st->reset_gpio)) - return PTR_ERR(st->reset_gpio); - - if (st->reset_gpio) { - udelay(1); - ret = gpiod_direction_output(st->reset_gpio, 1); - if (ret) - return ret; - mdelay(10); - } + ret = ad9467_reset(&spi->dev); + if (ret) + return ret; conv->chip_info = &info->axi_adc_info; + ret = ad9467_scale_fill(conv); + if (ret) + return ret; + id = ad9467_spi_read(spi, AN877_ADC_REG_CHIP_ID); if (id != conv->chip_info->id) { dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n", @@ -433,6 +496,7 @@ conv->reg_access = ad9467_reg_access; conv->write_raw = ad9467_write_raw; conv->read_raw = ad9467_read_raw; + conv->read_avail = ad9467_read_avail; conv->preenable_setup = ad9467_preenable_setup; st->output_mode = info->default_output_mode | only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/iio/adc/adi-axi-adc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/iio/adc/adi-axi-adc.c @@ -143,6 +143,20 @@ return conv->write_raw(conv, chan, val, val2, mask); } +static int adi_axi_adc_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct adi_axi_adc_state *st = iio_priv(indio_dev); + struct adi_axi_adc_conv *conv = &st->client->conv; + + if (!conv->read_avail) + return -EOPNOTSUPP; + + return conv->read_avail(conv, chan, vals, type, length, mask); +} + static int adi_axi_adc_update_scan_mode(struct iio_dev *indio_dev, const unsigned long *scan_mask) { @@ -227,69 +241,11 @@ } EXPORT_SYMBOL_NS_GPL(devm_adi_axi_adc_conv_register, IIO_ADI_AXI); -static ssize_t in_voltage_scale_available_show(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct adi_axi_adc_state *st = iio_priv(indio_dev); - struct adi_axi_adc_conv *conv = &st->client->conv; - size_t len = 0; - int i; - - for (i = 0; i < conv->chip_info->num_scales; i++) { - const unsigned int *s = conv->chip_info->scale_table[i]; - - len += scnprintf(buf + len, PAGE_SIZE - len, - "%u.%06u ", s[0], s[1]); - } - buf[len - 1] = '\n'; - - return len; -} - -static IIO_DEVICE_ATTR_RO(in_voltage_scale_available, 0); - -enum { - ADI_AXI_ATTR_SCALE_AVAIL, -}; - -#define ADI_AXI_ATTR(_en_, _file_) \ - [ADI_AXI_ATTR_##_en_] = &iio_dev_attr_##_file_.dev_attr.attr - -static struct attribute *adi_axi_adc_attributes[] = { - ADI_AXI_ATTR(SCALE_AVAIL, in_voltage_scale_available), - NULL -}; - -static umode_t axi_adc_attr_is_visible(struct kobject *kobj, - struct attribute *attr, int n) -{ - struct device *dev = kobj_to_dev(kobj); - struct iio_dev *indio_dev = dev_to_iio_dev(dev); - struct adi_axi_adc_state *st = iio_priv(indio_dev); - struct adi_axi_adc_conv *conv = &st->client->conv; - - switch (n) { - case ADI_AXI_ATTR_SCALE_AVAIL: - if (!conv->chip_info->num_scales) - return 0; - return attr->mode; - default: - return attr->mode; - } -} - -static const struct attribute_group adi_axi_adc_attribute_group = { - .attrs = adi_axi_adc_attributes, - .is_visible = axi_adc_attr_is_visible, -}; - static const struct iio_info adi_axi_adc_info = { .read_raw = &adi_axi_adc_read_raw, .write_raw = &adi_axi_adc_write_raw, - .attrs = &adi_axi_adc_attribute_group, .update_scan_mode = &adi_axi_adc_update_scan_mode, + .read_avail = &adi_axi_adc_read_avail, }; static const struct adi_axi_adc_core_info adi_axi_adc_10_0_a_info = { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/infiniband/hw/hns/hns_roce_pd.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/hw/hns/hns_roce_pd.c @@ -150,7 +150,7 @@ int ret; if (!(hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_XRC)) - return -EINVAL; + return -EOPNOTSUPP; ret = hns_roce_xrcd_alloc(hr_dev, &xrcd->xrcdn); if (ret) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/infiniband/hw/mthca/mthca_cmd.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -635,7 +635,7 @@ int mthca_SYS_EN(struct mthca_dev *dev) { - u64 out; + u64 out = 0; int ret; ret = mthca_cmd_imm(dev, 0, &out, 0, 0, CMD_SYS_EN, CMD_TIME_CLASS_D); @@ -1955,7 +1955,7 @@ int mthca_MGID_HASH(struct mthca_dev *dev, struct mthca_mailbox *mailbox, u16 *hash) { - u64 imm; + u64 imm = 0; int err; err = mthca_cmd_imm(dev, mailbox->dma, &imm, 0, 0, CMD_MGID_HASH, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/infiniband/hw/mthca/mthca_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/hw/mthca/mthca_main.c @@ -382,7 +382,7 @@ struct mthca_init_hca_param *init_hca, u64 icm_size) { - u64 aux_pages; + u64 aux_pages = 0; int err; err = mthca_SET_ICM_SIZE(mdev, icm_size, &aux_pages); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -531,21 +531,18 @@ if (test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) rec.join_state = SENDONLY_FULLMEMBER_JOIN; } - spin_unlock_irq(&priv->lock); multicast = ib_sa_join_multicast(&ipoib_sa_client, priv->ca, priv->port, - &rec, comp_mask, GFP_KERNEL, + &rec, comp_mask, GFP_ATOMIC, ipoib_mcast_join_complete, mcast); - spin_lock_irq(&priv->lock); if (IS_ERR(multicast)) { ret = PTR_ERR(multicast); ipoib_warn(priv, "ib_sa_join_multicast failed, status %d\n", ret); /* Requeue this join task with a backoff delay */ __ipoib_mcast_schedule_join_thread(priv, mcast, 1); clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); - spin_unlock_irq(&priv->lock); complete(&mcast->done); - spin_lock_irq(&priv->lock); + return ret; } return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/infiniband/ulp/iser/iscsi_iser.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/ulp/iser/iscsi_iser.h @@ -317,12 +317,10 @@ * * @mr: memory region * @sig_mr: signature memory region - * @mr_valid: is mr valid indicator */ struct iser_reg_resources { struct ib_mr *mr; struct ib_mr *sig_mr; - u8 mr_valid:1; }; /** only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/infiniband/ulp/iser/iser_initiator.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/ulp/iser/iser_initiator.c @@ -581,7 +581,10 @@ return -EINVAL; } - desc->rsc.mr_valid = 0; + if (desc->sig_protected) + desc->rsc.sig_mr->need_inval = false; + else + desc->rsc.mr->need_inval = false; return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/infiniband/ulp/iser/iser_memory.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/ulp/iser/iser_memory.c @@ -264,7 +264,7 @@ iser_set_prot_checks(iser_task->sc, &sig_attrs->check_mask); - if (rsc->mr_valid) + if (rsc->sig_mr->need_inval) iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr); ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); @@ -288,7 +288,7 @@ wr->access = IB_ACCESS_LOCAL_WRITE | IB_ACCESS_REMOTE_READ | IB_ACCESS_REMOTE_WRITE; - rsc->mr_valid = 1; + rsc->sig_mr->need_inval = true; sig_reg->sge.lkey = mr->lkey; sig_reg->rkey = mr->rkey; @@ -313,7 +313,7 @@ struct ib_reg_wr *wr = &tx_desc->reg_wr; int n; - if (rsc->mr_valid) + if (rsc->mr->need_inval) iser_inv_rkey(&tx_desc->inv_wr, mr, cqe, &wr->wr); ib_update_fast_reg_key(mr, ib_inc_rkey(mr->rkey)); @@ -336,7 +336,7 @@ IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_READ; - rsc->mr_valid = 1; + rsc->mr->need_inval = true; reg->sge.lkey = mr->lkey; reg->rkey = mr->rkey; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/infiniband/ulp/iser/iser_verbs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/infiniband/ulp/iser/iser_verbs.c @@ -129,7 +129,6 @@ goto err_alloc_mr_integrity; } } - desc->rsc.mr_valid = 0; return desc; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c @@ -243,6 +243,7 @@ static const struct of_device_id qcom_smmu_client_of_match[] __maybe_unused = { { .compatible = "qcom,adreno" }, + { .compatible = "qcom,adreno-gmu" }, { .compatible = "qcom,mdp4" }, { .compatible = "qcom,mdss" }, { .compatible = "qcom,sc7180-mdss" }, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/iommu/dma-iommu.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/iommu/dma-iommu.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "dma-iommu.h" @@ -1038,6 +1039,8 @@ return DMA_MAPPING_ERROR; } + trace_swiotlb_bounced(dev, phys, size); + aligned_size = iova_align(iovad, size); phys = swiotlb_tbl_map_single(dev, phys, size, aligned_size, iova_mask(iovad), dir, attrs); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/leds/trigger/ledtrig-panic.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/leds/trigger/ledtrig-panic.c @@ -64,10 +64,13 @@ static int __init ledtrig_panic_init(void) { + led_trigger_register_simple("panic", &trigger); + if (!trigger) + return -ENOMEM; + atomic_notifier_chain_register(&panic_notifier_list, &led_trigger_panic_nb); - led_trigger_register_simple("panic", &trigger); panic_blink = led_panic_blink; return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/mailbox/arm_mhuv2.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mailbox/arm_mhuv2.c @@ -553,7 +553,8 @@ priv = chan->con_priv; if (!IS_PROTOCOL_DOORBELL(priv)) { - writel_relaxed(1, &mhu->send->ch_wn[priv->ch_wn_idx + priv->windows - 1].int_clr); + for (i = 0; i < priv->windows; i++) + writel_relaxed(1, &mhu->send->ch_wn[priv->ch_wn_idx + i].int_clr); if (chan->cl) { mbox_chan_txdone(chan, 0); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/common/videobuf2/videobuf2-dma-sg.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/common/videobuf2/videobuf2-dma-sg.c @@ -488,9 +488,15 @@ static int vb2_dma_sg_dmabuf_ops_vmap(struct dma_buf *dbuf, struct iosys_map *map) { - struct vb2_dma_sg_buf *buf = dbuf->priv; + struct vb2_dma_sg_buf *buf; + void *vaddr; - iosys_map_set_vaddr(map, buf->vaddr); + buf = dbuf->priv; + vaddr = vb2_dma_sg_vaddr(buf->vb, buf); + if (!vaddr) + return -EINVAL; + + iosys_map_set_vaddr(map, vaddr); return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/dvb-core/dvbdev.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/dvb-core/dvbdev.c @@ -104,6 +104,8 @@ err = file->f_op->open(inode, file); up_read(&minor_rwsem); mutex_unlock(&dvbdev_mutex); + if (err) + dvb_device_put(dvbdev); return err; } fail: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/i2c/imx335.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/i2c/imx335.c @@ -971,8 +971,8 @@ imx335->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, &imx335_ctrl_ops, V4L2_CID_HBLANK, - IMX335_REG_MIN, - IMX335_REG_MAX, + mode->hblank, + mode->hblank, 1, mode->hblank); if (imx335->hblank_ctrl) imx335->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/i2c/imx355.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/i2c/imx355.c @@ -1788,10 +1788,6 @@ goto error_handler_free; } - ret = v4l2_async_register_subdev_sensor(&imx355->sd); - if (ret < 0) - goto error_media_entity; - /* * Device is already turned on by i2c-core with ACPI domain PM. * Enable runtime PM and turn off the device. @@ -1800,9 +1796,15 @@ pm_runtime_enable(&client->dev); pm_runtime_idle(&client->dev); + ret = v4l2_async_register_subdev_sensor(&imx355->sd); + if (ret < 0) + goto error_media_entity_runtime_pm; + return 0; -error_media_entity: +error_media_entity_runtime_pm: + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); media_entity_cleanup(&imx355->sd.entity); error_handler_free: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/i2c/ov01a10.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/i2c/ov01a10.c @@ -907,6 +907,7 @@ v4l2_ctrl_handler_free(sd->ctrl_handler); pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); } static int ov01a10_probe(struct i2c_client *client) @@ -953,17 +954,26 @@ goto err_media_entity_cleanup; } + /* + * Device is already turned on by i2c-core with ACPI domain PM. + * Enable runtime PM and turn off the device. + */ + pm_runtime_set_active(&client->dev); + pm_runtime_enable(dev); + pm_runtime_idle(dev); + ret = v4l2_async_register_subdev_sensor(&ov01a10->sd); if (ret < 0) { dev_err(dev, "Failed to register subdev: %d\n", ret); - goto err_media_entity_cleanup; + goto err_pm_disable; } - pm_runtime_enable(dev); - pm_runtime_idle(dev); - return 0; +err_pm_disable: + pm_runtime_disable(dev); + pm_runtime_set_suspended(&client->dev); + err_media_entity_cleanup: media_entity_cleanup(&ov01a10->sd.entity); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/i2c/ov13b10.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/i2c/ov13b10.c @@ -1438,24 +1438,27 @@ goto error_handler_free; } - ret = v4l2_async_register_subdev_sensor(&ov13b->sd); - if (ret < 0) - goto error_media_entity; /* * Device is already turned on by i2c-core with ACPI domain PM. * Enable runtime PM and turn off the device. */ - /* Set the device's state to active if it's in D0 state. */ if (full_power) pm_runtime_set_active(&client->dev); pm_runtime_enable(&client->dev); pm_runtime_idle(&client->dev); + ret = v4l2_async_register_subdev_sensor(&ov13b->sd); + if (ret < 0) + goto error_media_entity_runtime_pm; + return 0; -error_media_entity: +error_media_entity_runtime_pm: + pm_runtime_disable(&client->dev); + if (full_power) + pm_runtime_set_suspended(&client->dev); media_entity_cleanup(&ov13b->sd.entity); error_handler_free: @@ -1475,6 +1478,7 @@ ov13b10_free_controls(ov13b); pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); } static const struct dev_pm_ops ov13b10_pm_ops = { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/i2c/ov9734.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/i2c/ov9734.c @@ -939,6 +939,7 @@ media_entity_cleanup(&sd->entity); v4l2_ctrl_handler_free(sd->ctrl_handler); pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); mutex_destroy(&ov9734->mutex); } @@ -984,13 +985,6 @@ goto probe_error_v4l2_ctrl_handler_free; } - ret = v4l2_async_register_subdev_sensor(&ov9734->sd); - if (ret < 0) { - dev_err(&client->dev, "failed to register V4L2 subdev: %d", - ret); - goto probe_error_media_entity_cleanup; - } - /* * Device is already turned on by i2c-core with ACPI domain PM. * Enable runtime PM and turn off the device. @@ -999,9 +993,18 @@ pm_runtime_enable(&client->dev); pm_runtime_idle(&client->dev); + ret = v4l2_async_register_subdev_sensor(&ov9734->sd); + if (ret < 0) { + dev_err(&client->dev, "failed to register V4L2 subdev: %d", + ret); + goto probe_error_media_entity_cleanup_pm; + } + return 0; -probe_error_media_entity_cleanup: +probe_error_media_entity_cleanup_pm: + pm_runtime_disable(&client->dev); + pm_runtime_set_suspended(&client->dev); media_entity_cleanup(&ov9734->sd.entity); probe_error_v4l2_ctrl_handler_free: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/i2c/st-mipid02.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/i2c/st-mipid02.c @@ -759,6 +759,7 @@ struct v4l2_subdev_format *format) { struct mipid02_dev *bridge = to_mipid02_dev(sd); + struct v4l2_subdev_format source_fmt; struct v4l2_mbus_framefmt *fmt; format->format.code = get_fmt_code(format->format.code); @@ -770,8 +771,12 @@ *fmt = format->format; - /* Propagate the format change to the source pad */ - mipid02_set_fmt_source(sd, sd_state, format); + /* + * Propagate the format change to the source pad, taking + * care not to update the format pointer given back to user + */ + source_fmt = *format; + mipid02_set_fmt_source(sd, sd_state, &source_fmt); } static int mipid02_set_fmt(struct v4l2_subdev *sd, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/pci/ddbridge/ddbridge-main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/pci/ddbridge/ddbridge-main.c @@ -238,7 +238,7 @@ ddb_unmap(dev); pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); - return -1; + return stat; } /****************************************************************************/ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/platform/nxp/imx-mipi-csis.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/nxp/imx-mipi-csis.c @@ -1513,8 +1513,10 @@ v4l2_async_nf_cleanup(&csis->notifier); v4l2_async_unregister_subdev(&csis->sd); + if (!pm_runtime_enabled(&pdev->dev)) + mipi_csis_runtime_suspend(&pdev->dev); + pm_runtime_disable(&pdev->dev); - mipi_csis_runtime_suspend(&pdev->dev); mipi_csis_clk_disable(csis); v4l2_subdev_cleanup(&csis->sd); media_entity_cleanup(&csis->sd.entity); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/platform/rockchip/rga/rga.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/rockchip/rga/rga.c @@ -184,7 +184,7 @@ static struct rga_fmt formats[] = { { .fourcc = V4L2_PIX_FMT_ARGB32, - .color_swap = RGA_COLOR_RB_SWAP, + .color_swap = RGA_COLOR_ALPHA_SWAP, .hw_format = RGA_COLOR_FMT_ABGR8888, .depth = 32, .uv_factor = 1, @@ -192,17 +192,8 @@ .x_div = 1, }, { - .fourcc = V4L2_PIX_FMT_XRGB32, - .color_swap = RGA_COLOR_RB_SWAP, - .hw_format = RGA_COLOR_FMT_XBGR8888, - .depth = 32, - .uv_factor = 1, - .y_div = 1, - .x_div = 1, - }, - { .fourcc = V4L2_PIX_FMT_ABGR32, - .color_swap = RGA_COLOR_ALPHA_SWAP, + .color_swap = RGA_COLOR_RB_SWAP, .hw_format = RGA_COLOR_FMT_ABGR8888, .depth = 32, .uv_factor = 1, @@ -211,7 +202,7 @@ }, { .fourcc = V4L2_PIX_FMT_XBGR32, - .color_swap = RGA_COLOR_ALPHA_SWAP, + .color_swap = RGA_COLOR_RB_SWAP, .hw_format = RGA_COLOR_FMT_XBGR8888, .depth = 32, .uv_factor = 1, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h @@ -61,6 +61,14 @@ RKISP1_CIF_ISP_EXP_END | \ RKISP1_CIF_ISP_HIST_MEASURE_RDY) +/* IRQ lines */ +enum rkisp1_irq_line { + RKISP1_IRQ_ISP = 0, + RKISP1_IRQ_MI, + RKISP1_IRQ_MIPI, + RKISP1_NUM_IRQS, +}; + /* enum for the resizer pads */ enum rkisp1_rsz_pad { RKISP1_RSZ_PAD_SINK, @@ -441,7 +449,6 @@ * struct rkisp1_device - ISP platform device * * @base_addr: base register address - * @irq: the irq number * @dev: a pointer to the struct device * @clk_size: number of clocks * @clks: array of clocks @@ -459,6 +466,7 @@ * @stream_lock: serializes {start/stop}_streaming callbacks between the capture devices. * @debug: debug params to be exposed on debugfs * @info: version-specific ISP information + * @irqs: IRQ line numbers */ struct rkisp1_device { void __iomem *base_addr; @@ -479,6 +487,7 @@ struct mutex stream_lock; /* serialize {start/stop}_streaming cb between capture devices */ struct rkisp1_debug debug; const struct rkisp1_info *info; + int irqs[RKISP1_NUM_IRQS]; }; /* only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/rockchip/rkisp1/rkisp1-csi.c @@ -141,8 +141,20 @@ struct rkisp1_device *rkisp1 = csi->rkisp1; u32 val; - /* Mask and clear interrupts. */ + /* Mask MIPI interrupts. */ rkisp1_write(rkisp1, RKISP1_CIF_MIPI_IMSC, 0); + + /* Flush posted writes */ + rkisp1_read(rkisp1, RKISP1_CIF_MIPI_IMSC); + + /* + * Wait until the IRQ handler has ended. The IRQ handler may get called + * even after this, but it will return immediately as the MIPI + * interrupts have been masked. + */ + synchronize_irq(rkisp1->irqs[RKISP1_IRQ_MIPI]); + + /* Clear MIPI interrupt status */ rkisp1_write(rkisp1, RKISP1_CIF_MIPI_ICR, ~0); val = rkisp1_read(rkisp1, RKISP1_CIF_MIPI_CTRL); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -114,6 +114,7 @@ struct rkisp1_isr_data { const char *name; irqreturn_t (*isr)(int irq, void *ctx); + u32 line_mask; }; /* ---------------------------------------------------------------------------- @@ -442,17 +443,25 @@ static irqreturn_t rkisp1_isr(int irq, void *ctx) { + irqreturn_t ret = IRQ_NONE; + /* * Call rkisp1_capture_isr() first to handle the frame that * potentially completed using the current frame_sequence number before * it is potentially incremented by rkisp1_isp_isr() in the vertical * sync. */ - rkisp1_capture_isr(irq, ctx); - rkisp1_isp_isr(irq, ctx); - rkisp1_csi_isr(irq, ctx); - return IRQ_HANDLED; + if (rkisp1_capture_isr(irq, ctx) == IRQ_HANDLED) + ret = IRQ_HANDLED; + + if (rkisp1_isp_isr(irq, ctx) == IRQ_HANDLED) + ret = IRQ_HANDLED; + + if (rkisp1_csi_isr(irq, ctx) == IRQ_HANDLED) + ret = IRQ_HANDLED; + + return ret; } static const char * const px30_isp_clks[] = { @@ -463,9 +472,9 @@ }; static const struct rkisp1_isr_data px30_isp_isrs[] = { - { "isp", rkisp1_isp_isr }, - { "mi", rkisp1_capture_isr }, - { "mipi", rkisp1_csi_isr }, + { "isp", rkisp1_isp_isr, BIT(RKISP1_IRQ_ISP) }, + { "mi", rkisp1_capture_isr, BIT(RKISP1_IRQ_MI) }, + { "mipi", rkisp1_csi_isr, BIT(RKISP1_IRQ_MIPI) }, }; static const struct rkisp1_info px30_isp_info = { @@ -484,7 +493,7 @@ }; static const struct rkisp1_isr_data rk3399_isp_isrs[] = { - { NULL, rkisp1_isr }, + { NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) | BIT(RKISP1_IRQ_MIPI) }, }; static const struct rkisp1_info rk3399_isp_info = { @@ -535,6 +544,9 @@ if (IS_ERR(rkisp1->base_addr)) return PTR_ERR(rkisp1->base_addr); + for (unsigned int il = 0; il < ARRAY_SIZE(rkisp1->irqs); ++il) + rkisp1->irqs[il] = -1; + for (i = 0; i < info->isr_size; i++) { irq = info->isrs[i].name ? platform_get_irq_byname(pdev, info->isrs[i].name) @@ -542,6 +554,11 @@ if (irq < 0) return irq; + for (unsigned int il = 0; il < ARRAY_SIZE(rkisp1->irqs); ++il) { + if (info->isrs[i].line_mask & BIT(il)) + rkisp1->irqs[il] = irq; + } + ret = devm_request_irq(dev, irq, info->isrs[i].isr, IRQF_SHARED, dev_driver_string(dev), dev); if (ret) { @@ -582,7 +599,7 @@ ret = v4l2_device_register(rkisp1->dev, &rkisp1->v4l2_dev); if (ret) - goto err_pm_runtime_disable; + goto err_media_dev_cleanup; ret = media_device_register(&rkisp1->media_dev); if (ret) { @@ -617,6 +634,8 @@ media_device_unregister(&rkisp1->media_dev); err_unreg_v4l2_dev: v4l2_device_unregister(&rkisp1->v4l2_dev); +err_media_dev_cleanup: + media_device_cleanup(&rkisp1->media_dev); err_pm_runtime_disable: pm_runtime_disable(&pdev->dev); return ret; @@ -637,6 +656,8 @@ media_device_unregister(&rkisp1->media_dev); v4l2_device_unregister(&rkisp1->v4l2_dev); + media_device_cleanup(&rkisp1->media_dev); + pm_runtime_disable(&pdev->dev); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/rockchip/rkisp1/rkisp1-isp.c @@ -281,11 +281,25 @@ * ISP(mi) stop in mi frame end -> Stop ISP(mipi) -> * Stop ISP(isp) ->wait for ISP isp off */ - /* stop and clear MI and ISP interrupts */ - rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, 0); - rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, ~0); + /* Mask MI and ISP interrupts */ + rkisp1_write(rkisp1, RKISP1_CIF_ISP_IMSC, 0); rkisp1_write(rkisp1, RKISP1_CIF_MI_IMSC, 0); + + /* Flush posted writes */ + rkisp1_read(rkisp1, RKISP1_CIF_MI_IMSC); + + /* + * Wait until the IRQ handler has ended. The IRQ handler may get called + * even after this, but it will return immediately as the MI and ISP + * interrupts have been masked. + */ + synchronize_irq(rkisp1->irqs[RKISP1_IRQ_ISP]); + if (rkisp1->irqs[RKISP1_IRQ_ISP] != rkisp1->irqs[RKISP1_IRQ_MI]) + synchronize_irq(rkisp1->irqs[RKISP1_IRQ_MI]); + + /* Clear MI and ISP interrupt status */ + rkisp1_write(rkisp1, RKISP1_CIF_ISP_ICR, ~0); rkisp1_write(rkisp1, RKISP1_CIF_MI_ICR, ~0); /* stop ISP */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/platform/rockchip/rkisp1/rkisp1-resizer.c @@ -363,12 +363,8 @@ { struct rkisp1_resizer *rsz = container_of(sd, struct rkisp1_resizer, sd); - struct v4l2_subdev_pad_config dummy_cfg; - struct v4l2_subdev_state pad_state = { - .pads = &dummy_cfg - }; - u32 pad = code->pad; - int ret; + unsigned int index = code->index; + unsigned int i; if (code->pad == RKISP1_RSZ_PAD_SRC) { /* supported mbus codes on the src are the same as in the capture */ @@ -388,15 +384,29 @@ return 0; } - /* supported mbus codes on the sink pad are the same as isp src pad */ - code->pad = RKISP1_ISP_PAD_SOURCE_VIDEO; - ret = v4l2_subdev_call(&rsz->rkisp1->isp.sd, pad, enum_mbus_code, - &pad_state, code); - - /* restore pad */ - code->pad = pad; - code->flags = 0; - return ret; + /* + * Supported mbus codes on the sink pad are the same as on the ISP + * source pad. + */ + for (i = 0; ; i++) { + const struct rkisp1_mbus_info *fmt = + rkisp1_mbus_info_get_by_index(i); + + if (!fmt) + break; + + if (!(fmt->direction & RKISP1_ISP_SD_SRC)) + continue; + + if (!index) { + code->code = fmt->mbus_code; + return 0; + } + + index--; + } + + return -EINVAL; } static int rkisp1_rsz_init_config(struct v4l2_subdev *sd, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/test-drivers/visl/visl-video.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/test-drivers/visl/visl-video.c @@ -525,6 +525,9 @@ .vidioc_streamon = v4l2_m2m_ioctl_streamon, .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, + .vidioc_decoder_cmd = v4l2_m2m_ioctl_stateless_decoder_cmd, + .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_stateless_try_decoder_cmd, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/usb/cx231xx/cx231xx-core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/usb/cx231xx/cx231xx-core.c @@ -1024,6 +1024,7 @@ if (!dev->video_mode.isoc_ctl.urb) { dev_err(dev->dev, "cannot alloc memory for usb buffers\n"); + kfree(dma_q->p_left_data); return -ENOMEM; } @@ -1033,6 +1034,7 @@ dev_err(dev->dev, "cannot allocate memory for usbtransfer\n"); kfree(dev->video_mode.isoc_ctl.urb); + kfree(dma_q->p_left_data); return -ENOMEM; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/usb/pvrusb2/pvrusb2-context.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/usb/pvrusb2/pvrusb2-context.c @@ -268,7 +268,8 @@ { pvr2_hdw_disconnect(mp->hdw); mp->disconnect_flag = !0; - pvr2_context_notify(mp); + if (!pvr2_context_shutok()) + pvr2_context_notify(mp); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/usb/stk1160/stk1160-video.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/usb/stk1160/stk1160-video.c @@ -107,8 +107,7 @@ /* * TODO: These stk1160_dbg are very spammy! - * We should 1) check why we are getting them - * and 2) add ratelimit. + * We should check why we are getting them. * * UPDATE: One of the reasons (the only one?) for getting these * is incorrect standard (mismatch between expected and configured). @@ -151,7 +150,7 @@ /* Let the bug hunt begin! sanity checks! */ if (lencopy < 0) { - stk1160_dbg("copy skipped: negative lencopy\n"); + printk_ratelimited(KERN_DEBUG "copy skipped: negative lencopy\n"); return; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/media/usb/uvc/uvc_driver.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/media/usb/uvc/uvc_driver.c @@ -2592,6 +2592,15 @@ .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited }, + /* Chicony Electronics Co., Ltd Integrated Camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x04f2, + .idProduct = 0xb67c, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = UVC_PC_PROTOCOL_15, + .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_uvc11 }, /* Chicony EasyCamera */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -2994,6 +3003,15 @@ .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_FORCE_BPP) }, + /* SunplusIT Inc HD Camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x2b7e, + .idProduct = 0xb752, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = UVC_PC_PROTOCOL_15, + .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_uvc11 }, /* Lenovo Integrated Camera */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/mfd/intel-lpss.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mfd/intel-lpss.c @@ -301,8 +301,8 @@ snprintf(name, sizeof(name), "%s-div", devname); tmp = clk_register_fractional_divider(NULL, name, __clk_get_name(tmp), + 0, lpss->priv, 1, 15, 16, 15, CLK_FRAC_DIVIDER_POWER_OF_TWO_PS, - lpss->priv, 1, 15, 16, 15, 0, NULL); if (IS_ERR(tmp)) return PTR_ERR(tmp); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/mfd/rk8xx-core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mfd/rk8xx-core.c @@ -53,76 +53,68 @@ }; static const struct mfd_cell rk805s[] = { - { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, }, - { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, }, - { .name = "rk805-pinctrl", .id = PLATFORM_DEVID_NONE, }, + { .name = "rk808-clkout", }, + { .name = "rk808-regulator", }, + { .name = "rk805-pinctrl", }, { .name = "rk808-rtc", .num_resources = ARRAY_SIZE(rtc_resources), .resources = &rtc_resources[0], - .id = PLATFORM_DEVID_NONE, }, { .name = "rk805-pwrkey", .num_resources = ARRAY_SIZE(rk805_key_resources), .resources = &rk805_key_resources[0], - .id = PLATFORM_DEVID_NONE, }, }; static const struct mfd_cell rk806s[] = { - { .name = "rk805-pinctrl", .id = PLATFORM_DEVID_AUTO, }, - { .name = "rk808-regulator", .id = PLATFORM_DEVID_AUTO, }, + { .name = "rk805-pinctrl", }, + { .name = "rk808-regulator", }, { .name = "rk805-pwrkey", .resources = rk806_pwrkey_resources, .num_resources = ARRAY_SIZE(rk806_pwrkey_resources), - .id = PLATFORM_DEVID_AUTO, }, }; static const struct mfd_cell rk808s[] = { - { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, }, - { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, }, + { .name = "rk808-clkout", }, + { .name = "rk808-regulator", }, { .name = "rk808-rtc", .num_resources = ARRAY_SIZE(rtc_resources), .resources = rtc_resources, - .id = PLATFORM_DEVID_NONE, }, }; static const struct mfd_cell rk817s[] = { - { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, }, - { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, }, + { .name = "rk808-clkout", }, + { .name = "rk808-regulator", }, { .name = "rk805-pwrkey", .num_resources = ARRAY_SIZE(rk817_pwrkey_resources), .resources = &rk817_pwrkey_resources[0], - .id = PLATFORM_DEVID_NONE, }, { .name = "rk808-rtc", .num_resources = ARRAY_SIZE(rk817_rtc_resources), .resources = &rk817_rtc_resources[0], - .id = PLATFORM_DEVID_NONE, }, - { .name = "rk817-codec", .id = PLATFORM_DEVID_NONE, }, + { .name = "rk817-codec", }, { .name = "rk817-charger", .num_resources = ARRAY_SIZE(rk817_charger_resources), .resources = &rk817_charger_resources[0], - .id = PLATFORM_DEVID_NONE, }, }; static const struct mfd_cell rk818s[] = { - { .name = "rk808-clkout", .id = PLATFORM_DEVID_NONE, }, - { .name = "rk808-regulator", .id = PLATFORM_DEVID_NONE, }, + { .name = "rk808-clkout", }, + { .name = "rk808-regulator", }, { .name = "rk808-rtc", .num_resources = ARRAY_SIZE(rtc_resources), .resources = rtc_resources, - .id = PLATFORM_DEVID_NONE, }, }; @@ -680,7 +672,7 @@ pre_init_reg[i].addr); } - ret = devm_mfd_add_devices(dev, 0, cells, nr_cells, NULL, 0, + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, cells, nr_cells, NULL, 0, regmap_irq_get_domain(rk808->irq_data)); if (ret) return dev_err_probe(dev, ret, "failed to add MFD devices\n"); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/mfd/syscon.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mfd/syscon.c @@ -105,6 +105,10 @@ } syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%pa", np, &res.start); + if (!syscon_config.name) { + ret = -ENOMEM; + goto err_regmap; + } syscon_config.reg_stride = reg_io_width; syscon_config.val_bits = reg_io_width * 8; syscon_config.max_register = resource_size(&res) - reg_io_width; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/mfd/tps6594-core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mfd/tps6594-core.c @@ -433,6 +433,9 @@ tps6594_irq_chip.name = devm_kasprintf(dev, GFP_KERNEL, "%s-%ld-0x%02x", dev->driver->name, tps->chip_id, tps->reg); + if (!tps6594_irq_chip.name) + return -ENOMEM; + ret = devm_regmap_add_irq_chip(dev, tps->regmap, tps->irq, IRQF_SHARED | IRQF_ONESHOT, 0, &tps6594_irq_chip, &tps->irq_data); if (ret) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/misc/lis3lv02d/lis3lv02d_i2c.c @@ -150,6 +150,7 @@ lis3_dev.init = lis3_i2c_init; lis3_dev.read = lis3_i2c_read; lis3_dev.write = lis3_i2c_write; + lis3_dev.reg_ctrl = lis3_reg_ctrl; lis3_dev.irq = client->irq; lis3_dev.ac = lis3lv02d_axis_map; lis3_dev.pm_dev = &client->dev; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/mmc/host/mmc_spi.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mmc/host/mmc_spi.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -119,19 +119,14 @@ struct spi_transfer status; struct spi_message readback; - /* underlying DMA-aware controller, or null */ - struct device *dma_dev; - /* buffer used for commands and for message "overhead" */ struct scratch *data; - dma_addr_t data_dma; /* Specs say to write ones most of the time, even when the card * has no need to read its input data; and many cards won't care. * This is our source of those ones. */ void *ones; - dma_addr_t ones_dma; }; @@ -147,11 +142,8 @@ return spi_setup(host->spi); } -static int -mmc_spi_readbytes(struct mmc_spi_host *host, unsigned len) +static int mmc_spi_readbytes(struct mmc_spi_host *host, unsigned int len) { - int status; - if (len > sizeof(*host->data)) { WARN_ON(1); return -EIO; @@ -159,19 +151,7 @@ host->status.len = len; - if (host->dma_dev) - dma_sync_single_for_device(host->dma_dev, - host->data_dma, sizeof(*host->data), - DMA_FROM_DEVICE); - - status = spi_sync_locked(host->spi, &host->readback); - - if (host->dma_dev) - dma_sync_single_for_cpu(host->dma_dev, - host->data_dma, sizeof(*host->data), - DMA_FROM_DEVICE); - - return status; + return spi_sync_locked(host->spi, &host->readback); } static int mmc_spi_skip(struct mmc_spi_host *host, unsigned long timeout, @@ -506,23 +486,11 @@ t = &host->t; memset(t, 0, sizeof(*t)); t->tx_buf = t->rx_buf = data->status; - t->tx_dma = t->rx_dma = host->data_dma; t->len = cp - data->status; t->cs_change = 1; spi_message_add_tail(t, &host->m); - if (host->dma_dev) { - host->m.is_dma_mapped = 1; - dma_sync_single_for_device(host->dma_dev, - host->data_dma, sizeof(*host->data), - DMA_BIDIRECTIONAL); - } status = spi_sync_locked(host->spi, &host->m); - - if (host->dma_dev) - dma_sync_single_for_cpu(host->dma_dev, - host->data_dma, sizeof(*host->data), - DMA_BIDIRECTIONAL); if (status < 0) { dev_dbg(&host->spi->dev, " ... write returned %d\n", status); cmd->error = status; @@ -540,9 +508,6 @@ * We always provide TX data for data and CRC. The MMC/SD protocol * requires us to write ones; but Linux defaults to writing zeroes; * so we explicitly initialize it to all ones on RX paths. - * - * We also handle DMA mapping, so the underlying SPI controller does - * not need to (re)do it for each message. */ static void mmc_spi_setup_data_message( @@ -552,11 +517,8 @@ { struct spi_transfer *t; struct scratch *scratch = host->data; - dma_addr_t dma = host->data_dma; spi_message_init(&host->m); - if (dma) - host->m.is_dma_mapped = 1; /* for reads, readblock() skips 0xff bytes before finding * the token; for writes, this transfer issues that token. @@ -570,8 +532,6 @@ else scratch->data_token = SPI_TOKEN_SINGLE; t->tx_buf = &scratch->data_token; - if (dma) - t->tx_dma = dma + offsetof(struct scratch, data_token); spi_message_add_tail(t, &host->m); } @@ -581,7 +541,6 @@ t = &host->t; memset(t, 0, sizeof(*t)); t->tx_buf = host->ones; - t->tx_dma = host->ones_dma; /* length and actual buffer info are written later */ spi_message_add_tail(t, &host->m); @@ -591,14 +550,9 @@ if (direction == DMA_TO_DEVICE) { /* the actual CRC may get written later */ t->tx_buf = &scratch->crc_val; - if (dma) - t->tx_dma = dma + offsetof(struct scratch, crc_val); } else { t->tx_buf = host->ones; - t->tx_dma = host->ones_dma; t->rx_buf = &scratch->crc_val; - if (dma) - t->rx_dma = dma + offsetof(struct scratch, crc_val); } spi_message_add_tail(t, &host->m); @@ -621,10 +575,7 @@ memset(t, 0, sizeof(*t)); t->len = (direction == DMA_TO_DEVICE) ? sizeof(scratch->status) : 1; t->tx_buf = host->ones; - t->tx_dma = host->ones_dma; t->rx_buf = scratch->status; - if (dma) - t->rx_dma = dma + offsetof(struct scratch, status); t->cs_change = 1; spi_message_add_tail(t, &host->m); } @@ -653,23 +604,13 @@ if (host->mmc->use_spi_crc) scratch->crc_val = cpu_to_be16(crc_itu_t(0, t->tx_buf, t->len)); - if (host->dma_dev) - dma_sync_single_for_device(host->dma_dev, - host->data_dma, sizeof(*scratch), - DMA_BIDIRECTIONAL); status = spi_sync_locked(spi, &host->m); - if (status != 0) { dev_dbg(&spi->dev, "write error (%d)\n", status); return status; } - if (host->dma_dev) - dma_sync_single_for_cpu(host->dma_dev, - host->data_dma, sizeof(*scratch), - DMA_BIDIRECTIONAL); - /* * Get the transmission data-response reply. It must follow * immediately after the data block we transferred. This reply @@ -718,8 +659,6 @@ } t->tx_buf += t->len; - if (host->dma_dev) - t->tx_dma += t->len; /* Return when not busy. If we didn't collect that status yet, * we'll need some more I/O. @@ -783,30 +722,12 @@ } leftover = status << 1; - if (host->dma_dev) { - dma_sync_single_for_device(host->dma_dev, - host->data_dma, sizeof(*scratch), - DMA_BIDIRECTIONAL); - dma_sync_single_for_device(host->dma_dev, - t->rx_dma, t->len, - DMA_FROM_DEVICE); - } - status = spi_sync_locked(spi, &host->m); if (status < 0) { dev_dbg(&spi->dev, "read error %d\n", status); return status; } - if (host->dma_dev) { - dma_sync_single_for_cpu(host->dma_dev, - host->data_dma, sizeof(*scratch), - DMA_BIDIRECTIONAL); - dma_sync_single_for_cpu(host->dma_dev, - t->rx_dma, t->len, - DMA_FROM_DEVICE); - } - if (bitshift) { /* Walk through the data and the crc and do * all the magic to get byte-aligned data. @@ -841,8 +762,6 @@ } t->rx_buf += t->len; - if (host->dma_dev) - t->rx_dma += t->len; return 0; } @@ -857,7 +776,6 @@ struct mmc_data *data, u32 blk_size) { struct spi_device *spi = host->spi; - struct device *dma_dev = host->dma_dev; struct spi_transfer *t; enum dma_data_direction direction = mmc_get_dma_dir(data); struct scatterlist *sg; @@ -884,31 +802,8 @@ */ for_each_sg(data->sg, sg, data->sg_len, n_sg) { int status = 0; - dma_addr_t dma_addr = 0; void *kmap_addr; unsigned length = sg->length; - enum dma_data_direction dir = direction; - - /* set up dma mapping for controller drivers that might - * use DMA ... though they may fall back to PIO - */ - if (dma_dev) { - /* never invalidate whole *shared* pages ... */ - if ((sg->offset != 0 || length != PAGE_SIZE) - && dir == DMA_FROM_DEVICE) - dir = DMA_BIDIRECTIONAL; - - dma_addr = dma_map_page(dma_dev, sg_page(sg), 0, - PAGE_SIZE, dir); - if (dma_mapping_error(dma_dev, dma_addr)) { - data->error = -EFAULT; - break; - } - if (direction == DMA_TO_DEVICE) - t->tx_dma = dma_addr + sg->offset; - else - t->rx_dma = dma_addr + sg->offset; - } /* allow pio too; we don't allow highmem */ kmap_addr = kmap(sg_page(sg)); @@ -941,8 +836,6 @@ if (direction == DMA_FROM_DEVICE) flush_dcache_page(sg_page(sg)); kunmap(sg_page(sg)); - if (dma_dev) - dma_unmap_page(dma_dev, dma_addr, PAGE_SIZE, dir); if (status < 0) { data->error = status; @@ -977,21 +870,9 @@ scratch->status[0] = SPI_TOKEN_STOP_TRAN; host->early_status.tx_buf = host->early_status.rx_buf; - host->early_status.tx_dma = host->early_status.rx_dma; host->early_status.len = statlen; - if (host->dma_dev) - dma_sync_single_for_device(host->dma_dev, - host->data_dma, sizeof(*scratch), - DMA_BIDIRECTIONAL); - tmp = spi_sync_locked(spi, &host->m); - - if (host->dma_dev) - dma_sync_single_for_cpu(host->dma_dev, - host->data_dma, sizeof(*scratch), - DMA_BIDIRECTIONAL); - if (tmp < 0) { if (!data->error) data->error = tmp; @@ -1265,52 +1146,6 @@ return IRQ_HANDLED; } -#ifdef CONFIG_HAS_DMA -static int mmc_spi_dma_alloc(struct mmc_spi_host *host) -{ - struct spi_device *spi = host->spi; - struct device *dev; - - if (!spi->master->dev.parent->dma_mask) - return 0; - - dev = spi->master->dev.parent; - - host->ones_dma = dma_map_single(dev, host->ones, MMC_SPI_BLOCKSIZE, - DMA_TO_DEVICE); - if (dma_mapping_error(dev, host->ones_dma)) - return -ENOMEM; - - host->data_dma = dma_map_single(dev, host->data, sizeof(*host->data), - DMA_BIDIRECTIONAL); - if (dma_mapping_error(dev, host->data_dma)) { - dma_unmap_single(dev, host->ones_dma, MMC_SPI_BLOCKSIZE, - DMA_TO_DEVICE); - return -ENOMEM; - } - - dma_sync_single_for_cpu(dev, host->data_dma, sizeof(*host->data), - DMA_BIDIRECTIONAL); - - host->dma_dev = dev; - return 0; -} - -static void mmc_spi_dma_free(struct mmc_spi_host *host) -{ - if (!host->dma_dev) - return; - - dma_unmap_single(host->dma_dev, host->ones_dma, MMC_SPI_BLOCKSIZE, - DMA_TO_DEVICE); - dma_unmap_single(host->dma_dev, host->data_dma, sizeof(*host->data), - DMA_BIDIRECTIONAL); -} -#else -static inline int mmc_spi_dma_alloc(struct mmc_spi_host *host) { return 0; } -static inline void mmc_spi_dma_free(struct mmc_spi_host *host) {} -#endif - static int mmc_spi_probe(struct spi_device *spi) { void *ones; @@ -1402,24 +1237,17 @@ host->powerup_msecs = 250; } - /* preallocate dma buffers */ + /* Preallocate buffers */ host->data = kmalloc(sizeof(*host->data), GFP_KERNEL); if (!host->data) goto fail_nobuf1; - status = mmc_spi_dma_alloc(host); - if (status) - goto fail_dma; - /* setup message for status/busy readback */ spi_message_init(&host->readback); - host->readback.is_dma_mapped = (host->dma_dev != NULL); spi_message_add_tail(&host->status, &host->readback); host->status.tx_buf = host->ones; - host->status.tx_dma = host->ones_dma; host->status.rx_buf = &host->data->status; - host->status.rx_dma = host->data_dma + offsetof(struct scratch, status); host->status.cs_change = 1; /* register card detect irq */ @@ -1464,9 +1292,8 @@ if (!status) has_ro = true; - dev_info(&spi->dev, "SD/MMC host %s%s%s%s%s\n", + dev_info(&spi->dev, "SD/MMC host %s%s%s%s\n", dev_name(&mmc->class_dev), - host->dma_dev ? "" : ", no DMA", has_ro ? "" : ", no WP", (host->pdata && host->pdata->setpower) ? "" : ", no poweroff", @@ -1477,8 +1304,6 @@ fail_gpiod_request: mmc_remove_host(mmc); fail_glue_init: - mmc_spi_dma_free(host); -fail_dma: kfree(host->data); fail_nobuf1: mmc_spi_put_pdata(spi); @@ -1500,7 +1325,6 @@ mmc_remove_host(mmc); - mmc_spi_dma_free(host); kfree(host->data); kfree(host->ones); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/mtd/maps/vmu-flash.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mtd/maps/vmu-flash.c @@ -719,7 +719,7 @@ card = maple_get_drvdata(mdev); for (x = 0; x < card->partitions; x++) { mtd = &((card->mtd)[x]); - if (mtd->usecount > 0) + if (kref_read(&mtd->refcnt)) return 0; } return 1; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/mtd/mtd_blkdevs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mtd/mtd_blkdevs.c @@ -463,7 +463,7 @@ { struct mtd_blktrans_ops *tr; - if (mtd->type == MTD_ABSENT) + if (mtd->type == MTD_ABSENT || mtd->type == MTD_UBIVOLUME) return; list_for_each_entry(tr, &blktrans_majors, list) @@ -503,7 +503,7 @@ mutex_lock(&mtd_table_mutex); list_add(&tr->list, &blktrans_majors); mtd_for_each_device(mtd) - if (mtd->type != MTD_ABSENT) + if (mtd->type != MTD_ABSENT && mtd->type != MTD_UBIVOLUME) tr->add_mtd(tr, mtd); mutex_unlock(&mtd_table_mutex); return 0; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/mtd/nand/raw/fsl_ifc_nand.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/mtd/nand/raw/fsl_ifc_nand.c @@ -20,7 +20,7 @@ #define ERR_BYTE 0xFF /* Value returned for read bytes when read failed */ -#define IFC_TIMEOUT_MSECS 500 /* Maximum number of mSecs to wait +#define IFC_TIMEOUT_MSECS 1000 /* Maximum timeout to wait for IFC NAND Machine */ struct fsl_ifc_ctrl; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/amt.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/amt.c @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -80,11 +80,11 @@ static struct amt_skb_cb *amt_skb_cb(struct sk_buff *skb) { - BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct qdisc_skb_cb) > + BUILD_BUG_ON(sizeof(struct amt_skb_cb) + sizeof(struct tc_skb_cb) > sizeof_field(struct sk_buff, cb)); return (struct amt_skb_cb *)((void *)skb->cb + - sizeof(struct qdisc_skb_cb)); + sizeof(struct tc_skb_cb)); } static void __amt_source_gc_work(void) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/bonding/bond_alb.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/bonding/bond_alb.c @@ -985,7 +985,8 @@ if (netif_is_macvlan(upper) && !strict_match) { tags = bond_verify_device_path(bond->dev, upper, 0); if (IS_ERR_OR_NULL(tags)) - BUG(); + return -ENOMEM; + alb_send_lp_vid(slave, upper->dev_addr, tags[0].vlan_proto, tags[0].vlan_id); kfree(tags); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/dsa/mt7530.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/dsa/mt7530.c @@ -2848,8 +2848,7 @@ /* MT753x MAC works in 1G full duplex mode for all up-clocked * variants. */ - if (interface == PHY_INTERFACE_MODE_INTERNAL || - interface == PHY_INTERFACE_MODE_TRGMII || + if (interface == PHY_INTERFACE_MODE_TRGMII || (phy_interface_mode_is_8023z(interface))) { speed = SPEED_1000; duplex = DUPLEX_FULL; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/dsa/mv88e6xxx/chip.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/dsa/mv88e6xxx/chip.h @@ -620,8 +620,8 @@ int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port); int (*serdes_get_strings)(struct mv88e6xxx_chip *chip, int port, uint8_t *data); - int (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port, - uint64_t *data); + size_t (*serdes_get_stats)(struct mv88e6xxx_chip *chip, int port, + uint64_t *data); /* SERDES registers for ethtool */ int (*serdes_get_regs_len)(struct mv88e6xxx_chip *chip, int port); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/dsa/mv88e6xxx/serdes.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/dsa/mv88e6xxx/serdes.c @@ -338,8 +338,8 @@ return val; } -int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, - uint64_t *data) +size_t mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, + uint64_t *data) { struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port]; struct mv88e6352_serdes_hw_stat *stat; @@ -348,7 +348,7 @@ err = mv88e6352_g2_scratch_port_has_serdes(chip, port); if (err <= 0) - return err; + return 0; BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) > ARRAY_SIZE(mv88e6xxx_port->serdes_stats)); @@ -795,8 +795,8 @@ return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32); } -int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, - uint64_t *data) +size_t mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, + uint64_t *data) { struct mv88e6390_serdes_hw_stat *stat; int lane; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/dsa/mv88e6xxx/serdes.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/dsa/mv88e6xxx/serdes.h @@ -169,13 +169,13 @@ int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, int port, uint8_t *data); -int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, - uint64_t *data); +size_t mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, + uint64_t *data); int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip, int port, uint8_t *data); -int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, - uint64_t *data); +size_t mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, + uint64_t *data); int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port); void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/dsa/vitesse-vsc73xx-core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/dsa/vitesse-vsc73xx-core.c @@ -1119,6 +1119,8 @@ vsc->gc.label = devm_kasprintf(vsc->dev, GFP_KERNEL, "VSC%04x", vsc->chipid); + if (!vsc->gc.label) + return -ENOMEM; vsc->gc.ngpio = 4; vsc->gc.owner = THIS_MODULE; vsc->gc.parent = vsc->dev; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/amd/pds_core/debugfs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/debugfs.c @@ -64,6 +64,10 @@ void pdsc_debugfs_add_ident(struct pdsc *pdsc) { + /* This file will already exist in the reset flow */ + if (debugfs_lookup("identity", pdsc->dentry)) + return; + debugfs_create_file("identity", 0400, pdsc->dentry, pdsc, &identity_fops); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/amd/pds_core/fw.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/fw.c @@ -107,6 +107,9 @@ dev_info(pdsc->dev, "Installing firmware\n"); + if (!pdsc->cmd_regs) + return -ENXIO; + dl = priv_to_devlink(pdsc); devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/amd/pds_core/main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/amd/pds_core/main.c @@ -37,6 +37,11 @@ struct pdsc_dev_bar *bars = pdsc->bars; unsigned int i; + pdsc->info_regs = NULL; + pdsc->cmd_regs = NULL; + pdsc->intr_status = NULL; + pdsc->intr_ctrl = NULL; + for (i = 0; i < PDS_CORE_BARS_MAX; i++) { if (bars[i].vaddr) pci_iounmap(pdsc->pdev, bars[i].vaddr); @@ -293,7 +298,7 @@ err_out_teardown: pdsc_teardown(pdsc, PDSC_TEARDOWN_REMOVING); err_out_unmap_bars: - del_timer_sync(&pdsc->wdtimer); + timer_shutdown_sync(&pdsc->wdtimer); if (pdsc->wq) destroy_workqueue(pdsc->wq); mutex_destroy(&pdsc->config_lock); @@ -421,7 +426,7 @@ */ pdsc_sriov_configure(pdev, 0); - del_timer_sync(&pdsc->wdtimer); + timer_shutdown_sync(&pdsc->wdtimer); if (pdsc->wq) destroy_workqueue(pdsc->wq); @@ -434,7 +439,6 @@ mutex_destroy(&pdsc->config_lock); mutex_destroy(&pdsc->devcmd_lock); - pci_free_irq_vectors(pdev); pdsc_unmap_bars(pdsc); pci_release_regions(pdev); } @@ -447,12 +451,76 @@ devlink_free(dl); } +static void pdsc_stop_health_thread(struct pdsc *pdsc) +{ + timer_shutdown_sync(&pdsc->wdtimer); + if (pdsc->health_work.func) + cancel_work_sync(&pdsc->health_work); +} + +static void pdsc_restart_health_thread(struct pdsc *pdsc) +{ + timer_setup(&pdsc->wdtimer, pdsc_wdtimer_cb, 0); + mod_timer(&pdsc->wdtimer, jiffies + 1); +} + +static void pdsc_reset_prepare(struct pci_dev *pdev) +{ + struct pdsc *pdsc = pci_get_drvdata(pdev); + + pdsc_stop_health_thread(pdsc); + pdsc_fw_down(pdsc); + + pdsc_unmap_bars(pdsc); + pci_release_regions(pdev); + pci_disable_device(pdev); +} + +static void pdsc_reset_done(struct pci_dev *pdev) +{ + struct pdsc *pdsc = pci_get_drvdata(pdev); + struct device *dev = pdsc->dev; + int err; + + err = pci_enable_device(pdev); + if (err) { + dev_err(dev, "Cannot enable PCI device: %pe\n", ERR_PTR(err)); + return; + } + pci_set_master(pdev); + + if (!pdev->is_virtfn) { + pcie_print_link_status(pdsc->pdev); + + err = pci_request_regions(pdsc->pdev, PDS_CORE_DRV_NAME); + if (err) { + dev_err(pdsc->dev, "Cannot request PCI regions: %pe\n", + ERR_PTR(err)); + return; + } + + err = pdsc_map_bars(pdsc); + if (err) + return; + } + + pdsc_fw_up(pdsc); + pdsc_restart_health_thread(pdsc); +} + +static const struct pci_error_handlers pdsc_err_handler = { + /* FLR handling */ + .reset_prepare = pdsc_reset_prepare, + .reset_done = pdsc_reset_done, +}; + static struct pci_driver pdsc_driver = { .name = PDS_CORE_DRV_NAME, .id_table = pdsc_id_table, .probe = pdsc_probe, .remove = pdsc_remove, .sriov_configure = pdsc_sriov_configure, + .err_handler = &pdsc_err_handler, }; void *pdsc_get_pf_struct(struct pci_dev *vf_pdev) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_ring.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/aquantia/atlantic/aq_ring.h @@ -183,14 +183,14 @@ self->sw_head - self->sw_tail - 1); } -struct aq_ring_s *aq_ring_tx_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic, - unsigned int idx, - struct aq_nic_cfg_s *aq_nic_cfg); -struct aq_ring_s *aq_ring_rx_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic, - unsigned int idx, - struct aq_nic_cfg_s *aq_nic_cfg); +int aq_ring_tx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg); +int aq_ring_rx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, + unsigned int idx, + struct aq_nic_cfg_s *aq_nic_cfg); int aq_ring_init(struct aq_ring_s *self, const enum atl_ring_type ring_type); void aq_ring_rx_deinit(struct aq_ring_s *self); @@ -207,9 +207,9 @@ int budget); int aq_ring_rx_fill(struct aq_ring_s *self); -struct aq_ring_s *aq_ring_hwts_rx_alloc(struct aq_ring_s *self, - struct aq_nic_s *aq_nic, unsigned int idx, - unsigned int size, unsigned int dx_size); +int aq_ring_hwts_rx_alloc(struct aq_ring_s *self, + struct aq_nic_s *aq_nic, unsigned int idx, + unsigned int size, unsigned int dx_size); void aq_ring_hwts_rx_clean(struct aq_ring_s *self, struct aq_nic_s *aq_nic); unsigned int aq_ring_fill_stats_data(struct aq_ring_s *self, u64 *data); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/aquantia/atlantic/aq_vec.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/aquantia/atlantic/aq_vec.c @@ -136,35 +136,32 @@ const unsigned int idx_ring = AQ_NIC_CFG_TCVEC2RING(aq_nic_cfg, i, idx); - ring = aq_ring_tx_alloc(&self->ring[i][AQ_VEC_TX_ID], aq_nic, - idx_ring, aq_nic_cfg); - if (!ring) { - err = -ENOMEM; + ring = &self->ring[i][AQ_VEC_TX_ID]; + err = aq_ring_tx_alloc(ring, aq_nic, idx_ring, aq_nic_cfg); + if (err) goto err_exit; - } ++self->tx_rings; aq_nic_set_tx_ring(aq_nic, idx_ring, ring); - if (xdp_rxq_info_reg(&self->ring[i][AQ_VEC_RX_ID].xdp_rxq, + ring = &self->ring[i][AQ_VEC_RX_ID]; + if (xdp_rxq_info_reg(&ring->xdp_rxq, aq_nic->ndev, idx, self->napi.napi_id) < 0) { err = -ENOMEM; goto err_exit; } - if (xdp_rxq_info_reg_mem_model(&self->ring[i][AQ_VEC_RX_ID].xdp_rxq, + if (xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, MEM_TYPE_PAGE_SHARED, NULL) < 0) { - xdp_rxq_info_unreg(&self->ring[i][AQ_VEC_RX_ID].xdp_rxq); + xdp_rxq_info_unreg(&ring->xdp_rxq); err = -ENOMEM; goto err_exit; } - ring = aq_ring_rx_alloc(&self->ring[i][AQ_VEC_RX_ID], aq_nic, - idx_ring, aq_nic_cfg); - if (!ring) { - xdp_rxq_info_unreg(&self->ring[i][AQ_VEC_RX_ID].xdp_rxq); - err = -ENOMEM; + err = aq_ring_rx_alloc(ring, aq_nic, idx_ring, aq_nic_cfg); + if (err) { + xdp_rxq_info_unreg(&ring->xdp_rxq); goto err_exit; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/google/gve/gve_tx_dqo.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/google/gve/gve_tx_dqo.c @@ -351,6 +351,7 @@ /* Validates and prepares `skb` for TSO. * * Returns header length, or < 0 if invalid. + * Warning : Might change skb->head (and thus skb_shinfo). */ static int gve_prep_tso(struct sk_buff *skb) { @@ -452,8 +453,8 @@ static int gve_tx_add_skb_no_copy_dqo(struct gve_tx_ring *tx, struct sk_buff *skb) { - const struct skb_shared_info *shinfo = skb_shinfo(skb); const bool is_gso = skb_is_gso(skb); + struct skb_shared_info *shinfo; u32 desc_idx = tx->dqo_tx.tail; struct gve_tx_pending_packet_dqo *pkt; @@ -478,6 +479,8 @@ desc_idx = (desc_idx + 1) & tx->mask; } + /* Must get after gve_prep_tso(), which can change shinfo. */ + shinfo = skb_shinfo(skb); gve_tx_fill_general_ctx_desc(&tx->dqo.tx_ring[desc_idx].general_ctx, &metadata); desc_idx = (desc_idx + 1) & tx->mask; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/e1000e/e1000.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/e1000e/e1000.h @@ -360,23 +360,43 @@ * As a result, a shift of INCVALUE_SHIFT_n is used to fit a value of * INCVALUE_n into the TIMINCA register allowing 32+8+(24-INCVALUE_SHIFT_n) * bits to count nanoseconds leaving the rest for fractional nonseconds. + * + * Any given INCVALUE also has an associated maximum adjustment value. This + * maximum adjustment value is the largest increase (or decrease) which can be + * safely applied without overflowing the INCVALUE. Since INCVALUE has + * a maximum range of 24 bits, its largest value is 0xFFFFFF. + * + * To understand where the maximum value comes from, consider the following + * equation: + * + * new_incval = base_incval + (base_incval * adjustment) / 1billion + * + * To avoid overflow that means: + * max_incval = base_incval + (base_incval * max_adj) / billion + * + * Re-arranging: + * max_adj = floor(((max_incval - base_incval) * 1billion) / 1billion) */ #define INCVALUE_96MHZ 125 #define INCVALUE_SHIFT_96MHZ 17 #define INCPERIOD_SHIFT_96MHZ 2 #define INCPERIOD_96MHZ (12 >> INCPERIOD_SHIFT_96MHZ) +#define MAX_PPB_96MHZ 23999900 /* 23,999,900 ppb */ #define INCVALUE_25MHZ 40 #define INCVALUE_SHIFT_25MHZ 18 #define INCPERIOD_25MHZ 1 +#define MAX_PPB_25MHZ 599999900 /* 599,999,900 ppb */ #define INCVALUE_24MHZ 125 #define INCVALUE_SHIFT_24MHZ 14 #define INCPERIOD_24MHZ 3 +#define MAX_PPB_24MHZ 999999999 /* 999,999,999 ppb */ #define INCVALUE_38400KHZ 26 #define INCVALUE_SHIFT_38400KHZ 19 #define INCPERIOD_38400KHZ 1 +#define MAX_PPB_38400KHZ 230769100 /* 230,769,100 ppb */ /* Another drawback of scaling the incvalue by a large factor is the * 64-bit SYSTIM register overflows more quickly. This is dealt with only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/e1000e/ptp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/e1000e/ptp.c @@ -280,23 +280,31 @@ switch (hw->mac.type) { case e1000_pch2lan: + adapter->ptp_clock_info.max_adj = MAX_PPB_96MHZ; + break; case e1000_pch_lpt: + if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) + adapter->ptp_clock_info.max_adj = MAX_PPB_96MHZ; + else + adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ; + break; case e1000_pch_spt: + adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ; + break; case e1000_pch_cnp: case e1000_pch_tgp: case e1000_pch_adp: case e1000_pch_mtp: case e1000_pch_lnp: case e1000_pch_ptp: - if ((hw->mac.type < e1000_pch_lpt) || - (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI)) { - adapter->ptp_clock_info.max_adj = 24000000 - 1; - break; - } - fallthrough; + if (er32(TSYNCRXCTL) & E1000_TSYNCRXCTL_SYSCFI) + adapter->ptp_clock_info.max_adj = MAX_PPB_24MHZ; + else + adapter->ptp_clock_info.max_adj = MAX_PPB_38400KHZ; + break; case e1000_82574: case e1000_82583: - adapter->ptp_clock_info.max_adj = 600000000 - 1; + adapter->ptp_clock_info.max_adj = MAX_PPB_25MHZ; break; default: break; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ice/ice_base.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_base.c @@ -541,19 +541,27 @@ ring->rx_buf_len = ring->vsi->rx_buf_len; if (ring->vsi->type == ICE_VSI_PF) { - if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) - /* coverity[check_return] */ - __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, - ring->q_index, - ring->q_vector->napi.napi_id, - ring->vsi->rx_buf_len); + if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) { + err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, + ring->q_index, + ring->q_vector->napi.napi_id, + ring->rx_buf_len); + if (err) + return err; + } ring->xsk_pool = ice_xsk_pool(ring); if (ring->xsk_pool) { - xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq); + xdp_rxq_info_unreg(&ring->xdp_rxq); ring->rx_buf_len = xsk_pool_get_rx_frame_size(ring->xsk_pool); + err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, + ring->q_index, + ring->q_vector->napi.napi_id, + ring->rx_buf_len); + if (err) + return err; err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, MEM_TYPE_XSK_BUFF_POOL, NULL); @@ -564,13 +572,14 @@ dev_info(dev, "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n", ring->q_index); } else { - if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) - /* coverity[check_return] */ - __xdp_rxq_info_reg(&ring->xdp_rxq, - ring->netdev, - ring->q_index, - ring->q_vector->napi.napi_id, - ring->vsi->rx_buf_len); + if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) { + err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, + ring->q_index, + ring->q_vector->napi.napi_id, + ring->rx_buf_len); + if (err) + return err; + } err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, MEM_TYPE_PAGE_SHARED, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ice/ice_txrx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -513,11 +513,6 @@ if (ice_is_xdp_ena_vsi(rx_ring->vsi)) WRITE_ONCE(rx_ring->xdp_prog, rx_ring->vsi->xdp_prog); - if (rx_ring->vsi->type == ICE_VSI_PF && - !xdp_rxq_info_is_reg(&rx_ring->xdp_rxq)) - if (xdp_rxq_info_reg(&rx_ring->xdp_rxq, rx_ring->netdev, - rx_ring->q_index, rx_ring->q_vector->napi.napi_id)) - goto err; return 0; err: @@ -600,9 +595,7 @@ ret = ICE_XDP_CONSUMED; } exit: - rx_buf->act = ret; - if (unlikely(xdp_buff_has_frags(xdp))) - ice_set_rx_bufs_act(xdp, rx_ring, ret); + ice_set_rx_bufs_act(xdp, rx_ring, ret); } /** @@ -890,14 +883,17 @@ } if (unlikely(sinfo->nr_frags == MAX_SKB_FRAGS)) { - if (unlikely(xdp_buff_has_frags(xdp))) - ice_set_rx_bufs_act(xdp, rx_ring, ICE_XDP_CONSUMED); + ice_set_rx_bufs_act(xdp, rx_ring, ICE_XDP_CONSUMED); return -ENOMEM; } __skb_fill_page_desc_noacc(sinfo, sinfo->nr_frags++, rx_buf->page, rx_buf->page_offset, size); sinfo->xdp_frags_size += size; + /* remember frag count before XDP prog execution; bpf_xdp_adjust_tail() + * can pop off frags but driver has to handle it on its own + */ + rx_ring->nr_frags = sinfo->nr_frags; if (page_is_pfmemalloc(rx_buf->page)) xdp_buff_set_frag_pfmemalloc(xdp); @@ -1249,6 +1245,7 @@ xdp->data = NULL; rx_ring->first_desc = ntc; + rx_ring->nr_frags = 0; continue; construct_skb: if (likely(ice_ring_uses_build_skb(rx_ring))) @@ -1264,10 +1261,12 @@ ICE_XDP_CONSUMED); xdp->data = NULL; rx_ring->first_desc = ntc; + rx_ring->nr_frags = 0; break; } xdp->data = NULL; rx_ring->first_desc = ntc; + rx_ring->nr_frags = 0; stat_err_bits = BIT(ICE_RX_FLEX_DESC_STATUS0_RXE_S); if (unlikely(ice_test_staterr(rx_desc->wb.status_error0, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ice/ice_txrx.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_txrx.h @@ -333,6 +333,7 @@ struct ice_channel *ch; struct ice_tx_ring *xdp_ring; struct xsk_buff_pool *xsk_pool; + u32 nr_frags; dma_addr_t dma; /* physical address of ring */ u64 cached_phctime; u16 rx_buf_len; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ice/ice_txrx_lib.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_txrx_lib.h @@ -12,26 +12,39 @@ * act: action to store onto Rx buffers related to XDP buffer parts * * Set action that should be taken before putting Rx buffer from first frag - * to one before last. Last one is handled by caller of this function as it - * is the EOP frag that is currently being processed. This function is - * supposed to be called only when XDP buffer contains frags. + * to the last. */ static inline void ice_set_rx_bufs_act(struct xdp_buff *xdp, const struct ice_rx_ring *rx_ring, const unsigned int act) { - const struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp); - u32 first = rx_ring->first_desc; - u32 nr_frags = sinfo->nr_frags; + u32 sinfo_frags = xdp_get_shared_info_from_buff(xdp)->nr_frags; + u32 nr_frags = rx_ring->nr_frags + 1; + u32 idx = rx_ring->first_desc; u32 cnt = rx_ring->count; struct ice_rx_buf *buf; for (int i = 0; i < nr_frags; i++) { - buf = &rx_ring->rx_buf[first]; + buf = &rx_ring->rx_buf[idx]; buf->act = act; - if (++first == cnt) - first = 0; + if (++idx == cnt) + idx = 0; + } + + /* adjust pagecnt_bias on frags freed by XDP prog */ + if (sinfo_frags < rx_ring->nr_frags && act == ICE_XDP_CONSUMED) { + u32 delta = rx_ring->nr_frags - sinfo_frags; + + while (delta) { + if (idx == 0) + idx = cnt - 1; + else + idx--; + buf = &rx_ring->rx_buf[idx]; + buf->pagecnt_bias--; + delta--; + } } } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c @@ -131,6 +131,7 @@ { struct ice_hw *hw = &vsi->back->hw; struct ice_vsi_ctx *ctxt; + u8 *ivf; int err; /* do not allow modifying VLAN stripping when a port VLAN is configured @@ -143,19 +144,24 @@ if (!ctxt) return -ENOMEM; + ivf = &ctxt->info.inner_vlan_flags; + /* Here we are configuring what the VSI should do with the VLAN tag in * the Rx packet. We can either leave the tag in the packet or put it in * the Rx descriptor. */ - if (ena) + if (ena) { /* Strip VLAN tag from Rx packet and put it in the desc */ - ctxt->info.inner_vlan_flags = ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH; - else + *ivf = FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_EMODE_M, + ICE_AQ_VSI_INNER_VLAN_EMODE_STR_BOTH); + } else { /* Disable stripping. Leave tag in packet */ - ctxt->info.inner_vlan_flags = ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING; + *ivf = FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_EMODE_M, + ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING); + } /* Allow all packets untagged/tagged */ - ctxt->info.inner_vlan_flags |= ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL; + *ivf |= ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL; ctxt->info.valid_sections = cpu_to_le16(ICE_AQ_VSI_PROP_VLAN_VALID); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c @@ -123,14 +123,14 @@ if (ret_val) return ret_val; if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; /* Check to see if SFP+ module is supported */ ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset, &data_offset); if (ret_val) - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; break; default: break; @@ -213,7 +213,7 @@ break; default: - return IXGBE_ERR_LINK_SETUP; + return -EIO; } return 0; @@ -283,7 +283,7 @@ /* Validate the water mark configuration */ if (!hw->fc.pause_time) - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; /* Low water mark of zero causes XOFF floods */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { @@ -292,7 +292,7 @@ if (!hw->fc.low_water[i] || hw->fc.low_water[i] >= hw->fc.high_water[i]) { hw_dbg(hw, "Invalid water mark configuration\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } } } @@ -369,7 +369,7 @@ break; default: hw_dbg(hw, "Flow control param set incorrectly\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } /* Set 802.3x based flow control settings. */ @@ -438,7 +438,7 @@ msleep(100); } if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { - status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; + status = -EIO; hw_dbg(hw, "Autonegotiation did not complete.\n"); } } @@ -478,7 +478,7 @@ if (timeout == IXGBE_VALIDATE_LINK_READY_TIMEOUT) { hw_dbg(hw, "Link was indicated but link is down\n"); - return IXGBE_ERR_LINK_SETUP; + return -EIO; } return 0; @@ -594,7 +594,7 @@ speed &= link_capabilities; if (speed == IXGBE_LINK_SPEED_UNKNOWN) - return IXGBE_ERR_LINK_SETUP; + return -EINVAL; /* Set KX4/KX support according to speed requested */ else if (link_mode == IXGBE_AUTOC_LMS_KX4_AN || @@ -701,9 +701,9 @@ /* Init PHY and function pointers, perform SFP setup */ phy_status = hw->phy.ops.init(hw); - if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (phy_status == -EOPNOTSUPP) return phy_status; - if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT) + if (phy_status == -ENOENT) goto mac_reset_top; hw->phy.ops.reset(hw); @@ -727,7 +727,7 @@ udelay(1); } if (ctrl & IXGBE_CTRL_RST) { - status = IXGBE_ERR_RESET_FAILED; + status = -EIO; hw_dbg(hw, "Reset polling failed to complete.\n"); } @@ -789,7 +789,7 @@ /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", rar); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); @@ -814,7 +814,7 @@ /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", rar); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); @@ -845,7 +845,7 @@ u32 vftabyte; if (vlan > 4095) - return IXGBE_ERR_PARAM; + return -EINVAL; /* Determine 32-bit word position in array */ regindex = (vlan >> 5) & 0x7F; /* upper seven bits */ @@ -964,7 +964,7 @@ gssr = IXGBE_GSSR_PHY0_SM; if (hw->mac.ops.acquire_swfw_sync(hw, gssr) != 0) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; if (hw->phy.type == ixgbe_phy_nl) { /* @@ -993,7 +993,7 @@ if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) { hw_dbg(hw, "EEPROM read did not pass.\n"); - status = IXGBE_ERR_SFP_NOT_PRESENT; + status = -ENOENT; goto out; } @@ -1003,7 +1003,7 @@ *eeprom_data = (u8)(sfp_data >> 8); } else { - status = IXGBE_ERR_PHY; + status = -EIO; } out: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c @@ -117,7 +117,7 @@ ret_val = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); if (ret_val) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; if (hw->eeprom.ops.read(hw, ++data_offset, &data_value)) goto setup_sfp_err; @@ -144,7 +144,7 @@ if (ret_val) { hw_dbg(hw, " sfp module setup not complete\n"); - return IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; + return -EIO; } } @@ -159,7 +159,7 @@ usleep_range(hw->eeprom.semaphore_delay * 1000, hw->eeprom.semaphore_delay * 2000); hw_err(hw, "eeprom read at offset %d failed\n", data_offset); - return IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; + return -EIO; } /** @@ -184,7 +184,7 @@ ret_val = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); if (ret_val) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; *locked = true; } @@ -219,7 +219,7 @@ ret_val = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM); if (ret_val) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; locked = true; } @@ -400,7 +400,7 @@ break; default: - return IXGBE_ERR_LINK_SETUP; + return -EIO; } if (hw->phy.multispeed_fiber) { @@ -541,7 +541,7 @@ msleep(100); } if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { - status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; + status = -EIO; hw_dbg(hw, "Autoneg did not complete.\n"); } } @@ -794,7 +794,7 @@ speed &= link_capabilities; if (speed == IXGBE_LINK_SPEED_UNKNOWN) - return IXGBE_ERR_LINK_SETUP; + return -EINVAL; /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/ if (hw->mac.orig_link_settings_stored) @@ -861,8 +861,7 @@ msleep(100); } if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { - status = - IXGBE_ERR_AUTONEG_NOT_COMPLETE; + status = -EIO; hw_dbg(hw, "Autoneg did not complete.\n"); } } @@ -927,7 +926,7 @@ /* Identify PHY and related function pointers */ status = hw->phy.ops.init(hw); - if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (status == -EOPNOTSUPP) return status; /* Setup SFP module if there is one present. */ @@ -936,7 +935,7 @@ hw->phy.sfp_setup_needed = false; } - if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (status == -EOPNOTSUPP) return status; /* Reset PHY */ @@ -974,7 +973,7 @@ } if (ctrl & IXGBE_CTRL_RST_MASK) { - status = IXGBE_ERR_RESET_FAILED; + status = -EIO; hw_dbg(hw, "Reset polling failed to complete.\n"); } @@ -1093,7 +1092,7 @@ udelay(10); } - return IXGBE_ERR_FDIR_CMD_INCOMPLETE; + return -EIO; } /** @@ -1155,7 +1154,7 @@ } if (i >= IXGBE_FDIR_INIT_DONE_POLL) { hw_dbg(hw, "Flow Director Signature poll time exceeded!\n"); - return IXGBE_ERR_FDIR_REINIT_FAILED; + return -EIO; } /* Clear FDIR statistics registers (read to clear) */ @@ -1387,7 +1386,7 @@ break; default: hw_dbg(hw, " Error on flow type input\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } /* configure FDIRCMD register */ @@ -1546,7 +1545,7 @@ break; default: hw_dbg(hw, " Error on vm pool mask\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } switch (input_mask->formatted.flow_type & IXGBE_ATR_L4TYPE_MASK) { @@ -1555,14 +1554,14 @@ if (input_mask->formatted.dst_port || input_mask->formatted.src_port) { hw_dbg(hw, " Error on src/dst port mask\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } break; case IXGBE_ATR_L4TYPE_MASK: break; default: hw_dbg(hw, " Error on flow type mask\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } switch (ntohs(input_mask->formatted.vlan_id) & 0xEFFF) { @@ -1583,7 +1582,7 @@ break; default: hw_dbg(hw, " Error on VLAN mask\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } switch ((__force u16)input_mask->formatted.flex_bytes & 0xFFFF) { @@ -1595,7 +1594,7 @@ break; default: hw_dbg(hw, " Error on flexible byte mask\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } /* Now mask VM pool and destination IPv6 - bits 5 and 2 */ @@ -1824,7 +1823,7 @@ /* Return error if SFP module has been detected but is not supported */ if (hw->phy.type == ixgbe_phy_sfp_unsupported) - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; return status; } @@ -1863,13 +1862,13 @@ * Verifies that installed the firmware version is 0.6 or higher * for SFI devices. All 82599 SFI devices should have version 0.6 or higher. * - * Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or - * if the FW version is not supported. + * Return: -EACCES if the FW is not present or if the FW version is + * not supported. **/ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) { - s32 status = IXGBE_ERR_EEPROM_VERSION; u16 fw_offset, fw_ptp_cfg_offset; + s32 status = -EACCES; u16 offset; u16 fw_version = 0; @@ -1883,7 +1882,7 @@ goto fw_version_err; if (fw_offset == 0 || fw_offset == 0xFFFF) - return IXGBE_ERR_EEPROM_VERSION; + return -EACCES; /* get the offset to the Pass Through Patch Configuration block */ offset = fw_offset + IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR; @@ -1891,7 +1890,7 @@ goto fw_version_err; if (fw_ptp_cfg_offset == 0 || fw_ptp_cfg_offset == 0xFFFF) - return IXGBE_ERR_EEPROM_VERSION; + return -EACCES; /* get the firmware version */ offset = fw_ptp_cfg_offset + IXGBE_FW_PATCH_VERSION_4; @@ -1905,7 +1904,7 @@ fw_version_err: hw_err(hw, "eeprom read at offset %d failed\n", offset); - return IXGBE_ERR_EEPROM_VERSION; + return -EACCES; } /** @@ -2038,7 +2037,7 @@ if (!(anlp1_reg & IXGBE_ANLP1_AN_STATE_MASK)) { hw_dbg(hw, "auto negotiation not completed\n"); - ret_val = IXGBE_ERR_RESET_FAILED; + ret_val = -EIO; goto reset_pipeline_out; } @@ -2087,7 +2086,7 @@ if (!timeout) { hw_dbg(hw, "Driver can't access resource, acquiring I2C bus timeout.\n"); - status = IXGBE_ERR_I2C; + status = -EIO; goto release_i2c_access; } } @@ -2141,7 +2140,7 @@ if (!timeout) { hw_dbg(hw, "Driver can't access resource, acquiring I2C bus timeout.\n"); - status = IXGBE_ERR_I2C; + status = -EIO; goto release_i2c_access; } } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c @@ -124,7 +124,7 @@ */ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } /* @@ -215,7 +215,7 @@ break; default: hw_dbg(hw, "Flow control param set incorrectly\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } if (hw->mac.type != ixgbe_mac_X540) { @@ -500,7 +500,7 @@ if (pba_num == NULL) { hw_dbg(hw, "PBA string buffer was null\n"); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); @@ -526,7 +526,7 @@ /* we will need 11 characters to store the PBA */ if (pba_num_size < 11) { hw_dbg(hw, "PBA string buffer too small\n"); - return IXGBE_ERR_NO_SPACE; + return -ENOSPC; } /* extract hex string from data and pba_ptr */ @@ -563,13 +563,13 @@ if (length == 0xFFFF || length == 0) { hw_dbg(hw, "NVM PBA number section invalid length\n"); - return IXGBE_ERR_PBA_SECTION; + return -EIO; } /* check if pba_num buffer is big enough */ if (pba_num_size < (((u32)length * 2) - 1)) { hw_dbg(hw, "PBA string buffer too small\n"); - return IXGBE_ERR_NO_SPACE; + return -ENOSPC; } /* trim pba length from start of string */ @@ -805,7 +805,7 @@ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; /* To turn on the LED, set mode to ON. */ led_reg &= ~IXGBE_LED_MODE_MASK(index); @@ -826,7 +826,7 @@ u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; /* To turn off the LED, set mode to OFF. */ led_reg &= ~IXGBE_LED_MODE_MASK(index); @@ -904,11 +904,8 @@ hw->eeprom.ops.init_params(hw); - if (words == 0) - return IXGBE_ERR_INVALID_ARGUMENT; - - if (offset + words > hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + if (words == 0 || (offset + words > hw->eeprom.word_size)) + return -EINVAL; /* * The EEPROM page size cannot be queried from the chip. We do lazy @@ -962,7 +959,7 @@ if (ixgbe_ready_eeprom(hw) != 0) { ixgbe_release_eeprom(hw); - return IXGBE_ERR_EEPROM; + return -EIO; } for (i = 0; i < words; i++) { @@ -1028,7 +1025,7 @@ hw->eeprom.ops.init_params(hw); if (offset >= hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + return -EINVAL; return ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data); } @@ -1050,11 +1047,8 @@ hw->eeprom.ops.init_params(hw); - if (words == 0) - return IXGBE_ERR_INVALID_ARGUMENT; - - if (offset + words > hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + if (words == 0 || (offset + words > hw->eeprom.word_size)) + return -EINVAL; /* * We cannot hold synchronization semaphores for too long @@ -1099,7 +1093,7 @@ if (ixgbe_ready_eeprom(hw) != 0) { ixgbe_release_eeprom(hw); - return IXGBE_ERR_EEPROM; + return -EIO; } for (i = 0; i < words; i++) { @@ -1142,7 +1136,7 @@ hw->eeprom.ops.init_params(hw); if (offset >= hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + return -EINVAL; return ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data); } @@ -1165,11 +1159,8 @@ hw->eeprom.ops.init_params(hw); - if (words == 0) - return IXGBE_ERR_INVALID_ARGUMENT; - - if (offset >= hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + if (words == 0 || offset >= hw->eeprom.word_size) + return -EINVAL; for (i = 0; i < words; i++) { eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) | @@ -1262,11 +1253,8 @@ hw->eeprom.ops.init_params(hw); - if (words == 0) - return IXGBE_ERR_INVALID_ARGUMENT; - - if (offset >= hw->eeprom.word_size) - return IXGBE_ERR_EEPROM; + if (words == 0 || offset >= hw->eeprom.word_size) + return -EINVAL; for (i = 0; i < words; i++) { eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) | @@ -1328,7 +1316,7 @@ } udelay(5); } - return IXGBE_ERR_EEPROM; + return -EIO; } /** @@ -1344,7 +1332,7 @@ u32 i; if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; eec = IXGBE_READ_REG(hw, IXGBE_EEC(hw)); @@ -1366,7 +1354,7 @@ hw_dbg(hw, "Could not acquire EEPROM grant\n"); hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); - return IXGBE_ERR_EEPROM; + return -EIO; } /* Setup EEPROM for Read/Write */ @@ -1419,7 +1407,7 @@ swsm = IXGBE_READ_REG(hw, IXGBE_SWSM(hw)); if (swsm & IXGBE_SWSM_SMBI) { hw_dbg(hw, "Software semaphore SMBI between device drivers not granted.\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } } @@ -1447,7 +1435,7 @@ if (i >= timeout) { hw_dbg(hw, "SWESMBI Software EEPROM semaphore not granted.\n"); ixgbe_release_eeprom_semaphore(hw); - return IXGBE_ERR_EEPROM; + return -EIO; } return 0; @@ -1503,7 +1491,7 @@ */ if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) { hw_dbg(hw, "SPI EEPROM Status error\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } return 0; @@ -1715,7 +1703,7 @@ for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { if (hw->eeprom.ops.read(hw, i, &pointer)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } /* If the pointer seems invalid */ @@ -1724,7 +1712,7 @@ if (hw->eeprom.ops.read(hw, pointer, &length)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } if (length == 0xFFFF || length == 0) @@ -1733,7 +1721,7 @@ for (j = pointer + 1; j <= pointer + length; j++) { if (hw->eeprom.ops.read(hw, j, &word)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } checksum += word; } @@ -1786,7 +1774,7 @@ * calculated checksum */ if (read_checksum != checksum) - status = IXGBE_ERR_EEPROM_CHECKSUM; + status = -EIO; /* If the user cares, return the calculated checksum */ if (checksum_val) @@ -1845,7 +1833,7 @@ /* Make sure we are using a valid rar index range */ if (index >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", index); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } /* setup VMDq pool selection before this RAR gets enabled */ @@ -1897,7 +1885,7 @@ /* Make sure we are using a valid rar index range */ if (index >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", index); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } /* @@ -2146,7 +2134,7 @@ /* Validate the water mark configuration. */ if (!hw->fc.pause_time) - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; /* Low water mark of zero causes XOFF floods */ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { @@ -2155,7 +2143,7 @@ if (!hw->fc.low_water[i] || hw->fc.low_water[i] >= hw->fc.high_water[i]) { hw_dbg(hw, "Invalid water mark configuration\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } } } @@ -2212,7 +2200,7 @@ break; default: hw_dbg(hw, "Flow control param set incorrectly\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } /* Set 802.3x based flow control settings. */ @@ -2269,7 +2257,7 @@ u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm) { if ((!(adv_reg)) || (!(lp_reg))) - return IXGBE_ERR_FC_NOT_NEGOTIATED; + return -EINVAL; if ((adv_reg & adv_sym) && (lp_reg & lp_sym)) { /* @@ -2321,7 +2309,7 @@ linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA); if ((!!(linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) || (!!(linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) - return IXGBE_ERR_FC_NOT_NEGOTIATED; + return -EIO; pcs_anadv_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA); pcs_lpab_reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANLP); @@ -2353,12 +2341,12 @@ */ links = IXGBE_READ_REG(hw, IXGBE_LINKS); if ((links & IXGBE_LINKS_KX_AN_COMP) == 0) - return IXGBE_ERR_FC_NOT_NEGOTIATED; + return -EIO; if (hw->mac.type == ixgbe_mac_82599EB) { links2 = IXGBE_READ_REG(hw, IXGBE_LINKS2); if ((links2 & IXGBE_LINKS2_AN_SUPPORTED) == 0) - return IXGBE_ERR_FC_NOT_NEGOTIATED; + return -EIO; } /* * Read the 10g AN autoc and LP ability registers and resolve @@ -2407,8 +2395,8 @@ **/ void ixgbe_fc_autoneg(struct ixgbe_hw *hw) { - s32 ret_val = IXGBE_ERR_FC_NOT_NEGOTIATED; ixgbe_link_speed speed; + s32 ret_val = -EIO; bool link_up; /* @@ -2510,7 +2498,7 @@ * @hw: pointer to hardware structure * * Disables PCI-Express primary access and verifies there are no pending - * requests. IXGBE_ERR_PRIMARY_REQUESTS_PENDING is returned if primary disable + * requests. -EALREADY is returned if primary disable * bit hasn't caused the primary requests to be disabled, else 0 * is returned signifying primary requests disabled. **/ @@ -2575,7 +2563,7 @@ } hw_dbg(hw, "PCIe transaction pending bit also did not clear.\n"); - return IXGBE_ERR_PRIMARY_REQUESTS_PENDING; + return -EALREADY; } /** @@ -2600,7 +2588,7 @@ * SW_FW_SYNC bits (not just NVM) */ if (ixgbe_get_eeprom_semaphore(hw)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; gssr = IXGBE_READ_REG(hw, IXGBE_GSSR); if (!(gssr & (fwmask | swmask))) { @@ -2620,7 +2608,7 @@ ixgbe_release_swfw_sync(hw, gssr & (fwmask | swmask)); usleep_range(5000, 10000); - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } /** @@ -2757,7 +2745,7 @@ s32 ret_val; if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; /* * Link must be up to auto-blink the LEDs; @@ -2803,7 +2791,7 @@ s32 ret_val; if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); if (ret_val) @@ -2963,7 +2951,7 @@ /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", rar); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } mpsar_lo = IXGBE_READ_REG(hw, IXGBE_MPSAR_LO(rar)); @@ -3014,7 +3002,7 @@ /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { hw_dbg(hw, "RAR index %d is out of range.\n", rar); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } if (vmdq < 32) { @@ -3091,7 +3079,7 @@ * will simply bypass the VLVF if there are no entries present in the * VLVF that contain our VLAN */ - first_empty_slot = vlvf_bypass ? IXGBE_ERR_NO_SPACE : 0; + first_empty_slot = vlvf_bypass ? -ENOSPC : 0; /* add VLAN enable bit for comparison */ vlan |= IXGBE_VLVF_VIEN; @@ -3115,7 +3103,7 @@ if (!first_empty_slot) hw_dbg(hw, "No space in VLVF.\n"); - return first_empty_slot ? : IXGBE_ERR_NO_SPACE; + return first_empty_slot ? : -ENOSPC; } /** @@ -3135,7 +3123,7 @@ s32 vlvf_index; if ((vlan > 4095) || (vind > 63)) - return IXGBE_ERR_PARAM; + return -EINVAL; /* * this is a 2 part operation - first the VFTA, then the @@ -3611,7 +3599,8 @@ * * Communicates with the manageability block. On success return 0 * else returns semaphore error when encountering an error acquiring - * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + * semaphore, -EINVAL when incorrect parameters passed or -EIO when + * command fails. * * This function assumes that the IXGBE_GSSR_SW_MNG_SM semaphore is held * by the caller. @@ -3624,7 +3613,7 @@ if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EINVAL; } /* Set bit 9 of FWSTS clearing FW reset indication */ @@ -3635,13 +3624,13 @@ hicr = IXGBE_READ_REG(hw, IXGBE_HICR); if (!(hicr & IXGBE_HICR_EN)) { hw_dbg(hw, "IXGBE_HOST_EN bit disabled.\n"); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EIO; } /* Calculate length in DWORDs. We must be DWORD aligned */ if (length % sizeof(u32)) { hw_dbg(hw, "Buffer length failure, not aligned to dword"); - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; } dword_len = length >> 2; @@ -3666,7 +3655,7 @@ /* Check command successful completion. */ if ((timeout && i == timeout) || !(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV)) - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EIO; return 0; } @@ -3686,7 +3675,7 @@ * in these cases. * * Communicates with the manageability block. On success return 0 - * else return IXGBE_ERR_HOST_INTERFACE_COMMAND. + * else return -EIO or -EINVAL. **/ s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *buffer, u32 length, u32 timeout, @@ -3701,7 +3690,7 @@ if (!length || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EINVAL; } /* Take management host interface semaphore */ status = hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_SW_MNG_SM); @@ -3731,7 +3720,7 @@ if (length < round_up(buf_len, 4) + hdr_size) { hw_dbg(hw, "Buffer not large enough for reply message.\n"); - status = IXGBE_ERR_HOST_INTERFACE_COMMAND; + status = -EIO; goto rel_out; } @@ -3762,8 +3751,8 @@ * * Sends driver version number to firmware through the manageability * block. On success return 0 - * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring - * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + * else returns -EBUSY when encountering an error acquiring + * semaphore or -EIO when command fails. **/ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, u8 build, u8 sub, __always_unused u16 len, @@ -3799,7 +3788,7 @@ FW_CEM_RESP_STATUS_SUCCESS) ret_val = 0; else - ret_val = IXGBE_ERR_HOST_INTERFACE_COMMAND; + ret_val = -EIO; break; } @@ -3897,14 +3886,14 @@ return status; if ((*ets_offset == 0x0000) || (*ets_offset == 0xFFFF)) - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; status = hw->eeprom.ops.read(hw, *ets_offset, ets_cfg); if (status) return status; if ((*ets_cfg & IXGBE_ETS_TYPE_MASK) != IXGBE_ETS_TYPE_EMC_SHIFTED) - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; return 0; } @@ -3927,7 +3916,7 @@ /* Only support thermal sensors attached to physical port 0 */ if ((IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; status = ixgbe_get_ets_data(hw, &ets_cfg, &ets_offset); if (status) @@ -3987,7 +3976,7 @@ /* Only support thermal sensors attached to physical port 0 */ if ((IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_LAN_ID_1)) - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; status = ixgbe_get_ets_data(hw, &ets_cfg, &ets_offset); if (status) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -3370,7 +3370,7 @@ { struct ixgbe_adapter *adapter = netdev_priv(dev); struct ixgbe_hw *hw = &adapter->hw; - s32 status = IXGBE_ERR_PHY_ADDR_INVALID; + s32 status = -EFAULT; u8 databyte = 0xFF; int i = 0; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -2756,7 +2756,6 @@ { struct ixgbe_hw *hw = &adapter->hw; u32 eicr = adapter->interrupt_event; - s32 rc; if (test_bit(__IXGBE_DOWN, &adapter->state)) return; @@ -2790,14 +2789,13 @@ } /* Check if this is not due to overtemp */ - if (hw->phy.ops.check_overtemp(hw) != IXGBE_ERR_OVERTEMP) + if (!hw->phy.ops.check_overtemp(hw)) return; break; case IXGBE_DEV_ID_X550EM_A_1G_T: case IXGBE_DEV_ID_X550EM_A_1G_T_L: - rc = hw->phy.ops.check_overtemp(hw); - if (rc != IXGBE_ERR_OVERTEMP) + if (!hw->phy.ops.check_overtemp(hw)) return; break; default: @@ -5512,7 +5510,7 @@ { u32 speed; bool autoneg, link_up = false; - int ret = IXGBE_ERR_LINK_SETUP; + int ret = -EIO; if (hw->mac.ops.check_link) ret = hw->mac.ops.check_link(hw, &speed, &link_up, false); @@ -5983,13 +5981,13 @@ err = hw->mac.ops.init_hw(hw); switch (err) { case 0: - case IXGBE_ERR_SFP_NOT_PRESENT: - case IXGBE_ERR_SFP_NOT_SUPPORTED: + case -ENOENT: + case -EOPNOTSUPP: break; - case IXGBE_ERR_PRIMARY_REQUESTS_PENDING: + case -EALREADY: e_dev_err("primary disable timed out\n"); break; - case IXGBE_ERR_EEPROM_VERSION: + case -EACCES: /* We are running on a pre-production device, log a warning */ e_dev_warn("This device is a pre-production adapter/LOM. " "Please be aware there may be issues associated with " @@ -7829,10 +7827,10 @@ adapter->sfp_poll_time = jiffies + IXGBE_SFP_POLL_JIFFIES - 1; err = hw->phy.ops.identify_sfp(hw); - if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (err == -EOPNOTSUPP) goto sfp_out; - if (err == IXGBE_ERR_SFP_NOT_PRESENT) { + if (err == -ENOENT) { /* If no cable is present, then we need to reset * the next time we find a good cable. */ adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET; @@ -7858,7 +7856,7 @@ else err = hw->mac.ops.setup_sfp(hw); - if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (err == -EOPNOTSUPP) goto sfp_out; adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG; @@ -7867,8 +7865,8 @@ sfp_out: clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state); - if ((err == IXGBE_ERR_SFP_NOT_SUPPORTED) && - (adapter->netdev->reg_state == NETREG_REGISTERED)) { + if (err == -EOPNOTSUPP && + adapter->netdev->reg_state == NETREG_REGISTERED) { e_dev_err("failed to initialize because an unsupported " "SFP+ module type was detected.\n"); e_dev_err("Reload the driver after installing a " @@ -7938,7 +7936,7 @@ static void ixgbe_phy_interrupt_subtask(struct ixgbe_adapter *adapter) { struct ixgbe_hw *hw = &adapter->hw; - u32 status; + bool overtemp; if (!(adapter->flags2 & IXGBE_FLAG2_PHY_INTERRUPT)) return; @@ -7948,11 +7946,9 @@ if (!hw->phy.ops.handle_lasi) return; - status = hw->phy.ops.handle_lasi(&adapter->hw); - if (status != IXGBE_ERR_OVERTEMP) - return; - - e_crit(drv, "%s\n", ixgbe_overheat_msg); + hw->phy.ops.handle_lasi(&adapter->hw, &overtemp); + if (overtemp) + e_crit(drv, "%s\n", ixgbe_overheat_msg); } static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter) @@ -10925,9 +10921,9 @@ err = hw->mac.ops.reset_hw(hw); hw->phy.reset_if_overtemp = false; ixgbe_set_eee_capable(adapter); - if (err == IXGBE_ERR_SFP_NOT_PRESENT) { + if (err == -ENOENT) { err = 0; - } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) { + } else if (err == -EOPNOTSUPP) { e_dev_err("failed to load because an unsupported SFP+ or QSFP module type was detected.\n"); e_dev_err("Reload the driver after installing a supported module.\n"); goto err_sw_init; @@ -11146,7 +11142,7 @@ /* reset the hardware with the new settings */ err = hw->mac.ops.start_hw(hw); - if (err == IXGBE_ERR_EEPROM_VERSION) { + if (err == -EACCES) { /* We are running on a pre-production device, log a warning */ e_dev_warn("This device is a pre-production adapter/LOM. " "Please be aware there may be issues associated " only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.c @@ -24,7 +24,7 @@ size = mbx->size; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; return mbx->ops->read(hw, msg, size, mbx_id); } @@ -43,10 +43,10 @@ struct ixgbe_mbx_info *mbx = &hw->mbx; if (size > mbx->size) - return IXGBE_ERR_MBX; + return -EINVAL; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; return mbx->ops->write(hw, msg, size, mbx_id); } @@ -63,7 +63,7 @@ struct ixgbe_mbx_info *mbx = &hw->mbx; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; return mbx->ops->check_for_msg(hw, mbx_id); } @@ -80,7 +80,7 @@ struct ixgbe_mbx_info *mbx = &hw->mbx; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; return mbx->ops->check_for_ack(hw, mbx_id); } @@ -97,7 +97,7 @@ struct ixgbe_mbx_info *mbx = &hw->mbx; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; return mbx->ops->check_for_rst(hw, mbx_id); } @@ -115,12 +115,12 @@ int countdown = mbx->timeout; if (!countdown || !mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; while (mbx->ops->check_for_msg(hw, mbx_id)) { countdown--; if (!countdown) - return IXGBE_ERR_MBX; + return -EIO; udelay(mbx->usec_delay); } @@ -140,12 +140,12 @@ int countdown = mbx->timeout; if (!countdown || !mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; while (mbx->ops->check_for_ack(hw, mbx_id)) { countdown--; if (!countdown) - return IXGBE_ERR_MBX; + return -EIO; udelay(mbx->usec_delay); } @@ -169,7 +169,7 @@ s32 ret_val; if (!mbx->ops) - return IXGBE_ERR_MBX; + return -EIO; ret_val = ixgbe_poll_for_msg(hw, mbx_id); if (ret_val) @@ -197,7 +197,7 @@ /* exit if either we can't write or there isn't a defined timeout */ if (!mbx->ops || !mbx->timeout) - return IXGBE_ERR_MBX; + return -EIO; /* send msg */ ret_val = mbx->ops->write(hw, msg, size, mbx_id); @@ -217,7 +217,7 @@ return 0; } - return IXGBE_ERR_MBX; + return -EIO; } /** @@ -238,7 +238,7 @@ return 0; } - return IXGBE_ERR_MBX; + return -EIO; } /** @@ -259,7 +259,7 @@ return 0; } - return IXGBE_ERR_MBX; + return -EIO; } /** @@ -295,7 +295,7 @@ return 0; } - return IXGBE_ERR_MBX; + return -EIO; } /** @@ -317,7 +317,7 @@ if (p2v_mailbox & IXGBE_PFMAILBOX_PFU) return 0; - return IXGBE_ERR_MBX; + return -EIO; } /** only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_mbx.h @@ -7,7 +7,6 @@ #include "ixgbe_type.h" #define IXGBE_VFMAILBOX_SIZE 16 /* 16 32 bit words - 64 bytes */ -#define IXGBE_ERR_MBX -100 #define IXGBE_VFMAILBOX 0x002FC #define IXGBE_VFMBMEM 0x00200 only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c @@ -102,7 +102,7 @@ csum = ~csum; do { if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; ixgbe_i2c_start(hw); /* Device Address and write indication */ if (ixgbe_out_i2c_byte_ack(hw, addr)) @@ -150,7 +150,7 @@ hw_dbg(hw, "I2C byte read combined error.\n"); } while (retry < max_retry); - return IXGBE_ERR_I2C; + return -EIO; } /** @@ -179,7 +179,7 @@ csum = ~csum; do { if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; ixgbe_i2c_start(hw); /* Device Address and write indication */ if (ixgbe_out_i2c_byte_ack(hw, addr)) @@ -215,7 +215,7 @@ hw_dbg(hw, "I2C byte write combined error.\n"); } while (retry < max_retry); - return IXGBE_ERR_I2C; + return -EIO; } /** @@ -262,8 +262,8 @@ **/ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) { + u32 status = -EFAULT; u32 phy_addr; - u32 status = IXGBE_ERR_PHY_ADDR_INVALID; if (!hw->phy.phy_semaphore_mask) { if (hw->bus.lan_id) @@ -282,7 +282,7 @@ if (ixgbe_probe_phy(hw, phy_addr)) return 0; else - return IXGBE_ERR_PHY_ADDR_INVALID; + return -EFAULT; } for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { @@ -408,8 +408,7 @@ return status; /* Don't reset PHY if it's shut down due to overtemp. */ - if (!hw->phy.reset_if_overtemp && - (IXGBE_ERR_OVERTEMP == hw->phy.ops.check_overtemp(hw))) + if (!hw->phy.reset_if_overtemp && hw->phy.ops.check_overtemp(hw)) return 0; /* Blocked by MNG FW so bail */ @@ -457,7 +456,7 @@ if (ctrl & MDIO_CTRL1_RESET) { hw_dbg(hw, "PHY reset polling failed to complete.\n"); - return IXGBE_ERR_RESET_FAILED; + return -EIO; } return 0; @@ -500,7 +499,7 @@ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { hw_dbg(hw, "PHY address command did not complete.\n"); - return IXGBE_ERR_PHY; + return -EIO; } /* Address cycle complete, setup and write the read @@ -527,7 +526,7 @@ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { hw_dbg(hw, "PHY read command didn't complete\n"); - return IXGBE_ERR_PHY; + return -EIO; } /* Read operation is complete. Get the data @@ -559,7 +558,7 @@ phy_data); hw->mac.ops.release_swfw_sync(hw, gssr); } else { - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } return status; @@ -604,7 +603,7 @@ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { hw_dbg(hw, "PHY address cmd didn't complete\n"); - return IXGBE_ERR_PHY; + return -EIO; } /* @@ -632,7 +631,7 @@ if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { hw_dbg(hw, "PHY write cmd didn't complete\n"); - return IXGBE_ERR_PHY; + return -EIO; } return 0; @@ -657,7 +656,7 @@ phy_data); hw->mac.ops.release_swfw_sync(hw, gssr); } else { - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } return status; @@ -1430,7 +1429,7 @@ if ((phy_data & MDIO_CTRL1_RESET) != 0) { hw_dbg(hw, "PHY reset did not complete.\n"); - return IXGBE_ERR_PHY; + return -EIO; } /* Get init offsets */ @@ -1487,12 +1486,12 @@ hw_dbg(hw, "SOL\n"); } else { hw_dbg(hw, "Bad control value\n"); - return IXGBE_ERR_PHY; + return -EIO; } break; default: hw_dbg(hw, "Bad control type\n"); - return IXGBE_ERR_PHY; + return -EIO; } } @@ -1500,7 +1499,7 @@ err_eeprom: hw_err(hw, "eeprom read at offset %d failed\n", data_offset); - return IXGBE_ERR_PHY; + return -EIO; } /** @@ -1518,10 +1517,10 @@ return ixgbe_identify_qsfp_module_generic(hw); default: hw->phy.sfp_type = ixgbe_sfp_type_not_present; - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } /** @@ -1546,7 +1545,7 @@ if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) { hw->phy.sfp_type = ixgbe_sfp_type_not_present; - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } /* LAN ID is needed for sfp_type determination */ @@ -1561,7 +1560,7 @@ if (identifier != IXGBE_SFF_IDENTIFIER_SFP) { hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_1GBE_COMP_CODES, @@ -1752,7 +1751,7 @@ hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core0 || hw->phy.sfp_type == ixgbe_sfp_type_1g_sx_core1)) { hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } /* Anything else 82598-based is supported */ @@ -1776,7 +1775,7 @@ } hw_dbg(hw, "SFP+ module not supported\n"); hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } return 0; @@ -1786,7 +1785,7 @@ hw->phy.id = 0; hw->phy.type = ixgbe_phy_unknown; } - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } /** @@ -1813,7 +1812,7 @@ if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber_qsfp) { hw->phy.sfp_type = ixgbe_sfp_type_not_present; - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } /* LAN ID is needed for sfp_type determination */ @@ -1827,7 +1826,7 @@ if (identifier != IXGBE_SFF_IDENTIFIER_QSFP_PLUS) { hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } hw->phy.id = identifier; @@ -1895,7 +1894,7 @@ } else { /* unsupported module type */ hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } } @@ -1955,7 +1954,7 @@ } hw_dbg(hw, "QSFP module not supported\n"); hw->phy.type = ixgbe_phy_sfp_unsupported; - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } return 0; } @@ -1966,7 +1965,7 @@ hw->phy.id = 0; hw->phy.type = ixgbe_phy_unknown; - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; } /** @@ -1986,14 +1985,14 @@ u16 sfp_type = hw->phy.sfp_type; if (hw->phy.sfp_type == ixgbe_sfp_type_unknown) - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; if (hw->phy.sfp_type == ixgbe_sfp_type_not_present) - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; if ((hw->device_id == IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM) && (hw->phy.sfp_type == ixgbe_sfp_type_da_cu)) - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; /* * Limiting active cables and 1G Phys must be initialized as @@ -2014,11 +2013,11 @@ if (hw->eeprom.ops.read(hw, IXGBE_PHY_INIT_OFFSET_NL, list_offset)) { hw_err(hw, "eeprom read at %d failed\n", IXGBE_PHY_INIT_OFFSET_NL); - return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT; + return -EIO; } if ((!*list_offset) || (*list_offset == 0xFFFF)) - return IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT; + return -EIO; /* Shift offset to first ID word */ (*list_offset)++; @@ -2037,7 +2036,7 @@ goto err_phy; if ((!*data_offset) || (*data_offset == 0xFFFF)) { hw_dbg(hw, "SFP+ module not supported\n"); - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } else { break; } @@ -2050,14 +2049,14 @@ if (sfp_id == IXGBE_PHY_INIT_END_NL) { hw_dbg(hw, "No matching SFP+ module found\n"); - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } return 0; err_phy: hw_err(hw, "eeprom read at offset %d failed\n", *list_offset); - return IXGBE_ERR_PHY; + return -EIO; } /** @@ -2152,7 +2151,7 @@ do { if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; ixgbe_i2c_start(hw); @@ -2268,7 +2267,7 @@ u32 swfw_mask = hw->phy.phy_semaphore_mask; if (lock && hw->mac.ops.acquire_swfw_sync(hw, swfw_mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; do { ixgbe_i2c_start(hw); @@ -2510,7 +2509,7 @@ if (ack == 1) { hw_dbg(hw, "I2C ack was not received.\n"); - status = IXGBE_ERR_I2C; + status = -EIO; } ixgbe_lower_i2c_clk(hw, &i2cctl); @@ -2582,7 +2581,7 @@ udelay(IXGBE_I2C_T_LOW); } else { hw_dbg(hw, "I2C data was not set to %X\n", data); - return IXGBE_ERR_I2C; + return -EIO; } return 0; @@ -2678,7 +2677,7 @@ *i2cctl = IXGBE_READ_REG(hw, IXGBE_I2CCTL(hw)); if (data != ixgbe_get_i2c_data(hw, i2cctl)) { hw_dbg(hw, "Error - I2C data was not set to %X.\n", data); - return IXGBE_ERR_I2C; + return -EIO; } return 0; @@ -2748,22 +2747,24 @@ * @hw: pointer to hardware structure * * Checks if the LASI temp alarm status was triggered due to overtemp + * + * Return true when an overtemp event detected, otherwise false. **/ -s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) +bool ixgbe_tn_check_overtemp(struct ixgbe_hw *hw) { u16 phy_data = 0; + u32 status; if (hw->device_id != IXGBE_DEV_ID_82599_T3_LOM) - return 0; + return false; /* Check that the LASI temp alarm status was triggered */ - hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG, - MDIO_MMD_PMAPMD, &phy_data); - - if (!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM)) - return 0; + status = hw->phy.ops.read_reg(hw, IXGBE_TN_LASI_STATUS_REG, + MDIO_MMD_PMAPMD, &phy_data); + if (status) + return false; - return IXGBE_ERR_OVERTEMP; + return !!(phy_data & IXGBE_TN_LASI_STATUS_TEMP_ALARM); } /** ixgbe_set_copper_phy_power - Control power for copper phy only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h @@ -155,7 +155,7 @@ s32 ixgbe_get_sfp_init_sequence_offsets(struct ixgbe_hw *hw, u16 *list_offset, u16 *data_offset); -s32 ixgbe_tn_check_overtemp(struct ixgbe_hw *hw); +bool ixgbe_tn_check_overtemp(struct ixgbe_hw *hw); s32 ixgbe_read_i2c_byte_generic(struct ixgbe_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data); s32 ixgbe_read_i2c_byte_generic_unlocked(struct ixgbe_hw *hw, u8 byte_offset, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -3509,10 +3509,10 @@ s32 (*read_i2c_sff8472)(struct ixgbe_hw *, u8 , u8 *); s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *); s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8); - s32 (*check_overtemp)(struct ixgbe_hw *); + bool (*check_overtemp)(struct ixgbe_hw *); s32 (*set_phy_power)(struct ixgbe_hw *, bool on); s32 (*enter_lplu)(struct ixgbe_hw *); - s32 (*handle_lasi)(struct ixgbe_hw *hw); + s32 (*handle_lasi)(struct ixgbe_hw *hw, bool *); s32 (*read_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, u8 *value); s32 (*write_i2c_byte_unlocked)(struct ixgbe_hw *, u8 offset, u8 addr, @@ -3665,45 +3665,6 @@ const u32 *mvals; }; - -/* Error Codes */ -#define IXGBE_ERR_EEPROM -1 -#define IXGBE_ERR_EEPROM_CHECKSUM -2 -#define IXGBE_ERR_PHY -3 -#define IXGBE_ERR_CONFIG -4 -#define IXGBE_ERR_PARAM -5 -#define IXGBE_ERR_MAC_TYPE -6 -#define IXGBE_ERR_UNKNOWN_PHY -7 -#define IXGBE_ERR_LINK_SETUP -8 -#define IXGBE_ERR_ADAPTER_STOPPED -9 -#define IXGBE_ERR_INVALID_MAC_ADDR -10 -#define IXGBE_ERR_DEVICE_NOT_SUPPORTED -11 -#define IXGBE_ERR_PRIMARY_REQUESTS_PENDING -12 -#define IXGBE_ERR_INVALID_LINK_SETTINGS -13 -#define IXGBE_ERR_AUTONEG_NOT_COMPLETE -14 -#define IXGBE_ERR_RESET_FAILED -15 -#define IXGBE_ERR_SWFW_SYNC -16 -#define IXGBE_ERR_PHY_ADDR_INVALID -17 -#define IXGBE_ERR_I2C -18 -#define IXGBE_ERR_SFP_NOT_SUPPORTED -19 -#define IXGBE_ERR_SFP_NOT_PRESENT -20 -#define IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT -21 -#define IXGBE_ERR_NO_SAN_ADDR_PTR -22 -#define IXGBE_ERR_FDIR_REINIT_FAILED -23 -#define IXGBE_ERR_EEPROM_VERSION -24 -#define IXGBE_ERR_NO_SPACE -25 -#define IXGBE_ERR_OVERTEMP -26 -#define IXGBE_ERR_FC_NOT_NEGOTIATED -27 -#define IXGBE_ERR_FC_NOT_SUPPORTED -28 -#define IXGBE_ERR_SFP_SETUP_NOT_COMPLETE -30 -#define IXGBE_ERR_PBA_SECTION -31 -#define IXGBE_ERR_INVALID_ARGUMENT -32 -#define IXGBE_ERR_HOST_INTERFACE_COMMAND -33 -#define IXGBE_ERR_FDIR_CMD_INCOMPLETE -38 -#define IXGBE_ERR_FW_RESP_INVALID -39 -#define IXGBE_ERR_TOKEN_RETRY -40 -#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF - #define IXGBE_FUSES0_GROUP(_i) (0x11158 + ((_i) * 4)) #define IXGBE_FUSES0_300MHZ BIT(5) #define IXGBE_FUSES0_REV_MASK (3u << 6) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_x540.c @@ -84,7 +84,7 @@ status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); if (status) { hw_dbg(hw, "semaphore failed with %d", status); - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } ctrl = IXGBE_CTRL_RST; @@ -103,7 +103,7 @@ } if (ctrl & IXGBE_CTRL_RST_MASK) { - status = IXGBE_ERR_RESET_FAILED; + status = -EIO; hw_dbg(hw, "Reset polling failed to complete.\n"); } msleep(100); @@ -220,7 +220,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = ixgbe_read_eerd_generic(hw, offset, data); @@ -243,7 +243,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = ixgbe_read_eerd_buffer_generic(hw, offset, words, data); @@ -264,7 +264,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = ixgbe_write_eewr_generic(hw, offset, data); @@ -287,7 +287,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = ixgbe_write_eewr_buffer_generic(hw, offset, words, data); @@ -324,7 +324,7 @@ for (i = 0; i < checksum_last_word; i++) { if (ixgbe_read_eerd_generic(hw, i, &word)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } checksum += word; } @@ -349,7 +349,7 @@ if (ixgbe_read_eerd_generic(hw, pointer, &length)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } /* Skip pointer section if length is invalid. */ @@ -360,7 +360,7 @@ for (j = pointer + 1; j <= pointer + length; j++) { if (ixgbe_read_eerd_generic(hw, j, &word)) { hw_dbg(hw, "EEPROM read failed\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } checksum += word; } @@ -397,7 +397,7 @@ } if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = hw->eeprom.ops.calc_checksum(hw); if (status < 0) @@ -418,7 +418,7 @@ */ if (read_checksum != checksum) { hw_dbg(hw, "Invalid EEPROM checksum"); - status = IXGBE_ERR_EEPROM_CHECKSUM; + status = -EIO; } /* If the user cares, return the calculated checksum */ @@ -455,7 +455,7 @@ } if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = hw->eeprom.ops.calc_checksum(hw); if (status < 0) @@ -490,7 +490,7 @@ s32 status; status = ixgbe_poll_flash_update_done_X540(hw); - if (status == IXGBE_ERR_EEPROM) { + if (status == -EIO) { hw_dbg(hw, "Flash update time out\n"); return status; } @@ -540,7 +540,7 @@ return 0; udelay(5); } - return IXGBE_ERR_EEPROM; + return -EIO; } /** @@ -575,7 +575,7 @@ * SW_FW_SYNC bits (not just NVM) */ if (ixgbe_get_swfw_sync_semaphore(hw)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC(hw)); if (!(swfw_sync & (fwmask | swmask | hwmask))) { @@ -599,7 +599,7 @@ * bits in the SW_FW_SYNC register. */ if (ixgbe_get_swfw_sync_semaphore(hw)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; swfw_sync = IXGBE_READ_REG(hw, IXGBE_SWFW_SYNC(hw)); if (swfw_sync & (fwmask | hwmask)) { swfw_sync |= swmask; @@ -622,11 +622,11 @@ rmask |= IXGBE_GSSR_I2C_MASK; ixgbe_release_swfw_sync_X540(hw, rmask); ixgbe_release_swfw_sync_semaphore(hw); - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } ixgbe_release_swfw_sync_semaphore(hw); - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } /** @@ -680,7 +680,7 @@ if (i == timeout) { hw_dbg(hw, "Software semaphore SMBI between device drivers not granted.\n"); - return IXGBE_ERR_EEPROM; + return -EIO; } /* Now get the semaphore between SW/FW through the REGSMP bit */ @@ -697,7 +697,7 @@ */ hw_dbg(hw, "REGSMP Software NVM semaphore not granted\n"); ixgbe_release_swfw_sync_semaphore(hw); - return IXGBE_ERR_EEPROM; + return -EIO; } /** @@ -768,7 +768,7 @@ bool link_up; if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; /* Link should be up in order for the blink bit in the LED control * register to work. Force link and speed in the MAC if link is down. @@ -804,7 +804,7 @@ u32 ledctl_reg; if (index > 3) - return IXGBE_ERR_PARAM; + return -EINVAL; /* Restore the LED to its default value. */ ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c @@ -206,13 +206,13 @@ } if (retry == IXGBE_CS4227_RETRIES) { hw_err(hw, "CS4227 reset did not complete\n"); - return IXGBE_ERR_PHY; + return -EIO; } status = ixgbe_read_cs4227(hw, IXGBE_CS4227_EEPROM_STATUS, &value); if (status || !(value & IXGBE_CS4227_EEPROM_LOAD_OK)) { hw_err(hw, "CS4227 EEPROM did not load successfully\n"); - return IXGBE_ERR_PHY; + return -EIO; } return 0; @@ -350,13 +350,13 @@ static s32 ixgbe_read_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u16 *phy_data) { - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; } static s32 ixgbe_write_phy_reg_x550em(struct ixgbe_hw *hw, u32 reg_addr, u32 device_type, u16 phy_data) { - return IXGBE_NOT_IMPLEMENTED; + return -EOPNOTSUPP; } /** @@ -463,7 +463,7 @@ --retries; } while (retries > 0); - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EIO; } static const struct { @@ -511,7 +511,7 @@ hw->phy.id |= phy_id_lo & IXGBE_PHY_REVISION_MASK; hw->phy.revision = phy_id_lo & ~IXGBE_PHY_REVISION_MASK; if (!hw->phy.id || hw->phy.id == IXGBE_PHY_REVISION_MASK) - return IXGBE_ERR_PHY_ADDR_INVALID; + return -EFAULT; hw->phy.autoneg_advertised = hw->phy.speeds_supported; hw->phy.eee_speeds_supported = IXGBE_LINK_SPEED_100_FULL | @@ -568,7 +568,7 @@ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { hw_err(hw, "rx_pause not valid in strict IEEE mode\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } switch (hw->fc.requested_mode) { @@ -600,8 +600,10 @@ rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_SETUP_LINK, &setup); if (rc) return rc; + if (setup[0] == FW_PHY_ACT_SETUP_LINK_RSP_DOWN) - return IXGBE_ERR_OVERTEMP; + return -EIO; + return 0; } @@ -675,7 +677,7 @@ *ctrl = command; if (i == IXGBE_MDIO_COMMAND_TIMEOUT) { hw_dbg(hw, "IOSF wait timed out\n"); - return IXGBE_ERR_PHY; + return -EIO; } return 0; @@ -715,7 +717,8 @@ error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; hw_dbg(hw, "Failed to read, error %x\n", error); - return IXGBE_ERR_PHY; + ret = -EIO; + goto out; } if (!ret) @@ -750,9 +753,9 @@ if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) return 0; if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY) - return IXGBE_ERR_FW_RESP_INVALID; + return -EIO; - return IXGBE_ERR_TOKEN_RETRY; + return -EAGAIN; } /** @@ -778,7 +781,7 @@ return status; if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK) return 0; - return IXGBE_ERR_FW_RESP_INVALID; + return -EIO; } /** @@ -942,7 +945,7 @@ local_buffer = buf; } else { if (buffer_size < ptr) - return IXGBE_ERR_PARAM; + return -EINVAL; local_buffer = &buffer[ptr]; } @@ -960,7 +963,7 @@ } if (buffer && ((u32)start + (u32)length > buffer_size)) - return IXGBE_ERR_PARAM; + return -EINVAL; for (i = start; length; i++, length--) { if (i == bufsz && !buffer) { @@ -1012,7 +1015,7 @@ local_buffer = eeprom_ptrs; } else { if (buffer_size < IXGBE_EEPROM_LAST_WORD) - return IXGBE_ERR_PARAM; + return -EINVAL; local_buffer = buffer; } @@ -1148,7 +1151,7 @@ * calculated checksum */ if (read_checksum != checksum) { - status = IXGBE_ERR_EEPROM_CHECKSUM; + status = -EIO; hw_dbg(hw, "Invalid EEPROM checksum"); } @@ -1203,7 +1206,7 @@ hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); } else { hw_dbg(hw, "write ee hostif failed to get semaphore"); - status = IXGBE_ERR_SWFW_SYNC; + status = -EBUSY; } return status; @@ -1415,7 +1418,7 @@ error = (command & IXGBE_SB_IOSF_CTRL_CMPL_ERR_MASK) >> IXGBE_SB_IOSF_CTRL_CMPL_ERR_SHIFT; hw_dbg(hw, "Failed to write, error %x\n", error); - return IXGBE_ERR_PHY; + return -EIO; } out: @@ -1558,7 +1561,7 @@ /* iXFI is only supported with X552 */ if (mac->type != ixgbe_mac_X550EM_x) - return IXGBE_ERR_LINK_SETUP; + return -EIO; /* Disable AN and force speed to 10G Serial. */ status = ixgbe_read_iosf_sb_reg_x550(hw, @@ -1580,7 +1583,7 @@ break; default: /* Other link speeds are not supported by internal KR PHY. */ - return IXGBE_ERR_LINK_SETUP; + return -EINVAL; } status = ixgbe_write_iosf_sb_reg_x550(hw, @@ -1611,7 +1614,7 @@ { switch (hw->phy.sfp_type) { case ixgbe_sfp_type_not_present: - return IXGBE_ERR_SFP_NOT_PRESENT; + return -ENOENT; case ixgbe_sfp_type_da_cu_core0: case ixgbe_sfp_type_da_cu_core1: *linear = true; @@ -1630,7 +1633,7 @@ case ixgbe_sfp_type_1g_cu_core0: case ixgbe_sfp_type_1g_cu_core1: default: - return IXGBE_ERR_SFP_NOT_SUPPORTED; + return -EOPNOTSUPP; } return 0; @@ -1660,7 +1663,7 @@ * there is no reason to configure CS4227 and SFP not present error is * not accepted in the setup MAC link flow. */ - if (status == IXGBE_ERR_SFP_NOT_PRESENT) + if (status == -ENOENT) return 0; if (status) @@ -1718,7 +1721,7 @@ break; default: /* Other link speeds are not supported by internal PHY. */ - return IXGBE_ERR_LINK_SETUP; + return -EINVAL; } (void)mac->ops.write_iosf_sb_reg(hw, @@ -1803,7 +1806,7 @@ /* If no SFP module present, then return success. Return success since * SFP not present error is not excepted in the setup MAC link flow. */ - if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) + if (ret_val == -ENOENT) return 0; if (ret_val) @@ -1853,7 +1856,7 @@ /* If no SFP module present, then return success. Return success since * SFP not present error is not excepted in the setup MAC link flow. */ - if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT) + if (ret_val == -ENOENT) return 0; if (ret_val) @@ -1863,7 +1866,7 @@ ixgbe_setup_kr_speed_x550em(hw, speed); if (hw->phy.mdio.prtad == MDIO_PRTAD_NONE) - return IXGBE_ERR_PHY_ADDR_INVALID; + return -EFAULT; /* Get external PHY SKU id */ ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_EFUSE_PDF_SKU, @@ -1962,7 +1965,7 @@ u16 i, autoneg_status; if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) - return IXGBE_ERR_CONFIG; + return -EIO; status = ixgbe_check_mac_link_generic(hw, speed, link_up, link_up_wait_to_complete); @@ -2145,9 +2148,9 @@ */ static void ixgbe_fc_autoneg_sgmii_x550em_a(struct ixgbe_hw *hw) { - s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; u32 info[FW_PHY_ACT_DATA_COUNT] = { 0 }; ixgbe_link_speed speed; + s32 status = -EIO; bool link_up; /* AN should have completed when the cable was plugged in. @@ -2165,7 +2168,7 @@ /* Check if auto-negotiation has completed */ status = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &info); if (status || !(info[0] & FW_PHY_ACT_GET_LINK_INFO_AN_COMPLETE)) { - status = IXGBE_ERR_FC_NOT_NEGOTIATED; + status = -EIO; goto out; } @@ -2369,18 +2372,18 @@ * @hw: pointer to hardware structure * @lsc: pointer to boolean flag which indicates whether external Base T * PHY interrupt is lsc + * @is_overtemp: indicate whether an overtemp event encountered * * Determime if external Base T PHY interrupt cause is high temperature * failure alarm or link status change. - * - * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature - * failure alarm, else return PHY access status. **/ -static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc) +static s32 ixgbe_get_lasi_ext_t_x550em(struct ixgbe_hw *hw, bool *lsc, + bool *is_overtemp) { u32 status; u16 reg; + *is_overtemp = false; *lsc = false; /* Vendor alarm triggered */ @@ -2412,7 +2415,8 @@ if (reg & IXGBE_MDIO_GLOBAL_ALM_1_HI_TMP_FAIL) { /* power down the PHY in case the PHY FW didn't already */ ixgbe_set_copper_phy_power(hw, false); - return IXGBE_ERR_OVERTEMP; + *is_overtemp = true; + return -EIO; } if (reg & IXGBE_MDIO_GLOBAL_ALM_1_DEV_FAULT) { /* device fault alarm triggered */ @@ -2426,7 +2430,8 @@ if (reg == IXGBE_MDIO_GLOBAL_FAULT_MSG_HI_TMP) { /* power down the PHY in case the PHY FW didn't */ ixgbe_set_copper_phy_power(hw, false); - return IXGBE_ERR_OVERTEMP; + *is_overtemp = true; + return -EIO; } } @@ -2462,12 +2467,12 @@ **/ static s32 ixgbe_enable_lasi_ext_t_x550em(struct ixgbe_hw *hw) { + bool lsc, overtemp; u32 status; u16 reg; - bool lsc; /* Clear interrupt flags */ - status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); + status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc, &overtemp); /* Enable link status change alarm */ @@ -2546,21 +2551,20 @@ /** * ixgbe_handle_lasi_ext_t_x550em - Handle external Base T PHY interrupt * @hw: pointer to hardware structure + * @is_overtemp: indicate whether an overtemp event encountered * * Handle external Base T PHY interrupt. If high temperature * failure alarm then return error, else if link status change * then setup internal/external PHY link - * - * Return IXGBE_ERR_OVERTEMP if interrupt is high temperature - * failure alarm, else return PHY access status. **/ -static s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw) +static s32 ixgbe_handle_lasi_ext_t_x550em(struct ixgbe_hw *hw, + bool *is_overtemp) { struct ixgbe_phy_info *phy = &hw->phy; bool lsc; u32 status; - status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc); + status = ixgbe_get_lasi_ext_t_x550em(hw, &lsc, is_overtemp); if (status) return status; @@ -2692,7 +2696,7 @@ u16 speed; if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_copper) - return IXGBE_ERR_CONFIG; + return -EIO; if (!(hw->mac.type == ixgbe_mac_X550EM_x && !(hw->phy.nw_mng_if_sel & IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE))) { @@ -2735,7 +2739,7 @@ break; default: /* Internal PHY does not support anything else */ - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } return ixgbe_setup_ixfi_x550em(hw, &force_speed); @@ -2767,7 +2771,7 @@ u16 phy_data; if (led_idx >= IXGBE_X557_MAX_LED_INDEX) - return IXGBE_ERR_PARAM; + return -EINVAL; /* To turn on the LED, set mode to ON. */ hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, @@ -2789,7 +2793,7 @@ u16 phy_data; if (led_idx >= IXGBE_X557_MAX_LED_INDEX) - return IXGBE_ERR_PARAM; + return -EINVAL; /* To turn on the LED, set mode to ON. */ hw->phy.ops.read_reg(hw, IXGBE_X557_LED_PROVISIONING + led_idx, @@ -2813,8 +2817,9 @@ * * Sends driver version number to firmware through the manageability * block. On success return 0 - * else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring - * semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails. + * else returns -EBUSY when encountering an error acquiring + * semaphore, -EIO when command fails or -ENIVAL when incorrect + * params passed. **/ static s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min, u8 build, u8 sub, u16 len, @@ -2825,7 +2830,7 @@ int i; if (!len || !driver_ver || (len > sizeof(fw_cmd.driver_string))) - return IXGBE_ERR_INVALID_ARGUMENT; + return -EINVAL; fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len; @@ -2850,7 +2855,7 @@ if (fw_cmd.hdr.cmd_or_resp.ret_status != FW_CEM_RESP_STATUS_SUCCESS) - return IXGBE_ERR_HOST_INTERFACE_COMMAND; + return -EIO; return 0; } @@ -2907,7 +2912,7 @@ /* Validate the requested mode */ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { hw_err(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } /* 10gig parts do not have a word in the EEPROM to determine the @@ -2942,7 +2947,7 @@ break; default: hw_err(hw, "Flow control param set incorrectly\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } switch (hw->device_id) { @@ -2986,8 +2991,8 @@ static void ixgbe_fc_autoneg_backplane_x550em_a(struct ixgbe_hw *hw) { u32 link_s1, lp_an_page_low, an_cntl_1; - s32 status = IXGBE_ERR_FC_NOT_NEGOTIATED; ixgbe_link_speed speed; + s32 status = -EIO; bool link_up; /* AN should have completed when the cable was plugged in. @@ -3013,7 +3018,7 @@ if (status || (link_s1 & IXGBE_KRM_LINK_S1_MAC_AN_COMPLETE) == 0) { hw_dbg(hw, "Auto-Negotiation did not complete\n"); - status = IXGBE_ERR_FC_NOT_NEGOTIATED; + status = -EIO; goto out; } @@ -3187,21 +3192,23 @@ /** * ixgbe_check_overtemp_fw - Check firmware-controlled PHYs for overtemp * @hw: pointer to hardware structure + * + * Return true when an overtemp event detected, otherwise false. */ -static s32 ixgbe_check_overtemp_fw(struct ixgbe_hw *hw) +static bool ixgbe_check_overtemp_fw(struct ixgbe_hw *hw) { u32 store[FW_PHY_ACT_DATA_COUNT] = { 0 }; s32 rc; rc = ixgbe_fw_phy_activity(hw, FW_PHY_ACT_GET_LINK_INFO, &store); if (rc) - return rc; + return false; if (store[0] & FW_PHY_ACT_GET_LINK_INFO_TEMP) { ixgbe_shutdown_fw_phy(hw); - return IXGBE_ERR_OVERTEMP; + return true; } - return 0; + return false; } /** @@ -3251,8 +3258,7 @@ /* Identify the PHY or SFP module */ ret_val = phy->ops.identify(hw); - if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED || - ret_val == IXGBE_ERR_PHY_ADDR_INVALID) + if (ret_val == -EOPNOTSUPP || ret_val == -EFAULT) return ret_val; /* Setup function pointers based on detected hardware */ @@ -3460,8 +3466,7 @@ /* PHY ops must be identified and initialized prior to reset */ status = hw->phy.ops.init(hw); - if (status == IXGBE_ERR_SFP_NOT_SUPPORTED || - status == IXGBE_ERR_PHY_ADDR_INVALID) + if (status == -EOPNOTSUPP || status == -EFAULT) return status; /* start the external PHY */ @@ -3477,7 +3482,7 @@ hw->phy.sfp_setup_needed = false; } - if (status == IXGBE_ERR_SFP_NOT_SUPPORTED) + if (status == -EOPNOTSUPP) return status; /* Reset PHY */ @@ -3501,7 +3506,7 @@ status = hw->mac.ops.acquire_swfw_sync(hw, swfw_mask); if (status) { hw_dbg(hw, "semaphore failed with %d", status); - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; } ctrl |= IXGBE_READ_REG(hw, IXGBE_CTRL); @@ -3519,7 +3524,7 @@ } if (ctrl & IXGBE_CTRL_RST_MASK) { - status = IXGBE_ERR_RESET_FAILED; + status = -EIO; hw_dbg(hw, "Reset polling failed to complete.\n"); } @@ -3615,7 +3620,7 @@ /* Validate the requested mode */ if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { hw_err(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; + return -EINVAL; } if (hw->fc.requested_mode == ixgbe_fc_default) @@ -3672,7 +3677,7 @@ break; default: hw_err(hw, "Flow control param set incorrectly\n"); - return IXGBE_ERR_CONFIG; + return -EIO; } status = hw->mac.ops.write_iosf_sb_reg(hw, @@ -3768,7 +3773,7 @@ return 0; if (hmask) ixgbe_release_swfw_sync_X540(hw, hmask); - if (status != IXGBE_ERR_TOKEN_RETRY) + if (status != -EAGAIN) return status; msleep(FW_PHY_TOKEN_DELAY); } @@ -3812,7 +3817,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = hw->phy.ops.read_reg_mdi(hw, reg_addr, device_type, phy_data); @@ -3838,7 +3843,7 @@ s32 status; if (hw->mac.ops.acquire_swfw_sync(hw, mask)) - return IXGBE_ERR_SWFW_SYNC; + return -EBUSY; status = ixgbe_write_phy_reg_mdi(hw, reg_addr, device_type, phy_data); hw->mac.ops.release_swfw_sync(hw, mask); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/marvell/mvmdio.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/marvell/mvmdio.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -58,11 +59,6 @@ * - Armada 370 (Globalscale Mirabox): 41us to 43us (Polled) */ #define MVMDIO_SMI_TIMEOUT 1000 /* 1000us = 1ms */ -#define MVMDIO_SMI_POLL_INTERVAL_MIN 45 -#define MVMDIO_SMI_POLL_INTERVAL_MAX 55 - -#define MVMDIO_XSMI_POLL_INTERVAL_MIN 150 -#define MVMDIO_XSMI_POLL_INTERVAL_MAX 160 struct orion_mdio_dev { void __iomem *regs; @@ -84,8 +80,6 @@ struct orion_mdio_ops { int (*is_done)(struct orion_mdio_dev *); - unsigned int poll_interval_min; - unsigned int poll_interval_max; }; /* Wait for the SMI unit to be ready for another operation @@ -94,34 +88,23 @@ struct mii_bus *bus) { struct orion_mdio_dev *dev = bus->priv; - unsigned long timeout = usecs_to_jiffies(MVMDIO_SMI_TIMEOUT); - unsigned long end = jiffies + timeout; - int timedout = 0; + unsigned long timeout; + int done; - while (1) { - if (ops->is_done(dev)) + if (dev->err_interrupt <= 0) { + if (!read_poll_timeout_atomic(ops->is_done, done, done, 2, + MVMDIO_SMI_TIMEOUT, false, dev)) return 0; - else if (timedout) - break; - - if (dev->err_interrupt <= 0) { - usleep_range(ops->poll_interval_min, - ops->poll_interval_max); - - if (time_is_before_jiffies(end)) - ++timedout; - } else { - /* wait_event_timeout does not guarantee a delay of at - * least one whole jiffie, so timeout must be no less - * than two. - */ - if (timeout < 2) - timeout = 2; - wait_event_timeout(dev->smi_busy_wait, - ops->is_done(dev), timeout); + } else { + /* wait_event_timeout does not guarantee a delay of at + * least one whole jiffie, so timeout must be no less + * than two. + */ + timeout = max(usecs_to_jiffies(MVMDIO_SMI_TIMEOUT), 2); - ++timedout; - } + if (wait_event_timeout(dev->smi_busy_wait, + ops->is_done(dev), timeout)) + return 0; } dev_err(bus->parent, "Timeout: SMI busy for too long\n"); @@ -135,8 +118,6 @@ static const struct orion_mdio_ops orion_mdio_smi_ops = { .is_done = orion_mdio_smi_is_done, - .poll_interval_min = MVMDIO_SMI_POLL_INTERVAL_MIN, - .poll_interval_max = MVMDIO_SMI_POLL_INTERVAL_MAX, }; static int orion_mdio_smi_read(struct mii_bus *bus, int mii_id, @@ -194,8 +175,6 @@ static const struct orion_mdio_ops orion_mdio_xsmi_ops = { .is_done = orion_mdio_xsmi_is_done, - .poll_interval_min = MVMDIO_XSMI_POLL_INTERVAL_MIN, - .poll_interval_max = MVMDIO_XSMI_POLL_INTERVAL_MAX, }; static int orion_mdio_xsmi_read_c45(struct mii_bus *bus, int mii_id, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en/params.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en/params.c @@ -1061,8 +1061,8 @@ void *wq = MLX5_ADDR_OF(sqc, sqc, wq); bool allow_swp; - allow_swp = - mlx5_geneve_tx_allowed(mdev) || !!mlx5_ipsec_device_caps(mdev); + allow_swp = mlx5_geneve_tx_allowed(mdev) || + (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO); mlx5e_build_sq_param_common(mdev, param); MLX5_SET(wq, wq, log_wq_sz, params->log_sq_size); MLX5_SET(sqc, sqc, allow_swp, allow_swp); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c @@ -254,11 +254,13 @@ ft->g = kcalloc(MLX5E_ARFS_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL); - in = kvzalloc(inlen, GFP_KERNEL); - if (!in || !ft->g) { - kfree(ft->g); - kvfree(in); + if (!ft->g) return -ENOMEM; + + in = kvzalloc(inlen, GFP_KERNEL); + if (!in) { + err = -ENOMEM; + goto err_free_g; } mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria); @@ -278,7 +280,7 @@ break; default: err = -EINVAL; - goto out; + goto err_free_in; } switch (type) { @@ -300,7 +302,7 @@ break; default: err = -EINVAL; - goto out; + goto err_free_in; } MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); @@ -309,7 +311,7 @@ MLX5_SET_CFG(in, end_flow_index, ix - 1); ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); if (IS_ERR(ft->g[ft->num_groups])) - goto err; + goto err_clean_group; ft->num_groups++; memset(in, 0, inlen); @@ -318,18 +320,20 @@ MLX5_SET_CFG(in, end_flow_index, ix - 1); ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); if (IS_ERR(ft->g[ft->num_groups])) - goto err; + goto err_clean_group; ft->num_groups++; kvfree(in); return 0; -err: +err_clean_group: err = PTR_ERR(ft->g[ft->num_groups]); ft->g[ft->num_groups] = NULL; -out: +err_free_in: kvfree(in); - +err_free_g: + kfree(ft->g); + ft->g = NULL; return err; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge_mcast.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge_mcast.c @@ -78,9 +78,12 @@ xa_for_each(&entry->ports, idx, port) { dests[i].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; dests[i].ft = port->mcast.ft; + if (port->vport_num == MLX5_VPORT_UPLINK) + dests[i].ft->flags |= MLX5_FLOW_TABLE_UPLINK_VPORT; i++; } + rule_spec->flow_context.flags |= FLOW_CONTEXT_UPLINK_HAIRPIN_EN; rule_spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; dmac_v = MLX5_ADDR_OF(fte_match_param, rule_spec->match_value, outer_headers.dmac_47_16); ether_addr_copy(dmac_v, entry->key.addr); @@ -586,10 +589,7 @@ if (!rule_spec) return ERR_PTR(-ENOMEM); - if (MLX5_CAP_ESW_FLOWTABLE(bridge->br_offloads->esw->dev, flow_source) && - port->vport_num == MLX5_VPORT_UPLINK) - rule_spec->flow_context.flow_source = - MLX5_FLOW_CONTEXT_FLOW_SOURCE_LOCAL_VPORT; + rule_spec->flow_context.flags |= FLOW_CONTEXT_UPLINK_HAIRPIN_EN; rule_spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT; @@ -661,15 +661,11 @@ if (!rule_spec) return ERR_PTR(-ENOMEM); - if (MLX5_CAP_ESW_FLOWTABLE(bridge->br_offloads->esw->dev, flow_source) && - port->vport_num == MLX5_VPORT_UPLINK) - rule_spec->flow_context.flow_source = - MLX5_FLOW_CONTEXT_FLOW_SOURCE_LOCAL_VPORT; - if (MLX5_CAP_ESW(bridge->br_offloads->esw->dev, merged_eswitch)) { dest.vport.flags = MLX5_FLOW_DEST_VPORT_VHCA_ID; dest.vport.vhca_id = port->esw_owner_vhca_id; } + rule_spec->flow_context.flags |= FLOW_CONTEXT_UPLINK_HAIRPIN_EN; handle = mlx5_add_flow_rules(port->mcast.ft, rule_spec, &flow_act, &dest, 1); kvfree(rule_spec); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/fs_cmd.c @@ -566,6 +566,8 @@ fte->flow_context.flow_tag); MLX5_SET(flow_context, in_flow_context, flow_source, fte->flow_context.flow_source); + MLX5_SET(flow_context, in_flow_context, uplink_hairpin_en, + !!(fte->flow_context.flags & FLOW_CONTEXT_UPLINK_HAIRPIN_EN)); MLX5_SET(flow_context, in_flow_context, extended_destination, extended_dest); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c @@ -98,7 +98,7 @@ mlx5_fill_page_frag_array(&cq->wq_ctrl.buf, (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas)); - MLX5_SET(cqc, cqc, cq_period_mode, DIM_CQ_PERIOD_MODE_START_FROM_EQE); + MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE); MLX5_SET(cqc, cqc, c_eqn_or_apu_element, eqn); MLX5_SET(cqc, cqc, uar_page, mdev->priv.uar->index); MLX5_SET(cqc, cqc, log_page_size, cq->wq_ctrl.buf.page_shift - only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlx5/core/steering/dr_action.c @@ -781,6 +781,7 @@ switch (action_type) { case DR_ACTION_TYP_DROP: attr.final_icm_addr = nic_dmn->drop_icm_addr; + attr.hit_gvmi = nic_dmn->drop_icm_addr >> 48; break; case DR_ACTION_TYP_FT: dest_action = action; @@ -866,11 +867,17 @@ action->sampler->tx_icm_addr; break; case DR_ACTION_TYP_VPORT: - attr.hit_gvmi = action->vport->caps->vhca_gvmi; - dest_action = action; - attr.final_icm_addr = rx_rule ? - action->vport->caps->icm_address_rx : - action->vport->caps->icm_address_tx; + if (unlikely(rx_rule && action->vport->caps->num == MLX5_VPORT_UPLINK)) { + /* can't go to uplink on RX rule - dropping instead */ + attr.final_icm_addr = nic_dmn->drop_icm_addr; + attr.hit_gvmi = nic_dmn->drop_icm_addr >> 48; + } else { + attr.hit_gvmi = action->vport->caps->vhca_gvmi; + dest_action = action; + attr.final_icm_addr = rx_rule ? + action->vport->caps->icm_address_rx : + action->vport->caps->icm_address_tx; + } break; case DR_ACTION_TYP_POP_VLAN: if (!rx_rule && !(dmn->ste_ctx->actions_caps & only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_main.c @@ -130,9 +130,15 @@ { struct mlxbf_gige *priv = netdev_priv(netdev); struct phy_device *phydev = netdev->phydev; + u64 control; u64 int_en; int err; + /* Perform general init of GigE block */ + control = readq(priv->base + MLXBF_GIGE_CONTROL); + control |= MLXBF_GIGE_CONTROL_PORT_EN; + writeq(control, priv->base + MLXBF_GIGE_CONTROL); + err = mlxbf_gige_request_irqs(priv); if (err) return err; @@ -147,14 +153,14 @@ */ priv->valid_polarity = 0; - err = mlxbf_gige_rx_init(priv); + phy_start(phydev); + + err = mlxbf_gige_tx_init(priv); if (err) goto free_irqs; - err = mlxbf_gige_tx_init(priv); + err = mlxbf_gige_rx_init(priv); if (err) - goto rx_deinit; - - phy_start(phydev); + goto tx_deinit; netif_napi_add(netdev, &priv->napi, mlxbf_gige_poll); napi_enable(&priv->napi); @@ -176,8 +182,8 @@ return 0; -rx_deinit: - mlxbf_gige_rx_deinit(priv); +tx_deinit: + mlxbf_gige_tx_deinit(priv); free_irqs: mlxbf_gige_free_irqs(priv); @@ -365,7 +371,6 @@ void __iomem *plu_base; void __iomem *base; int addr, phy_irq; - u64 control; int err; base = devm_platform_ioremap_resource(pdev, MLXBF_GIGE_RES_MAC); @@ -380,11 +385,6 @@ if (IS_ERR(plu_base)) return PTR_ERR(plu_base); - /* Perform general init of GigE block */ - control = readq(base + MLXBF_GIGE_CONTROL); - control |= MLXBF_GIGE_CONTROL_PORT_EN; - writeq(control, base + MLXBF_GIGE_CONTROL); - netdev = devm_alloc_etherdev(&pdev->dev, sizeof(*priv)); if (!netdev) return -ENOMEM; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c @@ -301,6 +301,7 @@ unsigned long *p_index) { unsigned int num_rows, entry_size; + unsigned long index; /* We only allow allocations of entire rows */ if (num_erps % erp_core->num_erp_banks != 0) @@ -309,10 +310,11 @@ entry_size = erp_core->erpt_entries_size[region_type]; num_rows = num_erps / erp_core->num_erp_banks; - *p_index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size); - if (*p_index == 0) + index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size); + if (!index) return -ENOBUFS; - *p_index -= MLXSW_SP_ACL_ERP_GENALLOC_OFFSET; + + *p_index = index - MLXSW_SP_ACL_ERP_GENALLOC_OFFSET; return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c @@ -681,13 +681,13 @@ mlxsw_sp_acl_tcam_region_destroy(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_tcam_region *region) { + struct mlxsw_sp_acl_tcam *tcam = mlxsw_sp_acl_to_tcam(mlxsw_sp->acl); const struct mlxsw_sp_acl_tcam_ops *ops = mlxsw_sp->acl_tcam_ops; ops->region_fini(mlxsw_sp, region->priv); mlxsw_sp_acl_tcam_region_disable(mlxsw_sp, region); mlxsw_sp_acl_tcam_region_free(mlxsw_sp, region); - mlxsw_sp_acl_tcam_region_id_put(region->group->tcam, - region->id); + mlxsw_sp_acl_tcam_region_id_put(tcam, region->id); kfree(region); } @@ -1564,6 +1564,8 @@ tcam->max_groups = max_groups; tcam->max_group_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_GROUP_SIZE); + tcam->max_group_size = min_t(unsigned int, tcam->max_group_size, + MLXSW_REG_PAGT_ACL_MAX_NUM); err = ops->init(mlxsw_sp, tcam->priv, tcam); if (err) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -10960,6 +10960,13 @@ if (err) goto err_register_netevent_notifier; + mlxsw_sp->router->netdevice_nb.notifier_call = + mlxsw_sp_router_netdevice_event; + err = register_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), + &mlxsw_sp->router->netdevice_nb); + if (err) + goto err_register_netdev_notifier; + mlxsw_sp->router->nexthop_nb.notifier_call = mlxsw_sp_nexthop_obj_event; err = register_nexthop_notifier(mlxsw_sp_net(mlxsw_sp), @@ -10975,22 +10982,15 @@ if (err) goto err_register_fib_notifier; - mlxsw_sp->router->netdevice_nb.notifier_call = - mlxsw_sp_router_netdevice_event; - err = register_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), - &mlxsw_sp->router->netdevice_nb); - if (err) - goto err_register_netdev_notifier; - return 0; -err_register_netdev_notifier: - unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp), - &mlxsw_sp->router->fib_nb); err_register_fib_notifier: unregister_nexthop_notifier(mlxsw_sp_net(mlxsw_sp), &mlxsw_sp->router->nexthop_nb); err_register_nexthop_notifier: + unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), + &router->netdevice_nb); +err_register_netdev_notifier: unregister_netevent_notifier(&mlxsw_sp->router->netevent_nb); err_register_netevent_notifier: unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb); @@ -11038,11 +11038,11 @@ { struct mlxsw_sp_router *router = mlxsw_sp->router; - unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), - &router->netdevice_nb); unregister_fib_notifier(mlxsw_sp_net(mlxsw_sp), &router->fib_nb); unregister_nexthop_notifier(mlxsw_sp_net(mlxsw_sp), &router->nexthop_nb); + unregister_netdevice_notifier_net(mlxsw_sp_net(mlxsw_sp), + &router->netdevice_nb); unregister_netevent_notifier(&router->netevent_nb); unregister_inet6addr_validator_notifier(&router->inet6addr_valid_nb); unregister_inetaddr_validator_notifier(&router->inetaddr_valid_nb); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/microchip/lan966x/lan966x_port.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/microchip/lan966x/lan966x_port.c @@ -168,9 +168,10 @@ lan966x_taprio_speed_set(port, config->speed); /* Also the GIGA_MODE_ENA(1) needs to be set regardless of the - * port speed for QSGMII ports. + * port speed for QSGMII or SGMII ports. */ - if (phy_interface_num_ports(config->portmode) == 4) + if (phy_interface_num_ports(config->portmode) == 4 || + config->portmode == PHY_INTERFACE_MODE_SGMII) mode = DEV_MAC_MODE_CFG_GIGA_MODE_ENA_SET(1); lan_wr(config->duplex | mode, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c @@ -375,6 +375,10 @@ del_timer_sync(&ionic->watchdog_timer); if (ionic->lif) { + /* prevent adminq cmds if already known as down */ + if (test_and_clear_bit(IONIC_LIF_F_FW_RESET, ionic->lif->state)) + set_bit(IONIC_LIF_F_FW_STOPPING, ionic->lif->state); + ionic_lif_unregister(ionic->lif); ionic_devlink_unregister(ionic); ionic_lif_deinit(ionic->lif); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/pensando/ionic/ionic_dev.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/pensando/ionic/ionic_dev.c @@ -321,6 +321,7 @@ void ionic_dev_cmd_go(struct ionic_dev *idev, union ionic_dev_cmd *cmd) { + idev->opcode = cmd->cmd.opcode; memcpy_toio(&idev->dev_cmd_regs->cmd, cmd, sizeof(*cmd)); iowrite32(0, &idev->dev_cmd_regs->done); iowrite32(1, &idev->dev_cmd_regs->doorbell); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/pensando/ionic/ionic_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/pensando/ionic/ionic_main.c @@ -410,22 +410,28 @@ do_msg); } -int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) +static int __ionic_adminq_post_wait(struct ionic_lif *lif, + struct ionic_admin_ctx *ctx, + const bool do_msg) { int err; + if (!ionic_is_fw_running(&lif->ionic->idev)) + return 0; + err = ionic_adminq_post(lif, ctx); - return ionic_adminq_wait(lif, ctx, err, true); + return ionic_adminq_wait(lif, ctx, err, do_msg); } -int ionic_adminq_post_wait_nomsg(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) +int ionic_adminq_post_wait(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) { - int err; - - err = ionic_adminq_post(lif, ctx); + return __ionic_adminq_post_wait(lif, ctx, true); +} - return ionic_adminq_wait(lif, ctx, err, false); +int ionic_adminq_post_wait_nomsg(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) +{ + return __ionic_adminq_post_wait(lif, ctx, false); } static void ionic_dev_cmd_clean(struct ionic *ionic) @@ -465,7 +471,7 @@ */ max_wait = jiffies + (max_seconds * HZ); try_again: - opcode = readb(&idev->dev_cmd_regs->cmd.cmd.opcode); + opcode = idev->opcode; start_time = jiffies; for (fw_up = ionic_is_fw_running(idev); !done && fw_up && time_before(jiffies, max_wait); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -254,6 +254,7 @@ u32 msg_enable; int wolopts; int wol_irq; + bool wol_irq_disabled; int clk_csr; struct timer_list eee_ctrl_timer; int lpi_irq; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -752,10 +752,16 @@ if (wol->wolopts) { pr_info("stmmac: wakeup enable\n"); device_set_wakeup_enable(priv->device, 1); - enable_irq_wake(priv->wol_irq); + /* Avoid unbalanced enable_irq_wake calls */ + if (priv->wol_irq_disabled) + enable_irq_wake(priv->wol_irq); + priv->wol_irq_disabled = false; } else { device_set_wakeup_enable(priv->device, 0); - disable_irq_wake(priv->wol_irq); + /* Avoid unbalanced disable_irq_wake calls */ + if (!priv->wol_irq_disabled) + disable_irq_wake(priv->wol_irq); + priv->wol_irq_disabled = true; } mutex_lock(&priv->lock); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/fjes/fjes_hw.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/fjes/fjes_hw.c @@ -221,21 +221,25 @@ mem_size = FJES_DEV_REQ_BUF_SIZE(hw->max_epid); hw->hw_info.req_buf = kzalloc(mem_size, GFP_KERNEL); - if (!(hw->hw_info.req_buf)) - return -ENOMEM; + if (!(hw->hw_info.req_buf)) { + result = -ENOMEM; + goto free_ep_info; + } hw->hw_info.req_buf_size = mem_size; mem_size = FJES_DEV_RES_BUF_SIZE(hw->max_epid); hw->hw_info.res_buf = kzalloc(mem_size, GFP_KERNEL); - if (!(hw->hw_info.res_buf)) - return -ENOMEM; + if (!(hw->hw_info.res_buf)) { + result = -ENOMEM; + goto free_req_buf; + } hw->hw_info.res_buf_size = mem_size; result = fjes_hw_alloc_shared_status_region(hw); if (result) - return result; + goto free_res_buf; hw->hw_info.buffer_share_bit = 0; hw->hw_info.buffer_unshare_reserve_bit = 0; @@ -246,11 +250,11 @@ result = fjes_hw_alloc_epbuf(&buf_pair->tx); if (result) - return result; + goto free_epbuf; result = fjes_hw_alloc_epbuf(&buf_pair->rx); if (result) - return result; + goto free_epbuf; spin_lock_irqsave(&hw->rx_status_lock, flags); fjes_hw_setup_epbuf(&buf_pair->tx, mac, @@ -273,6 +277,25 @@ fjes_hw_init_command_registers(hw, ¶m); return 0; + +free_epbuf: + for (epidx = 0; epidx < hw->max_epid ; epidx++) { + if (epidx == hw->my_epid) + continue; + fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].tx); + fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].rx); + } + fjes_hw_free_shared_status_region(hw); +free_res_buf: + kfree(hw->hw_info.res_buf); + hw->hw_info.res_buf = NULL; +free_req_buf: + kfree(hw->hw_info.req_buf); + hw->hw_info.req_buf = NULL; +free_ep_info: + kfree(hw->ep_shm_info); + hw->ep_shm_info = NULL; + return result; } static void fjes_hw_cleanup(struct fjes_hw *hw) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/phy/at803x.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/phy/at803x.c @@ -2050,7 +2050,7 @@ .write_page = at803x_write_page, .get_features = at803x_get_features, .read_status = at803x_read_status, - .config_intr = &at803x_config_intr, + .config_intr = at803x_config_intr, .handle_interrupt = at803x_handle_interrupt, .get_tunable = at803x_get_tunable, .set_tunable = at803x_set_tunable, @@ -2080,7 +2080,7 @@ .resume = at803x_resume, .flags = PHY_POLL_CABLE_TEST, /* PHY_BASIC_FEATURES */ - .config_intr = &at803x_config_intr, + .config_intr = at803x_config_intr, .handle_interrupt = at803x_handle_interrupt, .cable_test_start = at803x_cable_test_start, .cable_test_get_status = at803x_cable_test_get_status, @@ -2096,7 +2096,7 @@ .resume = at803x_resume, .flags = PHY_POLL_CABLE_TEST, /* PHY_BASIC_FEATURES */ - .config_intr = &at803x_config_intr, + .config_intr = at803x_config_intr, .handle_interrupt = at803x_handle_interrupt, .cable_test_start = at803x_cable_test_start, .cable_test_get_status = at803x_cable_test_get_status, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/phy/mediatek-ge-soc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/phy/mediatek-ge-soc.c @@ -1,11 +1,14 @@ // SPDX-License-Identifier: GPL-2.0+ #include +#include +#include #include #include #include #include #include #include +#include #define MTK_GPHY_ID_MT7981 0x03a29461 #define MTK_GPHY_ID_MT7988 0x03a29481 @@ -208,9 +211,42 @@ #define MTK_PHY_DA_TX_R50_PAIR_C 0x53f #define MTK_PHY_DA_TX_R50_PAIR_D 0x540 +/* Registers on MDIO_MMD_VEND2 */ +#define MTK_PHY_LED0_ON_CTRL 0x24 +#define MTK_PHY_LED1_ON_CTRL 0x26 +#define MTK_PHY_LED_ON_MASK GENMASK(6, 0) +#define MTK_PHY_LED_ON_LINK1000 BIT(0) +#define MTK_PHY_LED_ON_LINK100 BIT(1) +#define MTK_PHY_LED_ON_LINK10 BIT(2) +#define MTK_PHY_LED_ON_LINKDOWN BIT(3) +#define MTK_PHY_LED_ON_FDX BIT(4) /* Full duplex */ +#define MTK_PHY_LED_ON_HDX BIT(5) /* Half duplex */ +#define MTK_PHY_LED_ON_FORCE_ON BIT(6) +#define MTK_PHY_LED_ON_POLARITY BIT(14) +#define MTK_PHY_LED_ON_ENABLE BIT(15) + +#define MTK_PHY_LED0_BLINK_CTRL 0x25 +#define MTK_PHY_LED1_BLINK_CTRL 0x27 +#define MTK_PHY_LED_BLINK_1000TX BIT(0) +#define MTK_PHY_LED_BLINK_1000RX BIT(1) +#define MTK_PHY_LED_BLINK_100TX BIT(2) +#define MTK_PHY_LED_BLINK_100RX BIT(3) +#define MTK_PHY_LED_BLINK_10TX BIT(4) +#define MTK_PHY_LED_BLINK_10RX BIT(5) +#define MTK_PHY_LED_BLINK_COLLISION BIT(6) +#define MTK_PHY_LED_BLINK_RX_CRC_ERR BIT(7) +#define MTK_PHY_LED_BLINK_RX_IDLE_ERR BIT(8) +#define MTK_PHY_LED_BLINK_FORCE_BLINK BIT(9) + +#define MTK_PHY_LED1_DEFAULT_POLARITIES BIT(1) + #define MTK_PHY_RG_BG_RASEL 0x115 #define MTK_PHY_RG_BG_RASEL_MASK GENMASK(2, 0) +/* 'boottrap' register reflecting the configuration of the 4 PHY LEDs */ +#define RG_GPIO_MISC_TPBANK0 0x6f0 +#define RG_GPIO_MISC_TPBANK0_BOOTMODE GENMASK(11, 8) + /* These macro privides efuse parsing for internal phy. */ #define EFS_DA_TX_I2MPB_A(x) (((x) >> 0) & GENMASK(5, 0)) #define EFS_DA_TX_I2MPB_B(x) (((x) >> 6) & GENMASK(5, 0)) @@ -238,13 +274,6 @@ PAIR_D, }; -enum { - GPHY_PORT0, - GPHY_PORT1, - GPHY_PORT2, - GPHY_PORT3, -}; - enum calibration_mode { EFUSE_K, SW_K @@ -263,6 +292,19 @@ SW_M }; +#define MTK_PHY_LED_STATE_FORCE_ON 0 +#define MTK_PHY_LED_STATE_FORCE_BLINK 1 +#define MTK_PHY_LED_STATE_NETDEV 2 + +struct mtk_socphy_priv { + unsigned long led_state; +}; + +struct mtk_socphy_shared { + u32 boottrap; + struct mtk_socphy_priv priv[4]; +}; + static int mtk_socphy_read_page(struct phy_device *phydev) { return __phy_read(phydev, MTK_EXT_PAGE_ACCESS); @@ -449,7 +491,7 @@ u16 reg, val; if (phydev->drv->phy_id == MTK_GPHY_ID_MT7988) - bias = -2; + bias = -1; val = clamp_val(bias + tx_r50_cal_val, 0, 63); @@ -665,6 +707,11 @@ static void mt798x_phy_common_finetune(struct phy_device *phydev) { phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); + /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ + __phy_write(phydev, 0x11, 0xc71); + __phy_write(phydev, 0x12, 0xc); + __phy_write(phydev, 0x10, 0x8fae); + /* EnabRandUpdTrig = 1 */ __phy_write(phydev, 0x11, 0x2f00); __phy_write(phydev, 0x12, 0xe); @@ -675,15 +722,56 @@ __phy_write(phydev, 0x12, 0x0); __phy_write(phydev, 0x10, 0x83aa); - /* TrFreeze = 0 */ + /* FfeUpdGainForce = 1(Enable), FfeUpdGainForceVal = 4 */ + __phy_write(phydev, 0x11, 0x240); + __phy_write(phydev, 0x12, 0x0); + __phy_write(phydev, 0x10, 0x9680); + + /* TrFreeze = 0 (mt7988 default) */ __phy_write(phydev, 0x11, 0x0); __phy_write(phydev, 0x12, 0x0); __phy_write(phydev, 0x10, 0x9686); + /* SSTrKp100 = 5 */ + /* SSTrKf100 = 6 */ + /* SSTrKp1000Mas = 5 */ + /* SSTrKf1000Mas = 6 */ /* SSTrKp1000Slv = 5 */ + /* SSTrKf1000Slv = 6 */ __phy_write(phydev, 0x11, 0xbaef); __phy_write(phydev, 0x12, 0x2e); __phy_write(phydev, 0x10, 0x968c); + phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); +} + +static void mt7981_phy_finetune(struct phy_device *phydev) +{ + u16 val[8] = { 0x01ce, 0x01c1, + 0x020f, 0x0202, + 0x03d0, 0x03c0, + 0x0013, 0x0005 }; + int i, k; + + /* 100M eye finetune: + * Keep middle level of TX MLT3 shapper as default. + * Only change TX MLT3 overshoot level here. + */ + for (k = 0, i = 1; i < 12; i++) { + if (i % 3 == 0) + continue; + phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); + } + + phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); + /* ResetSyncOffset = 6 */ + __phy_write(phydev, 0x11, 0x600); + __phy_write(phydev, 0x12, 0x0); + __phy_write(phydev, 0x10, 0x8fc0); + + /* VgaDecRate = 1 */ + __phy_write(phydev, 0x11, 0x4c2a); + __phy_write(phydev, 0x12, 0x3e); + __phy_write(phydev, 0x10, 0x8fa4); /* MrvlTrFix100Kp = 3, MrvlTrFix100Kf = 2, * MrvlTrFix1000Kp = 3, MrvlTrFix1000Kf = 2 @@ -698,7 +786,7 @@ __phy_write(phydev, 0x10, 0x8ec0); phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); - /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9*/ + /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 9 */ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0x9)); @@ -731,48 +819,6 @@ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LDO_OUTPUT_V, 0x2222); } -static void mt7981_phy_finetune(struct phy_device *phydev) -{ - u16 val[8] = { 0x01ce, 0x01c1, - 0x020f, 0x0202, - 0x03d0, 0x03c0, - 0x0013, 0x0005 }; - int i, k; - - /* 100M eye finetune: - * Keep middle level of TX MLT3 shapper as default. - * Only change TX MLT3 overshoot level here. - */ - for (k = 0, i = 1; i < 12; i++) { - if (i % 3 == 0) - continue; - phy_write_mmd(phydev, MDIO_MMD_VEND1, i, val[k++]); - } - - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); - /* SlvDSPreadyTime = 24, MasDSPreadyTime = 24 */ - __phy_write(phydev, 0x11, 0xc71); - __phy_write(phydev, 0x12, 0xc); - __phy_write(phydev, 0x10, 0x8fae); - - /* ResetSyncOffset = 6 */ - __phy_write(phydev, 0x11, 0x600); - __phy_write(phydev, 0x12, 0x0); - __phy_write(phydev, 0x10, 0x8fc0); - - /* VgaDecRate = 1 */ - __phy_write(phydev, 0x11, 0x4c2a); - __phy_write(phydev, 0x12, 0x3e); - __phy_write(phydev, 0x10, 0x8fa4); - - /* FfeUpdGainForce = 4 */ - __phy_write(phydev, 0x11, 0x240); - __phy_write(phydev, 0x12, 0x0); - __phy_write(phydev, 0x10, 0x9680); - - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); -} - static void mt7988_phy_finetune(struct phy_device *phydev) { u16 val[12] = { 0x0187, 0x01cd, 0x01c8, 0x0182, @@ -787,17 +833,7 @@ /* TCT finetune */ phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_TX_FILTER, 0x5); - /* Disable TX power saving */ - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, - MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_52B5); - - /* SlvDSPreadyTime = 24, MasDSPreadyTime = 12 */ - __phy_write(phydev, 0x11, 0x671); - __phy_write(phydev, 0x12, 0xc); - __phy_write(phydev, 0x10, 0x8fae); - /* ResetSyncOffset = 5 */ __phy_write(phydev, 0x11, 0x500); __phy_write(phydev, 0x12, 0x0); @@ -805,13 +841,27 @@ /* VgaDecRate is 1 at default on mt7988 */ - phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); + /* MrvlTrFix100Kp = 6, MrvlTrFix100Kf = 7, + * MrvlTrFix1000Kp = 6, MrvlTrFix1000Kf = 7 + */ + __phy_write(phydev, 0x11, 0xb90a); + __phy_write(phydev, 0x12, 0x6f); + __phy_write(phydev, 0x10, 0x8f82); + + /* RemAckCntLimitCtrl = 1 */ + __phy_write(phydev, 0x11, 0xfbba); + __phy_write(phydev, 0x12, 0xc3); + __phy_write(phydev, 0x10, 0x87f8); - phy_select_page(phydev, MTK_PHY_PAGE_EXTENDED_2A30); - /* TxClkOffset = 2 */ - __phy_modify(phydev, MTK_PHY_ANARG_RG, MTK_PHY_TCLKOFFSET_MASK, - FIELD_PREP(MTK_PHY_TCLKOFFSET_MASK, 0x2)); phy_restore_page(phydev, MTK_PHY_PAGE_STANDARD, 0); + + /* TR_OPEN_LOOP_EN = 1, lpf_x_average = 10 */ + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG234, + MTK_PHY_TR_OPEN_LOOP_EN_MASK | MTK_PHY_LPF_X_AVERAGE_MASK, + BIT(0) | FIELD_PREP(MTK_PHY_LPF_X_AVERAGE_MASK, 0xa)); + + /* rg_tr_lpf_cnt_val = 1023 */ + phy_write_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_LPF_CNT_VAL, 0x3ff); } static void mt798x_phy_eee(struct phy_device *phydev) @@ -844,11 +894,11 @@ MTK_PHY_LPI_SLV_SEND_TX_EN, FIELD_PREP(MTK_PHY_LPI_SLV_SEND_TX_TIMER_MASK, 0x120)); - phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, - MTK_PHY_LPI_SEND_LOC_TIMER_MASK | - MTK_PHY_LPI_TXPCS_LOC_RCV, - FIELD_PREP(MTK_PHY_LPI_SEND_LOC_TIMER_MASK, 0x117)); + /* Keep MTK_PHY_LPI_SEND_LOC_TIMER as 375 */ + phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG239, + MTK_PHY_LPI_TXPCS_LOC_RCV); + /* This also fixes some IoT issues, such as CH340 */ phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RG_DEV1E_REG2C7, MTK_PHY_MAX_GAIN_MASK | MTK_PHY_MIN_GAIN_MASK, FIELD_PREP(MTK_PHY_MAX_GAIN_MASK, 0x8) | @@ -882,7 +932,7 @@ __phy_write(phydev, 0x12, 0x0); __phy_write(phydev, 0x10, 0x9690); - /* REG_EEE_st2TrKf1000 = 3 */ + /* REG_EEE_st2TrKf1000 = 2 */ __phy_write(phydev, 0x11, 0x114f); __phy_write(phydev, 0x12, 0x2); __phy_write(phydev, 0x10, 0x969a); @@ -907,7 +957,7 @@ __phy_write(phydev, 0x12, 0x0); __phy_write(phydev, 0x10, 0x96b8); - /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 1 */ + /* REGEEE_wake_slv_tr_wait_dfesigdet_en = 0 */ __phy_write(phydev, 0x11, 0x1463); __phy_write(phydev, 0x12, 0x0); __phy_write(phydev, 0x10, 0x96ca); @@ -1073,6 +1123,378 @@ return mt798x_phy_calibration(phydev); } +static int mt798x_phy_hw_led_on_set(struct phy_device *phydev, u8 index, + bool on) +{ + unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); + struct mtk_socphy_priv *priv = phydev->priv; + bool changed; + + if (on) + changed = !test_and_set_bit(bit_on, &priv->led_state); + else + changed = !!test_and_clear_bit(bit_on, &priv->led_state); + + changed |= !!test_and_clear_bit(MTK_PHY_LED_STATE_NETDEV + + (index ? 16 : 0), &priv->led_state); + if (changed) + return phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? + MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, + MTK_PHY_LED_ON_MASK, + on ? MTK_PHY_LED_ON_FORCE_ON : 0); + else + return 0; +} + +static int mt798x_phy_hw_led_blink_set(struct phy_device *phydev, u8 index, + bool blinking) +{ + unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0); + struct mtk_socphy_priv *priv = phydev->priv; + bool changed; + + if (blinking) + changed = !test_and_set_bit(bit_blink, &priv->led_state); + else + changed = !!test_and_clear_bit(bit_blink, &priv->led_state); + + changed |= !!test_bit(MTK_PHY_LED_STATE_NETDEV + + (index ? 16 : 0), &priv->led_state); + if (changed) + return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? + MTK_PHY_LED1_BLINK_CTRL : MTK_PHY_LED0_BLINK_CTRL, + blinking ? MTK_PHY_LED_BLINK_FORCE_BLINK : 0); + else + return 0; +} + +static int mt798x_phy_led_blink_set(struct phy_device *phydev, u8 index, + unsigned long *delay_on, + unsigned long *delay_off) +{ + bool blinking = false; + int err = 0; + + if (index > 1) + return -EINVAL; + + if (delay_on && delay_off && (*delay_on > 0) && (*delay_off > 0)) { + blinking = true; + *delay_on = 50; + *delay_off = 50; + } + + err = mt798x_phy_hw_led_blink_set(phydev, index, blinking); + if (err) + return err; + + return mt798x_phy_hw_led_on_set(phydev, index, false); +} + +static int mt798x_phy_led_brightness_set(struct phy_device *phydev, + u8 index, enum led_brightness value) +{ + int err; + + err = mt798x_phy_hw_led_blink_set(phydev, index, false); + if (err) + return err; + + return mt798x_phy_hw_led_on_set(phydev, index, (value != LED_OFF)); +} + +static const unsigned long supported_triggers = (BIT(TRIGGER_NETDEV_FULL_DUPLEX) | + BIT(TRIGGER_NETDEV_HALF_DUPLEX) | + BIT(TRIGGER_NETDEV_LINK) | + BIT(TRIGGER_NETDEV_LINK_10) | + BIT(TRIGGER_NETDEV_LINK_100) | + BIT(TRIGGER_NETDEV_LINK_1000) | + BIT(TRIGGER_NETDEV_RX) | + BIT(TRIGGER_NETDEV_TX)); + +static int mt798x_phy_led_hw_is_supported(struct phy_device *phydev, u8 index, + unsigned long rules) +{ + if (index > 1) + return -EINVAL; + + /* All combinations of the supported triggers are allowed */ + if (rules & ~supported_triggers) + return -EOPNOTSUPP; + + return 0; +}; + +static int mt798x_phy_led_hw_control_get(struct phy_device *phydev, u8 index, + unsigned long *rules) +{ + unsigned int bit_blink = MTK_PHY_LED_STATE_FORCE_BLINK + (index ? 16 : 0); + unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); + unsigned int bit_on = MTK_PHY_LED_STATE_FORCE_ON + (index ? 16 : 0); + struct mtk_socphy_priv *priv = phydev->priv; + int on, blink; + + if (index > 1) + return -EINVAL; + + on = phy_read_mmd(phydev, MDIO_MMD_VEND2, + index ? MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL); + + if (on < 0) + return -EIO; + + blink = phy_read_mmd(phydev, MDIO_MMD_VEND2, + index ? MTK_PHY_LED1_BLINK_CTRL : + MTK_PHY_LED0_BLINK_CTRL); + if (blink < 0) + return -EIO; + + if ((on & (MTK_PHY_LED_ON_LINK1000 | MTK_PHY_LED_ON_LINK100 | + MTK_PHY_LED_ON_LINK10)) || + (blink & (MTK_PHY_LED_BLINK_1000RX | MTK_PHY_LED_BLINK_100RX | + MTK_PHY_LED_BLINK_10RX | MTK_PHY_LED_BLINK_1000TX | + MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX))) + set_bit(bit_netdev, &priv->led_state); + else + clear_bit(bit_netdev, &priv->led_state); + + if (on & MTK_PHY_LED_ON_FORCE_ON) + set_bit(bit_on, &priv->led_state); + else + clear_bit(bit_on, &priv->led_state); + + if (blink & MTK_PHY_LED_BLINK_FORCE_BLINK) + set_bit(bit_blink, &priv->led_state); + else + clear_bit(bit_blink, &priv->led_state); + + if (!rules) + return 0; + + if (on & (MTK_PHY_LED_ON_LINK1000 | MTK_PHY_LED_ON_LINK100 | MTK_PHY_LED_ON_LINK10)) + *rules |= BIT(TRIGGER_NETDEV_LINK); + + if (on & MTK_PHY_LED_ON_LINK10) + *rules |= BIT(TRIGGER_NETDEV_LINK_10); + + if (on & MTK_PHY_LED_ON_LINK100) + *rules |= BIT(TRIGGER_NETDEV_LINK_100); + + if (on & MTK_PHY_LED_ON_LINK1000) + *rules |= BIT(TRIGGER_NETDEV_LINK_1000); + + if (on & MTK_PHY_LED_ON_FDX) + *rules |= BIT(TRIGGER_NETDEV_FULL_DUPLEX); + + if (on & MTK_PHY_LED_ON_HDX) + *rules |= BIT(TRIGGER_NETDEV_HALF_DUPLEX); + + if (blink & (MTK_PHY_LED_BLINK_1000RX | MTK_PHY_LED_BLINK_100RX | MTK_PHY_LED_BLINK_10RX)) + *rules |= BIT(TRIGGER_NETDEV_RX); + + if (blink & (MTK_PHY_LED_BLINK_1000TX | MTK_PHY_LED_BLINK_100TX | MTK_PHY_LED_BLINK_10TX)) + *rules |= BIT(TRIGGER_NETDEV_TX); + + return 0; +}; + +static int mt798x_phy_led_hw_control_set(struct phy_device *phydev, u8 index, + unsigned long rules) +{ + unsigned int bit_netdev = MTK_PHY_LED_STATE_NETDEV + (index ? 16 : 0); + struct mtk_socphy_priv *priv = phydev->priv; + u16 on = 0, blink = 0; + int ret; + + if (index > 1) + return -EINVAL; + + if (rules & BIT(TRIGGER_NETDEV_FULL_DUPLEX)) + on |= MTK_PHY_LED_ON_FDX; + + if (rules & BIT(TRIGGER_NETDEV_HALF_DUPLEX)) + on |= MTK_PHY_LED_ON_HDX; + + if (rules & (BIT(TRIGGER_NETDEV_LINK_10) | BIT(TRIGGER_NETDEV_LINK))) + on |= MTK_PHY_LED_ON_LINK10; + + if (rules & (BIT(TRIGGER_NETDEV_LINK_100) | BIT(TRIGGER_NETDEV_LINK))) + on |= MTK_PHY_LED_ON_LINK100; + + if (rules & (BIT(TRIGGER_NETDEV_LINK_1000) | BIT(TRIGGER_NETDEV_LINK))) + on |= MTK_PHY_LED_ON_LINK1000; + + if (rules & BIT(TRIGGER_NETDEV_RX)) { + blink |= MTK_PHY_LED_BLINK_10RX | + MTK_PHY_LED_BLINK_100RX | + MTK_PHY_LED_BLINK_1000RX; + } + + if (rules & BIT(TRIGGER_NETDEV_TX)) { + blink |= MTK_PHY_LED_BLINK_10TX | + MTK_PHY_LED_BLINK_100TX | + MTK_PHY_LED_BLINK_1000TX; + } + + if (blink || on) + set_bit(bit_netdev, &priv->led_state); + else + clear_bit(bit_netdev, &priv->led_state); + + ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? + MTK_PHY_LED1_ON_CTRL : + MTK_PHY_LED0_ON_CTRL, + MTK_PHY_LED_ON_FDX | + MTK_PHY_LED_ON_HDX | + MTK_PHY_LED_ON_LINK10 | + MTK_PHY_LED_ON_LINK100 | + MTK_PHY_LED_ON_LINK1000, + on); + + if (ret) + return ret; + + return phy_write_mmd(phydev, MDIO_MMD_VEND2, index ? + MTK_PHY_LED1_BLINK_CTRL : + MTK_PHY_LED0_BLINK_CTRL, blink); +}; + +static bool mt7988_phy_led_get_polarity(struct phy_device *phydev, int led_num) +{ + struct mtk_socphy_shared *priv = phydev->shared->priv; + u32 polarities; + + if (led_num == 0) + polarities = ~(priv->boottrap); + else + polarities = MTK_PHY_LED1_DEFAULT_POLARITIES; + + if (polarities & BIT(phydev->mdio.addr)) + return true; + + return false; +} + +static int mt7988_phy_fix_leds_polarities(struct phy_device *phydev) +{ + struct pinctrl *pinctrl; + int index; + + /* Setup LED polarity according to bootstrap use of LED pins */ + for (index = 0; index < 2; ++index) + phy_modify_mmd(phydev, MDIO_MMD_VEND2, index ? + MTK_PHY_LED1_ON_CTRL : MTK_PHY_LED0_ON_CTRL, + MTK_PHY_LED_ON_POLARITY, + mt7988_phy_led_get_polarity(phydev, index) ? + MTK_PHY_LED_ON_POLARITY : 0); + + /* Only now setup pinctrl to avoid bogus blinking */ + pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "gbe-led"); + if (IS_ERR(pinctrl)) + dev_err(&phydev->mdio.bus->dev, "Failed to setup PHY LED pinctrl\n"); + + return 0; +} + +static int mt7988_phy_probe_shared(struct phy_device *phydev) +{ + struct device_node *np = dev_of_node(&phydev->mdio.bus->dev); + struct mtk_socphy_shared *shared = phydev->shared->priv; + struct regmap *regmap; + u32 reg; + int ret; + + /* The LED0 of the 4 PHYs in MT7988 are wired to SoC pins LED_A, LED_B, + * LED_C and LED_D respectively. At the same time those pins are used to + * bootstrap configuration of the reference clock source (LED_A), + * DRAM DDRx16b x2/x1 (LED_B) and boot device (LED_C, LED_D). + * In practise this is done using a LED and a resistor pulling the pin + * either to GND or to VIO. + * The detected value at boot time is accessible at run-time using the + * TPBANK0 register located in the gpio base of the pinctrl, in order + * to read it here it needs to be referenced by a phandle called + * 'mediatek,pio' in the MDIO bus hosting the PHY. + * The 4 bits in TPBANK0 are kept as package shared data and are used to + * set LED polarity for each of the LED0. + */ + regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,pio"); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + ret = regmap_read(regmap, RG_GPIO_MISC_TPBANK0, ®); + if (ret) + return ret; + + shared->boottrap = FIELD_GET(RG_GPIO_MISC_TPBANK0_BOOTMODE, reg); + + return 0; +} + +static void mt798x_phy_leds_state_init(struct phy_device *phydev) +{ + int i; + + for (i = 0; i < 2; ++i) + mt798x_phy_led_hw_control_get(phydev, i, NULL); +} + +static int mt7988_phy_probe(struct phy_device *phydev) +{ + struct mtk_socphy_shared *shared; + struct mtk_socphy_priv *priv; + int err; + + if (phydev->mdio.addr > 3) + return -EINVAL; + + err = devm_phy_package_join(&phydev->mdio.dev, phydev, 0, + sizeof(struct mtk_socphy_shared)); + if (err) + return err; + + if (phy_package_probe_once(phydev)) { + err = mt7988_phy_probe_shared(phydev); + if (err) + return err; + } + + shared = phydev->shared->priv; + priv = &shared->priv[phydev->mdio.addr]; + + phydev->priv = priv; + + mt798x_phy_leds_state_init(phydev); + + err = mt7988_phy_fix_leds_polarities(phydev); + if (err) + return err; + + /* Disable TX power saving at probing to: + * 1. Meet common mode compliance test criteria + * 2. Make sure that TX-VCM calibration works fine + */ + phy_modify_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_RXADC_CTRL_RG7, + MTK_PHY_DA_AD_BUF_BIAS_LP_MASK, 0x3 << 8); + + return mt798x_phy_calibration(phydev); +} + +static int mt7981_phy_probe(struct phy_device *phydev) +{ + struct mtk_socphy_priv *priv; + + priv = devm_kzalloc(&phydev->mdio.dev, sizeof(struct mtk_socphy_priv), + GFP_KERNEL); + if (!priv) + return -ENOMEM; + + phydev->priv = priv; + + mt798x_phy_leds_state_init(phydev); + + return mt798x_phy_calibration(phydev); +} + static struct phy_driver mtk_socphy_driver[] = { { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7981), @@ -1080,11 +1502,16 @@ .config_init = mt798x_phy_config_init, .config_intr = genphy_no_config_intr, .handle_interrupt = genphy_handle_interrupt_no_ack, - .probe = mt798x_phy_calibration, + .probe = mt7981_phy_probe, .suspend = genphy_suspend, .resume = genphy_resume, .read_page = mtk_socphy_read_page, .write_page = mtk_socphy_write_page, + .led_blink_set = mt798x_phy_led_blink_set, + .led_brightness_set = mt798x_phy_led_brightness_set, + .led_hw_is_supported = mt798x_phy_led_hw_is_supported, + .led_hw_control_set = mt798x_phy_led_hw_control_set, + .led_hw_control_get = mt798x_phy_led_hw_control_get, }, { PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7988), @@ -1092,11 +1519,16 @@ .config_init = mt798x_phy_config_init, .config_intr = genphy_no_config_intr, .handle_interrupt = genphy_handle_interrupt_no_ack, - .probe = mt798x_phy_calibration, + .probe = mt7988_phy_probe, .suspend = genphy_suspend, .resume = genphy_resume, .read_page = mtk_socphy_read_page, .write_page = mtk_socphy_write_page, + .led_blink_set = mt798x_phy_led_blink_set, + .led_brightness_set = mt798x_phy_led_brightness_set, + .led_hw_is_supported = mt798x_phy_led_hw_is_supported, + .led_hw_control_set = mt798x_phy_led_hw_control_set, + .led_hw_control_get = mt798x_phy_led_hw_control_get, }, }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/ath/ath11k/ahb.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ath/ath11k/ahb.c @@ -827,8 +827,8 @@ prproc = rproc_get_by_phandle(rproc_phandle); if (!prproc) { - ath11k_err(ab, "failed to get rproc\n"); - return -EINVAL; + ath11k_dbg(ab, ATH11K_DBG_AHB, "failed to get rproc, deferring\n"); + return -EPROBE_DEFER; } ab_ahb->tgt_rproc = prproc; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/ath/ath11k/pcic.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ath/ath11k/pcic.c @@ -460,8 +460,6 @@ { int i; - set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); - for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; @@ -471,6 +469,8 @@ } ath11k_pcic_ext_grp_enable(irq_grp); } + + set_bit(ATH11K_FLAG_EXT_IRQ_ENABLED, &ab->dev_flags); } EXPORT_SYMBOL(ath11k_pcic_ext_irq_enable); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/ath/ath12k/hal.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ath/ath12k/hal.c @@ -889,8 +889,8 @@ static bool ath12k_hw_wcn7850_rx_desc_is_da_mcbc(struct hal_rx_desc *desc) { - return __le16_to_cpu(desc->u.wcn7850.msdu_end.info5) & - RX_MSDU_END_INFO5_DA_IS_MCBC; + return __le32_to_cpu(desc->u.wcn7850.msdu_end.info13) & + RX_MSDU_END_INFO13_MCAST_BCAST; } static void ath12k_hw_wcn7850_rx_desc_get_dot11_hdr(struct hal_rx_desc *desc, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/ath/ath12k/hw.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ath/ath12k/hw.c @@ -942,7 +942,8 @@ .rx_mac_buf_ring = true, .vdev_start_delay = true, - .interface_modes = BIT(NL80211_IFTYPE_STATION), + .interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_AP), .supports_monitor = false, .idle_ps = true, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -652,9 +652,10 @@ struct ath9k_htc_tx_event *tx_pend; int i; - for (i = 0; i < txs->cnt; i++) { - WARN_ON(txs->cnt > HTC_MAX_TX_STATUS); + if (WARN_ON_ONCE(txs->cnt > HTC_MAX_TX_STATUS)) + return; + for (i = 0; i < txs->cnt; i++) { __txs = &txs->txstatus[i]; skb = ath9k_htc_tx_get_packet(priv, __txs); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -1094,7 +1094,7 @@ node_trig = (void *)node_tlv->data; } - memcpy(node_trig->data + offset, trig->data, trig_data_len); + memcpy((u8 *)node_trig->data + offset, trig->data, trig_data_len); node_tlv->length = cpu_to_le32(size); if (policy & IWL_FW_INI_APPLY_POLICY_OVERRIDE_CFG) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -1010,7 +1010,8 @@ IEEE80211_EHT_PHY_CAP3_NG_16_MU_FEEDBACK | IEEE80211_EHT_PHY_CAP3_CODEBOOK_4_2_SU_FDBK | IEEE80211_EHT_PHY_CAP3_CODEBOOK_7_5_MU_FDBK | - IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK); + IEEE80211_EHT_PHY_CAP3_TRIG_MU_BF_PART_BW_FDBK | + IEEE80211_EHT_PHY_CAP3_TRIG_CQI_FDBK); iftype_data->eht_cap.eht_cap_elem.phy_cap_info[4] &= ~(IEEE80211_EHT_PHY_CAP4_PART_BW_DL_MU_MIMO | IEEE80211_EHT_PHY_CAP4_POWER_BOOST_FACT_SUPP); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -1673,7 +1673,7 @@ char buf[buflen] = {}; \ size_t buf_size = min(count, sizeof(buf) - 1); \ \ - if (copy_from_user(buf, user_buf, sizeof(buf))) \ + if (copy_from_user(buf, user_buf, buf_size)) \ return -EFAULT; \ \ return _iwl_dbgfs_link_sta_wrap_write(iwl_dbgfs_##name##_write, \ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c @@ -99,17 +99,6 @@ active_cnt = 2; } - /* - * If the firmware requested it, then we know that it supports - * getting zero for the values to indicate "use one, but pick - * which one yourself", which means it can dynamically pick one - * that e.g. has better RSSI. - */ - if (mvm->fw_static_smps_request && active_cnt == 1 && idle_cnt == 1) { - idle_cnt = 0; - active_cnt = 0; - } - *rxchain_info = cpu_to_le32(iwl_mvm_get_valid_rx_ant(mvm) << PHY_RX_CHAIN_VALID_POS); *rxchain_info |= cpu_to_le32(idle_cnt << PHY_RX_CHAIN_CNT_POS); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/marvell/libertas/Kconfig +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/marvell/libertas/Kconfig @@ -2,8 +2,6 @@ config LIBERTAS tristate "Marvell 8xxx Libertas WLAN driver support" depends on CFG80211 - select WIRELESS_EXT - select WEXT_SPY select LIB80211 select FW_LOADER help only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -2046,6 +2046,8 @@ mwifiex_set_sys_config_invalid_data(bss_cfg); + memcpy(bss_cfg->mac_addr, priv->curr_addr, ETH_ALEN); + if (params->beacon_interval) bss_cfg->beacon_period = params->beacon_interval; if (params->dtim_period) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/marvell/mwifiex/ioctl.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/marvell/mwifiex/ioctl.h @@ -107,6 +107,7 @@ u8 qos_info; u8 power_constraint; struct mwifiex_types_wmm_info wmm_info; + u8 mac_addr[ETH_ALEN]; }; enum { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/marvell/mwifiex/sdio.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -331,6 +331,7 @@ .can_dump_fw = false, .can_auto_tdls = false, .can_ext_scan = false, + .fw_ready_extra_delay = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = { @@ -346,6 +347,7 @@ .can_dump_fw = false, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = { @@ -361,6 +363,7 @@ .can_dump_fw = false, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = { @@ -376,6 +379,7 @@ .can_dump_fw = true, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = { @@ -392,6 +396,7 @@ .fw_dump_enh = true, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = { @@ -408,6 +413,7 @@ .fw_dump_enh = true, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = true, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = { @@ -425,6 +431,7 @@ .fw_dump_enh = true, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = { @@ -440,6 +447,7 @@ .can_dump_fw = false, .can_auto_tdls = true, .can_ext_scan = true, + .fw_ready_extra_delay = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = { @@ -456,6 +464,7 @@ .fw_dump_enh = true, .can_auto_tdls = true, .can_ext_scan = true, + .fw_ready_extra_delay = false, }; static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = { @@ -471,6 +480,7 @@ .can_dump_fw = false, .can_auto_tdls = false, .can_ext_scan = true, + .fw_ready_extra_delay = false, }; static struct memory_type_mapping generic_mem_type_map[] = { @@ -563,6 +573,7 @@ card->fw_dump_enh = data->fw_dump_enh; card->can_auto_tdls = data->can_auto_tdls; card->can_ext_scan = data->can_ext_scan; + card->fw_ready_extra_delay = data->fw_ready_extra_delay; INIT_WORK(&card->work, mwifiex_sdio_work); } @@ -766,8 +777,9 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) { + struct sdio_mmc_card *card = adapter->card; int ret = 0; - u16 firmware_stat; + u16 firmware_stat = 0; u32 tries; for (tries = 0; tries < poll_num; tries++) { @@ -783,6 +795,13 @@ ret = -1; } + if (card->fw_ready_extra_delay && + firmware_stat == FIRMWARE_READY_SDIO) + /* firmware might pretend to be ready, when it's not. + * Wait a little bit more as a workaround. + */ + msleep(100); + return ret; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/marvell/mwifiex/sdio.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/marvell/mwifiex/sdio.h @@ -258,6 +258,7 @@ bool fw_dump_enh; bool can_auto_tdls; bool can_ext_scan; + bool fw_ready_extra_delay; struct mwifiex_sdio_mpa_tx mpa_tx; struct mwifiex_sdio_mpa_rx mpa_rx; @@ -281,6 +282,7 @@ bool fw_dump_enh; bool can_auto_tdls; bool can_ext_scan; + bool fw_ready_extra_delay; }; /* only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/marvell/mwifiex/uap_cmd.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/marvell/mwifiex/uap_cmd.c @@ -468,6 +468,7 @@ static int mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) { + struct host_cmd_tlv_mac_addr *mac_tlv; struct host_cmd_tlv_dtim_period *dtim_period; struct host_cmd_tlv_beacon_period *beacon_period; struct host_cmd_tlv_ssid *ssid; @@ -487,6 +488,13 @@ int i; u16 cmd_size = *param_size; + mac_tlv = (struct host_cmd_tlv_mac_addr *)tlv; + mac_tlv->header.type = cpu_to_le16(TLV_TYPE_UAP_MAC_ADDRESS); + mac_tlv->header.len = cpu_to_le16(ETH_ALEN); + memcpy(mac_tlv->mac_addr, bss_cfg->mac_addr, ETH_ALEN); + cmd_size += sizeof(struct host_cmd_tlv_mac_addr); + tlv += sizeof(struct host_cmd_tlv_mac_addr); + if (bss_cfg->ssid.ssid_len) { ssid = (struct host_cmd_tlv_ssid *)tlv; ssid->header.type = cpu_to_le16(TLV_TYPE_UAP_SSID); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/mediatek/mt76/eeprom.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/eeprom.c @@ -62,7 +62,7 @@ goto out_put_node; } - offset = be32_to_cpup(list); + offset += be32_to_cpup(list); ret = mtd_read(mtd, offset, len, &retlen, eep); put_mtd_device(mtd); if (mtd_is_bitflip(ret)) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7615/sdio.c @@ -204,8 +204,8 @@ mt76_worker_disable(&mdev->mt76.sdio.txrx_worker); mt76_worker_disable(&mdev->mt76.sdio.status_worker); mt76_worker_disable(&mdev->mt76.sdio.net_worker); + mt76_worker_disable(&mdev->mt76.sdio.stat_worker); - cancel_work_sync(&mdev->mt76.sdio.stat_work); clear_bit(MT76_READING_STATS, &mdev->mphy.state); mt76_tx_status_check(&mdev->mt76, true); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c @@ -1345,7 +1345,7 @@ sband = phy->hw->wiphy->bands[band]; eht_cap = ieee80211_get_eht_iftype_cap(sband, vif->type); - if (!eht_cap || !eht_cap->has_eht) + if (!eht_cap || !eht_cap->has_eht || !vif->bss_conf.eht_support) return mode; switch (band) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c @@ -1239,22 +1239,27 @@ u8 type[2]; u8 rsvd[64]; } __packed req = { + .ver = 1, .idx = idx, .env = env_cap, .acpi_conf = mt7921_acpi_get_flags(&dev->phy), }; int ret, valid_cnt = 0; - u8 i, *pos; + u16 buf_len = 0; + u8 *pos; if (!clc) return 0; + buf_len = le16_to_cpu(clc->len) - sizeof(*clc); pos = clc->data; - for (i = 0; i < clc->nr_country; i++) { + while (buf_len > 16) { struct mt7921_clc_rule *rule = (struct mt7921_clc_rule *)pos; u16 len = le16_to_cpu(rule->len); + u16 offset = len + sizeof(*rule); - pos += len + sizeof(*rule); + pos += offset; + buf_len -= offset; if (rule->alpha2[0] != alpha2[0] || rule->alpha2[1] != alpha2[1]) continue; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7921/sdio.c @@ -228,7 +228,7 @@ mt76_txq_schedule_all(&dev->mphy); mt76_worker_disable(&mdev->tx_worker); mt76_worker_disable(&mdev->sdio.status_worker); - cancel_work_sync(&mdev->sdio.stat_work); + mt76_worker_disable(&mdev->sdio.stat_worker); clear_bit(MT76_READING_STATS, &dev->mphy.state); mt76_tx_status_check(mdev, true); @@ -260,6 +260,7 @@ restore_worker: mt76_worker_enable(&mdev->tx_worker); mt76_worker_enable(&mdev->sdio.status_worker); + mt76_worker_enable(&mdev->sdio.stat_worker); if (!pm->ds_enable) mt76_connac_mcu_set_deep_sleep(mdev, false); @@ -292,6 +293,7 @@ mt76_worker_enable(&mdev->sdio.txrx_worker); mt76_worker_enable(&mdev->sdio.status_worker); mt76_worker_enable(&mdev->sdio.net_worker); + mt76_worker_enable(&mdev->sdio.stat_worker); /* restore previous ds setting */ if (!pm->ds_enable) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7921/sdio_mac.c @@ -107,7 +107,7 @@ mt76_worker_disable(&dev->mt76.sdio.txrx_worker); mt76_worker_disable(&dev->mt76.sdio.status_worker); mt76_worker_disable(&dev->mt76.sdio.net_worker); - cancel_work_sync(&dev->mt76.sdio.stat_work); + mt76_worker_disable(&dev->mt76.sdio.stat_worker); mt7921s_disable_irq(&dev->mt76); mt7921s_wfsys_reset(dev); @@ -115,6 +115,7 @@ mt76_worker_enable(&dev->mt76.sdio.txrx_worker); mt76_worker_enable(&dev->mt76.sdio.status_worker); mt76_worker_enable(&dev->mt76.sdio.net_worker); + mt76_worker_enable(&dev->mt76.sdio.stat_worker); dev->fw_assert = false; clear_bit(MT76_MCU_RESET, &dev->mphy.state); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/mediatek/mt76/mt7996/pci.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/mt7996/pci.c @@ -17,11 +17,13 @@ static const struct pci_device_id mt7996_pci_device_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7990) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7992) }, { }, }; static const struct pci_device_id mt7996_hif_device_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7991) }, + { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x799a) }, { }, }; @@ -60,7 +62,9 @@ static struct mt7996_hif *mt7996_pci_init_hif2(struct pci_dev *pdev) { hif_idx++; - if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL)) + + if (!pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x7991, NULL) && + !pci_get_device(PCI_VENDOR_ID_MEDIATEK, 0x799a, NULL)) return NULL; writel(hif_idx | MT_PCIE_RECOG_ID_SEM, @@ -113,7 +117,7 @@ mt76_pci_disable_aspm(pdev); - if (id->device == 0x7991) + if (id->device == 0x7991 || id->device == 0x799a) return mt7996_pci_hif2_probe(pdev); dev = mt7996_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0], only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/mediatek/mt76/sdio.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/mediatek/mt76/sdio.c @@ -481,21 +481,21 @@ if (dev->drv->tx_status_data && ndata_frames > 0 && !test_and_set_bit(MT76_READING_STATS, &dev->phy.state) && !test_bit(MT76_STATE_SUSPEND, &dev->phy.state)) - ieee80211_queue_work(dev->hw, &dev->sdio.stat_work); + mt76_worker_schedule(&sdio->stat_worker); } while (nframes > 0); if (resched) mt76_worker_schedule(&dev->tx_worker); } -static void mt76s_tx_status_data(struct work_struct *work) +static void mt76s_tx_status_data(struct mt76_worker *worker) { struct mt76_sdio *sdio; struct mt76_dev *dev; u8 update = 1; u16 count = 0; - sdio = container_of(work, struct mt76_sdio, stat_work); + sdio = container_of(worker, struct mt76_sdio, stat_worker); dev = container_of(sdio, struct mt76_dev, sdio); while (true) { @@ -508,7 +508,7 @@ } if (count && test_bit(MT76_STATE_RUNNING, &dev->phy.state)) - ieee80211_queue_work(dev->hw, &sdio->stat_work); + mt76_worker_schedule(&sdio->status_worker); else clear_bit(MT76_READING_STATS, &dev->phy.state); } @@ -600,8 +600,8 @@ mt76_worker_teardown(&sdio->txrx_worker); mt76_worker_teardown(&sdio->status_worker); mt76_worker_teardown(&sdio->net_worker); + mt76_worker_teardown(&sdio->stat_worker); - cancel_work_sync(&sdio->stat_work); clear_bit(MT76_READING_STATS, &dev->phy.state); mt76_tx_status_check(dev, true); @@ -644,10 +644,14 @@ if (err) return err; + err = mt76_worker_setup(dev->hw, &sdio->stat_worker, mt76s_tx_status_data, + "sdio-sta"); + if (err) + return err; + sched_set_fifo_low(sdio->status_worker.task); sched_set_fifo_low(sdio->net_worker.task); - - INIT_WORK(&sdio->stat_work, mt76s_tx_status_data); + sched_set_fifo_low(sdio->stat_worker.task); dev->queue_ops = &sdio_queue_ops; dev->bus = bus_ops; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/purelifi/plfxlc/usb.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/purelifi/plfxlc/usb.c @@ -493,9 +493,12 @@ void *context) { struct usb_device *udev = interface_to_usbdev(usb->ez_usb); - struct urb *urb = usb_alloc_urb(0, GFP_ATOMIC); + struct urb *urb; int r; + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) + return -ENOMEM; usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), (void *)buffer, buffer_len, complete_fn, context); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -8672,7 +8672,7 @@ rt2800_rfcsr_write_bank(rt2x00dev, 5, 4, saverfb5r4); rt2800_rfcsr_write_bank(rt2x00dev, 7, 4, saverfb7r4); - rt2800_bbp_write(rt2x00dev, 158, 141); + rt2800_bbp_write(rt2x00dev, 158, 140); bbpreg = rt2800_bbp_read(rt2x00dev, 159); bbpreg = bbpreg & (~0x40); rt2800_bbp_write(rt2x00dev, 159, bbpreg); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c @@ -101,6 +101,7 @@ rt2x00link_stop_tuner(rt2x00dev); rt2x00queue_stop_queues(rt2x00dev); rt2x00queue_flush_queues(rt2x00dev, true); + rt2x00queue_stop_queue(rt2x00dev->bcn); /* * Disable radio. @@ -1286,6 +1287,7 @@ rt2x00dev->intf_ap_count = 0; rt2x00dev->intf_sta_count = 0; rt2x00dev->intf_associated = 0; + rt2x00dev->intf_beaconing = 0; /* Enable the radio */ retval = rt2x00lib_enable_radio(rt2x00dev); @@ -1312,6 +1314,7 @@ rt2x00dev->intf_ap_count = 0; rt2x00dev->intf_sta_count = 0; rt2x00dev->intf_associated = 0; + rt2x00dev->intf_beaconing = 0; } static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c @@ -598,6 +598,17 @@ */ if (changes & BSS_CHANGED_BEACON_ENABLED) { mutex_lock(&intf->beacon_skb_mutex); + + /* + * Clear the 'enable_beacon' flag and clear beacon because + * the beacon queue has been stopped after hardware reset. + */ + if (test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags) && + intf->enable_beacon) { + intf->enable_beacon = false; + rt2x00queue_clear_beacon(rt2x00dev, vif); + } + if (!bss_conf->enable_beacon && intf->enable_beacon) { rt2x00dev->intf_beaconing--; intf->enable_beacon = false; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -7959,6 +7959,18 @@ .driver_info = (unsigned long)&rtl8192eu_fops}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818c, 0xff, 0xff, 0xff), .driver_info = (unsigned long)&rtl8192eu_fops}, +/* D-Link DWA-131 rev C1 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3312, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* TP-Link TL-WN8200ND V2 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0126, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* Mercusys MW300UM */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0100, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* Mercusys MW300UH */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2c4e, 0x0104, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, #endif { } }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/pci.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -164,21 +164,29 @@ struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + value &= PCI_EXP_LNKCTL_ASPMC; + if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) - value |= 0x40; + value |= PCI_EXP_LNKCTL_CCC; - pci_write_config_byte(rtlpci->pdev, 0x80, value); + pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_ASPMC | value, + value); return false; } -/*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/ -static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value) +/* @value is PCI_EXP_LNKCTL_CLKREQ_EN or 0 to enable/disable clk request. */ +static void _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u16 value) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - pci_write_config_byte(rtlpci->pdev, 0x81, value); + value &= PCI_EXP_LNKCTL_CLKREQ_EN; + + pcie_capability_clear_and_set_word(rtlpci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CLKREQ_EN, + value); if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) udelay(100); @@ -192,11 +200,8 @@ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; - u8 num4bytes = pcipriv->ndis_adapter.num4bytes; /*Retrieve original configuration settings. */ u8 linkctrl_reg = pcipriv->ndis_adapter.linkctrl_reg; - u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter. - pcibridge_linkctrlreg; u16 aspmlevel = 0; u8 tmp_u1b = 0; @@ -221,16 +226,8 @@ /*Set corresponding value. */ aspmlevel |= BIT(0) | BIT(1); linkctrl_reg &= ~aspmlevel; - pcibridge_linkctrlreg &= ~(BIT(0) | BIT(1)); _rtl_pci_platform_switch_device_pci_aspm(hw, linkctrl_reg); - udelay(50); - - /*4 Disable Pci Bridge ASPM */ - pci_write_config_byte(rtlpci->pdev, (num4bytes << 2), - pcibridge_linkctrlreg); - - udelay(50); } /*Enable RTL8192SE ASPM & Enable Pci Bridge ASPM for @@ -245,9 +242,7 @@ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; - u8 num4bytes = pcipriv->ndis_adapter.num4bytes; u16 aspmlevel; - u8 u_pcibridge_aspmsetting; u8 u_device_aspmsetting; if (!ppsc->support_aspm) @@ -259,25 +254,6 @@ return; } - /*4 Enable Pci Bridge ASPM */ - - u_pcibridge_aspmsetting = - pcipriv->ndis_adapter.pcibridge_linkctrlreg | - rtlpci->const_hostpci_aspm_setting; - - if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) - u_pcibridge_aspmsetting &= ~BIT(0); - - pci_write_config_byte(rtlpci->pdev, (num4bytes << 2), - u_pcibridge_aspmsetting); - - rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, - "PlatformEnableASPM(): Write reg[%x] = %x\n", - (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), - u_pcibridge_aspmsetting); - - udelay(50); - /*Get ASPM level (with/without Clock Req) */ aspmlevel = rtlpci->const_devicepci_aspm_setting; u_device_aspmsetting = pcipriv->ndis_adapter.linkctrl_reg; @@ -291,7 +267,8 @@ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_CLK_REQ) { _rtl_pci_switch_clk_req(hw, (ppsc->reg_rfps_level & - RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0); + RT_RF_OFF_LEVL_CLK_REQ) ? + PCI_EXP_LNKCTL_CLKREQ_EN : 0); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ); } udelay(100); @@ -358,22 +335,6 @@ return tpriv != NULL; } -static void rtl_pci_get_linkcontrol_field(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); - u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset; - u8 linkctrl_reg; - u8 num4bbytes; - - num4bbytes = (capabilityoffset + 0x10) / 4; - - /*Read Link Control Register */ - pci_read_config_byte(rtlpci->pdev, (num4bbytes << 2), &linkctrl_reg); - - pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg; -} - static void rtl_pci_parse_configuration(struct pci_dev *pdev, struct ieee80211_hw *hw) { @@ -2028,12 +1989,6 @@ PCI_SLOT(bridge_pdev->devfn); pcipriv->ndis_adapter.pcibridge_funcnum = PCI_FUNC(bridge_pdev->devfn); - pcipriv->ndis_adapter.pcibridge_pciehdr_offset = - pci_pcie_cap(bridge_pdev); - pcipriv->ndis_adapter.num4bytes = - (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4; - - rtl_pci_get_linkcontrol_field(hw); if (pcipriv->ndis_adapter.pcibridge_vendor == PCI_BRIDGE_VENDOR_AMD) { @@ -2050,13 +2005,11 @@ pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, - "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", + "pci_bridge busnumber:devnumber:funcnumber:vendor:amd %d:%d:%d:%x:%x\n", pcipriv->ndis_adapter.pcibridge_busnum, pcipriv->ndis_adapter.pcibridge_devnum, pcipriv->ndis_adapter.pcibridge_funcnum, pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], - pcipriv->ndis_adapter.pcibridge_pciehdr_offset, - pcipriv->ndis_adapter.pcibridge_linkctrlreg, pcipriv->ndis_adapter.amd_l1_patch); rtl_pci_parse_configuration(pdev, hw); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/pci.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/pci.h @@ -236,11 +236,6 @@ u16 pcibridge_vendorid; u16 pcibridge_deviceid; - u8 num4bytes; - - u8 pcibridge_pciehdr_offset; - u8 pcibridge_linkctrlreg; - bool amd_l1_patch; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/phy.c @@ -16,12 +16,6 @@ static void _rtl88e_phy_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data); -static u32 _rtl88e_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i = ffs(bitmask); - - return i ? i - 1 : 32; -} static bool _rtl88e_phy_bb8188e_config_parafile(struct ieee80211_hw *hw); static bool _rtl88e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); static bool phy_config_bb_with_headerfile(struct ieee80211_hw *hw, @@ -51,7 +45,7 @@ rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, @@ -74,7 +68,7 @@ if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((originalvalue & (~bitmask)) | (data << bitshift)); } @@ -99,7 +93,7 @@ original_value = _rtl88e_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock(&rtlpriv->locks.rf_lock); @@ -127,7 +121,7 @@ original_value = _rtl88e_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl88e_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.c @@ -17,7 +17,7 @@ rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, @@ -40,7 +40,7 @@ if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((originalvalue & (~bitmask)) | (data << bitshift)); } @@ -143,14 +143,6 @@ } EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); -u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i = ffs(bitmask); - - return i ? i - 1 : 32; -} -EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift); - static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) { rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8192c/phy_common.h @@ -196,7 +196,6 @@ void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); void rtl92c_phy_set_io(struct ieee80211_hw *hw); void rtl92c_bb_block_on(struct ieee80211_hw *hw); -u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, enum wireless_mode wirelessmode, u8 txpwridx); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.c @@ -39,7 +39,7 @@ rfpath, regaddr); } - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock(&rtlpriv->locks.rf_lock); @@ -110,7 +110,7 @@ original_value = _rtl92c_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); @@ -122,7 +122,7 @@ original_value = _rtl92c_phy_fw_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/phy.h @@ -94,7 +94,6 @@ u32 offset); u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset); -u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data); void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c @@ -32,7 +32,7 @@ original_value = _rtl92c_phy_fw_rf_serial_read(hw, rfpath, regaddr); } - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", @@ -56,7 +56,7 @@ original_value = _rtl92c_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); @@ -67,7 +67,7 @@ original_value = _rtl92c_phy_fw_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8192de/phy.c @@ -169,13 +169,6 @@ 157, 159, 161, 163, 165 }; -static u32 _rtl92d_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i = ffs(bitmask); - - return i ? i - 1 : 32; -} - u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -198,7 +191,7 @@ } else { originalvalue = rtl_read_dword(rtlpriv, regaddr); } - bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", @@ -230,7 +223,7 @@ dbi_direct); else originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((originalvalue & (~bitmask)) | (data << bitshift)); } if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) @@ -317,7 +310,7 @@ regaddr, rfpath, bitmask); spin_lock(&rtlpriv->locks.rf_lock); original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock(&rtlpriv->locks.rf_lock); rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, @@ -343,7 +336,7 @@ if (bitmask != RFREG_OFFSET_MASK) { original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c @@ -16,7 +16,6 @@ static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data); -static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask); static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw); static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw, @@ -46,7 +45,7 @@ rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, @@ -68,7 +67,7 @@ if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((originalvalue & (~bitmask)) | (data << bitshift)); } @@ -92,7 +91,7 @@ spin_lock(&rtlpriv->locks.rf_lock); original_value = _rtl92ee_phy_rf_serial_read(hw , rfpath, regaddr); - bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock(&rtlpriv->locks.rf_lock); @@ -119,7 +118,7 @@ if (bitmask != RFREG_OFFSET_MASK) { original_value = _rtl92ee_phy_rf_serial_read(hw, rfpath, addr); - bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = (original_value & (~bitmask)) | (data << bitshift); } @@ -201,13 +200,6 @@ pphyreg->rf3wire_offset, data_and_addr); } -static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i = ffs(bitmask); - - return i ? i - 1 : 32; -} - bool rtl92ee_phy_mac_config(struct ieee80211_hw *hw) { return _rtl92ee_phy_config_mac_with_headerfile(hw); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8192se/phy.c @@ -14,13 +14,6 @@ #include "hw.h" #include "table.h" -static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask) -{ - u32 i = ffs(bitmask); - - return i ? i - 1 : 32; -} - u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -30,7 +23,7 @@ regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", @@ -52,7 +45,7 @@ if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((originalvalue & (~bitmask)) | (data << bitshift)); } @@ -157,7 +150,7 @@ original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock(&rtlpriv->locks.rf_lock); @@ -188,7 +181,7 @@ if (bitmask != RFREG_OFFSET_MASK) { original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/phy.c @@ -49,7 +49,7 @@ rfpath, regaddr); } - bitshift = rtl8723_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock(&rtlpriv->locks.rf_lock); @@ -80,7 +80,7 @@ original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = rtl8723_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); @@ -89,7 +89,7 @@ rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data); } else { if (bitmask != RFREG_OFFSET_MASK) { - bitshift = rtl8723_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c @@ -41,7 +41,7 @@ spin_lock(&rtlpriv->locks.rf_lock); original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr); - bitshift = rtl8723_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock(&rtlpriv->locks.rf_lock); @@ -68,7 +68,7 @@ if (bitmask != RFREG_OFFSET_MASK) { original_value = rtl8723_phy_rf_serial_read(hw, path, regaddr); - bitshift = rtl8723_phy_calculate_bit_shift(bitmask); + bitshift = calculate_bit_shift(bitmask); data = ((original_value & (~bitmask)) | (data << bitshift)); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c @@ -29,9 +29,10 @@ u32 data); static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask) { - u32 i = ffs(bitmask); + if (WARN_ON_ONCE(!bitmask)) + return 0; - return i ? i - 1 : 32; + return __ffs(bitmask); } static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw); /*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtlwifi/wifi.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtlwifi/wifi.h @@ -3080,4 +3080,11 @@ return ieee80211_find_sta(mac->vif, mac_addr); } +static inline u32 calculate_bit_shift(u32 bitmask) +{ + if (WARN_ON_ONCE(!bitmask)) + return 0; + + return __ffs(bitmask); +} #endif only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtw88/mac80211.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw88/mac80211.c @@ -280,9 +280,9 @@ if (changed_flags & FIF_ALLMULTI) { if (*new_flags & FIF_ALLMULTI) - rtwdev->hal.rcr |= BIT_AM | BIT_AB; + rtwdev->hal.rcr |= BIT_AM; else - rtwdev->hal.rcr &= ~(BIT_AM | BIT_AB); + rtwdev->hal.rcr &= ~(BIT_AM); } if (changed_flags & FIF_FCSFAIL) { if (*new_flags & FIF_FCSFAIL) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtw88/sdio.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw88/sdio.c @@ -500,19 +500,40 @@ static int rtw_sdio_read_port(struct rtw_dev *rtwdev, u8 *buf, size_t count) { struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv; + struct mmc_host *host = rtwsdio->sdio_func->card->host; bool bus_claim = rtw_sdio_bus_claim_needed(rtwsdio); u32 rxaddr = rtwsdio->rx_addr++; - int ret; + int ret = 0, err; + size_t bytes; if (bus_claim) sdio_claim_host(rtwsdio->sdio_func); - ret = sdio_memcpy_fromio(rtwsdio->sdio_func, buf, - RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), count); - if (ret) - rtw_warn(rtwdev, - "Failed to read %zu byte(s) from SDIO port 0x%08x", - count, rxaddr); + while (count > 0) { + bytes = min_t(size_t, host->max_req_size, count); + + err = sdio_memcpy_fromio(rtwsdio->sdio_func, buf, + RTW_SDIO_ADDR_RX_RX0FF_GEN(rxaddr), + bytes); + if (err) { + rtw_warn(rtwdev, + "Failed to read %zu byte(s) from SDIO port 0x%08x: %d", + bytes, rxaddr, err); + + /* Signal to the caller that reading did not work and + * that the data in the buffer is short/corrupted. + */ + ret = err; + + /* Don't stop here - instead drain the remaining data + * from the card's buffer, else the card will return + * corrupt data for the next rtw_sdio_read_port() call. + */ + } + + count -= bytes; + buf += bytes; + } if (bus_claim) sdio_release_host(rtwsdio->sdio_func); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtw89/coex.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw89/coex.c @@ -131,7 +131,7 @@ .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, - .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, + .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .info_buf = 1800, .max_role_num = 6, }, {RTL8852C, RTW89_FW_VER_CODE(0, 27, 57, 0), @@ -159,7 +159,7 @@ .fcxbtcrpt = 105, .fcxtdma = 3, .fcxslots = 1, .fcxcysta = 5, .fcxstep = 3, .fcxnullsta = 2, .fcxmreg = 2, .fcxgpiodbg = 1, .fcxbtver = 1, .fcxbtscan = 2, .fcxbtafh = 2, .fcxbtdevinfo = 1, - .fwlrole = 1, .frptmap = 3, .fcxctrl = 1, + .fwlrole = 2, .frptmap = 3, .fcxctrl = 1, .info_buf = 1800, .max_role_num = 6, }, {RTL8852B, RTW89_FW_VER_CODE(0, 29, 14, 0), only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtw89/core.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw89/core.c @@ -2520,7 +2520,7 @@ if (hw->conf.flags & IEEE80211_CONF_IDLE) ieee80211_queue_delayed_work(hw, &roc->roc_work, - RTW89_ROC_IDLE_TIMEOUT); + msecs_to_jiffies(RTW89_ROC_IDLE_TIMEOUT)); } void rtw89_roc_work(struct work_struct *work) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtw89/core.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw89/core.h @@ -2027,12 +2027,6 @@ u8 state_phase; /* [0:3] train state, [4:7] train phase */ } __packed; -struct rtw89_btc_fbtc_fddt_cell_status_v5 { - s8 wl_tx_pwr; - s8 bt_tx_pwr; - s8 bt_rx_gain; -} __packed; - struct rtw89_btc_fbtc_cysta_v3 { /* statistics for cycles */ u8 fver; u8 rsvd; @@ -2096,9 +2090,9 @@ struct rtw89_btc_fbtc_cycle_a2dp_empty_info a2dp_ept; struct rtw89_btc_fbtc_a2dp_trx_stat_v4 a2dp_trx[BTC_CYCLE_SLOT_MAX]; struct rtw89_btc_fbtc_cycle_fddt_info_v5 fddt_trx[BTC_CYCLE_SLOT_MAX]; - struct rtw89_btc_fbtc_fddt_cell_status_v5 fddt_cells[FDD_TRAIN_WL_DIRECTION] - [FDD_TRAIN_WL_RSSI_LEVEL] - [FDD_TRAIN_BT_RSSI_LEVEL]; + struct rtw89_btc_fbtc_fddt_cell_status fddt_cells[FDD_TRAIN_WL_DIRECTION] + [FDD_TRAIN_WL_RSSI_LEVEL] + [FDD_TRAIN_BT_RSSI_LEVEL]; __le32 except_map; } __packed; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtw89/mac.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw89/mac.c @@ -3825,11 +3825,9 @@ } static void rtw89_mac_port_cfg_tx_sw(struct rtw89_dev *rtwdev, - struct rtw89_vif *rtwvif) + struct rtw89_vif *rtwvif, bool en) { const struct rtw89_port_reg *p = &rtw_port_base; - bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || - rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; if (en) rtw89_write32_port_set(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); @@ -3837,6 +3835,24 @@ rtw89_write32_port_clr(rtwdev, rtwvif, p->port_cfg, B_AX_BCNTX_EN); } +static void rtw89_mac_port_cfg_tx_sw_by_nettype(struct rtw89_dev *rtwdev, + struct rtw89_vif *rtwvif) +{ + bool en = rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || + rtwvif->net_type == RTW89_NET_TYPE_AD_HOC; + + rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en); +} + +void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en) +{ + struct rtw89_vif *rtwvif; + + rtw89_for_each_rtwvif(rtwdev, rtwvif) + if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE) + rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif, en); +} + static void rtw89_mac_port_cfg_bcn_intv(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif) { @@ -4129,7 +4145,7 @@ rtw89_mac_port_cfg_bcn_prct(rtwdev, rtwvif); rtw89_mac_port_cfg_rx_sw(rtwdev, rtwvif); rtw89_mac_port_cfg_rx_sync(rtwdev, rtwvif); - rtw89_mac_port_cfg_tx_sw(rtwdev, rtwvif); + rtw89_mac_port_cfg_tx_sw_by_nettype(rtwdev, rtwvif); rtw89_mac_port_cfg_bcn_intv(rtwdev, rtwvif); rtw89_mac_port_cfg_hiq_win(rtwdev, rtwvif); rtw89_mac_port_cfg_hiq_dtim(rtwdev, rtwvif); @@ -4290,8 +4306,10 @@ switch (reason) { case RTW89_SCAN_LEAVE_CH_NOTIFY: - if (rtw89_is_op_chan(rtwdev, band, chan)) + if (rtw89_is_op_chan(rtwdev, band, chan)) { + rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, false); ieee80211_stop_queues(rtwdev->hw); + } return; case RTW89_SCAN_END_SCAN_NOTIFY: if (rtwvif && rtwvif->scan_req && @@ -4309,6 +4327,7 @@ if (rtw89_is_op_chan(rtwdev, band, chan)) { rtw89_assign_entity_chan(rtwdev, rtwvif->sub_entity_idx, &rtwdev->scan_info.op_chan); + rtw89_mac_enable_beacon_for_ap_vifs(rtwdev, true); ieee80211_wake_queues(rtwdev->hw); } else { rtw89_chan_create(&new, chan, chan, band, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtw89/mac.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw89/mac.h @@ -933,6 +933,7 @@ void rtw89_mac_set_he_obss_narrow_bw_ru(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); void rtw89_mac_stop_ap(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); +void rtw89_mac_enable_beacon_for_ap_vifs(struct rtw89_dev *rtwdev, bool en); int rtw89_mac_remove_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *vif); void rtw89_mac_disable_cpu(struct rtw89_dev *rtwdev); int rtw89_mac_enable_cpu(struct rtw89_dev *rtwdev, u8 boot_reason, bool dlfw); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/realtek/rtw89/mac80211.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -468,6 +468,9 @@ return -EOPNOTSUPP; } + if (rtwdev->scanning) + rtw89_hw_scan_abort(rtwdev, rtwdev->scan_info.scanning_vif); + ether_addr_copy(rtwvif->bssid, vif->bss_conf.bssid); rtw89_cam_bssid_changed(rtwdev, rtwvif); rtw89_mac_port_update(rtwdev, rtwvif); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/net/wireless/silabs/wfx/sta.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/net/wireless/silabs/wfx/sta.c @@ -354,29 +354,38 @@ return 0; } -static void wfx_set_mfp_ap(struct wfx_vif *wvif) +static int wfx_set_mfp_ap(struct wfx_vif *wvif) { struct ieee80211_vif *vif = wvif_to_vif(wvif); struct sk_buff *skb = ieee80211_beacon_get(wvif->wdev->hw, vif, 0); const int ieoffset = offsetof(struct ieee80211_mgmt, u.beacon.variable); - const u16 *ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset, - skb->len - ieoffset); const int pairwise_cipher_suite_count_offset = 8 / sizeof(u16); const int pairwise_cipher_suite_size = 4 / sizeof(u16); const int akm_suite_size = 4 / sizeof(u16); + const u16 *ptr; - if (ptr) { - ptr += pairwise_cipher_suite_count_offset; - if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) - return; - ptr += 1 + pairwise_cipher_suite_size * *ptr; - if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) - return; - ptr += 1 + akm_suite_size * *ptr; - if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) - return; - wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6)); - } + if (unlikely(!skb)) + return -ENOMEM; + + ptr = (u16 *)cfg80211_find_ie(WLAN_EID_RSN, skb->data + ieoffset, + skb->len - ieoffset); + if (unlikely(!ptr)) + return -EINVAL; + + ptr += pairwise_cipher_suite_count_offset; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return -EINVAL; + + ptr += 1 + pairwise_cipher_suite_size * *ptr; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return -EINVAL; + + ptr += 1 + akm_suite_size * *ptr; + if (WARN_ON(ptr > (u16 *)skb_tail_pointer(skb))) + return -EINVAL; + + wfx_hif_set_mfp(wvif, *ptr & BIT(7), *ptr & BIT(6)); + return 0; } int wfx_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, @@ -394,8 +403,7 @@ ret = wfx_hif_start(wvif, &vif->bss_conf, wvif->channel); if (ret > 0) return -EIO; - wfx_set_mfp_ap(wvif); - return ret; + return wfx_set_mfp_ap(wvif); } void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/nvme/target/trace.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/nvme/target/trace.h @@ -53,8 +53,7 @@ return; } - strncpy(name, req->ns->device_path, - min_t(size_t, DISK_NAME_LEN, strlen(req->ns->device_path))); + strscpy_pad(name, req->ns->device_path, DISK_NAME_LEN); } #endif @@ -85,7 +84,7 @@ __entry->flags = cmd->common.flags; __entry->nsid = le32_to_cpu(cmd->common.nsid); __entry->metadata = le64_to_cpu(cmd->common.metadata); - memcpy(__entry->cdw10, &cmd->common.cdw10, + memcpy(__entry->cdw10, &cmd->common.cdws, sizeof(__entry->cdw10)); ), TP_printk("nvmet%s: %sqid=%d, cmdid=%u, nsid=%u, flags=%#x, " only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/of/base.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/of/base.c @@ -1463,6 +1463,7 @@ out_args->np = new; of_node_put(cur); cur = new; + new = NULL; } put: of_node_put(cur); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/of/unittest-data/tests-phandle.dtsi +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/of/unittest-data/tests-phandle.dtsi @@ -38,6 +38,13 @@ phandle-map-pass-thru = <0x0 0xf0>; }; + provider5: provider5 { + #phandle-cells = <2>; + phandle-map = <2 7 &provider4 2 3>; + phandle-map-mask = <0xff 0xf>; + phandle-map-pass-thru = <0x0 0xf0>; + }; + consumer-a { phandle-list = <&provider1 1>, <&provider2 2 0>, @@ -64,7 +71,8 @@ <&provider4 4 0x100>, <&provider4 0 0x61>, <&provider0>, - <&provider4 19 0x20>; + <&provider4 19 0x20>, + <&provider5 2 7>; phandle-list-bad-phandle = <12345678 0 0>; phandle-list-bad-args = <&provider2 1 0>, <&provider4 0>; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/pci/controller/dwc/pcie-designware-ep.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -598,6 +598,7 @@ } aligned_offset = msg_addr & (epc->mem->window.page_size - 1); + msg_addr &= ~aligned_offset; ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, epc->mem->window.page_size); if (ret) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/pci/controller/pcie-mediatek-gen3.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/controller/pcie-mediatek-gen3.c @@ -245,35 +245,60 @@ resource_size_t cpu_addr, resource_size_t pci_addr, resource_size_t size, - unsigned long type, int num) + unsigned long type, int *num) { + resource_size_t remaining = size; + resource_size_t table_size; + resource_size_t addr_align; + const char *range_type; void __iomem *table; u32 val; - if (num >= PCIE_MAX_TRANS_TABLES) { - dev_err(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n", - (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES); - return -ENODEV; - } + while (remaining && (*num < PCIE_MAX_TRANS_TABLES)) { + /* Table size needs to be a power of 2 */ + table_size = BIT(fls(remaining) - 1); + + if (cpu_addr > 0) { + addr_align = BIT(ffs(cpu_addr) - 1); + table_size = min(table_size, addr_align); + } + + /* Minimum size of translate table is 4KiB */ + if (table_size < 0x1000) { + dev_err(pcie->dev, "illegal table size %#llx\n", + (unsigned long long)table_size); + return -EINVAL; + } + + table = pcie->base + PCIE_TRANS_TABLE_BASE_REG + *num * PCIE_ATR_TLB_SET_OFFSET; + writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(table_size) - 1), table); + writel_relaxed(upper_32_bits(cpu_addr), table + PCIE_ATR_SRC_ADDR_MSB_OFFSET); + writel_relaxed(lower_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET); + writel_relaxed(upper_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET); + + if (type == IORESOURCE_IO) { + val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO; + range_type = "IO"; + } else { + val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM; + range_type = "MEM"; + } - table = pcie->base + PCIE_TRANS_TABLE_BASE_REG + - num * PCIE_ATR_TLB_SET_OFFSET; + writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET); - writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(size) - 1), - table); - writel_relaxed(upper_32_bits(cpu_addr), - table + PCIE_ATR_SRC_ADDR_MSB_OFFSET); - writel_relaxed(lower_32_bits(pci_addr), - table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET); - writel_relaxed(upper_32_bits(pci_addr), - table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET); - - if (type == IORESOURCE_IO) - val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO; - else - val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM; + dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n", + range_type, *num, (unsigned long long)cpu_addr, + (unsigned long long)pci_addr, (unsigned long long)table_size); + + cpu_addr += table_size; + pci_addr += table_size; + remaining -= table_size; + (*num)++; + } - writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET); + if (remaining) + dev_warn(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n", + (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES); return 0; } @@ -380,30 +405,20 @@ resource_size_t cpu_addr; resource_size_t pci_addr; resource_size_t size; - const char *range_type; - if (type == IORESOURCE_IO) { + if (type == IORESOURCE_IO) cpu_addr = pci_pio_to_address(res->start); - range_type = "IO"; - } else if (type == IORESOURCE_MEM) { + else if (type == IORESOURCE_MEM) cpu_addr = res->start; - range_type = "MEM"; - } else { + else continue; - } pci_addr = res->start - entry->offset; size = resource_size(res); err = mtk_pcie_set_trans_table(pcie, cpu_addr, pci_addr, size, - type, table_index); + type, &table_index); if (err) return err; - - dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n", - range_type, table_index, (unsigned long long)cpu_addr, - (unsigned long long)pci_addr, (unsigned long long)size); - - table_index++; } return 0; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/pci/controller/pcie-mediatek.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/controller/pcie-mediatek.c @@ -617,12 +617,18 @@ if (status & MSI_STATUS){ unsigned long imsi_status; + /* + * The interrupt status can be cleared even if the + * MSI status remains pending. As such, given the + * edge-triggered interrupt type, its status should + * be cleared before being dispatched to the + * handler of the underlying device. + */ + writel(MSI_STATUS, port->base + PCIE_INT_STATUS); while ((imsi_status = readl(port->base + PCIE_IMSI_STATUS))) { for_each_set_bit(bit, &imsi_status, MTK_MSI_IRQS_NUM) generic_handle_domain_irq(port->inner_domain, bit); } - /* Clear MSI interrupt status */ - writel(MSI_STATUS, port->base + PCIE_INT_STATUS); } } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/pci/switch/switchtec.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pci/switch/switchtec.c @@ -1308,13 +1308,6 @@ { struct switchtec_dev *stdev = to_stdev(dev); - if (stdev->dma_mrpc) { - iowrite32(0, &stdev->mmio_mrpc->dma_en); - flush_wc_buf(stdev); - writeq(0, &stdev->mmio_mrpc->dma_addr); - dma_free_coherent(&stdev->pdev->dev, sizeof(*stdev->dma_mrpc), - stdev->dma_mrpc, stdev->dma_mrpc_dma_addr); - } kfree(stdev); } @@ -1358,7 +1351,7 @@ return ERR_PTR(-ENOMEM); stdev->alive = true; - stdev->pdev = pdev; + stdev->pdev = pci_dev_get(pdev); INIT_LIST_HEAD(&stdev->mrpc_queue); mutex_init(&stdev->mrpc_mutex); stdev->mrpc_busy = 0; @@ -1391,6 +1384,7 @@ return stdev; err_put: + pci_dev_put(stdev->pdev); put_device(&stdev->dev); return ERR_PTR(rc); } @@ -1644,6 +1638,18 @@ return 0; } +static void switchtec_exit_pci(struct switchtec_dev *stdev) +{ + if (stdev->dma_mrpc) { + iowrite32(0, &stdev->mmio_mrpc->dma_en); + flush_wc_buf(stdev); + writeq(0, &stdev->mmio_mrpc->dma_addr); + dma_free_coherent(&stdev->pdev->dev, sizeof(*stdev->dma_mrpc), + stdev->dma_mrpc, stdev->dma_mrpc_dma_addr); + stdev->dma_mrpc = NULL; + } +} + static int switchtec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -1703,6 +1709,9 @@ ida_free(&switchtec_minor_ida, MINOR(stdev->dev.devt)); dev_info(&stdev->dev, "unregistered.\n"); stdev_kill(stdev); + switchtec_exit_pci(stdev); + pci_dev_put(stdev->pdev); + stdev->pdev = NULL; put_device(&stdev->dev); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/perf/hisilicon/hisi_uncore_uc_pmu.c @@ -383,8 +383,8 @@ HISI_PMU_EVENT_ATTR(cpu_rd, 0x10), HISI_PMU_EVENT_ATTR(cpu_rd64, 0x17), HISI_PMU_EVENT_ATTR(cpu_rs64, 0x19), - HISI_PMU_EVENT_ATTR(cpu_mru, 0x1a), - HISI_PMU_EVENT_ATTR(cycles, 0x9c), + HISI_PMU_EVENT_ATTR(cpu_mru, 0x1c), + HISI_PMU_EVENT_ATTR(cycles, 0x95), HISI_PMU_EVENT_ATTR(spipe_hit, 0xb3), HISI_PMU_EVENT_ATTR(hpipe_hit, 0xdb), HISI_PMU_EVENT_ATTR(cring_rxdat_cnt, 0xfa), only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/pinctrl/intel/pinctrl-baytrail.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -991,13 +991,14 @@ unsigned int num_configs) { struct intel_pinctrl *vg = pinctrl_dev_get_drvdata(pctl_dev); - unsigned int param, arg; void __iomem *conf_reg = byt_gpio_reg(vg, offset, BYT_CONF0_REG); void __iomem *val_reg = byt_gpio_reg(vg, offset, BYT_VAL_REG); void __iomem *db_reg = byt_gpio_reg(vg, offset, BYT_DEBOUNCE_REG); + enum pin_config_param param; unsigned long flags; u32 conf, val, debounce; int i, ret = 0; + u32 arg; raw_spin_lock_irqsave(&byt_lock, flags); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/platform/surface/surface_acpi_notify.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/platform/surface/surface_acpi_notify.c @@ -741,6 +741,7 @@ struct acpi_handle_list dep_devices; acpi_handle supplier = ACPI_HANDLE(&pdev->dev); acpi_status status; + bool ret = false; int i; if (!acpi_has_method(handle, "_DEP")) @@ -753,11 +754,14 @@ } for (i = 0; i < dep_devices.count; i++) { - if (dep_devices.handles[i] == supplier) - return true; + if (dep_devices.handles[i] == supplier) { + ret = true; + break; + } } - return false; + acpi_handle_list_free(&dep_devices); + return ret; } static acpi_status san_consumer_setup(acpi_handle handle, u32 lvl, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/platform/x86/intel/uncore-frequency/uncore-frequency-common.h @@ -26,14 +26,14 @@ * @instance_id: Unique instance id to append to directory name * @name: Sysfs entry name for this instance * @uncore_attr_group: Attribute group storage - * @max_freq_khz_dev_attr: Storage for device attribute max_freq_khz - * @mix_freq_khz_dev_attr: Storage for device attribute min_freq_khz - * @initial_max_freq_khz_dev_attr: Storage for device attribute initial_max_freq_khz - * @initial_min_freq_khz_dev_attr: Storage for device attribute initial_min_freq_khz - * @current_freq_khz_dev_attr: Storage for device attribute current_freq_khz - * @domain_id_dev_attr: Storage for device attribute domain_id - * @fabric_cluster_id_dev_attr: Storage for device attribute fabric_cluster_id - * @package_id_dev_attr: Storage for device attribute package_id + * @max_freq_khz_kobj_attr: Storage for kobject attribute max_freq_khz + * @mix_freq_khz_kobj_attr: Storage for kobject attribute min_freq_khz + * @initial_max_freq_khz_kobj_attr: Storage for kobject attribute initial_max_freq_khz + * @initial_min_freq_khz_kobj_attr: Storage for kobject attribute initial_min_freq_khz + * @current_freq_khz_kobj_attr: Storage for kobject attribute current_freq_khz + * @domain_id_kobj_attr: Storage for kobject attribute domain_id + * @fabric_cluster_id_kobj_attr: Storage for kobject attribute fabric_cluster_id + * @package_id_kobj_attr: Storage for kobject attribute package_id * @uncore_attrs: Attribute storage for group creation * * This structure is used to encapsulate all data related to uncore sysfs @@ -53,14 +53,14 @@ char name[32]; struct attribute_group uncore_attr_group; - struct device_attribute max_freq_khz_dev_attr; - struct device_attribute min_freq_khz_dev_attr; - struct device_attribute initial_max_freq_khz_dev_attr; - struct device_attribute initial_min_freq_khz_dev_attr; - struct device_attribute current_freq_khz_dev_attr; - struct device_attribute domain_id_dev_attr; - struct device_attribute fabric_cluster_id_dev_attr; - struct device_attribute package_id_dev_attr; + struct kobj_attribute max_freq_khz_kobj_attr; + struct kobj_attribute min_freq_khz_kobj_attr; + struct kobj_attribute initial_max_freq_khz_kobj_attr; + struct kobj_attribute initial_min_freq_khz_kobj_attr; + struct kobj_attribute current_freq_khz_kobj_attr; + struct kobj_attribute domain_id_kobj_attr; + struct kobj_attribute fabric_cluster_id_kobj_attr; + struct kobj_attribute package_id_kobj_attr; struct attribute *uncore_attrs[9]; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/platform/x86/intel/vsec.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/platform/x86/intel/vsec.c @@ -120,6 +120,8 @@ { struct intel_vsec_device *intel_vsec_dev = dev_to_ivdev(dev); + xa_erase(&auxdev_array, intel_vsec_dev->id); + mutex_lock(&vsec_ida_lock); ida_free(intel_vsec_dev->ida, intel_vsec_dev->auxdev.id); mutex_unlock(&vsec_ida_lock); @@ -135,19 +137,28 @@ struct auxiliary_device *auxdev = &intel_vsec_dev->auxdev; int ret, id; - mutex_lock(&vsec_ida_lock); - ret = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); - mutex_unlock(&vsec_ida_lock); + ret = xa_alloc(&auxdev_array, &intel_vsec_dev->id, intel_vsec_dev, + PMT_XA_LIMIT, GFP_KERNEL); if (ret < 0) { kfree(intel_vsec_dev->resource); kfree(intel_vsec_dev); return ret; } + mutex_lock(&vsec_ida_lock); + id = ida_alloc(intel_vsec_dev->ida, GFP_KERNEL); + mutex_unlock(&vsec_ida_lock); + if (id < 0) { + xa_erase(&auxdev_array, intel_vsec_dev->id); + kfree(intel_vsec_dev->resource); + kfree(intel_vsec_dev); + return id; + } + if (!parent) parent = &pdev->dev; - auxdev->id = ret; + auxdev->id = id; auxdev->name = name; auxdev->dev.parent = parent; auxdev->dev.release = intel_vsec_dev_release; @@ -169,12 +180,6 @@ if (ret < 0) return ret; - /* Add auxdev to list */ - ret = xa_alloc(&auxdev_array, &id, intel_vsec_dev, PMT_XA_LIMIT, - GFP_KERNEL); - if (ret) - return ret; - return 0; } EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, INTEL_VSEC); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/platform/x86/intel/vsec.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/platform/x86/intel/vsec.h @@ -45,6 +45,7 @@ struct ida *ida; struct intel_vsec_platform_info *info; int num_resources; + int id; /* xa */ void *priv_data; size_t priv_data_size; }; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/platform/x86/p2sb.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/platform/x86/p2sb.c @@ -26,6 +26,21 @@ {} }; +/* + * Cache BAR0 of P2SB device functions 0 to 7. + * TODO: The constant 8 is the number of functions that PCI specification + * defines. Same definitions exist tree-wide. Unify this definition and + * the other definitions then move to include/uapi/linux/pci.h. + */ +#define NR_P2SB_RES_CACHE 8 + +struct p2sb_res_cache { + u32 bus_dev_id; + struct resource res; +}; + +static struct p2sb_res_cache p2sb_resources[NR_P2SB_RES_CACHE]; + static int p2sb_get_devfn(unsigned int *devfn) { unsigned int fn = P2SB_DEVFN_DEFAULT; @@ -39,8 +54,16 @@ return 0; } +static bool p2sb_valid_resource(struct resource *res) +{ + if (res->flags) + return true; + + return false; +} + /* Copy resource from the first BAR of the device in question */ -static int p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem) +static void p2sb_read_bar0(struct pci_dev *pdev, struct resource *mem) { struct resource *bar0 = &pdev->resource[0]; @@ -56,49 +79,66 @@ mem->end = bar0->end; mem->flags = bar0->flags; mem->desc = bar0->desc; - - return 0; } -static int p2sb_scan_and_read(struct pci_bus *bus, unsigned int devfn, struct resource *mem) +static void p2sb_scan_and_cache_devfn(struct pci_bus *bus, unsigned int devfn) { + struct p2sb_res_cache *cache = &p2sb_resources[PCI_FUNC(devfn)]; struct pci_dev *pdev; - int ret; pdev = pci_scan_single_device(bus, devfn); if (!pdev) - return -ENODEV; + return; - ret = p2sb_read_bar0(pdev, mem); + p2sb_read_bar0(pdev, &cache->res); + cache->bus_dev_id = bus->dev.id; pci_stop_and_remove_bus_device(pdev); - return ret; } -/** - * p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR - * @bus: PCI bus to communicate with - * @devfn: PCI slot and function to communicate with - * @mem: memory resource to be filled in - * - * The BIOS prevents the P2SB device from being enumerated by the PCI - * subsystem, so we need to unhide and hide it back to lookup the BAR. - * - * if @bus is NULL, the bus 0 in domain 0 will be used. - * If @devfn is 0, it will be replaced by devfn of the P2SB device. - * - * Caller must provide a valid pointer to @mem. - * - * Locking is handled by pci_rescan_remove_lock mutex. - * - * Return: - * 0 on success or appropriate errno value on error. - */ -int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem) +static int p2sb_scan_and_cache(struct pci_bus *bus, unsigned int devfn) +{ + unsigned int slot, fn; + + if (PCI_FUNC(devfn) == 0) { + /* + * When function number of the P2SB device is zero, scan it and + * other function numbers, and if devices are available, cache + * their BAR0s. + */ + slot = PCI_SLOT(devfn); + for (fn = 0; fn < NR_P2SB_RES_CACHE; fn++) + p2sb_scan_and_cache_devfn(bus, PCI_DEVFN(slot, fn)); + } else { + /* Scan the P2SB device and cache its BAR0 */ + p2sb_scan_and_cache_devfn(bus, devfn); + } + + if (!p2sb_valid_resource(&p2sb_resources[PCI_FUNC(devfn)].res)) + return -ENOENT; + + return 0; +} + +static struct pci_bus *p2sb_get_bus(struct pci_bus *bus) +{ + static struct pci_bus *p2sb_bus; + + bus = bus ?: p2sb_bus; + if (bus) + return bus; + + /* Assume P2SB is on the bus 0 in domain 0 */ + p2sb_bus = pci_find_bus(0, 0); + return p2sb_bus; +} + +static int p2sb_cache_resources(void) { - struct pci_dev *pdev_p2sb; unsigned int devfn_p2sb; u32 value = P2SBC_HIDE; + struct pci_bus *bus; + u16 class; int ret; /* Get devfn for P2SB device itself */ @@ -106,8 +146,17 @@ if (ret) return ret; - /* if @bus is NULL, use bus 0 in domain 0 */ - bus = bus ?: pci_find_bus(0, 0); + bus = p2sb_get_bus(NULL); + if (!bus) + return -ENODEV; + + /* + * When a device with same devfn exists and its device class is not + * PCI_CLASS_MEMORY_OTHER for P2SB, do not touch it. + */ + pci_bus_read_config_word(bus, devfn_p2sb, PCI_CLASS_DEVICE, &class); + if (!PCI_POSSIBLE_ERROR(class) && class != PCI_CLASS_MEMORY_OTHER) + return -ENODEV; /* * Prevent concurrent PCI bus scan from seeing the P2SB device and @@ -115,17 +164,16 @@ */ pci_lock_rescan_remove(); - /* Unhide the P2SB device, if needed */ + /* + * The BIOS prevents the P2SB device from being enumerated by the PCI + * subsystem, so we need to unhide and hide it back to lookup the BAR. + * Unhide the P2SB device here, if needed. + */ pci_bus_read_config_dword(bus, devfn_p2sb, P2SBC, &value); if (value & P2SBC_HIDE) pci_bus_write_config_dword(bus, devfn_p2sb, P2SBC, 0); - pdev_p2sb = pci_scan_single_device(bus, devfn_p2sb); - if (devfn) - ret = p2sb_scan_and_read(bus, devfn, mem); - else - ret = p2sb_read_bar0(pdev_p2sb, mem); - pci_stop_and_remove_bus_device(pdev_p2sb); + ret = p2sb_scan_and_cache(bus, devfn_p2sb); /* Hide the P2SB device, if it was hidden */ if (value & P2SBC_HIDE) @@ -133,12 +181,62 @@ pci_unlock_rescan_remove(); - if (ret) - return ret; + return ret; +} - if (mem->flags == 0) +/** + * p2sb_bar - Get Primary to Sideband (P2SB) bridge device BAR + * @bus: PCI bus to communicate with + * @devfn: PCI slot and function to communicate with + * @mem: memory resource to be filled in + * + * If @bus is NULL, the bus 0 in domain 0 will be used. + * If @devfn is 0, it will be replaced by devfn of the P2SB device. + * + * Caller must provide a valid pointer to @mem. + * + * Return: + * 0 on success or appropriate errno value on error. + */ +int p2sb_bar(struct pci_bus *bus, unsigned int devfn, struct resource *mem) +{ + struct p2sb_res_cache *cache; + int ret; + + bus = p2sb_get_bus(bus); + if (!bus) return -ENODEV; + if (!devfn) { + ret = p2sb_get_devfn(&devfn); + if (ret) + return ret; + } + + cache = &p2sb_resources[PCI_FUNC(devfn)]; + if (cache->bus_dev_id != bus->dev.id) + return -ENODEV; + + if (!p2sb_valid_resource(&cache->res)) + return -ENOENT; + + memcpy(mem, &cache->res, sizeof(*mem)); return 0; } EXPORT_SYMBOL_GPL(p2sb_bar); + +static int __init p2sb_fs_init(void) +{ + p2sb_cache_resources(); + return 0; +} + +/* + * pci_rescan_remove_lock to avoid access to unhidden P2SB devices can + * not be locked in sysfs pci bus rescan path because of deadlock. To + * avoid the deadlock, access to P2SB devices with the lock at an early + * step in kernel initialization and cache required resources. This + * should happen after subsys_initcall which initializes PCI subsystem + * and before device_initcall which requires P2SB resources. + */ +fs_initcall(p2sb_fs_init); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/pnp/pnpacpi/rsparser.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pnp/pnpacpi/rsparser.c @@ -151,13 +151,13 @@ static void pnpacpi_parse_allocated_vendor(struct pnp_dev *dev, struct acpi_resource_vendor_typed *vendor) { - if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, 16)) { - u64 start, length; + struct { u64 start, length; } range; - memcpy(&start, vendor->byte_data, sizeof(start)); - memcpy(&length, vendor->byte_data + 8, sizeof(length)); - - pnp_add_mem_resource(dev, start, start + length - 1, 0); + if (vendor_resource_matches(dev, vendor, &hp_ccsr_uuid, + sizeof(range))) { + memcpy(&range, vendor->byte_data, sizeof(range)); + pnp_add_mem_resource(dev, range.start, range.start + + range.length - 1, 0); } } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/power/supply/bq256xx_charger.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/power/supply/bq256xx_charger.c @@ -1574,13 +1574,16 @@ wd_reg_val = i; break; } - if (bq->watchdog_timer > bq256xx_watchdog_time[i] && + if (i + 1 < BQ256XX_NUM_WD_VAL && + bq->watchdog_timer > bq256xx_watchdog_time[i] && bq->watchdog_timer < bq256xx_watchdog_time[i + 1]) wd_reg_val = i; } ret = regmap_update_bits(bq->regmap, BQ256XX_CHARGER_CONTROL_1, BQ256XX_WATCHDOG_MASK, wd_reg_val << BQ256XX_WDT_BIT_SHIFT); + if (ret) + return ret; ret = power_supply_get_battery_info(bq->charger, &bat_info); if (ret == -ENOMEM) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/power/supply/cw2015_battery.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/power/supply/cw2015_battery.c @@ -491,7 +491,7 @@ case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: if (cw_battery_valid_time_to_empty(cw_bat)) - val->intval = cw_bat->time_to_empty; + val->intval = cw_bat->time_to_empty * 60; else val->intval = 0; break; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/pwm/pwm-jz4740.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pwm/pwm-jz4740.c @@ -60,9 +60,10 @@ snprintf(name, sizeof(name), "timer%u", pwm->hwpwm); clk = clk_get(chip->dev, name); - if (IS_ERR(clk)) - return dev_err_probe(chip->dev, PTR_ERR(clk), - "Failed to get clock\n"); + if (IS_ERR(clk)) { + dev_err(chip->dev, "error %pe: Failed to get clock\n", clk); + return PTR_ERR(clk); + } err = clk_prepare_enable(clk); if (err < 0) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/pwm/pwm-stm32.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/pwm/pwm-stm32.c @@ -579,32 +579,23 @@ priv->have_complementary_output = (ccer != 0); } -static int stm32_pwm_detect_channels(struct stm32_pwm *priv) +static unsigned int stm32_pwm_detect_channels(struct stm32_pwm *priv, + unsigned int *num_enabled) { - u32 ccer; - int npwm = 0; + u32 ccer, ccer_backup; /* * If channels enable bits don't exist writing 1 will have no * effect so we can detect and count them. */ + regmap_read(priv->regmap, TIM_CCER, &ccer_backup); regmap_set_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); regmap_read(priv->regmap, TIM_CCER, &ccer); - regmap_clear_bits(priv->regmap, TIM_CCER, TIM_CCER_CCXE); + regmap_write(priv->regmap, TIM_CCER, ccer_backup); - if (ccer & TIM_CCER_CC1E) - npwm++; + *num_enabled = hweight32(ccer_backup & TIM_CCER_CCXE); - if (ccer & TIM_CCER_CC2E) - npwm++; - - if (ccer & TIM_CCER_CC3E) - npwm++; - - if (ccer & TIM_CCER_CC4E) - npwm++; - - return npwm; + return hweight32(ccer & TIM_CCER_CCXE); } static int stm32_pwm_probe(struct platform_device *pdev) @@ -613,6 +604,8 @@ struct device_node *np = dev->of_node; struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); struct stm32_pwm *priv; + unsigned int num_enabled; + unsigned int i; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -635,7 +628,11 @@ priv->chip.dev = dev; priv->chip.ops = &stm32pwm_ops; - priv->chip.npwm = stm32_pwm_detect_channels(priv); + priv->chip.npwm = stm32_pwm_detect_channels(priv, &num_enabled); + + /* Initialize clock refcount to number of enabled PWM channels. */ + for (i = 0; i < num_enabled; i++) + clk_enable(priv->clk); ret = pwmchip_add(&priv->chip); if (ret < 0) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/regulator/ti-abb-regulator.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/regulator/ti-abb-regulator.c @@ -734,9 +734,25 @@ return PTR_ERR(abb->setup_reg); } - abb->int_base = devm_platform_ioremap_resource_byname(pdev, "int-address"); - if (IS_ERR(abb->int_base)) - return PTR_ERR(abb->int_base); + pname = "int-address"; + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); + if (!res) { + dev_err(dev, "Missing '%s' IO resource\n", pname); + return -ENODEV; + } + /* + * The MPU interrupt status register (PRM_IRQSTATUS_MPU) is + * shared between regulator-abb-{ivahd,dspeve,gpu} driver + * instances. Therefore use devm_ioremap() rather than + * devm_platform_ioremap_resource_byname() to avoid busy + * resource region conflicts. + */ + abb->int_base = devm_ioremap(dev, res->start, + resource_size(res)); + if (!abb->int_base) { + dev_err(dev, "Unable to map '%s'\n", pname); + return -ENOMEM; + } /* Map Optional resources */ pname = "efuse-address"; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/rpmsg/virtio_rpmsg_bus.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/rpmsg/virtio_rpmsg_bus.c @@ -378,6 +378,7 @@ struct rpmsg_device *rpdev = to_rpmsg_device(dev); struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev); + kfree(rpdev->driver_override); kfree(vch); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/rtc/rtc-cmos.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/rtc/rtc-cmos.c @@ -231,7 +231,7 @@ if (!pm_trace_rtc_valid()) return -EIO; - ret = mc146818_get_time(t); + ret = mc146818_get_time(t, 1000); if (ret < 0) { dev_err_ratelimited(dev, "unable to read current time\n"); return ret; @@ -292,7 +292,7 @@ /* This not only a rtc_op, but also called directly */ if (!is_valid_irq(cmos->irq)) - return -EIO; + return -ETIMEDOUT; /* Basic alarms only support hour, minute, and seconds fields. * Some also support day and month, for alarms up to a year in @@ -307,7 +307,7 @@ * * Use the mc146818_avoid_UIP() function to avoid this. */ - if (!mc146818_avoid_UIP(cmos_read_alarm_callback, &p)) + if (!mc146818_avoid_UIP(cmos_read_alarm_callback, 10, &p)) return -EIO; if (!(p.rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { @@ -556,8 +556,8 @@ * * Use mc146818_avoid_UIP() to avoid this. */ - if (!mc146818_avoid_UIP(cmos_set_alarm_callback, &p)) - return -EIO; + if (!mc146818_avoid_UIP(cmos_set_alarm_callback, 10, &p)) + return -ETIMEDOUT; cmos->alarm_expires = rtc_tm_to_time64(&t->time); @@ -818,18 +818,24 @@ } #ifdef CONFIG_X86 -/* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */ static void use_acpi_alarm_quirks(void) { - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_INTEL: + if (dmi_get_bios_year() < 2015) + return; + break; + case X86_VENDOR_AMD: + case X86_VENDOR_HYGON: + if (dmi_get_bios_year() < 2021) + return; + break; + default: return; - + } if (!is_hpet_enabled()) return; - if (dmi_get_bios_year() < 2015) - return; - use_acpi_alarm = true; } #else only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/rtc/rtc-mc146818-lib.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/rtc/rtc-mc146818-lib.c @@ -8,26 +8,31 @@ #include #endif +#define UIP_RECHECK_DELAY 100 /* usec */ +#define UIP_RECHECK_DELAY_MS (USEC_PER_MSEC / UIP_RECHECK_DELAY) +#define UIP_RECHECK_LOOPS_MS(x) (x / UIP_RECHECK_DELAY_MS) + /* * Execute a function while the UIP (Update-in-progress) bit of the RTC is - * unset. + * unset. The timeout is configurable by the caller in ms. * * Warning: callback may be executed more then once. */ bool mc146818_avoid_UIP(void (*callback)(unsigned char seconds, void *param), + int timeout, void *param) { int i; unsigned long flags; unsigned char seconds; - for (i = 0; i < 100; i++) { + for (i = 0; UIP_RECHECK_LOOPS_MS(i) < timeout; i++) { spin_lock_irqsave(&rtc_lock, flags); /* * Check whether there is an update in progress during which the * readout is unspecified. The maximum update time is ~2ms. Poll - * every 100 usec for completion. + * for completion. * * Store the second value before checking UIP so a long lasting * NMI which happens to hit after the UIP check cannot make @@ -37,7 +42,7 @@ if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) { spin_unlock_irqrestore(&rtc_lock, flags); - udelay(100); + udelay(UIP_RECHECK_DELAY); continue; } @@ -56,7 +61,7 @@ */ if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP) { spin_unlock_irqrestore(&rtc_lock, flags); - udelay(100); + udelay(UIP_RECHECK_DELAY); continue; } @@ -72,6 +77,10 @@ } spin_unlock_irqrestore(&rtc_lock, flags); + if (UIP_RECHECK_LOOPS_MS(i) >= 100) + pr_warn("Reading current time from RTC took around %li ms\n", + UIP_RECHECK_LOOPS_MS(i)); + return true; } return false; @@ -84,7 +93,7 @@ */ bool mc146818_does_rtc_work(void) { - return mc146818_avoid_UIP(NULL, NULL); + return mc146818_avoid_UIP(NULL, 1000, NULL); } EXPORT_SYMBOL_GPL(mc146818_does_rtc_work); @@ -130,15 +139,27 @@ p->ctrl = CMOS_READ(RTC_CONTROL); } -int mc146818_get_time(struct rtc_time *time) +/** + * mc146818_get_time - Get the current time from the RTC + * @time: pointer to struct rtc_time to store the current time + * @timeout: timeout value in ms + * + * This function reads the current time from the RTC and stores it in the + * provided struct rtc_time. The timeout parameter specifies the maximum + * time to wait for the RTC to become ready. + * + * Return: 0 on success, -ETIMEDOUT if the RTC did not become ready within + * the specified timeout, or another error code if an error occurred. + */ +int mc146818_get_time(struct rtc_time *time, int timeout) { struct mc146818_get_time_callback_param p = { .time = time }; - if (!mc146818_avoid_UIP(mc146818_get_time_callback, &p)) { + if (!mc146818_avoid_UIP(mc146818_get_time_callback, timeout, &p)) { memset(time, 0, sizeof(*time)); - return -EIO; + return -ETIMEDOUT; } if (!(p.ctrl & RTC_DM_BINARY) || RTC_ALWAYS_BCD) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/scsi/arcmsr/arcmsr.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/arcmsr/arcmsr.h @@ -78,9 +78,13 @@ #ifndef PCI_DEVICE_ID_ARECA_1203 #define PCI_DEVICE_ID_ARECA_1203 0x1203 #endif +#ifndef PCI_DEVICE_ID_ARECA_1883 +#define PCI_DEVICE_ID_ARECA_1883 0x1883 +#endif #ifndef PCI_DEVICE_ID_ARECA_1884 #define PCI_DEVICE_ID_ARECA_1884 0x1884 #endif +#define PCI_DEVICE_ID_ARECA_1886_0 0x1886 #define PCI_DEVICE_ID_ARECA_1886 0x188A #define ARCMSR_HOURS (1000 * 60 * 60 * 4) #define ARCMSR_MINUTES (1000 * 60 * 60) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/scsi/arcmsr/arcmsr_hba.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/arcmsr/arcmsr_hba.c @@ -214,8 +214,12 @@ .driver_data = ACB_ADAPTER_TYPE_A}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1880), .driver_data = ACB_ADAPTER_TYPE_C}, + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1883), + .driver_data = ACB_ADAPTER_TYPE_C}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1884), .driver_data = ACB_ADAPTER_TYPE_E}, + {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1886_0), + .driver_data = ACB_ADAPTER_TYPE_F}, {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1886), .driver_data = ACB_ADAPTER_TYPE_F}, {0, 0}, /* Terminating entry */ @@ -4706,9 +4710,11 @@ case PCI_DEVICE_ID_ARECA_1680: case PCI_DEVICE_ID_ARECA_1681: case PCI_DEVICE_ID_ARECA_1880: + case PCI_DEVICE_ID_ARECA_1883: case PCI_DEVICE_ID_ARECA_1884: type = "SAS/SATA"; break; + case PCI_DEVICE_ID_ARECA_1886_0: case PCI_DEVICE_ID_ARECA_1886: type = "NVMe/SAS/SATA"; break; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/scsi/bfa/bfad_bsg.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/bfa/bfad_bsg.c @@ -2550,7 +2550,7 @@ static void bfad_reset_sdev_bflags(struct bfad_im_port_s *im_port, int lunmask_cfg) { - const u32 scan_flags = BLIST_NOREPORTLUN | BLIST_SPARSELUN; + const blist_flags_t scan_flags = BLIST_NOREPORTLUN | BLIST_SPARSELUN; struct bfad_itnim_s *itnim; struct scsi_device *sdev; unsigned long flags; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/scsi/fnic/fnic_debugfs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/fnic/fnic_debugfs.c @@ -52,9 +52,10 @@ fc_trc_flag->fnic_trace = 2; fc_trc_flag->fc_trace = 3; fc_trc_flag->fc_clear = 4; + return 0; } - return 0; + return -ENOMEM; } /* only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/scsi/hisi_sas/hisi_sas_main.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -1572,12 +1572,12 @@ static int hisi_sas_controller_prereset(struct hisi_hba *hisi_hba) { if (!hisi_hba->hw->soft_reset) - return -1; + return -ENOENT; down(&hisi_hba->sem); if (test_and_set_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags)) { up(&hisi_hba->sem); - return -1; + return -EPERM; } if (hisi_sas_debugfs_enable && hisi_hba->debugfs_itct[0].itct) @@ -1648,7 +1648,10 @@ task->task_state_flags |= SAS_TASK_STATE_ABORTED; spin_unlock_irqrestore(&task->task_state_lock, flags); - if (slot && task->task_proto & SAS_PROTOCOL_SSP) { + if (!slot) + goto out; + + if (task->task_proto & SAS_PROTOCOL_SSP) { u16 tag = slot->idx; int rc2; @@ -1695,7 +1698,7 @@ rc = hisi_sas_softreset_ata_disk(device); } } - } else if (slot && task->task_proto & SAS_PROTOCOL_SMP) { + } else if (task->task_proto & SAS_PROTOCOL_SMP) { /* SMP */ u32 tag = slot->idx; struct hisi_sas_cq *cq = &hisi_hba->cq[slot->dlvry_queue]; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/scsi/isci/request.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/isci/request.c @@ -3390,7 +3390,7 @@ return SCI_FAILURE; } - return SCI_SUCCESS; + return status; } static struct isci_request *isci_request_from_tag(struct isci_host *ihost, u16 tag) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/scsi/libfc/fc_fcp.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/libfc/fc_fcp.c @@ -265,6 +265,11 @@ if (!fsp->seq_ptr) return -EINVAL; + if (fsp->state & FC_SRB_ABORT_PENDING) { + FC_FCP_DBG(fsp, "abort already pending\n"); + return -EBUSY; + } + this_cpu_inc(fsp->lp->stats->FcpPktAborts); fsp->state |= FC_SRB_ABORT_PENDING; @@ -1671,7 +1676,7 @@ if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY) fc_fcp_rec(fsp); else - fc_fcp_recovery(fsp, FC_ERROR); + fc_fcp_recovery(fsp, FC_TIMED_OUT); break; } fc_fcp_unlock_pkt(fsp); @@ -1690,11 +1695,12 @@ fsp->status_code = code; fsp->cdb_status = 0; fsp->io_status = 0; - /* - * if this fails then we let the scsi command timer fire and - * scsi-ml escalate. - */ - fc_fcp_send_abort(fsp); + if (!fsp->cmd) + /* + * Only abort non-scsi commands; otherwise let the + * scsi command timer fire and scsi-ml escalate. + */ + fc_fcp_send_abort(fsp); } /** only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/scsi/lpfc/lpfc_vmid.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/scsi/lpfc/lpfc_vmid.c @@ -321,5 +321,6 @@ if (!hash_empty(vport->hash_table)) hash_for_each_safe(vport->hash_table, bucket, tmp, cur, hnode) hash_del(&cur->hnode); + vport->vmid_flag = 0; write_unlock(&vport->vmid_lock); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/soc/fsl/qe/qmc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soc/fsl/qe/qmc.c @@ -175,7 +175,7 @@ struct list_head list; unsigned int id; struct qmc *qmc; - void *__iomem s_param; + void __iomem *s_param; enum qmc_mode mode; u64 tx_ts_mask; u64 rx_ts_mask; @@ -203,9 +203,9 @@ struct qmc { struct device *dev; struct tsa_serial *tsa_serial; - void *__iomem scc_regs; - void *__iomem scc_pram; - void *__iomem dpram; + void __iomem *scc_regs; + void __iomem *scc_pram; + void __iomem *dpram; u16 scc_pram_offset; cbd_t __iomem *bd_table; dma_addr_t bd_dma_addr; @@ -218,37 +218,37 @@ struct qmc_chan *chans[64]; }; -static inline void qmc_write16(void *__iomem addr, u16 val) +static inline void qmc_write16(void __iomem *addr, u16 val) { iowrite16be(val, addr); } -static inline u16 qmc_read16(void *__iomem addr) +static inline u16 qmc_read16(void __iomem *addr) { return ioread16be(addr); } -static inline void qmc_setbits16(void *__iomem addr, u16 set) +static inline void qmc_setbits16(void __iomem *addr, u16 set) { qmc_write16(addr, qmc_read16(addr) | set); } -static inline void qmc_clrbits16(void *__iomem addr, u16 clr) +static inline void qmc_clrbits16(void __iomem *addr, u16 clr) { qmc_write16(addr, qmc_read16(addr) & ~clr); } -static inline void qmc_write32(void *__iomem addr, u32 val) +static inline void qmc_write32(void __iomem *addr, u32 val) { iowrite32be(val, addr); } -static inline u32 qmc_read32(void *__iomem addr) +static inline u32 qmc_read32(void __iomem *addr) { return ioread32be(addr); } -static inline void qmc_setbits32(void *__iomem addr, u32 set) +static inline void qmc_setbits32(void __iomem *addr, u32 set) { qmc_write32(addr, qmc_read32(addr) | set); } @@ -318,7 +318,7 @@ { struct qmc_xfer_desc *xfer_desc; unsigned long flags; - cbd_t *__iomem bd; + cbd_t __iomem *bd; u16 ctrl; int ret; @@ -374,7 +374,7 @@ void (*complete)(void *context); unsigned long flags; void *context; - cbd_t *__iomem bd; + cbd_t __iomem *bd; u16 ctrl; /* @@ -425,7 +425,7 @@ { struct qmc_xfer_desc *xfer_desc; unsigned long flags; - cbd_t *__iomem bd; + cbd_t __iomem *bd; u16 ctrl; int ret; @@ -488,7 +488,7 @@ void (*complete)(void *context, size_t size); struct qmc_xfer_desc *xfer_desc; unsigned long flags; - cbd_t *__iomem bd; + cbd_t __iomem *bd; void *context; u16 datalen; u16 ctrl; @@ -663,7 +663,7 @@ { struct qmc_xfer_desc *xfer_desc; unsigned long flags; - cbd_t *__iomem bd; + cbd_t __iomem *bd; u16 ctrl; spin_lock_irqsave(&chan->rx_lock, flags); @@ -685,7 +685,6 @@ qmc_read16(chan->s_param + QMC_SPE_RBASE)); chan->rx_pending = 0; - chan->is_rx_stopped = false; spin_unlock_irqrestore(&chan->rx_lock, flags); } @@ -694,7 +693,7 @@ { struct qmc_xfer_desc *xfer_desc; unsigned long flags; - cbd_t *__iomem bd; + cbd_t __iomem *bd; u16 ctrl; spin_lock_irqsave(&chan->tx_lock, flags); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/soc/fsl/qe/tsa.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soc/fsl/qe/tsa.c @@ -98,9 +98,9 @@ #define TSA_SIRP 0x10 struct tsa_entries_area { - void *__iomem entries_start; - void *__iomem entries_next; - void *__iomem last_entry; + void __iomem *entries_start; + void __iomem *entries_next; + void __iomem *last_entry; }; struct tsa_tdm { @@ -117,8 +117,8 @@ struct tsa { struct device *dev; - void *__iomem si_regs; - void *__iomem si_ram; + void __iomem *si_regs; + void __iomem *si_ram; resource_size_t si_ram_sz; spinlock_t lock; int tdms; /* TSA_TDMx ORed */ @@ -135,27 +135,27 @@ return container_of(tsa_serial, struct tsa, serials[tsa_serial->id]); } -static inline void tsa_write32(void *__iomem addr, u32 val) +static inline void tsa_write32(void __iomem *addr, u32 val) { iowrite32be(val, addr); } -static inline void tsa_write8(void *__iomem addr, u32 val) +static inline void tsa_write8(void __iomem *addr, u32 val) { iowrite8(val, addr); } -static inline u32 tsa_read32(void *__iomem addr) +static inline u32 tsa_read32(void __iomem *addr) { return ioread32be(addr); } -static inline void tsa_clrbits32(void *__iomem addr, u32 clr) +static inline void tsa_clrbits32(void __iomem *addr, u32 clr) { tsa_write32(addr, tsa_read32(addr) & ~clr); } -static inline void tsa_clrsetbits32(void *__iomem addr, u32 clr, u32 set) +static inline void tsa_clrsetbits32(void __iomem *addr, u32 clr, u32 set) { tsa_write32(addr, (tsa_read32(addr) & ~clr) | set); } @@ -313,7 +313,7 @@ static int tsa_add_entry(struct tsa *tsa, struct tsa_entries_area *area, u32 count, u32 serial_id) { - void *__iomem addr; + void __iomem *addr; u32 left; u32 val; u32 cnt; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/soc/xilinx/xlnx_event_manager.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soc/xilinx/xlnx_event_manager.c @@ -477,7 +477,7 @@ } } if (!is_callback_found) - pr_warn("Didn't find any registered callback for 0x%x 0x%x\n", + pr_warn("Unhandled SGI node 0x%x event 0x%x. Expected with Xen hypervisor\n", payload[1], payload[2]); } @@ -555,7 +555,7 @@ static int xlnx_event_init_sgi(struct platform_device *pdev) { int ret = 0; - int cpu = smp_processor_id(); + int cpu; /* * IRQ related structures are used for the following: * for each SGI interrupt ensure its mapped by GIC IRQ domain @@ -592,9 +592,12 @@ sgi_fwspec.param[0] = sgi_num; virq_sgi = irq_create_fwspec_mapping(&sgi_fwspec); + cpu = get_cpu(); per_cpu(cpu_number1, cpu) = cpu; ret = request_percpu_irq(virq_sgi, xlnx_event_handler, "xlnx_event_mgmt", &cpu_number1); + put_cpu(); + WARN_ON(ret); if (ret) { irq_dispose_mapping(virq_sgi); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/soundwire/amd_manager.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soundwire/amd_manager.c @@ -927,6 +927,14 @@ amd_manager->bus.clk_stop_timeout = 200; amd_manager->bus.link_id = amd_manager->instance; + /* + * Due to BIOS compatibility, the two links are exposed within + * the scope of a single controller. If this changes, the + * controller_id will have to be updated with drv_data + * information. + */ + amd_manager->bus.controller_id = 0; + switch (amd_manager->instance) { case ACP_SDW0: amd_manager->num_dout_ports = AMD_SDW0_MAX_TX_PORTS; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/soundwire/bus.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soundwire/bus.c @@ -22,6 +22,10 @@ return rc; bus->id = rc; + + if (bus->controller_id == -1) + bus->controller_id = rc; + return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/soundwire/debugfs.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soundwire/debugfs.c @@ -20,7 +20,7 @@ return; /* create the debugfs master-N */ - snprintf(name, sizeof(name), "master-%d-%d", bus->id, bus->link_id); + snprintf(name, sizeof(name), "master-%d-%d", bus->controller_id, bus->link_id); bus->debugfs = debugfs_create_dir(name, sdw_debugfs_root); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/soundwire/intel_auxdevice.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soundwire/intel_auxdevice.c @@ -164,6 +164,9 @@ cdns->instance = sdw->instance; cdns->msg_count = 0; + /* single controller for all SoundWire links */ + bus->controller_id = 0; + bus->link_id = auxdev->id; bus->dev_num_ida_min = INTEL_DEV_NUM_IDA_MIN; bus->clk_stop_timeout = 1; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/soundwire/master.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soundwire/master.c @@ -145,7 +145,7 @@ md->dev.fwnode = fwnode; md->dev.dma_mask = parent->dma_mask; - dev_set_name(&md->dev, "sdw-master-%d", bus->id); + dev_set_name(&md->dev, "sdw-master-%d-%d", bus->controller_id, bus->link_id); ret = device_register(&md->dev); if (ret) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/soundwire/qcom.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soundwire/qcom.c @@ -1613,6 +1613,9 @@ } } + /* FIXME: is there a DT-defined value to use ? */ + ctrl->bus.controller_id = -1; + ret = sdw_bus_master_add(&ctrl->bus, dev, dev->fwnode); if (ret) { dev_err(dev, "Failed to register Soundwire controller (%d)\n", only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/soundwire/slave.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/soundwire/slave.c @@ -39,14 +39,14 @@ slave->dev.fwnode = fwnode; if (id->unique_id == SDW_IGNORED_UNIQUE_ID) { - /* name shall be sdw:link:mfg:part:class */ - dev_set_name(&slave->dev, "sdw:%01x:%04x:%04x:%02x", - bus->link_id, id->mfg_id, id->part_id, + /* name shall be sdw:ctrl:link:mfg:part:class */ + dev_set_name(&slave->dev, "sdw:%01x:%01x:%04x:%04x:%02x", + bus->controller_id, bus->link_id, id->mfg_id, id->part_id, id->class_id); } else { - /* name shall be sdw:link:mfg:part:class:unique */ - dev_set_name(&slave->dev, "sdw:%01x:%04x:%04x:%02x:%01x", - bus->link_id, id->mfg_id, id->part_id, + /* name shall be sdw:ctrl:link:mfg:part:class:unique */ + dev_set_name(&slave->dev, "sdw:%01x:%01x:%04x:%04x:%02x:%01x", + bus->controller_id, bus->link_id, id->mfg_id, id->part_id, id->class_id, id->unique_id); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/spi/spi-bcm-qspi.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi-bcm-qspi.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include "spi-bcm-qspi.h" @@ -1221,7 +1221,7 @@ /* non-aligned and very short transfers are handled by MSPI */ if (!IS_ALIGNED((uintptr_t)addr, 4) || !IS_ALIGNED((uintptr_t)buf, 4) || - len < 4) + len < 4 || op->cmd.opcode == SPINOR_OP_RDSFDP) mspi_read = true; if (!has_bspi(qspi) || mspi_read) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/spi/spi-coldfire-qspi.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi-coldfire-qspi.c @@ -444,7 +444,6 @@ mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR); mcfqspi_cs_teardown(mcfqspi); - clk_disable_unprepare(mcfqspi->clk); } #ifdef CONFIG_PM_SLEEP only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/spi/spi-sh-msiof.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/spi/spi-sh-msiof.c @@ -30,12 +30,15 @@ #include +#define SH_MSIOF_FLAG_FIXED_DTDL_200 BIT(0) + struct sh_msiof_chipdata { u32 bits_per_word_mask; u16 tx_fifo_size; u16 rx_fifo_size; u16 ctlr_flags; u16 min_div_pow; + u32 flags; }; struct sh_msiof_spi_priv { @@ -1073,6 +1076,16 @@ .min_div_pow = 1, }; +static const struct sh_msiof_chipdata rcar_r8a7795_data = { + .bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16) | + SPI_BPW_MASK(24) | SPI_BPW_MASK(32), + .tx_fifo_size = 64, + .rx_fifo_size = 64, + .ctlr_flags = SPI_CONTROLLER_MUST_TX, + .min_div_pow = 1, + .flags = SH_MSIOF_FLAG_FIXED_DTDL_200, +}; + static const struct of_device_id sh_msiof_match[] __maybe_unused = { { .compatible = "renesas,sh-mobile-msiof", .data = &sh_data }, { .compatible = "renesas,msiof-r8a7743", .data = &rcar_gen2_data }, @@ -1083,6 +1096,7 @@ { .compatible = "renesas,msiof-r8a7793", .data = &rcar_gen2_data }, { .compatible = "renesas,msiof-r8a7794", .data = &rcar_gen2_data }, { .compatible = "renesas,rcar-gen2-msiof", .data = &rcar_gen2_data }, + { .compatible = "renesas,msiof-r8a7795", .data = &rcar_r8a7795_data }, { .compatible = "renesas,msiof-r8a7796", .data = &rcar_gen3_data }, { .compatible = "renesas,rcar-gen3-msiof", .data = &rcar_gen3_data }, { .compatible = "renesas,rcar-gen4-msiof", .data = &rcar_gen3_data }, @@ -1280,6 +1294,9 @@ return -ENXIO; } + if (chipdata->flags & SH_MSIOF_FLAG_FIXED_DTDL_200) + info->dtdl = 200; + if (info->mode == MSIOF_SPI_SLAVE) ctlr = spi_alloc_slave(&pdev->dev, sizeof(struct sh_msiof_spi_priv)); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/spmi/spmi-mtk-pmif.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/spmi/spmi-mtk-pmif.c @@ -50,6 +50,7 @@ struct clk_bulk_data clks[PMIF_MAX_CLKS]; size_t nclks; const struct pmif_data *data; + raw_spinlock_t lock; }; static const char * const pmif_clock_names[] = { @@ -314,6 +315,7 @@ struct ch_reg *inf_reg; int ret; u32 data, cmd; + unsigned long flags; /* Check for argument validation. */ if (sid & ~0xf) { @@ -334,6 +336,7 @@ else return -EINVAL; + raw_spin_lock_irqsave(&arb->lock, flags); /* Wait for Software Interface FSM state to be IDLE. */ inf_reg = &arb->chan; ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], @@ -343,6 +346,7 @@ /* set channel ready if the data has transferred */ if (pmif_is_fsm_vldclr(arb)) pmif_writel(arb, 1, inf_reg->ch_rdy); + raw_spin_unlock_irqrestore(&arb->lock, flags); dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); return ret; } @@ -350,6 +354,7 @@ /* Send the command. */ cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr; pmif_writel(arb, cmd, inf_reg->ch_send); + raw_spin_unlock_irqrestore(&arb->lock, flags); /* * Wait for Software Interface FSM state to be WFVLDCLR, @@ -376,7 +381,8 @@ struct pmif *arb = spmi_controller_get_drvdata(ctrl); struct ch_reg *inf_reg; int ret; - u32 data, cmd; + u32 data, wdata, cmd; + unsigned long flags; if (len > 4) { dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len); @@ -394,6 +400,10 @@ else return -EINVAL; + /* Set the write data. */ + memcpy(&wdata, buf, len); + + raw_spin_lock_irqsave(&arb->lock, flags); /* Wait for Software Interface FSM state to be IDLE. */ inf_reg = &arb->chan; ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], @@ -403,17 +413,17 @@ /* set channel ready if the data has transferred */ if (pmif_is_fsm_vldclr(arb)) pmif_writel(arb, 1, inf_reg->ch_rdy); + raw_spin_unlock_irqrestore(&arb->lock, flags); dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); return ret; } - /* Set the write data. */ - memcpy(&data, buf, len); - pmif_writel(arb, data, inf_reg->wdata); + pmif_writel(arb, wdata, inf_reg->wdata); /* Send the command. */ cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr; pmif_writel(arb, cmd, inf_reg->ch_send); + raw_spin_unlock_irqrestore(&arb->lock, flags); return 0; } @@ -465,7 +475,7 @@ for (i = 0; i < arb->nclks; i++) arb->clks[i].id = pmif_clock_names[i]; - err = devm_clk_bulk_get(&pdev->dev, arb->nclks, arb->clks); + err = clk_bulk_get(&pdev->dev, arb->nclks, arb->clks); if (err) { dev_err(&pdev->dev, "Failed to get clocks: %d\n", err); goto err_put_ctrl; @@ -474,7 +484,7 @@ err = clk_bulk_prepare_enable(arb->nclks, arb->clks); if (err) { dev_err(&pdev->dev, "Failed to enable clocks: %d\n", err); - goto err_put_ctrl; + goto err_put_clks; } ctrl->cmd = pmif_arb_cmd; @@ -488,6 +498,8 @@ arb->chan.ch_send = PMIF_SWINF_0_ACC + chan_offset; arb->chan.ch_rdy = PMIF_SWINF_0_VLD_CLR + chan_offset; + raw_spin_lock_init(&arb->lock); + platform_set_drvdata(pdev, ctrl); err = spmi_controller_add(ctrl); @@ -498,6 +510,8 @@ err_domain_remove: clk_bulk_disable_unprepare(arb->nclks, arb->clks); +err_put_clks: + clk_bulk_put(arb->nclks, arb->clks); err_put_ctrl: spmi_controller_put(ctrl); return err; @@ -509,6 +523,7 @@ struct pmif *arb = spmi_controller_get_drvdata(ctrl); clk_bulk_disable_unprepare(arb->nclks, arb->clks); + clk_bulk_put(arb->nclks, arb->clks); spmi_controller_remove(ctrl); spmi_controller_put(ctrl); } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/target/target_core_file.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/target/target_core_file.c @@ -332,11 +332,13 @@ } iov_iter_bvec(&iter, is_write, bvec, sgl_nents, len); - if (is_write) + if (is_write) { + file_start_write(fd); ret = vfs_iter_write(fd, &iter, &pos, 0); - else + file_end_write(fd); + } else { ret = vfs_iter_read(fd, &iter, &pos, 0); - + } if (is_write) { if (ret < 0 || ret != data_length) { pr_err("%s() write returned %d\n", __func__, ret); @@ -467,7 +469,9 @@ } iov_iter_bvec(&iter, ITER_SOURCE, bvec, nolb, len); + file_start_write(fd_dev->fd_file); ret = vfs_iter_write(fd_dev->fd_file, &iter, &pos, 0); + file_end_write(fd_dev->fd_file); kfree(bvec); if (ret < 0 || ret != len) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/thermal/gov_bang_bang.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/gov_bang_bang.c @@ -13,28 +13,21 @@ #include "thermal_core.h" -static int thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id) +static int thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_index) { - struct thermal_trip trip; + const struct thermal_trip *trip = &tz->trips[trip_index]; struct thermal_instance *instance; - int ret; - ret = __thermal_zone_get_trip(tz, trip_id, &trip); - if (ret) { - pr_warn_once("Failed to retrieve trip point %d\n", trip_id); - return ret; - } - - if (!trip.hysteresis) + if (!trip->hysteresis) dev_info_once(&tz->device, "Zero hysteresis value for thermal zone %s\n", tz->type); dev_dbg(&tz->device, "Trip%d[temp=%d]:temp=%d:hyst=%d\n", - trip_id, trip.temperature, tz->temperature, - trip.hysteresis); + trip_index, trip->temperature, tz->temperature, + trip->hysteresis); list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (instance->trip != trip_id) + if (instance->trip != trip) continue; /* in case fan is in initial state, switch the fan off */ @@ -52,10 +45,10 @@ * enable fan when temperature exceeds trip_temp and disable * the fan in case it falls below trip_temp minus hysteresis */ - if (instance->target == 0 && tz->temperature >= trip.temperature) + if (instance->target == 0 && tz->temperature >= trip->temperature) instance->target = 1; else if (instance->target == 1 && - tz->temperature <= trip.temperature - trip.hysteresis) + tz->temperature <= trip->temperature - trip->hysteresis) instance->target = 0; dev_dbg(&instance->cdev->device, "target=%d\n", only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/thermal/gov_fair_share.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/gov_fair_share.c @@ -49,7 +49,7 @@ /** * fair_share_throttle - throttles devices associated with the given zone * @tz: thermal_zone_device - * @trip: trip point index + * @trip_index: trip point index * * Throttling Logic: This uses three parameters to calculate the new * throttle state of the cooling devices associated with the given zone. @@ -65,8 +65,9 @@ * (Heavily assumes the trip points are in ascending order) * new_state of cooling device = P3 * P2 * P1 */ -static int fair_share_throttle(struct thermal_zone_device *tz, int trip) +static int fair_share_throttle(struct thermal_zone_device *tz, int trip_index) { + const struct thermal_trip *trip = &tz->trips[trip_index]; struct thermal_instance *instance; int total_weight = 0; int total_instance = 0; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/thermal/gov_power_allocator.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/gov_power_allocator.c @@ -90,12 +90,14 @@ u32 sustainable_power = 0; struct thermal_instance *instance; struct power_allocator_params *params = tz->governor_data; + const struct thermal_trip *trip_max_desired_temperature = + &tz->trips[params->trip_max_desired_temperature]; list_for_each_entry(instance, &tz->thermal_instances, tz_node) { struct thermal_cooling_device *cdev = instance->cdev; u32 min_power; - if (instance->trip != params->trip_max_desired_temperature) + if (instance->trip != trip_max_desired_temperature) continue; if (!cdev_is_power_actor(cdev)) @@ -383,12 +385,13 @@ { struct thermal_instance *instance; struct power_allocator_params *params = tz->governor_data; + const struct thermal_trip *trip_max_desired_temperature = + &tz->trips[params->trip_max_desired_temperature]; u32 *req_power, *max_power, *granted_power, *extra_actor_power; u32 *weighted_req_power; u32 total_req_power, max_allocatable_power, total_weighted_req_power; u32 total_granted_power, power_range; int i, num_actors, total_weight, ret = 0; - int trip_max_desired_temperature = params->trip_max_desired_temperature; num_actors = 0; total_weight = 0; @@ -564,12 +567,14 @@ { struct thermal_instance *instance; struct power_allocator_params *params = tz->governor_data; + const struct thermal_trip *trip_max_desired_temperature = + &tz->trips[params->trip_max_desired_temperature]; u32 req_power; list_for_each_entry(instance, &tz->thermal_instances, tz_node) { struct thermal_cooling_device *cdev = instance->cdev; - if ((instance->trip != params->trip_max_desired_temperature) || + if ((instance->trip != trip_max_desired_temperature) || (!cdev_is_power_actor(instance->cdev))) continue; @@ -710,7 +715,7 @@ ret = __thermal_zone_get_trip(tz, params->trip_switch_on, &trip); if (!ret && (tz->temperature < trip.temperature)) { - update = (tz->last_temperature >= trip.temperature); + update = tz->passive; tz->passive = 0; reset_pid_controller(params); allow_maximum_power(tz, update); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/thermal/gov_step_wise.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/gov_step_wise.c @@ -81,26 +81,24 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip_id) { + const struct thermal_trip *trip = &tz->trips[trip_id]; enum thermal_trend trend; struct thermal_instance *instance; - struct thermal_trip trip; bool throttle = false; int old_target; - __thermal_zone_get_trip(tz, trip_id, &trip); - trend = get_tz_trend(tz, trip_id); - if (tz->temperature >= trip.temperature) { + if (tz->temperature >= trip->temperature) { throttle = true; - trace_thermal_zone_trip(tz, trip_id, trip.type); + trace_thermal_zone_trip(tz, trip_id, trip->type); } dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n", - trip_id, trip.type, trip.temperature, trend, throttle); + trip_id, trip->type, trip->temperature, trend, throttle); list_for_each_entry(instance, &tz->thermal_instances, tz_node) { - if (instance->trip != trip_id) + if (instance->trip != trip) continue; old_target = instance->target; @@ -114,11 +112,11 @@ /* Activate a passive thermal instance */ if (old_target == THERMAL_NO_TARGET && instance->target != THERMAL_NO_TARGET) - update_passive_instance(tz, trip.type, 1); + update_passive_instance(tz, trip->type, 1); /* Deactivate a passive thermal instance */ else if (old_target != THERMAL_NO_TARGET && instance->target == THERMAL_NO_TARGET) - update_passive_instance(tz, trip.type, -1); + update_passive_instance(tz, trip->type, -1); instance->initialized = true; mutex_lock(&instance->cdev->lock); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/thermal/intel/intel_hfi.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/intel/intel_hfi.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,9 @@ #include #include #include +#include #include +#include #include #include @@ -347,6 +350,52 @@ hfi_instance->data = hfi_instance->hdr + hfi_features.hdr_size; } +/* Caller must hold hfi_instance_lock. */ +static void hfi_enable(void) +{ + u64 msr_val; + + rdmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val); + msr_val |= HW_FEEDBACK_CONFIG_HFI_ENABLE_BIT; + wrmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val); +} + +static void hfi_set_hw_table(struct hfi_instance *hfi_instance) +{ + phys_addr_t hw_table_pa; + u64 msr_val; + + hw_table_pa = virt_to_phys(hfi_instance->hw_table); + msr_val = hw_table_pa | HW_FEEDBACK_PTR_VALID_BIT; + wrmsrl(MSR_IA32_HW_FEEDBACK_PTR, msr_val); +} + +/* Caller must hold hfi_instance_lock. */ +static void hfi_disable(void) +{ + u64 msr_val; + int i; + + rdmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val); + msr_val &= ~HW_FEEDBACK_CONFIG_HFI_ENABLE_BIT; + wrmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val); + + /* + * Wait for hardware to acknowledge the disabling of HFI. Some + * processors may not do it. Wait for ~2ms. This is a reasonable + * time for hardware to complete any pending actions on the HFI + * memory. + */ + for (i = 0; i < 2000; i++) { + rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val); + if (msr_val & PACKAGE_THERM_STATUS_HFI_UPDATED) + break; + + udelay(1); + cpu_relax(); + } +} + /** * intel_hfi_online() - Enable HFI on @cpu * @cpu: CPU in which the HFI will be enabled @@ -364,8 +413,6 @@ { struct hfi_instance *hfi_instance; struct hfi_cpu_info *info; - phys_addr_t hw_table_pa; - u64 msr_val; u16 die_id; /* Nothing to do if hfi_instances are missing. */ @@ -403,14 +450,16 @@ /* * Hardware is programmed with the physical address of the first page * frame of the table. Hence, the allocated memory must be page-aligned. + * + * Some processors do not forget the initial address of the HFI table + * even after having been reprogrammed. Keep using the same pages. Do + * not free them. */ hfi_instance->hw_table = alloc_pages_exact(hfi_features.nr_table_pages, GFP_KERNEL | __GFP_ZERO); if (!hfi_instance->hw_table) goto unlock; - hw_table_pa = virt_to_phys(hfi_instance->hw_table); - /* * Allocate memory to keep a local copy of the table that * hardware generates. @@ -420,16 +469,6 @@ if (!hfi_instance->local_table) goto free_hw_table; - /* - * Program the address of the feedback table of this die/package. On - * some processors, hardware remembers the old address of the HFI table - * even after having been reprogrammed and re-enabled. Thus, do not free - * the pages allocated for the table or reprogram the hardware with a - * new base address. Namely, program the hardware only once. - */ - msr_val = hw_table_pa | HW_FEEDBACK_PTR_VALID_BIT; - wrmsrl(MSR_IA32_HW_FEEDBACK_PTR, msr_val); - init_hfi_instance(hfi_instance); INIT_DELAYED_WORK(&hfi_instance->update_work, hfi_update_work_fn); @@ -438,13 +477,8 @@ cpumask_set_cpu(cpu, hfi_instance->cpus); - /* - * Enable the hardware feedback interface and never disable it. See - * comment on programming the address of the table. - */ - rdmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val); - msr_val |= HW_FEEDBACK_CONFIG_HFI_ENABLE_BIT; - wrmsrl(MSR_IA32_HW_FEEDBACK_CONFIG, msr_val); + hfi_set_hw_table(hfi_instance); + hfi_enable(); unlock: mutex_unlock(&hfi_instance_lock); @@ -484,6 +518,10 @@ mutex_lock(&hfi_instance_lock); cpumask_clear_cpu(cpu, hfi_instance->cpus); + + if (!cpumask_weight(hfi_instance->cpus)) + hfi_disable(); + mutex_unlock(&hfi_instance_lock); } @@ -532,6 +570,30 @@ return 0; } +static void hfi_do_enable(void) +{ + /* This code runs only on the boot CPU. */ + struct hfi_cpu_info *info = &per_cpu(hfi_cpu_info, 0); + struct hfi_instance *hfi_instance = info->hfi_instance; + + /* No locking needed. There is no concurrency with CPU online. */ + hfi_set_hw_table(hfi_instance); + hfi_enable(); +} + +static int hfi_do_disable(void) +{ + /* No locking needed. There is no concurrency with CPU offline. */ + hfi_disable(); + + return 0; +} + +static struct syscore_ops hfi_pm_ops = { + .resume = hfi_do_enable, + .suspend = hfi_do_disable, +}; + void __init intel_hfi_init(void) { struct hfi_instance *hfi_instance; @@ -563,6 +625,8 @@ if (!hfi_updates_wq) goto err_nomem; + register_syscore_ops(&hfi_pm_ops); + return; err_nomem: only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/thermal/thermal_core.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_core.h @@ -91,7 +91,7 @@ char name[THERMAL_NAME_LENGTH]; struct thermal_zone_device *tz; struct thermal_cooling_device *cdev; - int trip; + const struct thermal_trip *trip; bool initialized; unsigned long upper; /* Highest cooling state for this trip point */ unsigned long lower; /* Lowest cooling state for this trip point */ @@ -123,6 +123,8 @@ void __thermal_zone_set_trips(struct thermal_zone_device *tz); int __thermal_zone_get_trip(struct thermal_zone_device *tz, int trip_id, struct thermal_trip *trip); +int thermal_zone_trip_id(struct thermal_zone_device *tz, + const struct thermal_trip *trip); int __thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); /* sysfs I/F */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/thermal/thermal_helpers.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/thermal/thermal_helpers.c @@ -41,14 +41,17 @@ struct thermal_instance * get_thermal_instance(struct thermal_zone_device *tz, - struct thermal_cooling_device *cdev, int trip) + struct thermal_cooling_device *cdev, int trip_index) { struct thermal_instance *pos = NULL; struct thermal_instance *target_instance = NULL; + const struct thermal_trip *trip; mutex_lock(&tz->lock); mutex_lock(&cdev->lock); + trip = &tz->trips[trip_index]; + list_for_each_entry(pos, &tz->thermal_instances, tz_node) { if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) { target_instance = pos; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/tty/serial/8250/8250_bcm2835aux.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/8250/8250_bcm2835aux.c @@ -119,6 +119,8 @@ /* get the clock - this also enables the HW */ data->clk = devm_clk_get_optional(&pdev->dev, NULL); + if (IS_ERR(data->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(data->clk), "could not get clk\n"); /* get the interrupt */ ret = platform_get_irq(pdev, 0); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/tty/serial/8250/8250_exar.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/8250/8250_exar.c @@ -446,7 +446,7 @@ } static const struct serial_rs485 generic_rs485_supported = { - .flags = SER_RS485_ENABLED, + .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND, }; static const struct exar8250_platform exar8250_default_platform = { @@ -490,7 +490,8 @@ } static const struct serial_rs485 iot2040_rs485_supported = { - .flags = SER_RS485_ENABLED | SER_RS485_RX_DURING_TX | SER_RS485_TERMINATE_BUS, + .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | + SER_RS485_RX_DURING_TX | SER_RS485_TERMINATE_BUS, }; static const struct property_entry iot2040_gpio_properties[] = { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/tty/serial/apbuart.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/apbuart.c @@ -124,7 +124,7 @@ { u8 ch; - uart_port_tx_limited(port, ch, port->fifosize >> 1, + uart_port_tx_limited(port, ch, port->fifosize, true, UART_PUT_CHAR(port, ch), ({})); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/tty/serial/imx.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/imx.c @@ -422,13 +422,13 @@ ucr1 = imx_uart_readl(sport, UCR1); imx_uart_writel(sport, ucr1 & ~UCR1_TRDYEN, UCR1); + ucr4 = imx_uart_readl(sport, UCR4); usr2 = imx_uart_readl(sport, USR2); - if (!(usr2 & USR2_TXDC)) { + if ((!(usr2 & USR2_TXDC)) && (ucr4 & UCR4_TCEN)) { /* The shifter is still busy, so retry once TC triggers */ return; } - ucr4 = imx_uart_readl(sport, UCR4); ucr4 &= ~UCR4_TCEN; imx_uart_writel(sport, ucr4, UCR4); @@ -1948,10 +1948,6 @@ rs485conf->flags & SER_RS485_RX_DURING_TX) imx_uart_start_rx(port); - if (port->rs485_rx_during_tx_gpio) - gpiod_set_value_cansleep(port->rs485_rx_during_tx_gpio, - !!(rs485conf->flags & SER_RS485_RX_DURING_TX)); - return 0; } @@ -2215,7 +2211,6 @@ return HRTIMER_NORESTART; } -static const struct serial_rs485 imx_no_rs485 = {}; /* No RS485 if no RTS */ static const struct serial_rs485 imx_rs485_supported = { .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | SER_RS485_RX_DURING_TX, @@ -2300,8 +2295,6 @@ /* RTS is required to control the RS485 transmitter */ if (sport->have_rtscts || sport->have_rtsgpio) sport->port.rs485_supported = imx_rs485_supported; - else - sport->port.rs485_supported = imx_no_rs485; sport->port.flags = UPF_BOOT_AUTOCONF; timer_setup(&sport->timer, imx_uart_timeout, 0); @@ -2328,19 +2321,13 @@ /* For register access, we only need to enable the ipg clock. */ ret = clk_prepare_enable(sport->clk_ipg); if (ret) { - dev_err(&pdev->dev, "failed to enable per clk: %d\n", ret); + dev_err(&pdev->dev, "failed to enable ipg clk: %d\n", ret); return ret; } ret = uart_get_rs485_mode(&sport->port); - if (ret) { - clk_disable_unprepare(sport->clk_ipg); - return ret; - } - - if (sport->port.rs485.flags & SER_RS485_ENABLED && - (!sport->have_rtscts && !sport->have_rtsgpio)) - dev_err(&pdev->dev, "no RTS control, disabling rs485\n"); + if (ret) + goto err_clk; /* * If using the i.MX UART RTS/CTS control then the RTS (CTS_B) @@ -2420,8 +2407,6 @@ imx_uart_writel(sport, ucr3, UCR3); } - clk_disable_unprepare(sport->clk_ipg); - hrtimer_init(&sport->trigger_start_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer_init(&sport->trigger_stop_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL); sport->trigger_start_tx.function = imx_trigger_start_tx; @@ -2437,7 +2422,7 @@ if (ret) { dev_err(&pdev->dev, "failed to request rx irq: %d\n", ret); - return ret; + goto err_clk; } ret = devm_request_irq(&pdev->dev, txirq, imx_uart_txint, 0, @@ -2445,7 +2430,7 @@ if (ret) { dev_err(&pdev->dev, "failed to request tx irq: %d\n", ret); - return ret; + goto err_clk; } ret = devm_request_irq(&pdev->dev, rtsirq, imx_uart_rtsint, 0, @@ -2453,14 +2438,14 @@ if (ret) { dev_err(&pdev->dev, "failed to request rts irq: %d\n", ret); - return ret; + goto err_clk; } } else { ret = devm_request_irq(&pdev->dev, rxirq, imx_uart_int, 0, dev_name(&pdev->dev), sport); if (ret) { dev_err(&pdev->dev, "failed to request irq: %d\n", ret); - return ret; + goto err_clk; } } @@ -2468,7 +2453,12 @@ platform_set_drvdata(pdev, sport); - return uart_add_one_port(&imx_uart_uart_driver, &sport->port); + ret = uart_add_one_port(&imx_uart_uart_driver, &sport->port); + +err_clk: + clk_disable_unprepare(sport->clk_ipg); + + return ret; } static int imx_uart_remove(struct platform_device *pdev) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/tty/serial/omap-serial.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/omap-serial.c @@ -1490,6 +1490,13 @@ return omap_up_info; } +static const struct serial_rs485 serial_omap_rs485_supported = { + .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | + SER_RS485_RX_DURING_TX, + .delay_rts_before_send = 1, + .delay_rts_after_send = 1, +}; + static int serial_omap_probe_rs485(struct uart_omap_port *up, struct device *dev) { @@ -1504,6 +1511,9 @@ if (!np) return 0; + up->port.rs485_config = serial_omap_config_rs485; + up->port.rs485_supported = serial_omap_rs485_supported; + ret = uart_get_rs485_mode(&up->port); if (ret) return ret; @@ -1538,13 +1548,6 @@ return 0; } -static const struct serial_rs485 serial_omap_rs485_supported = { - .flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND | SER_RS485_RTS_AFTER_SEND | - SER_RS485_RX_DURING_TX, - .delay_rts_before_send = 1, - .delay_rts_after_send = 1, -}; - static int serial_omap_probe(struct platform_device *pdev) { struct omap_uart_port_info *omap_up_info = dev_get_platdata(&pdev->dev); @@ -1612,17 +1615,11 @@ dev_info(up->port.dev, "no wakeirq for uart%d\n", up->port.line); - ret = serial_omap_probe_rs485(up, &pdev->dev); - if (ret < 0) - goto err_rs485; - sprintf(up->name, "OMAP UART%d", up->port.line); up->port.mapbase = mem->start; up->port.membase = base; up->port.flags = omap_up_info->flags; up->port.uartclk = omap_up_info->uartclk; - up->port.rs485_config = serial_omap_config_rs485; - up->port.rs485_supported = serial_omap_rs485_supported; if (!up->port.uartclk) { up->port.uartclk = DEFAULT_CLK_SPEED; dev_warn(&pdev->dev, @@ -1630,6 +1627,10 @@ DEFAULT_CLK_SPEED); } + ret = serial_omap_probe_rs485(up, &pdev->dev); + if (ret < 0) + goto err_rs485; + up->latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; up->calc_latency = PM_QOS_CPU_LATENCY_DEFAULT_VALUE; cpu_latency_qos_add_request(&up->pm_qos_request, up->latency); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/tty/serial/stm32-usart.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/serial/stm32-usart.c @@ -226,12 +226,6 @@ stm32_usart_clr_bits(port, ofs->cr1, BIT(cfg->uart_enable_bit)); - if (port->rs485_rx_during_tx_gpio) - gpiod_set_value_cansleep(port->rs485_rx_during_tx_gpio, - !!(rs485conf->flags & SER_RS485_RX_DURING_TX)); - else - rs485conf->flags |= SER_RS485_RX_DURING_TX; - if (rs485conf->flags & SER_RS485_ENABLED) { cr1 = readl_relaxed(port->membase + ofs->cr1); cr3 = readl_relaxed(port->membase + ofs->cr3); @@ -256,6 +250,8 @@ writel_relaxed(cr3, port->membase + ofs->cr3); writel_relaxed(cr1, port->membase + ofs->cr1); + + rs485conf->flags |= SER_RS485_RX_DURING_TX; } else { stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DEM | USART_CR3_DEP); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/tty/tty.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/tty.h @@ -63,7 +63,7 @@ void __stop_tty(struct tty_struct *tty); void __start_tty(struct tty_struct *tty); void tty_write_unlock(struct tty_struct *tty); -int tty_write_lock(struct tty_struct *tty, int ndelay); +int tty_write_lock(struct tty_struct *tty, bool ndelay); void tty_vhangup_session(struct tty_struct *tty); void tty_open_proc_set_tty(struct file *filp, struct tty_struct *tty); int tty_signal_session_leader(struct tty_struct *tty, int exit_session); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/tty/tty_io.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/tty_io.c @@ -948,7 +948,7 @@ wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT); } -int tty_write_lock(struct tty_struct *tty, int ndelay) +int tty_write_lock(struct tty_struct *tty, bool ndelay) { if (!mutex_trylock(&tty->atomic_write_lock)) { if (ndelay) @@ -1162,7 +1162,7 @@ return 0; } - if (tty_write_lock(tty, 0) < 0) + if (tty_write_lock(tty, false) < 0) return -ERESTARTSYS; down_read(&tty->termios_rwsem); @@ -2485,22 +2485,25 @@ return 0; if (tty->driver->flags & TTY_DRIVER_HARDWARE_BREAK) - retval = tty->ops->break_ctl(tty, duration); - else { - /* Do the work ourselves */ - if (tty_write_lock(tty, 0) < 0) - return -EINTR; - retval = tty->ops->break_ctl(tty, -1); - if (retval) - goto out; - if (!signal_pending(current)) - msleep_interruptible(duration); + return tty->ops->break_ctl(tty, duration); + + /* Do the work ourselves */ + if (tty_write_lock(tty, false) < 0) + return -EINTR; + + retval = tty->ops->break_ctl(tty, -1); + if (!retval) { + msleep_interruptible(duration); retval = tty->ops->break_ctl(tty, 0); -out: - tty_write_unlock(tty); - if (signal_pending(current)) - retval = -EINTR; + } else if (retval == -EOPNOTSUPP) { + /* some drivers can tell only dynamically */ + retval = 0; } + tty_write_unlock(tty); + + if (signal_pending(current)) + retval = -EINTR; + return retval; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/tty/tty_ioctl.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/tty/tty_ioctl.c @@ -507,7 +507,7 @@ if (retval < 0) return retval; - if (tty_write_lock(tty, 0) < 0) + if (tty_write_lock(tty, false) < 0) goto retry_write_wait; /* Racing writer? */ @@ -860,7 +860,7 @@ ret = -EFAULT; return ret; case TIOCSLCKTRMIOS: - if (!capable(CAP_SYS_ADMIN)) + if (!checkpoint_restore_ns_capable(&init_user_ns)) return -EPERM; copy_termios_locked(real_tty, &kterm); if (user_termios_to_kernel_termios(&kterm, @@ -877,7 +877,7 @@ ret = -EFAULT; return ret; case TIOCSLCKTRMIOS: - if (!capable(CAP_SYS_ADMIN)) + if (!checkpoint_restore_ns_capable(&init_user_ns)) return -EPERM; copy_termios_locked(real_tty, &kterm); if (user_termios_to_kernel_termios_1(&kterm, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/usb/cdns3/cdns3-gadget.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/cdns3/cdns3-gadget.c @@ -1118,6 +1118,8 @@ dma_addr_t trb_dma; u32 togle_pcs = 1; int sg_iter = 0; + int num_trb_req; + int trb_burst; int num_trb; int address; u32 control; @@ -1126,15 +1128,13 @@ struct scatterlist *s = NULL; bool sg_supported = !!(request->num_mapped_sgs); + num_trb_req = sg_supported ? request->num_mapped_sgs : 1; + + /* ISO transfer require each SOF have a TD, each TD include some TRBs */ if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) - num_trb = priv_ep->interval; + num_trb = priv_ep->interval * num_trb_req; else - num_trb = sg_supported ? request->num_mapped_sgs : 1; - - if (num_trb > priv_ep->free_trbs) { - priv_ep->flags |= EP_RING_FULL; - return -ENOBUFS; - } + num_trb = num_trb_req; priv_req = to_cdns3_request(request); address = priv_ep->endpoint.desc->bEndpointAddress; @@ -1183,14 +1183,31 @@ link_trb->control = cpu_to_le32(((priv_ep->pcs) ? TRB_CYCLE : 0) | TRB_TYPE(TRB_LINK) | TRB_TOGGLE | ch_bit); + + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) { + /* + * ISO require LINK TRB must be first one of TD. + * Fill LINK TRBs for left trb space to simply software process logic. + */ + while (priv_ep->enqueue) { + *trb = *link_trb; + trace_cdns3_prepare_trb(priv_ep, trb); + + cdns3_ep_inc_enq(priv_ep); + trb = priv_ep->trb_pool + priv_ep->enqueue; + priv_req->trb = trb; + } + } + } + + if (num_trb > priv_ep->free_trbs) { + priv_ep->flags |= EP_RING_FULL; + return -ENOBUFS; } if (priv_dev->dev_ver <= DEV_VER_V2) togle_pcs = cdns3_wa1_update_guard(priv_ep, trb); - if (sg_supported) - s = request->sg; - /* set incorrect Cycle Bit for first trb*/ control = priv_ep->pcs ? 0 : TRB_CYCLE; trb->length = 0; @@ -1208,6 +1225,9 @@ do { u32 length; + if (!(sg_iter % num_trb_req) && sg_supported) + s = request->sg; + /* fill TRB */ control |= TRB_TYPE(TRB_NORMAL); if (sg_supported) { @@ -1222,7 +1242,36 @@ total_tdl += DIV_ROUND_UP(length, priv_ep->endpoint.maxpacket); - trb->length |= cpu_to_le32(TRB_BURST_LEN(priv_ep->trb_burst_size) | + trb_burst = priv_ep->trb_burst_size; + + /* + * Supposed DMA cross 4k bounder problem should be fixed at DEV_VER_V2, but still + * met problem when do ISO transfer if sg enabled. + * + * Data pattern likes below when sg enabled, package size is 1k and mult is 2 + * [UVC Header(8B) ] [data(3k - 8)] ... + * + * The received data at offset 0xd000 will get 0xc000 data, len 0x70. Error happen + * as below pattern: + * 0xd000: wrong + * 0xe000: wrong + * 0xf000: correct + * 0x10000: wrong + * 0x11000: wrong + * 0x12000: correct + * ... + * + * But it is still unclear about why error have not happen below 0xd000, it should + * cross 4k bounder. But anyway, the below code can fix this problem. + * + * To avoid DMA cross 4k bounder at ISO transfer, reduce burst len according to 16. + */ + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_dev->dev_ver <= DEV_VER_V2) + if (ALIGN_DOWN(trb->buffer, SZ_4K) != + ALIGN_DOWN(trb->buffer + length, SZ_4K)) + trb_burst = 16; + + trb->length |= cpu_to_le32(TRB_BURST_LEN(trb_burst) | TRB_LEN(length)); pcs = priv_ep->pcs ? TRB_CYCLE : 0; @@ -1249,7 +1298,7 @@ if (sg_supported) { trb->control |= cpu_to_le32(TRB_ISP); /* Don't set chain bit for last TRB */ - if (sg_iter < num_trb - 1) + if ((sg_iter % num_trb_req) < num_trb_req - 1) trb->control |= cpu_to_le32(TRB_CHAIN); s = sg_next(s); @@ -1507,6 +1556,12 @@ /* The TRB was changed as link TRB, and the request was handled at ep_dequeue */ while (TRB_FIELD_TO_TYPE(le32_to_cpu(trb->control)) == TRB_LINK) { + + /* ISO ep_traddr may stop at LINK TRB */ + if (priv_ep->dequeue == cdns3_get_dma_pos(priv_dev, priv_ep) && + priv_ep->type == USB_ENDPOINT_XFER_ISOC) + break; + trace_cdns3_complete_trb(priv_ep, trb); cdns3_ep_inc_deq(priv_ep); trb = priv_ep->trb_pool + priv_ep->dequeue; @@ -1539,6 +1594,10 @@ } if (request_handled) { + /* TRBs are duplicated by priv_ep->interval time for ISO IN */ + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && priv_ep->dir) + request->actual /= priv_ep->interval; + cdns3_gadget_giveback(priv_ep, priv_req, 0); request_handled = false; transfer_end = false; @@ -2034,11 +2093,10 @@ bool is_iso_ep = (priv_ep->type == USB_ENDPOINT_XFER_ISOC); struct cdns3_device *priv_dev = priv_ep->cdns3_dev; u32 bEndpointAddress = priv_ep->num | priv_ep->dir; - u32 max_packet_size = 0; - u8 maxburst = 0; + u32 max_packet_size = priv_ep->wMaxPacketSize; + u8 maxburst = priv_ep->bMaxBurst; u32 ep_cfg = 0; u8 buffering; - u8 mult = 0; int ret; buffering = priv_dev->ep_buf_size - 1; @@ -2060,8 +2118,7 @@ break; default: ep_cfg = EP_CFG_EPTYPE(USB_ENDPOINT_XFER_ISOC); - mult = priv_dev->ep_iso_burst - 1; - buffering = mult + 1; + buffering = (priv_ep->bMaxBurst + 1) * (priv_ep->mult + 1) - 1; } switch (priv_dev->gadget.speed) { @@ -2072,17 +2129,8 @@ max_packet_size = is_iso_ep ? 1024 : 512; break; case USB_SPEED_SUPER: - /* It's limitation that driver assumes in driver. */ - mult = 0; - max_packet_size = 1024; - if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) { - maxburst = priv_dev->ep_iso_burst - 1; - buffering = (mult + 1) * - (maxburst + 1); - - if (priv_ep->interval > 1) - buffering++; - } else { + if (priv_ep->type != USB_ENDPOINT_XFER_ISOC) { + max_packet_size = 1024; maxburst = priv_dev->ep_buf_size - 1; } break; @@ -2111,7 +2159,6 @@ if (priv_dev->dev_ver < DEV_VER_V2) priv_ep->trb_burst_size = 16; - mult = min_t(u8, mult, EP_CFG_MULT_MAX); buffering = min_t(u8, buffering, EP_CFG_BUFFERING_MAX); maxburst = min_t(u8, maxburst, EP_CFG_MAXBURST_MAX); @@ -2145,7 +2192,7 @@ } ep_cfg |= EP_CFG_MAXPKTSIZE(max_packet_size) | - EP_CFG_MULT(mult) | + EP_CFG_MULT(priv_ep->mult) | /* must match EP setting */ EP_CFG_BUFFERING(buffering) | EP_CFG_MAXBURST(maxburst); @@ -2235,6 +2282,13 @@ priv_ep->type = usb_endpoint_type(desc); priv_ep->flags |= EP_CLAIMED; priv_ep->interval = desc->bInterval ? BIT(desc->bInterval - 1) : 0; + priv_ep->wMaxPacketSize = usb_endpoint_maxp(desc); + priv_ep->mult = USB_EP_MAXP_MULT(priv_ep->wMaxPacketSize); + priv_ep->wMaxPacketSize &= USB_ENDPOINT_MAXP_MASK; + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC && comp_desc) { + priv_ep->mult = USB_SS_MULT(comp_desc->bmAttributes) - 1; + priv_ep->bMaxBurst = comp_desc->bMaxBurst; + } spin_unlock_irqrestore(&priv_dev->lock, flags); return &priv_ep->endpoint; @@ -3018,22 +3072,40 @@ struct cdns3_endpoint *priv_ep; struct usb_ep *ep; int n_in = 0; + int iso = 0; + int out = 1; int total; + int n; list_for_each_entry(ep, &gadget->ep_list, ep_list) { priv_ep = ep_to_cdns3_ep(ep); - if ((priv_ep->flags & EP_CLAIMED) && (ep->address & USB_DIR_IN)) - n_in++; + if (!(priv_ep->flags & EP_CLAIMED)) + continue; + + n = (priv_ep->mult + 1) * (priv_ep->bMaxBurst + 1); + if (ep->address & USB_DIR_IN) { + /* + * ISO transfer: DMA start move data when get ISO, only transfer + * data as min(TD size, iso). No benefit for allocate bigger + * internal memory than 'iso'. + */ + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) + iso += n; + else + n_in++; + } else { + if (priv_ep->type == USB_ENDPOINT_XFER_ISOC) + out = max_t(int, out, n); + } } /* 2KB are reserved for EP0, 1KB for out*/ - total = 2 + n_in + 1; + total = 2 + n_in + out + iso; if (total > priv_dev->onchip_buffers) return -ENOMEM; - priv_dev->ep_buf_size = priv_dev->ep_iso_burst = - (priv_dev->onchip_buffers - 2) / (n_in + 1); + priv_dev->ep_buf_size = (priv_dev->onchip_buffers - 2 - iso) / (n_in + out); return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/usb/cdns3/cdns3-gadget.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/cdns3/cdns3-gadget.h @@ -1168,6 +1168,9 @@ u8 dir; u8 num; u8 type; + u8 mult; + u8 bMaxBurst; + u16 wMaxPacketSize; int interval; int free_trbs; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/usb/dwc3/ep0.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/dwc3/ep0.c @@ -238,7 +238,10 @@ struct dwc3_request *req; req = next_request(&dep->pending_list); - dwc3_gadget_giveback(dep, req, -ECONNRESET); + if (!dwc->connected) + dwc3_gadget_giveback(dep, req, -ESHUTDOWN); + else + dwc3_gadget_giveback(dep, req, -ECONNRESET); } dwc->eps[0]->trb_enqueue = 0; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/usb/dwc3/gadget.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/dwc3/gadget.c @@ -2103,7 +2103,17 @@ list_for_each_entry(r, &dep->pending_list, list) { if (r == req) { - dwc3_gadget_giveback(dep, req, -ECONNRESET); + /* + * Explicitly check for EP0/1 as dequeue for those + * EPs need to be handled differently. Control EP + * only deals with one USB req, and giveback will + * occur during dwc3_ep0_stall_and_restart(). EP0 + * requests are never added to started_list. + */ + if (dep->number > 1) + dwc3_gadget_giveback(dep, req, -ECONNRESET); + else + dwc3_ep0_reset_state(dwc); goto out; } } @@ -3973,6 +3983,13 @@ usb_gadget_set_state(dwc->gadget, USB_STATE_NOTATTACHED); dwc3_ep0_reset_state(dwc); + + /* + * Request PM idle to address condition where usage count is + * already decremented to zero, but waiting for the disconnect + * interrupt to set dwc->connected to FALSE. + */ + pm_request_idle(dwc->dev); } static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/usb/gadget/function/f_uvc.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/gadget/function/f_uvc.c @@ -960,7 +960,8 @@ struct uvc_device *uvc = to_uvc(f); struct f_uvc_opts *opts = container_of(f->fi, struct f_uvc_opts, func_inst); - config_item_put(&uvc->header->item); + if (!opts->header) + config_item_put(&uvc->header->item); --opts->refcnt; kfree(uvc); } @@ -1052,25 +1053,29 @@ uvc->desc.hs_streaming = opts->hs_streaming; uvc->desc.ss_streaming = opts->ss_streaming; - streaming = config_group_find_item(&opts->func_inst.group, "streaming"); - if (!streaming) - goto err_config; - - header = config_group_find_item(to_config_group(streaming), "header"); - config_item_put(streaming); - if (!header) - goto err_config; - - h = config_group_find_item(to_config_group(header), "h"); - config_item_put(header); - if (!h) - goto err_config; - - uvc->header = to_uvcg_streaming_header(h); - if (!uvc->header->linked) { - mutex_unlock(&opts->lock); - kfree(uvc); - return ERR_PTR(-EBUSY); + if (opts->header) { + uvc->header = opts->header; + } else { + streaming = config_group_find_item(&opts->func_inst.group, "streaming"); + if (!streaming) + goto err_config; + + header = config_group_find_item(to_config_group(streaming), "header"); + config_item_put(streaming); + if (!header) + goto err_config; + + h = config_group_find_item(to_config_group(header), "h"); + config_item_put(header); + if (!h) + goto err_config; + + uvc->header = to_uvcg_streaming_header(h); + if (!uvc->header->linked) { + mutex_unlock(&opts->lock); + kfree(uvc); + return ERR_PTR(-EBUSY); + } } uvc->desc.extension_units = &opts->extension_units; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/usb/gadget/function/u_uvc.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/gadget/function/u_uvc.h @@ -98,6 +98,12 @@ */ struct mutex lock; int refcnt; + + /* + * Only for legacy gadget. Shall be NULL for configfs-composed gadgets, + * which is guaranteed by alloc_inst implementation of f_uvc doing kzalloc. + */ + struct uvcg_streaming_header *header; }; #endif /* U_UVC_H */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/usb/gadget/legacy/webcam.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/gadget/legacy/webcam.c @@ -12,6 +12,7 @@ #include #include "u_uvc.h" +#include "uvc_configfs.h" USB_GADGET_COMPOSITE_OPTIONS(); @@ -84,8 +85,6 @@ .bNumConfigurations = 0, /* dynamic */ }; -DECLARE_UVC_HEADER_DESCRIPTOR(1); - static const struct UVC_HEADER_DESCRIPTOR(1) uvc_control_header = { .bLength = UVC_DT_HEADER_SIZE(1), .bDescriptorType = USB_DT_CS_INTERFACE, @@ -158,43 +157,112 @@ .bmaControls[1][0] = 4, }; -static const struct uvc_format_uncompressed uvc_format_yuv = { - .bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED, - .bFormatIndex = 1, - .bNumFrameDescriptors = 2, - .guidFormat = - { 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, - 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}, - .bBitsPerPixel = 16, - .bDefaultFrameIndex = 1, - .bAspectRatioX = 0, - .bAspectRatioY = 0, - .bmInterlaceFlags = 0, - .bCopyProtect = 0, +static const struct uvcg_color_matching uvcg_color_matching = { + .desc = { + .bLength = UVC_DT_COLOR_MATCHING_SIZE, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = UVC_VS_COLORFORMAT, + .bColorPrimaries = 1, + .bTransferCharacteristics = 1, + .bMatrixCoefficients = 4, + }, +}; + +static struct uvcg_uncompressed uvcg_format_yuv = { + .fmt = { + .type = UVCG_UNCOMPRESSED, + /* add to .frames and fill .num_frames at runtime */ + .color_matching = (struct uvcg_color_matching *)&uvcg_color_matching, + }, + .desc = { + .bLength = UVC_DT_FORMAT_UNCOMPRESSED_SIZE, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = UVC_VS_FORMAT_UNCOMPRESSED, + .bFormatIndex = 1, + .bNumFrameDescriptors = 2, + .guidFormat = { + 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 + }, + .bBitsPerPixel = 16, + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, + .bmInterlaceFlags = 0, + .bCopyProtect = 0, + }, +}; + +static struct uvcg_format_ptr uvcg_format_ptr_yuv = { + .fmt = &uvcg_format_yuv.fmt, }; DECLARE_UVC_FRAME_UNCOMPRESSED(1); DECLARE_UVC_FRAME_UNCOMPRESSED(3); +#define UVCG_WIDTH_360P 640 +#define UVCG_HEIGHT_360P 360 +#define UVCG_MIN_BITRATE_360P 18432000 +#define UVCG_MAX_BITRATE_360P 55296000 +#define UVCG_MAX_VIDEO_FB_SZ_360P 460800 +#define UVCG_FRM_INTERV_0_360P 666666 +#define UVCG_FRM_INTERV_1_360P 1000000 +#define UVCG_FRM_INTERV_2_360P 5000000 +#define UVCG_DEFAULT_FRM_INTERV_360P UVCG_FRM_INTERV_0_360P + static const struct UVC_FRAME_UNCOMPRESSED(3) uvc_frame_yuv_360p = { .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3), .bDescriptorType = USB_DT_CS_INTERFACE, .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, .bFrameIndex = 1, .bmCapabilities = 0, - .wWidth = cpu_to_le16(640), - .wHeight = cpu_to_le16(360), - .dwMinBitRate = cpu_to_le32(18432000), - .dwMaxBitRate = cpu_to_le32(55296000), - .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), - .dwDefaultFrameInterval = cpu_to_le32(666666), + .wWidth = cpu_to_le16(UVCG_WIDTH_360P), + .wHeight = cpu_to_le16(UVCG_HEIGHT_360P), + .dwMinBitRate = cpu_to_le32(UVCG_MIN_BITRATE_360P), + .dwMaxBitRate = cpu_to_le32(UVCG_MAX_BITRATE_360P), + .dwMaxVideoFrameBufferSize = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_360P), + .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_360P), .bFrameIntervalType = 3, - .dwFrameInterval[0] = cpu_to_le32(666666), - .dwFrameInterval[1] = cpu_to_le32(1000000), - .dwFrameInterval[2] = cpu_to_le32(5000000), -}; + .dwFrameInterval[0] = cpu_to_le32(UVCG_FRM_INTERV_0_360P), + .dwFrameInterval[1] = cpu_to_le32(UVCG_FRM_INTERV_1_360P), + .dwFrameInterval[2] = cpu_to_le32(UVCG_FRM_INTERV_2_360P), +}; + +static u32 uvcg_frame_yuv_360p_dw_frame_interval[] = { + [0] = UVCG_FRM_INTERV_0_360P, + [1] = UVCG_FRM_INTERV_1_360P, + [2] = UVCG_FRM_INTERV_2_360P, +}; + +static const struct uvcg_frame uvcg_frame_yuv_360p = { + .fmt_type = UVCG_UNCOMPRESSED, + .frame = { + .b_length = UVC_DT_FRAME_UNCOMPRESSED_SIZE(3), + .b_descriptor_type = USB_DT_CS_INTERFACE, + .b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED, + .b_frame_index = 1, + .bm_capabilities = 0, + .w_width = UVCG_WIDTH_360P, + .w_height = UVCG_HEIGHT_360P, + .dw_min_bit_rate = UVCG_MIN_BITRATE_360P, + .dw_max_bit_rate = UVCG_MAX_BITRATE_360P, + .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_360P, + .dw_default_frame_interval = UVCG_DEFAULT_FRM_INTERV_360P, + .b_frame_interval_type = 3, + }, + .dw_frame_interval = uvcg_frame_yuv_360p_dw_frame_interval, +}; + +static struct uvcg_frame_ptr uvcg_frame_ptr_yuv_360p = { + .frm = (struct uvcg_frame *)&uvcg_frame_yuv_360p, +}; +#define UVCG_WIDTH_720P 1280 +#define UVCG_HEIGHT_720P 720 +#define UVCG_MIN_BITRATE_720P 29491200 +#define UVCG_MAX_BITRATE_720P 29491200 +#define UVCG_MAX_VIDEO_FB_SZ_720P 1843200 +#define UVCG_FRM_INTERV_0_720P 5000000 +#define UVCG_DEFAULT_FRM_INTERV_720P UVCG_FRM_INTERV_0_720P static const struct UVC_FRAME_UNCOMPRESSED(1) uvc_frame_yuv_720p = { .bLength = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), @@ -202,28 +270,66 @@ .bDescriptorSubType = UVC_VS_FRAME_UNCOMPRESSED, .bFrameIndex = 2, .bmCapabilities = 0, - .wWidth = cpu_to_le16(1280), - .wHeight = cpu_to_le16(720), - .dwMinBitRate = cpu_to_le32(29491200), - .dwMaxBitRate = cpu_to_le32(29491200), - .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), - .dwDefaultFrameInterval = cpu_to_le32(5000000), + .wWidth = cpu_to_le16(UVCG_WIDTH_720P), + .wHeight = cpu_to_le16(UVCG_HEIGHT_720P), + .dwMinBitRate = cpu_to_le32(UVCG_MIN_BITRATE_720P), + .dwMaxBitRate = cpu_to_le32(UVCG_MAX_BITRATE_720P), + .dwMaxVideoFrameBufferSize = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_720P), + .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_720P), .bFrameIntervalType = 1, - .dwFrameInterval[0] = cpu_to_le32(5000000), + .dwFrameInterval[0] = cpu_to_le32(UVCG_FRM_INTERV_0_720P), }; -static const struct uvc_format_mjpeg uvc_format_mjpg = { - .bLength = UVC_DT_FORMAT_MJPEG_SIZE, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = UVC_VS_FORMAT_MJPEG, - .bFormatIndex = 2, - .bNumFrameDescriptors = 2, - .bmFlags = 0, - .bDefaultFrameIndex = 1, - .bAspectRatioX = 0, - .bAspectRatioY = 0, - .bmInterlaceFlags = 0, - .bCopyProtect = 0, +static u32 uvcg_frame_yuv_720p_dw_frame_interval[] = { + [0] = UVCG_FRM_INTERV_0_720P, +}; + +static const struct uvcg_frame uvcg_frame_yuv_720p = { + .fmt_type = UVCG_UNCOMPRESSED, + .frame = { + .b_length = UVC_DT_FRAME_UNCOMPRESSED_SIZE(1), + .b_descriptor_type = USB_DT_CS_INTERFACE, + .b_descriptor_subtype = UVC_VS_FRAME_UNCOMPRESSED, + .b_frame_index = 2, + .bm_capabilities = 0, + .w_width = UVCG_WIDTH_720P, + .w_height = UVCG_HEIGHT_720P, + .dw_min_bit_rate = UVCG_MIN_BITRATE_720P, + .dw_max_bit_rate = UVCG_MAX_BITRATE_720P, + .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_720P, + .dw_default_frame_interval = UVCG_DEFAULT_FRM_INTERV_720P, + .b_frame_interval_type = 1, + }, + .dw_frame_interval = uvcg_frame_yuv_720p_dw_frame_interval, +}; + +static struct uvcg_frame_ptr uvcg_frame_ptr_yuv_720p = { + .frm = (struct uvcg_frame *)&uvcg_frame_yuv_720p, +}; + +static struct uvcg_mjpeg uvcg_format_mjpeg = { + .fmt = { + .type = UVCG_MJPEG, + /* add to .frames and fill .num_frames at runtime */ + .color_matching = (struct uvcg_color_matching *)&uvcg_color_matching, + }, + .desc = { + .bLength = UVC_DT_FORMAT_MJPEG_SIZE, + .bDescriptorType = USB_DT_CS_INTERFACE, + .bDescriptorSubType = UVC_VS_FORMAT_MJPEG, + .bFormatIndex = 2, + .bNumFrameDescriptors = 2, + .bmFlags = 0, + .bDefaultFrameIndex = 1, + .bAspectRatioX = 0, + .bAspectRatioY = 0, + .bmInterlaceFlags = 0, + .bCopyProtect = 0, + }, +}; + +static struct uvcg_format_ptr uvcg_format_ptr_mjpeg = { + .fmt = &uvcg_format_mjpeg.fmt, }; DECLARE_UVC_FRAME_MJPEG(1); @@ -235,16 +341,45 @@ .bDescriptorSubType = UVC_VS_FRAME_MJPEG, .bFrameIndex = 1, .bmCapabilities = 0, - .wWidth = cpu_to_le16(640), - .wHeight = cpu_to_le16(360), - .dwMinBitRate = cpu_to_le32(18432000), - .dwMaxBitRate = cpu_to_le32(55296000), - .dwMaxVideoFrameBufferSize = cpu_to_le32(460800), - .dwDefaultFrameInterval = cpu_to_le32(666666), + .wWidth = cpu_to_le16(UVCG_WIDTH_360P), + .wHeight = cpu_to_le16(UVCG_HEIGHT_360P), + .dwMinBitRate = cpu_to_le32(UVCG_MIN_BITRATE_360P), + .dwMaxBitRate = cpu_to_le32(UVCG_MAX_BITRATE_360P), + .dwMaxVideoFrameBufferSize = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_360P), + .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_360P), .bFrameIntervalType = 3, - .dwFrameInterval[0] = cpu_to_le32(666666), - .dwFrameInterval[1] = cpu_to_le32(1000000), - .dwFrameInterval[2] = cpu_to_le32(5000000), + .dwFrameInterval[0] = cpu_to_le32(UVCG_FRM_INTERV_0_360P), + .dwFrameInterval[1] = cpu_to_le32(UVCG_FRM_INTERV_1_360P), + .dwFrameInterval[2] = cpu_to_le32(UVCG_FRM_INTERV_2_360P), +}; + +static u32 uvcg_frame_mjpeg_360p_dw_frame_interval[] = { + [0] = UVCG_FRM_INTERV_0_360P, + [1] = UVCG_FRM_INTERV_1_360P, + [2] = UVCG_FRM_INTERV_2_360P, +}; + +static const struct uvcg_frame uvcg_frame_mjpeg_360p = { + .fmt_type = UVCG_MJPEG, + .frame = { + .b_length = UVC_DT_FRAME_MJPEG_SIZE(3), + .b_descriptor_type = USB_DT_CS_INTERFACE, + .b_descriptor_subtype = UVC_VS_FRAME_MJPEG, + .b_frame_index = 1, + .bm_capabilities = 0, + .w_width = UVCG_WIDTH_360P, + .w_height = UVCG_HEIGHT_360P, + .dw_min_bit_rate = UVCG_MIN_BITRATE_360P, + .dw_max_bit_rate = UVCG_MAX_BITRATE_360P, + .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_360P, + .dw_default_frame_interval = UVCG_DEFAULT_FRM_INTERV_360P, + .b_frame_interval_type = 3, + }, + .dw_frame_interval = uvcg_frame_mjpeg_360p_dw_frame_interval, +}; + +static struct uvcg_frame_ptr uvcg_frame_ptr_mjpeg_360p = { + .frm = (struct uvcg_frame *)&uvcg_frame_mjpeg_360p, }; static const struct UVC_FRAME_MJPEG(1) uvc_frame_mjpg_720p = { @@ -253,23 +388,44 @@ .bDescriptorSubType = UVC_VS_FRAME_MJPEG, .bFrameIndex = 2, .bmCapabilities = 0, - .wWidth = cpu_to_le16(1280), - .wHeight = cpu_to_le16(720), - .dwMinBitRate = cpu_to_le32(29491200), - .dwMaxBitRate = cpu_to_le32(29491200), - .dwMaxVideoFrameBufferSize = cpu_to_le32(1843200), - .dwDefaultFrameInterval = cpu_to_le32(5000000), + .wWidth = cpu_to_le16(UVCG_WIDTH_720P), + .wHeight = cpu_to_le16(UVCG_HEIGHT_720P), + .dwMinBitRate = cpu_to_le32(UVCG_MIN_BITRATE_720P), + .dwMaxBitRate = cpu_to_le32(UVCG_MAX_BITRATE_720P), + .dwMaxVideoFrameBufferSize = cpu_to_le32(UVCG_MAX_VIDEO_FB_SZ_720P), + .dwDefaultFrameInterval = cpu_to_le32(UVCG_DEFAULT_FRM_INTERV_720P), .bFrameIntervalType = 1, - .dwFrameInterval[0] = cpu_to_le32(5000000), + .dwFrameInterval[0] = cpu_to_le32(UVCG_FRM_INTERV_0_720P), }; -static const struct uvc_color_matching_descriptor uvc_color_matching = { - .bLength = UVC_DT_COLOR_MATCHING_SIZE, - .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubType = UVC_VS_COLORFORMAT, - .bColorPrimaries = 1, - .bTransferCharacteristics = 1, - .bMatrixCoefficients = 4, +static u32 uvcg_frame_mjpeg_720p_dw_frame_interval[] = { + [0] = UVCG_FRM_INTERV_0_720P, +}; + +static const struct uvcg_frame uvcg_frame_mjpeg_720p = { + .fmt_type = UVCG_MJPEG, + .frame = { + .b_length = UVC_DT_FRAME_MJPEG_SIZE(1), + .b_descriptor_type = USB_DT_CS_INTERFACE, + .b_descriptor_subtype = UVC_VS_FRAME_MJPEG, + .b_frame_index = 2, + .bm_capabilities = 0, + .w_width = UVCG_WIDTH_720P, + .w_height = UVCG_HEIGHT_720P, + .dw_min_bit_rate = UVCG_MIN_BITRATE_720P, + .dw_max_bit_rate = UVCG_MAX_BITRATE_720P, + .dw_max_video_frame_buffer_size = UVCG_MAX_VIDEO_FB_SZ_720P, + .dw_default_frame_interval = UVCG_DEFAULT_FRM_INTERV_720P, + .b_frame_interval_type = 1, + }, + .dw_frame_interval = uvcg_frame_mjpeg_720p_dw_frame_interval, +}; + +static struct uvcg_frame_ptr uvcg_frame_ptr_mjpeg_720p = { + .frm = (struct uvcg_frame *)&uvcg_frame_mjpeg_720p, +}; + +static struct uvcg_streaming_header uvcg_streaming_header = { }; static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = { @@ -290,40 +446,40 @@ static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = { (const struct uvc_descriptor_header *) &uvc_input_header, - (const struct uvc_descriptor_header *) &uvc_format_yuv, + (const struct uvc_descriptor_header *) &uvcg_format_yuv.desc, (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, - (const struct uvc_descriptor_header *) &uvc_color_matching, - (const struct uvc_descriptor_header *) &uvc_format_mjpg, + (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, + (const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, - (const struct uvc_descriptor_header *) &uvc_color_matching, + (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, NULL, }; static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = { (const struct uvc_descriptor_header *) &uvc_input_header, - (const struct uvc_descriptor_header *) &uvc_format_yuv, + (const struct uvc_descriptor_header *) &uvcg_format_yuv.desc, (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, - (const struct uvc_descriptor_header *) &uvc_color_matching, - (const struct uvc_descriptor_header *) &uvc_format_mjpg, + (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, + (const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, - (const struct uvc_descriptor_header *) &uvc_color_matching, + (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, NULL, }; static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = { (const struct uvc_descriptor_header *) &uvc_input_header, - (const struct uvc_descriptor_header *) &uvc_format_yuv, + (const struct uvc_descriptor_header *) &uvcg_format_yuv.desc, (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, - (const struct uvc_descriptor_header *) &uvc_color_matching, - (const struct uvc_descriptor_header *) &uvc_format_mjpg, + (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, + (const struct uvc_descriptor_header *) &uvcg_format_mjpeg.desc, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, - (const struct uvc_descriptor_header *) &uvc_color_matching, + (const struct uvc_descriptor_header *) &uvcg_color_matching.desc, NULL, }; @@ -387,6 +543,23 @@ uvc_opts->hs_streaming = uvc_hs_streaming_cls; uvc_opts->ss_streaming = uvc_ss_streaming_cls; + INIT_LIST_HEAD(&uvcg_format_yuv.fmt.frames); + list_add_tail(&uvcg_frame_ptr_yuv_360p.entry, &uvcg_format_yuv.fmt.frames); + list_add_tail(&uvcg_frame_ptr_yuv_720p.entry, &uvcg_format_yuv.fmt.frames); + uvcg_format_yuv.fmt.num_frames = 2; + + INIT_LIST_HEAD(&uvcg_format_mjpeg.fmt.frames); + list_add_tail(&uvcg_frame_ptr_mjpeg_360p.entry, &uvcg_format_mjpeg.fmt.frames); + list_add_tail(&uvcg_frame_ptr_mjpeg_720p.entry, &uvcg_format_mjpeg.fmt.frames); + uvcg_format_mjpeg.fmt.num_frames = 2; + + INIT_LIST_HEAD(&uvcg_streaming_header.formats); + list_add_tail(&uvcg_format_ptr_yuv.entry, &uvcg_streaming_header.formats); + list_add_tail(&uvcg_format_ptr_mjpeg.entry, &uvcg_streaming_header.formats); + uvcg_streaming_header.num_fmt = 2; + + uvc_opts->header = &uvcg_streaming_header; + /* Allocate string descriptor numbers ... note that string contents * can be overridden by the composite_dev glue. */ only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/usb/host/xhci-mtk.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/host/xhci-mtk.c @@ -7,6 +7,7 @@ * Chunfeng Yun */ +#include #include #include #include @@ -73,6 +74,9 @@ #define FRMCNT_LEV1_RANG (0x12b << 8) #define FRMCNT_LEV1_RANG_MASK GENMASK(19, 8) +#define HSCH_CFG1 0x960 +#define SCH3_RXFIFO_DEPTH_MASK GENMASK(21, 20) + #define SS_GEN2_EOF_CFG 0x990 #define SSG2EOF_OFFSET 0x3c @@ -114,6 +118,8 @@ #define SSC_IP_SLEEP_EN BIT(4) #define SSC_SPM_INT_EN BIT(1) +#define SCH_FIFO_TO_KB(x) ((x) >> 10) + enum ssusb_uwk_vers { SSUSB_UWK_V1 = 1, SSUSB_UWK_V2, @@ -165,6 +171,35 @@ writel(value, hcd->regs + SS_GEN2_EOF_CFG); } +/* + * workaround: usb3.2 gen1 isoc rx hw issue + * host send out unexpected ACK afer device fininsh a burst transfer with + * a short packet. + */ +static void xhci_mtk_rxfifo_depth_set(struct xhci_hcd_mtk *mtk) +{ + struct usb_hcd *hcd = mtk->hcd; + u32 value; + + if (!mtk->rxfifo_depth) + return; + + value = readl(hcd->regs + HSCH_CFG1); + value &= ~SCH3_RXFIFO_DEPTH_MASK; + value |= FIELD_PREP(SCH3_RXFIFO_DEPTH_MASK, + SCH_FIFO_TO_KB(mtk->rxfifo_depth) - 1); + writel(value, hcd->regs + HSCH_CFG1); +} + +static void xhci_mtk_init_quirk(struct xhci_hcd_mtk *mtk) +{ + /* workaround only for mt8195 */ + xhci_mtk_set_frame_interval(mtk); + + /* workaround for SoCs using SSUSB about before IPM v1.6.0 */ + xhci_mtk_rxfifo_depth_set(mtk); +} + static int xhci_mtk_host_enable(struct xhci_hcd_mtk *mtk) { struct mu3c_ippc_regs __iomem *ippc = mtk->ippc_regs; @@ -448,8 +483,7 @@ if (ret) return ret; - /* workaround only for mt8195 */ - xhci_mtk_set_frame_interval(mtk); + xhci_mtk_init_quirk(mtk); } ret = xhci_gen_setup(hcd, xhci_mtk_quirks); @@ -527,6 +561,8 @@ of_property_read_u32(node, "mediatek,u2p-dis-msk", &mtk->u2p_dis_msk); + of_property_read_u32(node, "rx-fifo-depth", &mtk->rxfifo_depth); + ret = usb_wakeup_of_property_parse(mtk, node); if (ret) { dev_err(dev, "failed to parse uwk property\n"); only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/usb/host/xhci-mtk.h +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/host/xhci-mtk.h @@ -160,6 +160,8 @@ struct regmap *uwk; u32 uwk_reg_base; u32 uwk_vers; + /* quirk */ + u32 rxfifo_depth; }; static inline struct xhci_hcd_mtk *hcd_to_mtk(struct usb_hcd *hcd) only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/usb/mon/mon_bin.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/usb/mon/mon_bin.c @@ -1250,14 +1250,19 @@ struct mon_reader_bin *rp = vmf->vma->vm_private_data; unsigned long offset, chunk_idx; struct page *pageptr; + unsigned long flags; + spin_lock_irqsave(&rp->b_lock, flags); offset = vmf->pgoff << PAGE_SHIFT; - if (offset >= rp->b_size) + if (offset >= rp->b_size) { + spin_unlock_irqrestore(&rp->b_lock, flags); return VM_FAULT_SIGBUS; + } chunk_idx = offset / CHUNK_SIZE; pageptr = rp->b_vec[chunk_idx].pg; get_page(pageptr); vmf->page = pageptr; + spin_unlock_irqrestore(&rp->b_lock, flags); return 0; } only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/vdpa/alibaba/eni_vdpa.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/vdpa/alibaba/eni_vdpa.c @@ -497,7 +497,7 @@ if (!eni_vdpa->vring) { ret = -ENOMEM; ENI_ERR(pdev, "failed to allocate virtqueues\n"); - goto err; + goto err_remove_vp_legacy; } for (i = 0; i < eni_vdpa->queues; i++) { @@ -509,11 +509,13 @@ ret = vdpa_register_device(&eni_vdpa->vdpa, eni_vdpa->queues); if (ret) { ENI_ERR(pdev, "failed to register to vdpa bus\n"); - goto err; + goto err_remove_vp_legacy; } return 0; +err_remove_vp_legacy: + vp_legacy_remove(&eni_vdpa->ldev); err: put_device(&eni_vdpa->vdpa.dev); return ret; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -694,6 +694,7 @@ size_t len, loff_t *pos) { struct hisi_acc_vf_migration_file *migf = filp->private_data; + u8 *vf_data = (u8 *)&migf->vf_data; loff_t requested_length; ssize_t done = 0; int ret; @@ -715,7 +716,7 @@ goto out_unlock; } - ret = copy_from_user(&migf->vf_data, buf, len); + ret = copy_from_user(vf_data + *pos, buf, len); if (ret) { done = -EFAULT; goto out_unlock; @@ -835,7 +836,9 @@ len = min_t(size_t, migf->total_length - *pos, len); if (len) { - ret = copy_to_user(buf, &migf->vf_data, len); + u8 *vf_data = (u8 *)&migf->vf_data; + + ret = copy_to_user(buf, vf_data + *pos, len); if (ret) { done = -EFAULT; goto out_unlock; only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/vhost/vsock.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/vhost/vsock.c @@ -438,6 +438,7 @@ .notify_send_pre_enqueue = virtio_transport_notify_send_pre_enqueue, .notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue, .notify_buffer_size = virtio_transport_notify_buffer_size, + .notify_set_rcvlowat = virtio_transport_notify_set_rcvlowat, .read_skb = virtio_transport_read_skb, }, only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/video/fbdev/core/fb_defio.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/video/fbdev/core/fb_defio.c @@ -132,11 +132,7 @@ return 0; inode_lock(inode); - /* Kill off the delayed work */ - cancel_delayed_work_sync(&info->deferred_work); - - /* Run it immediately */ - schedule_delayed_work(&info->deferred_work, 0); + flush_delayed_work(&info->deferred_work); inode_unlock(inode); return 0; @@ -317,7 +313,7 @@ struct page *page; int i; - cancel_delayed_work_sync(&info->deferred_work); + flush_delayed_work(&info->deferred_work); /* clear out the mapping that we setup */ for (i = 0 ; i < info->fix.smem_len; i += PAGE_SIZE) { only in patch2: unchanged: --- linux-lowlatency-hwe-6.5-6.5.0.orig/drivers/video/fbdev/imxfb.c +++ linux-lowlatency-hwe-6.5-6.5.0/drivers/video/fbdev/imxfb.c @@ -42,6 +42,7 @@ #include