diff -u linux-6.2.0/Documentation/admin-guide/cgroup-v1/memory.rst linux-6.2.0/Documentation/admin-guide/cgroup-v1/memory.rst --- linux-6.2.0/Documentation/admin-guide/cgroup-v1/memory.rst +++ linux-6.2.0/Documentation/admin-guide/cgroup-v1/memory.rst @@ -91,8 +91,13 @@ memory.oom_control set/show oom controls. memory.numa_stat show the number of memory usage per numa node - memory.kmem.limit_in_bytes This knob is deprecated and writing to - it will return -ENOTSUPP. + memory.kmem.limit_in_bytes Deprecated knob to set and read the kernel + memory hard limit. Kernel hard limit is not + supported since 5.16. Writing any value to + do file will not have any effect same as if + nokmem kernel parameter was specified. + Kernel memory is still charged and reported + by memory.kmem.usage_in_bytes. memory.kmem.usage_in_bytes show current kernel memory allocation memory.kmem.failcnt show the number of kernel memory usage hits limits diff -u linux-6.2.0/Documentation/arm64/silicon-errata.rst linux-6.2.0/Documentation/arm64/silicon-errata.rst --- linux-6.2.0/Documentation/arm64/silicon-errata.rst +++ linux-6.2.0/Documentation/arm64/silicon-errata.rst @@ -63,6 +63,8 @@ +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A510 | #1902691 | ARM64_ERRATUM_1902691 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A520 | #2966298 | ARM64_ERRATUM_2966298 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A53 | #826319 | ARM64_ERRATUM_826319 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A53 | #827319 | ARM64_ERRATUM_827319 | @@ -195,6 +197,9 @@ +----------------+-----------------+-----------------+-----------------------------+ | Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +| Hisilicon | Hip08 SMMU PMCG | #162001900 | N/A | +| | Hip09 SMMU PMCG | | | ++----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 | +----------------+-----------------+-----------------+-----------------------------+ diff -u linux-6.2.0/Documentation/networking/ip-sysctl.rst linux-6.2.0/Documentation/networking/ip-sysctl.rst --- linux-6.2.0/Documentation/networking/ip-sysctl.rst +++ linux-6.2.0/Documentation/networking/ip-sysctl.rst @@ -2250,6 +2250,14 @@ Default: 1 +accept_ra_min_lft - INTEGER + Minimum acceptable lifetime value in Router Advertisement. + + RA sections with a lifetime less than this value shall be + ignored. Zero lifetimes stay unaffected. + + Default: 0 + accept_ra_pinfo - BOOLEAN Learn Prefix Information in Router Advertisement. diff -u linux-6.2.0/Makefile linux-6.2.0/Makefile --- linux-6.2.0/Makefile +++ linux-6.2.0/Makefile @@ -1303,7 +1303,7 @@ # All the preparing.. prepare: prepare0 ifdef CONFIG_RUST - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh $(Q)$(MAKE) $(build)=rust endif @@ -1831,7 +1831,7 @@ # "Is Rust available?" target PHONY += rustavailable rustavailable: - $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh -v && echo "Rust is available!" + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/rust_is_available.sh && echo "Rust is available!" # Documentation target # @@ -1953,7 +1953,9 @@ modules_install: $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst +ifndef modules_sign_only $(call cmd,depmod) +endif else # CONFIG_MODULES diff -u linux-6.2.0/arch/arm/boot/dts/qcom-ipq4019.dtsi linux-6.2.0/arch/arm/boot/dts/qcom-ipq4019.dtsi --- linux-6.2.0/arch/arm/boot/dts/qcom-ipq4019.dtsi +++ linux-6.2.0/arch/arm/boot/dts/qcom-ipq4019.dtsi @@ -228,9 +228,12 @@ interrupts = , ; interrupt-names = "hc_irq", "pwr_irq"; bus-width = <8>; - clocks = <&gcc GCC_SDCC1_AHB_CLK>, <&gcc GCC_SDCC1_APPS_CLK>, - <&gcc GCC_DCD_XO_CLK>; - clock-names = "iface", "core", "xo"; + clocks = <&gcc GCC_SDCC1_AHB_CLK>, + <&gcc GCC_SDCC1_APPS_CLK>, + <&xo>; + clock-names = "iface", + "core", + "xo"; status = "disabled"; }; diff -u linux-6.2.0/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi linux-6.2.0/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi --- linux-6.2.0/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi +++ linux-6.2.0/arch/arm/boot/dts/stm32mp15xx-dhcor-avenger96.dtsi @@ -111,17 +111,39 @@ vdda-supply = <&vdda>; vref-supply = <&vdda>; status = "okay"; +}; + +&adc1 { + channel@0 { + reg = <0>; + st,min-sample-time-ns = <5000>; + }; + + channel@1 { + reg = <1>; + st,min-sample-time-ns = <5000>; + }; + + channel@6 { + reg = <6>; + st,min-sample-time-ns = <5000>; + }; +}; + +&adc2 { + channel@0 { + reg = <0>; + st,min-sample-time-ns = <5000>; + }; - adc1: adc@0 { - st,adc-channels = <0 1 6>; - st,min-sample-time-nsecs = <5000>; - status = "okay"; + channel@1 { + reg = <1>; + st,min-sample-time-ns = <5000>; }; - adc2: adc@100 { - st,adc-channels = <0 1 2>; - st,min-sample-time-nsecs = <5000>; - status = "okay"; + channel@2 { + reg = <2>; + st,min-sample-time-ns = <5000>; }; }; diff -u linux-6.2.0/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi linux-6.2.0/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi --- linux-6.2.0/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi +++ linux-6.2.0/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi @@ -227,8 +227,8 @@ &m4_rproc { memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, <&vdev0vring1>, <&vdev0buffer>; - mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; - mbox-names = "vq0", "vq1", "shutdown"; + mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>; + mbox-names = "vq0", "vq1", "shutdown", "detach"; interrupt-parent = <&exti>; interrupts = <68 1>; status = "okay"; diff -u linux-6.2.0/arch/arm64/Kconfig linux-6.2.0/arch/arm64/Kconfig --- linux-6.2.0/arch/arm64/Kconfig +++ linux-6.2.0/arch/arm64/Kconfig @@ -1005,6 +1005,19 @@ If unsure, say Y. +config ARM64_ERRATUM_2966298 + bool "Cortex-A520: 2966298: workaround for speculatively executed unprivileged load" + default y + help + This option adds the workaround for ARM Cortex-A520 erratum 2966298. + + On an affected Cortex-A520 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. + config CAVIUM_ERRATUM_22375 bool "Cavium erratum 22375, 24313" default y diff -u linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra194.dtsi linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra194.dtsi --- linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra194.dtsi @@ -259,7 +259,8 @@ clocks = <&bpmp TEGRA194_CLK_AHUB>; clock-names = "ahub"; assigned-clocks = <&bpmp TEGRA194_CLK_AHUB>; - assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLA_OUT0>; + assigned-clock-parents = <&bpmp TEGRA194_CLK_PLLP_OUT0>; + assigned-clock-rates = <81600000>; #address-cells = <1>; #size-cells = <1>; ranges = <0x02900800 0x02900800 0x11800>; diff -u linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra234.dtsi linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra234.dtsi --- linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra234.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra234.dtsi @@ -84,7 +84,8 @@ clocks = <&bpmp TEGRA234_CLK_AHUB>; clock-names = "ahub"; assigned-clocks = <&bpmp TEGRA234_CLK_AHUB>; - assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLA_OUT0>; + assigned-clock-parents = <&bpmp TEGRA234_CLK_PLLP_OUT0>; + assigned-clock-rates = <81600000>; #address-cells = <1>; #size-cells = <1>; ranges = <0x02900800 0x02900800 0x11800>; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/apq8016-sbc.dts linux-6.2.0/arch/arm64/boot/dts/qcom/apq8016-sbc.dts --- linux-6.2.0/arch/arm64/boot/dts/qcom/apq8016-sbc.dts +++ linux-6.2.0/arch/arm64/boot/dts/qcom/apq8016-sbc.dts @@ -289,9 +289,9 @@ clock-names = "xclk"; clock-frequency = <23880000>; - vdddo-supply = <&camera_vdddo_1v8>; - vdda-supply = <&camera_vdda_2v8>; - vddd-supply = <&camera_vddd_1v5>; + DOVDD-supply = <&camera_vdddo_1v8>; + AVDD-supply = <&camera_vdda_2v8>; + DVDD-supply = <&camera_vddd_1v5>; /* No camera mezzanine by default */ status = "disabled"; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/msm8996.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/msm8996.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/msm8996.dtsi @@ -1063,7 +1063,7 @@ reg-names = "dsi_ctrl"; interrupt-parent = <&mdss>; - interrupts = <4>; + interrupts = <5>; clocks = <&mmcc MDSS_MDP_CLK>, <&mmcc MDSS_BYTE1_CLK>, @@ -3317,6 +3317,9 @@ #size-cells = <1>; ranges; + interrupts = ; + interrupt-names = "hs_phy_irq"; + clocks = <&gcc GCC_PERIPH_NOC_USB20_AHB_CLK>, <&gcc GCC_USB20_MASTER_CLK>, <&gcc GCC_USB20_MOCK_UTMI_CLK>, diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/msm8998.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/msm8998.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/msm8998.dtsi @@ -2419,10 +2419,10 @@ clocks = <&mmcc MNOC_AHB_CLK>, <&mmcc BIMC_SMMU_AHB_CLK>, - <&rpmcc RPM_SMD_MMAXI_CLK>, <&mmcc BIMC_SMMU_AXI_CLK>; - clock-names = "iface-mm", "iface-smmu", - "bus-mm", "bus-smmu"; + clock-names = "iface-mm", + "iface-smmu", + "bus-smmu"; #global-interrupts = <0>; interrupts = @@ -2446,6 +2446,8 @@ , , ; + + power-domains = <&mmcc BIMC_SMMU_GDSC>; }; remoteproc_adsp: remoteproc@17300000 { diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/pmi8950.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/pmi8950.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/pmi8950.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/pmi8950.dtsi @@ -87,8 +87,9 @@ pmi8950_wled: leds@d800 { compatible = "qcom,pmi8950-wled"; reg = <0xd800>, <0xd900>; - interrupts = <0x3 0xd8 0x02 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "short"; + interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>, + <0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "ovp", "short"; label = "backlight"; status = "disabled"; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/pmi8994.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/pmi8994.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/pmi8994.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/pmi8994.dtsi @@ -54,8 +54,9 @@ pmi8994_wled: wled@d800 { compatible = "qcom,pmi8994-wled"; reg = <0xd800>, <0xd900>; - interrupts = <3 0xd8 0x02 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "short"; + interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>, + <0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "ovp", "short"; qcom,cabc; qcom,external-pfet; status = "disabled"; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/pmk8350.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/pmk8350.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/pmk8350.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/pmk8350.dtsi @@ -49,7 +49,7 @@ }; pmk8350_adc_tm: adc-tm@3400 { - compatible = "qcom,adc-tm7"; + compatible = "qcom,spmi-adc-tm5-gen2"; reg = <0x3400>; interrupts = ; #address-cells = <1>; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts linux-6.2.0/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts --- linux-6.2.0/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts @@ -703,7 +703,7 @@ }; &tlmm { - gpio-reserved-ranges = <70 2>, <74 6>, <83 4>, <125 2>, <128 2>, <154 7>; + gpio-reserved-ranges = <70 2>, <74 6>, <125 2>, <128 2>, <154 4>; hall_int_n_default: hall-int-n-state { pins = "gpio107"; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/sc8280xp.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/sc8280xp.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sc8280xp.dtsi @@ -448,6 +448,7 @@ firmware { scm: scm { compatible = "qcom,scm-sc8280xp", "qcom,scm"; + interconnects = <&aggre2_noc MASTER_CRYPTO 0 &mc_virt SLAVE_EBI1 0>; }; }; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/sdm845-db845c.dts linux-6.2.0/arch/arm64/boot/dts/qcom/sdm845-db845c.dts --- linux-6.2.0/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sdm845-db845c.dts @@ -100,6 +100,14 @@ }; }; + reserved-memory { + /* Cont splash region set up by the bootloader */ + cont_splash_mem: framebuffer@9d400000 { + reg = <0x0 0x9d400000 0x0 0x2400000>; + no-map; + }; + }; + lt9611_1v8: lt9611-vdd18-regulator { compatible = "regulator-fixed"; regulator-name = "LT9611_1V8"; @@ -518,6 +526,7 @@ }; &mdss { + memory-region = <&cont_splash_mem>; status = "okay"; }; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/sdm845.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/sdm845.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -1099,6 +1099,7 @@ #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + power-domains = <&rpmhpd SDM845_CX>; }; qfprom@784000 { @@ -2520,7 +2521,7 @@ <0 0>, <0 0>, <0 0>, - <0 300000000>; + <75000000 300000000>; status = "disabled"; }; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts linux-6.2.0/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts --- linux-6.2.0/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts @@ -74,7 +74,7 @@ reg = <0x0 0xffc40000 0x0 0xc0000>; record-size = <0x1000>; console-size = <0x40000>; - msg-size = <0x20000 0x20000>; + pmsg-size = <0x20000>; }; cmdline_mem: memory@ffd00000 { diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/sm6350.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/sm6350.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/sm6350.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sm6350.dtsi @@ -306,11 +306,6 @@ no-map; }; - pil_gpu_mem: memory@8b715400 { - reg = <0 0x8b715400 0 0x2000>; - no-map; - }; - pil_modem_mem: memory@8b800000 { reg = <0 0x8b800000 0 0xf800000>; no-map; @@ -331,6 +326,11 @@ no-map; }; + pil_gpu_mem: memory@f0d00000 { + reg = <0 0xf0d00000 0 0x1000>; + no-map; + }; + debug_region: memory@ffb00000 { reg = <0 0xffb00000 0 0xc0000>; no-map; @@ -346,7 +346,7 @@ reg = <0 0xffc00000 0 0x100000>; record-size = <0x1000>; console-size = <0x40000>; - msg-size = <0x20000 0x20000>; + pmsg-size = <0x20000>; ecc-size = <16>; no-map; }; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi @@ -127,7 +127,7 @@ reg = <0x0 0xffc00000 0x0 0x100000>; record-size = <0x1000>; console-size = <0x40000>; - msg-size = <0x20000 0x20000>; + pmsg-size = <0x20000>; ecc-size = <16>; no-map; }; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/sm8150.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/sm8150.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sm8150.dtsi @@ -1196,7 +1196,7 @@ dma-names = "tx", "rx"; pinctrl-names = "default"; pinctrl-0 = <&qup_i2c7_default>; - interrupts = ; + interrupts = ; #address-cells = <1>; #size-cells = <0>; status = "disabled"; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi @@ -51,12 +51,26 @@ gpio_keys: gpio-keys { compatible = "gpio-keys"; - /* - * Camera focus (light press) and camera snapshot (full press) - * seem not to work properly.. Adding the former one stalls the CPU - * and the latter kills the volume down key for whatever reason. In any - * case, they are both on &pm8150b_gpios: camera focus(2), camera snapshot(1). - */ + pinctrl-0 = <&focus_n &snapshot_n &vol_down_n>; + pinctrl-names = "default"; + + key-camera-focus { + label = "Camera Focus"; + linux,code = ; + gpios = <&pm8150b_gpios 2 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + wakeup-source; + }; + + key-camera-snapshot { + label = "Camera Snapshot"; + linux,code = ; + gpios = <&pm8150b_gpios 1 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + wakeup-source; + }; key-vol-down { label = "Volume Down"; @@ -112,7 +126,7 @@ reg = <0x0 0xffc00000 0x0 0x100000>; record-size = <0x1000>; console-size = <0x40000>; - msg-size = <0x20000 0x20000>; + pmsg-size = <0x20000>; ecc-size = <16>; no-map; }; @@ -553,6 +567,34 @@ vdda-pll-supply = <&vreg_l9a_1p2>; }; +&pm8150_gpios { + vol_down_n: vol-down-n-state { + pins = "gpio1"; + function = "normal"; + power-source = <0>; + bias-pull-up; + input-enable; + }; +}; + +&pm8150b_gpios { + snapshot_n: snapshot-n-state { + pins = "gpio1"; + function = "normal"; + power-source = <0>; + bias-pull-up; + input-enable; + }; + + focus_n: focus-n-state { + pins = "gpio2"; + function = "normal"; + power-source = <0>; + bias-pull-up; + input-enable; + }; +}; + &pon_pwrkey { status = "okay"; }; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/sm8250.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/sm8250.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -99,7 +99,7 @@ reg = <0x0 0x0>; enable-method = "psci"; capacity-dmips-mhz = <448>; - dynamic-power-coefficient = <205>; + dynamic-power-coefficient = <105>; next-level-cache = <&L2_0>; power-domains = <&CPU_PD0>; power-domain-names = "psci"; @@ -123,7 +123,7 @@ reg = <0x0 0x100>; enable-method = "psci"; capacity-dmips-mhz = <448>; - dynamic-power-coefficient = <205>; + dynamic-power-coefficient = <105>; next-level-cache = <&L2_100>; power-domains = <&CPU_PD1>; power-domain-names = "psci"; @@ -144,7 +144,7 @@ reg = <0x0 0x200>; enable-method = "psci"; capacity-dmips-mhz = <448>; - dynamic-power-coefficient = <205>; + dynamic-power-coefficient = <105>; next-level-cache = <&L2_200>; power-domains = <&CPU_PD2>; power-domain-names = "psci"; @@ -165,7 +165,7 @@ reg = <0x0 0x300>; enable-method = "psci"; capacity-dmips-mhz = <448>; - dynamic-power-coefficient = <205>; + dynamic-power-coefficient = <105>; next-level-cache = <&L2_300>; power-domains = <&CPU_PD3>; power-domain-names = "psci"; @@ -1861,6 +1861,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pcie0_default_state>; + dma-coherent; status = "disabled"; }; @@ -1967,6 +1968,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pcie1_default_state>; + dma-coherent; status = "disabled"; }; @@ -2075,6 +2077,7 @@ pinctrl-names = "default"; pinctrl-0 = <&pcie2_default_state>; + dma-coherent; status = "disabled"; }; diff -u linux-6.2.0/arch/arm64/boot/dts/qcom/sm8350.dtsi linux-6.2.0/arch/arm64/boot/dts/qcom/sm8350.dtsi --- linux-6.2.0/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -63,7 +63,7 @@ CPU0: cpu@0 { device_type = "cpu"; - compatible = "qcom,kryo685"; + compatible = "arm,cortex-a55"; reg = <0x0 0x0>; enable-method = "psci"; next-level-cache = <&L2_0>; @@ -82,7 +82,7 @@ CPU1: cpu@100 { device_type = "cpu"; - compatible = "qcom,kryo685"; + compatible = "arm,cortex-a55"; reg = <0x0 0x100>; enable-method = "psci"; next-level-cache = <&L2_100>; @@ -98,7 +98,7 @@ CPU2: cpu@200 { device_type = "cpu"; - compatible = "qcom,kryo685"; + compatible = "arm,cortex-a55"; reg = <0x0 0x200>; enable-method = "psci"; next-level-cache = <&L2_200>; @@ -114,7 +114,7 @@ CPU3: cpu@300 { device_type = "cpu"; - compatible = "qcom,kryo685"; + compatible = "arm,cortex-a55"; reg = <0x0 0x300>; enable-method = "psci"; next-level-cache = <&L2_300>; @@ -130,7 +130,7 @@ CPU4: cpu@400 { device_type = "cpu"; - compatible = "qcom,kryo685"; + compatible = "arm,cortex-a78"; reg = <0x0 0x400>; enable-method = "psci"; next-level-cache = <&L2_400>; @@ -146,7 +146,7 @@ CPU5: cpu@500 { device_type = "cpu"; - compatible = "qcom,kryo685"; + compatible = "arm,cortex-a78"; reg = <0x0 0x500>; enable-method = "psci"; next-level-cache = <&L2_500>; @@ -163,7 +163,7 @@ CPU6: cpu@600 { device_type = "cpu"; - compatible = "qcom,kryo685"; + compatible = "arm,cortex-a78"; reg = <0x0 0x600>; enable-method = "psci"; next-level-cache = <&L2_600>; @@ -179,7 +179,7 @@ CPU7: cpu@700 { device_type = "cpu"; - compatible = "qcom,kryo685"; + compatible = "arm,cortex-x1"; reg = <0x0 0x700>; enable-method = "psci"; next-level-cache = <&L2_700>; @@ -236,8 +236,8 @@ compatible = "arm,idle-state"; idle-state-name = "silver-rail-power-collapse"; arm,psci-suspend-param = <0x40000004>; - entry-latency-us = <355>; - exit-latency-us = <909>; + entry-latency-us = <360>; + exit-latency-us = <531>; min-residency-us = <3934>; local-timer-stop; }; @@ -246,8 +246,8 @@ compatible = "arm,idle-state"; idle-state-name = "gold-rail-power-collapse"; arm,psci-suspend-param = <0x40000004>; - entry-latency-us = <241>; - exit-latency-us = <1461>; + entry-latency-us = <702>; + exit-latency-us = <1061>; min-residency-us = <4488>; local-timer-stop; }; @@ -2113,6 +2113,13 @@ <0 0x18593000 0 0x1000>; reg-names = "freq-domain0", "freq-domain1", "freq-domain2"; + interrupts = , + , + ; + interrupt-names = "dcvsh-irq-0", + "dcvsh-irq-1", + "dcvsh-irq-2"; + clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_GPLL0>; clock-names = "xo", "alternate"; diff -u linux-6.2.0/arch/arm64/kernel/cpu_errata.c linux-6.2.0/arch/arm64/kernel/cpu_errata.c --- linux-6.2.0/arch/arm64/kernel/cpu_errata.c +++ linux-6.2.0/arch/arm64/kernel/cpu_errata.c @@ -730,6 +730,14 @@ .cpu_enable = cpu_clear_bf16_from_user_emulation, }, #endif +#ifdef CONFIG_ARM64_ERRATUM_2966298 + { + .desc = "ARM erratum 2966298", + .capability = ARM64_WORKAROUND_2966298, + /* Cortex-A520 r0p0 - r0p1 */ + ERRATA_MIDR_REV_RANGE(MIDR_CORTEX_A520, 0, 0, 1), + }, +#endif #ifdef CONFIG_AMPERE_ERRATUM_AC03_CPU_38 { .desc = "AmpereOne erratum AC03_CPU_38", diff -u linux-6.2.0/arch/arm64/kernel/cpufeature.c linux-6.2.0/arch/arm64/kernel/cpufeature.c --- linux-6.2.0/arch/arm64/kernel/cpufeature.c +++ linux-6.2.0/arch/arm64/kernel/cpufeature.c @@ -214,7 +214,8 @@ static const struct arm64_ftr_bits ftr_id_aa64isar2[] = { ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CSSC_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_RPRFM_SHIFT, 4, 0), - ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_CLRBHB_SHIFT, 4, 0), + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR2_EL1_BC_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), FTR_STRICT, FTR_EXACT, ID_AA64ISAR2_EL1_APA3_SHIFT, 4, 0), ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_PTR_AUTH), diff -u linux-6.2.0/arch/arm64/kernel/entry.S linux-6.2.0/arch/arm64/kernel/entry.S --- linux-6.2.0/arch/arm64/kernel/entry.S +++ linux-6.2.0/arch/arm64/kernel/entry.S @@ -422,6 +422,10 @@ 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 @@ -996,9 +1000,13 @@ mov x19, x1 -#if defined(CONFIG_VMAP_STACK) || defined(CONFIG_SHADOW_CALL_STACK) + /* Store the registered-event for crash_smp_send_stop() */ ldrb w4, [x19, #SDEI_EVENT_PRIORITY] -#endif + cbnz w4, 1f + adr_this_cpu dst=x5, sym=sdei_active_normal_event, tmp=x6 + b 2f +1: adr_this_cpu dst=x5, sym=sdei_active_critical_event, tmp=x6 +2: str x19, [x5] #ifdef CONFIG_VMAP_STACK /* @@ -1065,6 +1073,14 @@ ldr_l x2, sdei_exit_mode + /* Clear the registered-event seen by crash_smp_send_stop() */ + ldrb w3, [x4, #SDEI_EVENT_PRIORITY] + cbnz w3, 1f + adr_this_cpu dst=x5, sym=sdei_active_normal_event, tmp=x6 + b 2f +1: adr_this_cpu dst=x5, sym=sdei_active_critical_event, tmp=x6 +2: str xzr, [x5] + alternative_if_not ARM64_UNMAP_KERNEL_AT_EL0 sdei_handler_exit exit_mode=x2 alternative_else_nop_endif @@ -1077,2 +1093,13 @@ NOKPROBE(__sdei_asm_handler) + +SYM_CODE_START(__sdei_handler_abort) + mov_q x0, SDEI_1_0_FN_SDEI_EVENT_COMPLETE_AND_RESUME + adr x1, 1f + ldr_l x2, sdei_exit_mode + sdei_handler_exit exit_mode=x2 + // exit the handler and jump to the next instruction. + // Exit will stomp x0-x17, PSTATE, ELR_ELx, and SPSR_ELx. +1: ret +SYM_CODE_END(__sdei_handler_abort) +NOKPROBE(__sdei_handler_abort) #endif /* CONFIG_ARM_SDE_INTERFACE */ diff -u linux-6.2.0/arch/arm64/kernel/fpsimd.c linux-6.2.0/arch/arm64/kernel/fpsimd.c --- linux-6.2.0/arch/arm64/kernel/fpsimd.c +++ linux-6.2.0/arch/arm64/kernel/fpsimd.c @@ -1177,9 +1177,6 @@ */ u64 read_zcr_features(void) { - u64 zcr; - unsigned int vq_max; - /* * Set the maximum possible VL, and write zeroes to all other * bits to see if they stick. @@ -1187,12 +1184,8 @@ sve_kernel_enable(NULL); write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL1); - zcr = read_sysreg_s(SYS_ZCR_EL1); - zcr &= ~(u64)ZCR_ELx_LEN_MASK; /* find sticky 1s outside LEN field */ - vq_max = sve_vq_from_vl(sve_get_vl()); - zcr |= vq_max - 1; /* set LEN field to maximum effective value */ - - return zcr; + /* Return LEN value that would be written to get the maximum VL */ + return sve_vq_from_vl(sve_get_vl()) - 1; } void __init sve_setup(void) @@ -1336,11 +1329,7 @@ */ u64 read_smcr_features(void) { - u64 smcr; - unsigned int vq_max; - sme_kernel_enable(NULL); - sme_smstart_sm(); /* * Set the maximum possible VL. @@ -1348,14 +1337,8 @@ write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_LEN_MASK, SYS_SMCR_EL1); - smcr = read_sysreg_s(SYS_SMCR_EL1); - smcr &= ~(u64)SMCR_ELx_LEN_MASK; /* Only the LEN field */ - vq_max = sve_vq_from_vl(sve_get_vl()); - smcr |= vq_max - 1; /* set LEN field to maximum effective value */ - - sme_smstop_sm(); - - return smcr; + /* Return LEN value that would be written to get the maximum VL */ + return sve_vq_from_vl(sme_get_vl()) - 1; } void __init sme_setup(void) diff -u linux-6.2.0/arch/arm64/kernel/ptrace.c linux-6.2.0/arch/arm64/kernel/ptrace.c --- linux-6.2.0/arch/arm64/kernel/ptrace.c +++ linux-6.2.0/arch/arm64/kernel/ptrace.c @@ -891,7 +891,8 @@ break; default: WARN_ON_ONCE(1); - return -EINVAL; + ret = -EINVAL; + goto out; } /* diff -u linux-6.2.0/arch/arm64/tools/cpucaps linux-6.2.0/arch/arm64/tools/cpucaps --- linux-6.2.0/arch/arm64/tools/cpucaps +++ linux-6.2.0/arch/arm64/tools/cpucaps @@ -73,6 +73,7 @@ WORKAROUND_2457168 WORKAROUND_2645198 WORKAROUND_2658417 +WORKAROUND_2966298 WORKAROUND_AMPERE_AC03_CPU_38 WORKAROUND_TRBE_OVERWRITE_FILL_MODE WORKAROUND_TSB_FLUSH_FAILURE diff -u linux-6.2.0/arch/arm64/tools/sysreg linux-6.2.0/arch/arm64/tools/sysreg --- linux-6.2.0/arch/arm64/tools/sysreg +++ linux-6.2.0/arch/arm64/tools/sysreg @@ -1248,7 +1248,11 @@ 0b0000 NI 0b0001 IMP EndEnum -Res0 47:28 +Res0 47:32 +Enum 31:28 CLRBHB + 0b0000 NI + 0b0001 IMP +EndEnum Enum 27:24 PAC_frac 0b0000 NI 0b0001 IMP diff -u linux-6.2.0/arch/loongarch/include/asm/loongarch.h linux-6.2.0/arch/loongarch/include/asm/loongarch.h --- linux-6.2.0/arch/loongarch/include/asm/loongarch.h +++ linux-6.2.0/arch/loongarch/include/asm/loongarch.h @@ -1488,7 +1488,7 @@ #define write_fcsr(dest, val) \ do { \ __asm__ __volatile__( \ - " movgr2fcsr %0, "__stringify(dest)" \n" \ + " movgr2fcsr "__stringify(dest)", %0 \n" \ : : "r" (val)); \ } while (0) diff -u linux-6.2.0/arch/mips/Kconfig linux-6.2.0/arch/mips/Kconfig --- linux-6.2.0/arch/mips/Kconfig +++ linux-6.2.0/arch/mips/Kconfig @@ -83,7 +83,6 @@ select HAVE_LD_DEAD_CODE_DATA_ELIMINATION select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI - select HAVE_PATA_PLATFORM select HAVE_PERF_EVENTS select HAVE_PERF_REGS select HAVE_PERF_USER_STACK_DUMP diff -u linux-6.2.0/arch/mips/Makefile linux-6.2.0/arch/mips/Makefile --- linux-6.2.0/arch/mips/Makefile +++ linux-6.2.0/arch/mips/Makefile @@ -308,8 +308,8 @@ endif endif - ifeq ($(KBUILD_SYM32)$(call cc-option-yn,-msym32), yy) - cflags-y += -msym32 -DKBUILD_64BIT_SYM32 + ifeq ($(KBUILD_SYM32), y) + cflags-$(KBUILD_SYM32) += -msym32 -DKBUILD_64BIT_SYM32 else ifeq ($(CONFIG_CPU_DADDI_WORKAROUNDS), y) $(error CONFIG_CPU_DADDI_WORKAROUNDS unsupported without -msym32) @@ -350,7 +350,7 @@ KBUILD_LDFLAGS += -m $(ld-emul) -ifdef CONFIG_MIPS +ifdef need-compiler CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ grep -E -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g') diff -u linux-6.2.0/arch/mips/alchemy/devboards/db1000.c linux-6.2.0/arch/mips/alchemy/devboards/db1000.c --- linux-6.2.0/arch/mips/alchemy/devboards/db1000.c +++ linux-6.2.0/arch/mips/alchemy/devboards/db1000.c @@ -164,6 +164,7 @@ /******************************************************************************/ +#ifdef CONFIG_MMC_AU1X static irqreturn_t db1100_mmc_cd(int irq, void *ptr) { mmc_detect_change(ptr, msecs_to_jiffies(500)); @@ -369,6 +370,7 @@ .num_resources = ARRAY_SIZE(au1100_mmc1_res), .resource = au1100_mmc1_res, }; +#endif /* CONFIG_MMC_AU1X */ /******************************************************************************/ @@ -432,8 +434,10 @@ static struct platform_device *db1100_devs[] = { &au1100_lcd_device, +#ifdef CONFIG_MMC_AU1X &db1100_mmc0_dev, &db1100_mmc1_dev, +#endif }; int __init db1000_dev_setup(void) diff -u linux-6.2.0/arch/mips/alchemy/devboards/db1200.c linux-6.2.0/arch/mips/alchemy/devboards/db1200.c --- linux-6.2.0/arch/mips/alchemy/devboards/db1200.c +++ linux-6.2.0/arch/mips/alchemy/devboards/db1200.c @@ -326,6 +326,7 @@ /**********************************************************************/ +#ifdef CONFIG_MMC_AU1X /* SD carddetects: they're supposed to be edge-triggered, but ack * doesn't seem to work (CPLD Rev 2). Instead, the screaming one * is disabled and its counterpart enabled. The 200ms timeout is @@ -584,6 +585,7 @@ .num_resources = ARRAY_SIZE(au1200_mmc1_res), .resource = au1200_mmc1_res, }; +#endif /* CONFIG_MMC_AU1X */ /**********************************************************************/ @@ -751,7 +753,9 @@ static struct platform_device *db1200_devs[] __initdata = { NULL, /* PSC0, selected by S6.8 */ &db1200_ide_dev, +#ifdef CONFIG_MMC_AU1X &db1200_mmc0_dev, +#endif &au1200_lcd_dev, &db1200_eth_dev, &db1200_nand_dev, @@ -762,7 +766,9 @@ }; static struct platform_device *pb1200_devs[] __initdata = { +#ifdef CONFIG_MMC_AU1X &pb1200_mmc1_dev, +#endif }; /* Some peripheral base addresses differ on the PB1200 */ diff -u linux-6.2.0/arch/mips/alchemy/devboards/db1300.c linux-6.2.0/arch/mips/alchemy/devboards/db1300.c --- linux-6.2.0/arch/mips/alchemy/devboards/db1300.c +++ linux-6.2.0/arch/mips/alchemy/devboards/db1300.c @@ -450,6 +450,7 @@ /**********************************************************************/ +#ifdef CONFIG_MMC_AU1X static irqreturn_t db1300_mmc_cd(int irq, void *ptr) { disable_irq_nosync(irq); @@ -632,6 +633,7 @@ .resource = au1300_sd0_res, .num_resources = ARRAY_SIZE(au1300_sd0_res), }; +#endif /* CONFIG_MMC_AU1X */ /**********************************************************************/ @@ -767,8 +769,10 @@ &db1300_5waysw_dev, &db1300_nand_dev, &db1300_ide_dev, +#ifdef CONFIG_MMC_AU1X &db1300_sd0_dev, &db1300_sd1_dev, +#endif &db1300_lcd_dev, &db1300_ac97_dev, &db1300_i2s_dev, diff -u linux-6.2.0/arch/powerpc/boot/Makefile linux-6.2.0/arch/powerpc/boot/Makefile --- linux-6.2.0/arch/powerpc/boot/Makefile +++ linux-6.2.0/arch/powerpc/boot/Makefile @@ -34,8 +34,6 @@ BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \ - $(call cc-option,-mno-prefixed) $(call cc-option,-mno-pcrel) \ - $(call cc-option,-mno-mma) \ $(call cc-option,-mno-spe) $(call cc-option,-mspe=no) \ -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ $(LINUXINCLUDE) @@ -71,6 +69,10 @@ BOOTARFLAGS := -crD +BOOTCFLAGS += $(call cc-option,-mno-prefixed) \ + $(call cc-option,-mno-pcrel) \ + $(call cc-option,-mno-mma) + ifdef CONFIG_CC_IS_CLANG BOOTCFLAGS += $(CLANG_FLAGS) BOOTAFLAGS += $(CLANG_FLAGS) diff -u linux-6.2.0/arch/powerpc/include/asm/paca.h linux-6.2.0/arch/powerpc/include/asm/paca.h --- linux-6.2.0/arch/powerpc/include/asm/paca.h +++ linux-6.2.0/arch/powerpc/include/asm/paca.h @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #ifdef CONFIG_PPC_BOOK3E_64 @@ -47,14 +46,11 @@ #define get_paca() local_paca #endif -#ifdef CONFIG_PPC_PSERIES -#define get_lppaca() (get_paca()->lppaca_ptr) -#endif - #define get_slb_shadow() (get_paca()->slb_shadow_ptr) struct task_struct; struct rtas_args; +struct lppaca; /* * Defines the layout of the paca. diff -u linux-6.2.0/arch/powerpc/kernel/iommu.c linux-6.2.0/arch/powerpc/kernel/iommu.c --- linux-6.2.0/arch/powerpc/kernel/iommu.c +++ linux-6.2.0/arch/powerpc/kernel/iommu.c @@ -171,17 +171,28 @@ return 0; } -static struct notifier_block fail_iommu_bus_notifier = { +/* + * PCI and VIO buses need separate notifier_block structs, since they're linked + * list nodes. Sharing a notifier_block would mean that any notifiers later + * registered for PCI buses would also get called by VIO buses and vice versa. + */ +static struct notifier_block fail_iommu_pci_bus_notifier = { .notifier_call = fail_iommu_bus_notify }; +#ifdef CONFIG_IBMVIO +static struct notifier_block fail_iommu_vio_bus_notifier = { + .notifier_call = fail_iommu_bus_notify +}; +#endif + static int __init fail_iommu_setup(void) { #ifdef CONFIG_PCI - bus_register_notifier(&pci_bus_type, &fail_iommu_bus_notifier); + bus_register_notifier(&pci_bus_type, &fail_iommu_pci_bus_notifier); #endif #ifdef CONFIG_IBMVIO - bus_register_notifier(&vio_bus_type, &fail_iommu_bus_notifier); + bus_register_notifier(&vio_bus_type, &fail_iommu_vio_bus_notifier); #endif return 0; diff -u linux-6.2.0/arch/powerpc/mm/book3s64/radix_tlb.c linux-6.2.0/arch/powerpc/mm/book3s64/radix_tlb.c --- linux-6.2.0/arch/powerpc/mm/book3s64/radix_tlb.c +++ linux-6.2.0/arch/powerpc/mm/book3s64/radix_tlb.c @@ -127,21 +127,6 @@ trace_tlbie(0, 0, rb, rs, ric, prs, r); } -static __always_inline void __tlbie_pid_lpid(unsigned long pid, - unsigned long lpid, - unsigned long ric) -{ - unsigned long rb, rs, prs, r; - - rb = PPC_BIT(53); /* IS = 1 */ - rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31))); - prs = 1; /* process scoped */ - r = 1; /* radix format */ - - asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) - : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); - trace_tlbie(0, 0, rb, rs, ric, prs, r); -} static __always_inline void __tlbie_lpid(unsigned long lpid, unsigned long ric) { unsigned long rb,rs,prs,r; @@ -202,23 +187,6 @@ trace_tlbie(0, 0, rb, rs, ric, prs, r); } -static __always_inline void __tlbie_va_lpid(unsigned long va, unsigned long pid, - unsigned long lpid, - unsigned long ap, unsigned long ric) -{ - unsigned long rb, rs, prs, r; - - rb = va & ~(PPC_BITMASK(52, 63)); - rb |= ap << PPC_BITLSHIFT(58); - rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31))); - prs = 1; /* process scoped */ - r = 1; /* radix format */ - - asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) - : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); - trace_tlbie(0, 0, rb, rs, ric, prs, r); -} - static __always_inline void __tlbie_lpid_va(unsigned long va, unsigned long lpid, unsigned long ap, unsigned long ric) { @@ -264,22 +232,6 @@ } } -static inline void fixup_tlbie_va_range_lpid(unsigned long va, - unsigned long pid, - unsigned long lpid, - unsigned long ap) -{ - if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) { - asm volatile("ptesync" : : : "memory"); - __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB); - } - - if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) { - asm volatile("ptesync" : : : "memory"); - __tlbie_va_lpid(va, pid, lpid, ap, RIC_FLUSH_TLB); - } -} - static inline void fixup_tlbie_pid(unsigned long pid) { /* @@ -299,26 +251,6 @@ } } -static inline void fixup_tlbie_pid_lpid(unsigned long pid, unsigned long lpid) -{ - /* - * We can use any address for the invalidation, pick one which is - * probably unused as an optimisation. - */ - unsigned long va = ((1UL << 52) - 1); - - if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) { - asm volatile("ptesync" : : : "memory"); - __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB); - } - - if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) { - asm volatile("ptesync" : : : "memory"); - __tlbie_va_lpid(va, pid, lpid, mmu_get_ap(MMU_PAGE_64K), - RIC_FLUSH_TLB); - } -} - static inline void fixup_tlbie_lpid_va(unsigned long va, unsigned long lpid, unsigned long ap) { @@ -416,31 +348,6 @@ asm volatile("eieio; tlbsync; ptesync": : :"memory"); } -static inline void _tlbie_pid_lpid(unsigned long pid, unsigned long lpid, - unsigned long ric) -{ - asm volatile("ptesync" : : : "memory"); - - /* - * Workaround the fact that the "ric" argument to __tlbie_pid - * must be a compile-time contraint to match the "i" constraint - * in the asm statement. - */ - switch (ric) { - case RIC_FLUSH_TLB: - __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_TLB); - fixup_tlbie_pid_lpid(pid, lpid); - break; - case RIC_FLUSH_PWC: - __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC); - break; - case RIC_FLUSH_ALL: - default: - __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_ALL); - fixup_tlbie_pid_lpid(pid, lpid); - } - asm volatile("eieio; tlbsync; ptesync" : : : "memory"); -} struct tlbiel_pid { unsigned long pid; unsigned long ric; @@ -566,20 +473,6 @@ fixup_tlbie_va_range(addr - page_size, pid, ap); } -static inline void __tlbie_va_range_lpid(unsigned long start, unsigned long end, - unsigned long pid, unsigned long lpid, - unsigned long page_size, - unsigned long psize) -{ - unsigned long addr; - unsigned long ap = mmu_get_ap(psize); - - for (addr = start; addr < end; addr += page_size) - __tlbie_va_lpid(addr, pid, lpid, ap, RIC_FLUSH_TLB); - - fixup_tlbie_va_range_lpid(addr - page_size, pid, lpid, ap); -} - static __always_inline void _tlbie_va(unsigned long va, unsigned long pid, unsigned long psize, unsigned long ric) { @@ -660,18 +553,6 @@ asm volatile("eieio; tlbsync; ptesync": : :"memory"); } -static inline void _tlbie_va_range_lpid(unsigned long start, unsigned long end, - unsigned long pid, unsigned long lpid, - unsigned long page_size, - unsigned long psize, bool also_pwc) -{ - asm volatile("ptesync" : : : "memory"); - if (also_pwc) - __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC); - __tlbie_va_range_lpid(start, end, pid, lpid, page_size, psize); - asm volatile("eieio; tlbsync; ptesync" : : : "memory"); -} - static inline void _tlbiel_va_range_multicast(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned long pid, unsigned long page_size, @@ -1476,6 +1357,127 @@ } #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +static __always_inline void __tlbie_pid_lpid(unsigned long pid, + unsigned long lpid, + unsigned long ric) +{ + unsigned long rb, rs, prs, r; + + rb = PPC_BIT(53); /* IS = 1 */ + rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31))); + prs = 1; /* process scoped */ + r = 1; /* radix format */ + + asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) + : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); + trace_tlbie(0, 0, rb, rs, ric, prs, r); +} + +static __always_inline void __tlbie_va_lpid(unsigned long va, unsigned long pid, + unsigned long lpid, + unsigned long ap, unsigned long ric) +{ + unsigned long rb, rs, prs, r; + + rb = va & ~(PPC_BITMASK(52, 63)); + rb |= ap << PPC_BITLSHIFT(58); + rs = (pid << PPC_BITLSHIFT(31)) | (lpid & ~(PPC_BITMASK(0, 31))); + prs = 1; /* process scoped */ + r = 1; /* radix format */ + + asm volatile(PPC_TLBIE_5(%0, %4, %3, %2, %1) + : : "r"(rb), "i"(r), "i"(prs), "i"(ric), "r"(rs) : "memory"); + trace_tlbie(0, 0, rb, rs, ric, prs, r); +} + +static inline void fixup_tlbie_pid_lpid(unsigned long pid, unsigned long lpid) +{ + /* + * We can use any address for the invalidation, pick one which is + * probably unused as an optimisation. + */ + unsigned long va = ((1UL << 52) - 1); + + if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) { + asm volatile("ptesync" : : : "memory"); + __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB); + } + + if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) { + asm volatile("ptesync" : : : "memory"); + __tlbie_va_lpid(va, pid, lpid, mmu_get_ap(MMU_PAGE_64K), + RIC_FLUSH_TLB); + } +} + +static inline void _tlbie_pid_lpid(unsigned long pid, unsigned long lpid, + unsigned long ric) +{ + asm volatile("ptesync" : : : "memory"); + + /* + * Workaround the fact that the "ric" argument to __tlbie_pid + * must be a compile-time contraint to match the "i" constraint + * in the asm statement. + */ + switch (ric) { + case RIC_FLUSH_TLB: + __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_TLB); + fixup_tlbie_pid_lpid(pid, lpid); + break; + case RIC_FLUSH_PWC: + __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC); + break; + case RIC_FLUSH_ALL: + default: + __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_ALL); + fixup_tlbie_pid_lpid(pid, lpid); + } + asm volatile("eieio; tlbsync; ptesync" : : : "memory"); +} + +static inline void fixup_tlbie_va_range_lpid(unsigned long va, + unsigned long pid, + unsigned long lpid, + unsigned long ap) +{ + if (cpu_has_feature(CPU_FTR_P9_TLBIE_ERAT_BUG)) { + asm volatile("ptesync" : : : "memory"); + __tlbie_pid_lpid(0, lpid, RIC_FLUSH_TLB); + } + + if (cpu_has_feature(CPU_FTR_P9_TLBIE_STQ_BUG)) { + asm volatile("ptesync" : : : "memory"); + __tlbie_va_lpid(va, pid, lpid, ap, RIC_FLUSH_TLB); + } +} + +static inline void __tlbie_va_range_lpid(unsigned long start, unsigned long end, + unsigned long pid, unsigned long lpid, + unsigned long page_size, + unsigned long psize) +{ + unsigned long addr; + unsigned long ap = mmu_get_ap(psize); + + for (addr = start; addr < end; addr += page_size) + __tlbie_va_lpid(addr, pid, lpid, ap, RIC_FLUSH_TLB); + + fixup_tlbie_va_range_lpid(addr - page_size, pid, lpid, ap); +} + +static inline void _tlbie_va_range_lpid(unsigned long start, unsigned long end, + unsigned long pid, unsigned long lpid, + unsigned long page_size, + unsigned long psize, bool also_pwc) +{ + asm volatile("ptesync" : : : "memory"); + if (also_pwc) + __tlbie_pid_lpid(pid, lpid, RIC_FLUSH_PWC); + __tlbie_va_range_lpid(start, end, pid, lpid, page_size, psize); + asm volatile("eieio; tlbsync; ptesync" : : : "memory"); +} + /* * Performs process-scoped invalidations for a given LPID * as part of H_RPT_INVALIDATE hcall. diff -u linux-6.2.0/arch/powerpc/platforms/pseries/hvCall.S linux-6.2.0/arch/powerpc/platforms/pseries/hvCall.S --- linux-6.2.0/arch/powerpc/platforms/pseries/hvCall.S +++ linux-6.2.0/arch/powerpc/platforms/pseries/hvCall.S @@ -89,6 +89,7 @@ b 1f; \ END_FTR_SECTION(0, 1); \ LOAD_REG_ADDR(r12, hcall_tracepoint_refcount) ; \ + ld r12,0(r12); \ std r12,32(r1); \ cmpdi r12,0; \ bne- LABEL; \ diff -u linux-6.2.0/arch/powerpc/xmon/xmon.c linux-6.2.0/arch/powerpc/xmon/xmon.c --- linux-6.2.0/arch/powerpc/xmon/xmon.c +++ linux-6.2.0/arch/powerpc/xmon/xmon.c @@ -58,6 +58,7 @@ #ifdef CONFIG_PPC64 #include #include +#include #endif #include "nonstdio.h" diff -u linux-6.2.0/arch/riscv/kernel/elf_kexec.c linux-6.2.0/arch/riscv/kernel/elf_kexec.c --- linux-6.2.0/arch/riscv/kernel/elf_kexec.c +++ linux-6.2.0/arch/riscv/kernel/elf_kexec.c @@ -98,7 +98,13 @@ kbuf.image = image; kbuf.buf_min = lowest_paddr; kbuf.buf_max = ULONG_MAX; - kbuf.buf_align = PAGE_SIZE; + + /* + * Current riscv boot protocol requires 2MB alignment for + * RV64 and 4MB alignment for RV32 + * + */ + kbuf.buf_align = PMD_SIZE; kbuf.mem = KEXEC_BUF_MEM_UNKNOWN; kbuf.memsz = ALIGN(kernel_len, PAGE_SIZE); kbuf.top_down = false; diff -u linux-6.2.0/arch/s390/kernel/ipl.c linux-6.2.0/arch/s390/kernel/ipl.c --- linux-6.2.0/arch/s390/kernel/ipl.c +++ linux-6.2.0/arch/s390/kernel/ipl.c @@ -638,6 +638,8 @@ static struct attribute *ipl_unknown_attrs[] = { &sys_ipl_type_attr.attr, + &sys_ipl_secure_attr.attr, + &sys_ipl_has_secure_attr.attr, NULL, }; diff -u linux-6.2.0/arch/um/drivers/Makefile linux-6.2.0/arch/um/drivers/Makefile --- linux-6.2.0/arch/um/drivers/Makefile +++ linux-6.2.0/arch/um/drivers/Makefile @@ -54,7 +54,7 @@ obj-$(CONFIG_MCONSOLE) += mconsole.o obj-$(CONFIG_MMAPPER) += mmapper_kern.o obj-$(CONFIG_BLK_DEV_UBD) += ubd.o -obj-$(CONFIG_HOSTAUDIO) += hostaudio.o +obj-$(CONFIG_UML_SOUND) += hostaudio.o obj-$(CONFIG_NULL_CHAN) += null.o obj-$(CONFIG_PORT_CHAN) += port.o obj-$(CONFIG_PTY_CHAN) += pty.o diff -u linux-6.2.0/arch/x86/boot/compressed/sev.c linux-6.2.0/arch/x86/boot/compressed/sev.c --- linux-6.2.0/arch/x86/boot/compressed/sev.c +++ linux-6.2.0/arch/x86/boot/compressed/sev.c @@ -103,6 +103,16 @@ return ES_OK; } +static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size) +{ + return ES_OK; +} + +static bool fault_in_kernel_space(unsigned long address) +{ + return false; +} + #undef __init #undef __pa #define __init diff -u linux-6.2.0/arch/x86/events/amd/core.c linux-6.2.0/arch/x86/events/amd/core.c --- linux-6.2.0/arch/x86/events/amd/core.c +++ linux-6.2.0/arch/x86/events/amd/core.c @@ -534,8 +534,12 @@ /* Clear enable bits i.e. PerfCntrGlobalCtl.PerfCntrEn */ wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_CTL, 0); - /* Clear overflow bits i.e. PerfCntrGLobalStatus.PerfCntrOvfl */ - wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, amd_pmu_global_cntr_mask); + /* + * Clear freeze and overflow bits i.e. PerfCntrGLobalStatus.LbrFreeze + * and PerfCntrGLobalStatus.PerfCntrOvfl + */ + wrmsrl(MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, + GLOBAL_STATUS_LBRS_FROZEN | amd_pmu_global_cntr_mask); } static int amd_pmu_cpu_prepare(int cpu) @@ -570,6 +574,7 @@ int i, nb_id; cpuc->perf_ctr_virt_mask = AMD64_EVENTSEL_HOSTONLY; + amd_pmu_cpu_reset(cpu); if (!x86_pmu.amd_nb_constraints) return; @@ -591,8 +596,6 @@ cpuc->amd_nb->nb_id = nb_id; cpuc->amd_nb->refcnt++; - - amd_pmu_cpu_reset(cpu); } static void amd_pmu_cpu_dead(int cpu) @@ -601,6 +604,7 @@ kfree(cpuhw->lbr_sel); cpuhw->lbr_sel = NULL; + amd_pmu_cpu_reset(cpu); if (!x86_pmu.amd_nb_constraints) return; @@ -613,8 +617,6 @@ cpuhw->amd_nb = NULL; } - - amd_pmu_cpu_reset(cpu); } static inline void amd_pmu_set_global_ctl(u64 ctl) @@ -884,7 +886,7 @@ struct hw_perf_event *hwc; struct perf_event *event; int handled = 0, idx; - u64 status, mask; + u64 reserved, status, mask; bool pmu_enabled; /* @@ -909,6 +911,14 @@ status &= ~GLOBAL_STATUS_LBRS_FROZEN; } + reserved = status & ~amd_pmu_global_cntr_mask; + if (reserved) + pr_warn_once("Reserved PerfCntrGlobalStatus bits are set (0x%llx), please consider updating microcode\n", + reserved); + + /* Clear any reserved bits set by buggy microcode */ + status &= amd_pmu_global_cntr_mask; + for (idx = 0; idx < x86_pmu.num_counters; idx++) { if (!test_bit(idx, cpuc->active_mask)) continue; diff -u linux-6.2.0/arch/x86/events/intel/uncore_snbep.c linux-6.2.0/arch/x86/events/intel/uncore_snbep.c --- linux-6.2.0/arch/x86/events/intel/uncore_snbep.c +++ linux-6.2.0/arch/x86/events/intel/uncore_snbep.c @@ -6428,8 +6428,18 @@ type = uncore_find_type_by_id(uncore_msr_uncores, UNCORE_SPR_CHA); if (type) { + /* + * The value from the discovery table (stored in the type->num_boxes + * of UNCORE_SPR_CHA) is incorrect on some SPR variants because of a + * firmware bug. Using the value from SPR_MSR_UNC_CBO_CONFIG to replace it. + */ rdmsrl(SPR_MSR_UNC_CBO_CONFIG, num_cbo); - type->num_boxes = num_cbo; + /* + * The MSR doesn't work on the EMR XCC, but the firmware bug doesn't impact + * the EMR XCC. Don't let the value from the MSR replace the existing value. + */ + if (num_cbo) + type->num_boxes = num_cbo; } spr_uncore_iio_free_running.num_boxes = uncore_type_max_boxes(uncore_msr_uncores, UNCORE_SPR_IIO); } diff -u linux-6.2.0/arch/x86/include/asm/cpufeatures.h linux-6.2.0/arch/x86/include/asm/cpufeatures.h --- linux-6.2.0/arch/x86/include/asm/cpufeatures.h +++ linux-6.2.0/arch/x86/include/asm/cpufeatures.h @@ -316,6 +316,9 @@ #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */ #define X86_FEATURE_AVX512_BF16 (12*32+ 5) /* AVX512 BFLOAT16 instructions */ #define X86_FEATURE_CMPCCXADD (12*32+ 7) /* "" CMPccXADD instructions */ +#define X86_FEATURE_FZRM (12*32+10) /* "" Fast zero-length REP MOVSB */ +#define X86_FEATURE_FSRS (12*32+11) /* "" Fast short REP STOSB */ +#define X86_FEATURE_FSRC (12*32+12) /* "" Fast short REP {CMPSB,SCASB} */ #define X86_FEATURE_AMX_FP16 (12*32+21) /* "" AMX fp16 Support */ #define X86_FEATURE_AVX_IFMA (12*32+23) /* "" Support for VPMADD52[H,L]UQ */ diff -u linux-6.2.0/arch/x86/include/asm/linkage.h linux-6.2.0/arch/x86/include/asm/linkage.h --- linux-6.2.0/arch/x86/include/asm/linkage.h +++ linux-6.2.0/arch/x86/include/asm/linkage.h @@ -8,6 +8,14 @@ #undef notrace #define notrace __attribute__((no_instrument_function)) +#ifdef CONFIG_64BIT +/* + * The generic version tends to create spurious ENDBR instructions under + * certain conditions. + */ +#define _THIS_IP_ ({ unsigned long __here; asm ("lea 0(%%rip), %0" : "=r" (__here)); __here; }) +#endif + #ifdef CONFIG_X86_32 #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0))) #endif /* CONFIG_X86_32 */ diff -u linux-6.2.0/arch/x86/include/asm/mem_encrypt.h linux-6.2.0/arch/x86/include/asm/mem_encrypt.h --- linux-6.2.0/arch/x86/include/asm/mem_encrypt.h +++ linux-6.2.0/arch/x86/include/asm/mem_encrypt.h @@ -50,8 +50,8 @@ int __init early_set_memory_decrypted(unsigned long vaddr, unsigned long size); int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size); -void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, - bool enc); +void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, + unsigned long size, bool enc); void __init mem_encrypt_free_decrypted_mem(void); @@ -84,7 +84,7 @@ static inline int __init early_set_memory_encrypted(unsigned long vaddr, unsigned long size) { return 0; } static inline void __init -early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc) {} +early_set_mem_enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc) {} static inline void mem_encrypt_free_decrypted_mem(void) { } diff -u linux-6.2.0/arch/x86/include/asm/processor.h linux-6.2.0/arch/x86/include/asm/processor.h --- linux-6.2.0/arch/x86/include/asm/processor.h +++ linux-6.2.0/arch/x86/include/asm/processor.h @@ -680,12 +680,10 @@ #ifdef CONFIG_CPU_SUP_AMD extern u32 amd_get_nodes_per_socket(void); extern u32 amd_get_highest_perf(void); -extern bool cpu_has_ibpb_brtype_microcode(void); extern void amd_clear_divider(void); #else static inline u32 amd_get_nodes_per_socket(void) { return 0; } static inline u32 amd_get_highest_perf(void) { return 0; } -static inline bool cpu_has_ibpb_brtype_microcode(void) { return false; } static inline void amd_clear_divider(void) { } #endif diff -u linux-6.2.0/arch/x86/include/asm/reboot.h linux-6.2.0/arch/x86/include/asm/reboot.h --- linux-6.2.0/arch/x86/include/asm/reboot.h +++ linux-6.2.0/arch/x86/include/asm/reboot.h @@ -25,6 +25,8 @@ #define MRR_BIOS 0 #define MRR_APM 1 +typedef void crash_vmclear_fn(void); +extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; void cpu_emergency_disable_virtualization(void); typedef void (*nmi_shootdown_cb)(int, struct pt_regs*); diff -u linux-6.2.0/arch/x86/include/asm/virtext.h linux-6.2.0/arch/x86/include/asm/virtext.h --- linux-6.2.0/arch/x86/include/asm/virtext.h +++ linux-6.2.0/arch/x86/include/asm/virtext.h @@ -101,12 +101,6 @@ return 0; } - if (boot_cpu_data.extended_cpuid_level < SVM_CPUID_FUNC) { - if (msg) - *msg = "can't execute cpuid_8000000a"; - return 0; - } - if (!boot_cpu_has(X86_FEATURE_SVM)) { if (msg) *msg = "svm not available"; diff -u linux-6.2.0/arch/x86/kernel/alternative.c linux-6.2.0/arch/x86/kernel/alternative.c --- linux-6.2.0/arch/x86/kernel/alternative.c +++ linux-6.2.0/arch/x86/kernel/alternative.c @@ -606,13 +606,8 @@ { s32 *s; - /* - * Do not patch out the default return thunks if those needed are the - * ones generated by the compiler. - */ - if (cpu_feature_enabled(X86_FEATURE_RETHUNK) && - (x86_return_thunk == __x86_return_thunk)) - return; + if (cpu_feature_enabled(X86_FEATURE_RETHUNK)) + static_call_force_reinit(); for (s = start; s < end; s++) { void *dest = NULL, *addr = (void *)s + *s; diff -u linux-6.2.0/arch/x86/kernel/cpu/amd.c linux-6.2.0/arch/x86/kernel/cpu/amd.c --- linux-6.2.0/arch/x86/kernel/cpu/amd.c +++ linux-6.2.0/arch/x86/kernel/cpu/amd.c @@ -766,6 +766,15 @@ if (cpu_has(c, X86_FEATURE_TOPOEXT)) smp_num_siblings = ((cpuid_ebx(0x8000001e) >> 8) & 0xff) + 1; + + if (!cpu_has(c, X86_FEATURE_HYPERVISOR) && !cpu_has(c, X86_FEATURE_IBPB_BRTYPE)) { + if (c->x86 == 0x17 && boot_cpu_has(X86_FEATURE_AMD_IBPB)) + setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); + else if (c->x86 >= 0x19 && !wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { + setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); + setup_force_cpu_cap(X86_FEATURE_SBPB); + } + } } static void init_amd_k8(struct cpuinfo_x86 *c) @@ -1267,25 +1276,6 @@ on_each_cpu(zenbleed_check_cpu, NULL, 1); } -bool cpu_has_ibpb_brtype_microcode(void) -{ - switch (boot_cpu_data.x86) { - /* Zen1/2 IBPB flushes branch type predictions too. */ - case 0x17: - return boot_cpu_has(X86_FEATURE_AMD_IBPB); - case 0x19: - /* Poke the MSR bit on Zen3/4 to check its presence. */ - if (!wrmsrl_safe(MSR_IA32_PRED_CMD, PRED_CMD_SBPB)) { - setup_force_cpu_cap(X86_FEATURE_SBPB); - return true; - } else { - return false; - } - default: - return false; - } -} - /* * Issue a DIV 0/1 insn to clear any division data from previous DIV * operations. diff -u linux-6.2.0/arch/x86/kernel/cpu/bugs.c linux-6.2.0/arch/x86/kernel/cpu/bugs.c --- linux-6.2.0/arch/x86/kernel/cpu/bugs.c +++ linux-6.2.0/arch/x86/kernel/cpu/bugs.c @@ -2404,27 +2404,16 @@ static void __init srso_select_mitigation(void) { - bool has_microcode; + bool has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE); if (!boot_cpu_has_bug(X86_BUG_SRSO) || cpu_mitigations_off()) goto pred_cmd; - /* - * The first check is for the kernel running as a guest in order - * for guests to verify whether IBPB is a viable mitigation. - */ - has_microcode = boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) || cpu_has_ibpb_brtype_microcode(); if (!has_microcode) { pr_warn("IBPB-extending microcode not applied!\n"); pr_warn(SRSO_NOTICE); } else { /* - * Enable the synthetic (even if in a real CPUID leaf) - * flags for guests. - */ - setup_force_cpu_cap(X86_FEATURE_IBPB_BRTYPE); - - /* * Zen1/2 with SMT off aren't vulnerable after the right * IBPB microcode has been applied. */ @@ -2444,7 +2433,7 @@ switch (srso_cmd) { case SRSO_CMD_OFF: - return; + goto pred_cmd; case SRSO_CMD_MICROCODE: if (has_microcode) { @@ -2716,7 +2705,7 @@ return sysfs_emit(buf, "%s%s\n", srso_strings[srso_mitigation], - (cpu_has_ibpb_brtype_microcode() ? "" : ", no microcode")); + boot_cpu_has(X86_FEATURE_IBPB_BRTYPE) ? "" : ", no microcode"); } static ssize_t gds_show_state(char *buf) diff -u linux-6.2.0/arch/x86/kernel/cpu/common.c linux-6.2.0/arch/x86/kernel/cpu/common.c --- linux-6.2.0/arch/x86/kernel/cpu/common.c +++ linux-6.2.0/arch/x86/kernel/cpu/common.c @@ -1280,11 +1280,11 @@ VULNBL_INTEL_STEPPINGS(BROADWELL_G, X86_STEPPING_ANY, SRBDS), VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO), VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS), - VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), VULNBL_INTEL_STEPPINGS(SKYLAKE_X, X86_STEPPING_ANY, MMIO | RETBLEED | GDS), - VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED), - VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS), - VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, SRBDS | MMIO | RETBLEED | GDS), + VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), + VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), + VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), + VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPING_ANY, MMIO | RETBLEED | GDS | SRBDS), VULNBL_INTEL_STEPPINGS(CANNONLAKE_L, X86_STEPPING_ANY, RETBLEED), VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPING_ANY, MMIO | MMIO_SBDS | RETBLEED | GDS), VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPING_ANY, MMIO | GDS), @@ -1303,7 +1303,7 @@ VULNBL_AMD(0x15, RETBLEED), VULNBL_AMD(0x16, RETBLEED), VULNBL_AMD(0x17, RETBLEED | SMT_RSB | SRSO), - VULNBL_HYGON(0x18, RETBLEED | SMT_RSB), + VULNBL_HYGON(0x18, RETBLEED | SMT_RSB | SRSO), VULNBL_AMD(0x19, SRSO), {} }; diff -u linux-6.2.0/arch/x86/kernel/cpu/mce/core.c linux-6.2.0/arch/x86/kernel/cpu/mce/core.c --- linux-6.2.0/arch/x86/kernel/cpu/mce/core.c +++ linux-6.2.0/arch/x86/kernel/cpu/mce/core.c @@ -857,6 +857,26 @@ } /* + * Some Zen-based Instruction Fetch Units set EIPV=RIPV=0 on poison consumption + * errors. This means mce_gather_info() will not save the "ip" and "cs" registers. + * + * However, the context is still valid, so save the "cs" register for later use. + * + * The "ip" register is truly unknown, so don't save it or fixup EIPV/RIPV. + * + * The Instruction Fetch Unit is at MCA bank 1 for all affected systems. + */ +static __always_inline void quirk_zen_ifu(int bank, struct mce *m, struct pt_regs *regs) +{ + if (bank != 1) + return; + if (!(m->status & MCI_STATUS_POISON)) + return; + + m->cs = regs->cs; +} + +/* * Do a quick check if any of the events requires a panic. * This decides if we keep the events around or clear them. */ @@ -875,6 +895,9 @@ if (mce_flags.snb_ifu_quirk) quirk_sandybridge_ifu(i, m, regs); + if (mce_flags.zen_ifu_quirk) + quirk_zen_ifu(i, m, regs); + m->bank = i; if (mce_severity(m, regs, &tmp, true) >= MCE_PANIC_SEVERITY) { mce_read_aux(m, i); @@ -1852,6 +1875,9 @@ if (c->x86 == 0x15 && c->x86_model <= 0xf) mce_flags.overflow_recov = 1; + if (c->x86 >= 0x17 && c->x86 <= 0x1A) + mce_flags.zen_ifu_quirk = 1; + } if (c->x86_vendor == X86_VENDOR_INTEL) { diff -u linux-6.2.0/arch/x86/kernel/crash.c linux-6.2.0/arch/x86/kernel/crash.c --- linux-6.2.0/arch/x86/kernel/crash.c +++ linux-6.2.0/arch/x86/kernel/crash.c @@ -48,27 +48,6 @@ unsigned int type; }; -/* - * This is used to VMCLEAR all VMCSs loaded on the - * processor. And when loading kvm_intel module, the - * callback function pointer will be assigned. - * - * protected by rcu. - */ -crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss = NULL; -EXPORT_SYMBOL_GPL(crash_vmclear_loaded_vmcss); - -static inline void cpu_crash_vmclear_loaded_vmcss(void) -{ - crash_vmclear_fn *do_vmclear_operation = NULL; - - rcu_read_lock(); - do_vmclear_operation = rcu_dereference(crash_vmclear_loaded_vmcss); - if (do_vmclear_operation) - do_vmclear_operation(); - rcu_read_unlock(); -} - #if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC) static void kdump_nmi_callback(int cpu, struct pt_regs *regs) @@ -76,11 +55,6 @@ crash_save_cpu(regs, cpu); /* - * VMCLEAR VMCSs loaded on all cpus if needed. - */ - cpu_crash_vmclear_loaded_vmcss(); - - /* * Disable Intel PT to stop its logging */ cpu_emergency_stop_pt(); @@ -133,11 +107,6 @@ crash_smp_send_stop(); - /* - * VMCLEAR VMCSs loaded on this cpu if needed. - */ - cpu_crash_vmclear_loaded_vmcss(); - cpu_emergency_disable_virtualization(); /* diff -u linux-6.2.0/arch/x86/kernel/reboot.c linux-6.2.0/arch/x86/kernel/reboot.c --- linux-6.2.0/arch/x86/kernel/reboot.c +++ linux-6.2.0/arch/x86/kernel/reboot.c @@ -827,6 +827,26 @@ } #endif +/* + * This is used to VMCLEAR all VMCSs loaded on the + * processor. And when loading kvm_intel module, the + * callback function pointer will be assigned. + * + * protected by rcu. + */ +crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; +EXPORT_SYMBOL_GPL(crash_vmclear_loaded_vmcss); + +static inline void cpu_crash_vmclear_loaded_vmcss(void) +{ + crash_vmclear_fn *do_vmclear_operation = NULL; + + rcu_read_lock(); + do_vmclear_operation = rcu_dereference(crash_vmclear_loaded_vmcss); + if (do_vmclear_operation) + do_vmclear_operation(); + rcu_read_unlock(); +} /* This is the CPU performing the emergency shutdown work. */ int crashing_cpu = -1; @@ -838,6 +858,8 @@ */ void cpu_emergency_disable_virtualization(void) { + cpu_crash_vmclear_loaded_vmcss(); + cpu_emergency_vmxoff(); cpu_emergency_svm_disable(); } diff -u linux-6.2.0/arch/x86/kernel/setup.c linux-6.2.0/arch/x86/kernel/setup.c --- linux-6.2.0/arch/x86/kernel/setup.c +++ linux-6.2.0/arch/x86/kernel/setup.c @@ -366,15 +366,11 @@ #if defined(CONFIG_HAVE_IMA_KEXEC) && !defined(CONFIG_OF_FLATTREE) int __init ima_free_kexec_buffer(void) { - int rc; - if (!ima_kexec_buffer_size) return -ENOENT; - rc = memblock_phys_free(ima_kexec_buffer_phys, - ima_kexec_buffer_size); - if (rc) - return rc; + memblock_free_late(ima_kexec_buffer_phys, + ima_kexec_buffer_size); ima_kexec_buffer_phys = 0; ima_kexec_buffer_size = 0; diff -u linux-6.2.0/arch/x86/kernel/sev.c linux-6.2.0/arch/x86/kernel/sev.c --- linux-6.2.0/arch/x86/kernel/sev.c +++ linux-6.2.0/arch/x86/kernel/sev.c @@ -512,6 +512,33 @@ return ES_OK; } +static enum es_result vc_ioio_check(struct es_em_ctxt *ctxt, u16 port, size_t size) +{ + BUG_ON(size > 4); + + if (user_mode(ctxt->regs)) { + struct thread_struct *t = ¤t->thread; + struct io_bitmap *iobm = t->io_bitmap; + size_t idx; + + if (!iobm) + goto fault; + + for (idx = port; idx < port + size; ++idx) { + if (test_bit(idx, iobm->bitmap)) + goto fault; + } + } + + return ES_OK; + +fault: + ctxt->fi.vector = X86_TRAP_GP; + ctxt->fi.error_code = 0; + + return ES_EXCEPTION; +} + /* Include code shared with pre-decompression boot stage */ #include "sev-shared.c" @@ -1552,6 +1579,9 @@ return ES_DECODE_FAILED; } + if (user_mode(ctxt->regs)) + return ES_UNSUPPORTED; + switch (mmio) { case INSN_MMIO_WRITE: memcpy(ghcb->shared_buffer, reg_data, bytes); diff -u linux-6.2.0/arch/x86/kernel/vmlinux.lds.S linux-6.2.0/arch/x86/kernel/vmlinux.lds.S --- linux-6.2.0/arch/x86/kernel/vmlinux.lds.S +++ linux-6.2.0/arch/x86/kernel/vmlinux.lds.S @@ -157,7 +157,7 @@ ALIGN_ENTRY_TEXT_END *(.gnu.warning) - } :text =0xcccc + } :text = 0xcccccccc /* End of text section, which should occupy whole number of pages */ _etext = .; diff -u linux-6.2.0/arch/x86/kvm/mmu/mmu.c linux-6.2.0/arch/x86/kvm/mmu/mmu.c --- linux-6.2.0/arch/x86/kvm/mmu/mmu.c +++ linux-6.2.0/arch/x86/kvm/mmu/mmu.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -56,6 +57,8 @@ extern bool itlb_multihit_kvm_mitigation; +static bool nx_hugepage_mitigation_hard_disabled; + int __read_mostly nx_huge_pages = -1; static uint __read_mostly nx_huge_pages_recovery_period_ms; #ifdef CONFIG_PREEMPT_RT @@ -65,12 +68,13 @@ static uint __read_mostly nx_huge_pages_recovery_ratio = 60; #endif +static int get_nx_huge_pages(char *buffer, const struct kernel_param *kp); static int set_nx_huge_pages(const char *val, const struct kernel_param *kp); static int set_nx_huge_pages_recovery_param(const char *val, const struct kernel_param *kp); static const struct kernel_param_ops nx_huge_pages_ops = { .set = set_nx_huge_pages, - .get = param_get_bool, + .get = get_nx_huge_pages, }; static const struct kernel_param_ops nx_huge_pages_recovery_param_ops = { @@ -6130,7 +6134,6 @@ void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end) { bool flush; - int i; if (WARN_ON_ONCE(gfn_end <= gfn_start)) return; @@ -6141,11 +6144,8 @@ flush = kvm_rmap_zap_gfn_range(kvm, gfn_start, gfn_end); - if (tdp_mmu_enabled) { - for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) - flush = kvm_tdp_mmu_zap_leafs(kvm, i, gfn_start, - gfn_end, true, flush); - } + if (tdp_mmu_enabled) + flush = kvm_tdp_mmu_zap_leafs(kvm, gfn_start, gfn_end, flush); if (flush) kvm_flush_remote_tlbs_with_address(kvm, gfn_start, @@ -6699,6 +6699,14 @@ kmem_cache_destroy(mmu_page_header_cache); } +static int get_nx_huge_pages(char *buffer, const struct kernel_param *kp) +{ + if (nx_hugepage_mitigation_hard_disabled) + return sprintf(buffer, "never\n"); + + return param_get_bool(buffer, kp); +} + static bool get_nx_auto_mode(void) { /* Return true when CPU has the bug, and mitigations are ON */ @@ -6715,15 +6723,29 @@ bool old_val = nx_huge_pages; bool new_val; + if (nx_hugepage_mitigation_hard_disabled) + return -EPERM; + /* In "auto" mode deploy workaround only if CPU has the bug. */ - if (sysfs_streq(val, "off")) + if (sysfs_streq(val, "off")) { new_val = 0; - else if (sysfs_streq(val, "force")) + } else if (sysfs_streq(val, "force")) { new_val = 1; - else if (sysfs_streq(val, "auto")) + } else if (sysfs_streq(val, "auto")) { new_val = get_nx_auto_mode(); - else if (strtobool(val, &new_val) < 0) + } else if (sysfs_streq(val, "never")) { + new_val = 0; + + mutex_lock(&kvm_lock); + if (!list_empty(&vm_list)) { + mutex_unlock(&kvm_lock); + return -EBUSY; + } + nx_hugepage_mitigation_hard_disabled = true; + mutex_unlock(&kvm_lock); + } else if (kstrtobool(val, &new_val) < 0) { return -EINVAL; + } __set_nx_huge_pages(new_val); @@ -6861,6 +6883,9 @@ uint old_period, new_period; int err; + if (nx_hugepage_mitigation_hard_disabled) + return -EPERM; + was_recovery_enabled = calc_nx_huge_pages_recovery_period(&old_period); err = param_set_uint(val, kp); @@ -7019,6 +7044,9 @@ { int err; + if (nx_hugepage_mitigation_hard_disabled) + return 0; + err = kvm_vm_create_worker_thread(kvm, kvm_nx_huge_page_recovery_worker, 0, "kvm-nx-lpage-recovery", &kvm->arch.nx_huge_page_recovery_thread); diff -u linux-6.2.0/arch/x86/kvm/mmu/tdp_mmu.c linux-6.2.0/arch/x86/kvm/mmu/tdp_mmu.c --- linux-6.2.0/arch/x86/kvm/mmu/tdp_mmu.c +++ linux-6.2.0/arch/x86/kvm/mmu/tdp_mmu.c @@ -210,8 +210,12 @@ #define for_each_valid_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared) \ __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, _shared, true) -#define for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id) \ - __for_each_tdp_mmu_root_yield_safe(_kvm, _root, _as_id, false, false) +#define for_each_tdp_mmu_root_yield_safe(_kvm, _root) \ + for (_root = tdp_mmu_next_root(_kvm, NULL, false, false); \ + _root; \ + _root = tdp_mmu_next_root(_kvm, _root, false, false)) \ + if (!kvm_lockdep_assert_mmu_lock_held(_kvm, false)) { \ + } else /* * Iterate over all TDP MMU roots. Requires that mmu_lock be held for write, @@ -950,13 +954,12 @@ * true if a TLB flush is needed before releasing the MMU lock, i.e. if one or * more SPTEs were zapped since the MMU lock was last acquired. */ -bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, gfn_t end, - bool can_yield, bool flush) +bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush) { struct kvm_mmu_page *root; - for_each_tdp_mmu_root_yield_safe(kvm, root, as_id) - flush = tdp_mmu_zap_leafs(kvm, root, start, end, can_yield, flush); + for_each_tdp_mmu_root_yield_safe(kvm, root) + flush = tdp_mmu_zap_leafs(kvm, root, start, end, true, flush); return flush; } @@ -964,7 +967,6 @@ void kvm_tdp_mmu_zap_all(struct kvm *kvm) { struct kvm_mmu_page *root; - int i; /* * Zap all roots, including invalid roots, as all SPTEs must be dropped @@ -978,10 +980,8 @@ * is being destroyed or the userspace VMM has exited. In both cases, * KVM_RUN is unreachable, i.e. no vCPUs will ever service the request. */ - for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { - for_each_tdp_mmu_root_yield_safe(kvm, root, i) - tdp_mmu_zap_root(kvm, root, false); - } + for_each_tdp_mmu_root_yield_safe(kvm, root) + tdp_mmu_zap_root(kvm, root, false); } /* @@ -1220,8 +1220,13 @@ bool kvm_tdp_mmu_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range, bool flush) { - return kvm_tdp_mmu_zap_leafs(kvm, range->slot->as_id, range->start, - range->end, range->may_block, flush); + struct kvm_mmu_page *root; + + __for_each_tdp_mmu_root_yield_safe(kvm, root, range->slot->as_id, false, false) + flush = tdp_mmu_zap_leafs(kvm, root, range->start, range->end, + range->may_block, flush); + + return flush; } typedef bool (*tdp_handler_t)(struct kvm *kvm, struct tdp_iter *iter, diff -u linux-6.2.0/arch/x86/kvm/mmu/tdp_mmu.h linux-6.2.0/arch/x86/kvm/mmu/tdp_mmu.h --- linux-6.2.0/arch/x86/kvm/mmu/tdp_mmu.h +++ linux-6.2.0/arch/x86/kvm/mmu/tdp_mmu.h @@ -20,8 +20,7 @@ void kvm_tdp_mmu_put_root(struct kvm *kvm, struct kvm_mmu_page *root, bool shared); -bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, int as_id, gfn_t start, - gfn_t end, bool can_yield, bool flush); +bool kvm_tdp_mmu_zap_leafs(struct kvm *kvm, gfn_t start, gfn_t end, bool flush); bool kvm_tdp_mmu_zap_sp(struct kvm *kvm, struct kvm_mmu_page *sp); void kvm_tdp_mmu_zap_all(struct kvm *kvm); void kvm_tdp_mmu_invalidate_all_roots(struct kvm *kvm); diff -u linux-6.2.0/arch/x86/kvm/svm/avic.c linux-6.2.0/arch/x86/kvm/svm/avic.c --- linux-6.2.0/arch/x86/kvm/svm/avic.c +++ linux-6.2.0/arch/x86/kvm/svm/avic.c @@ -810,6 +810,7 @@ int ret = 0; unsigned long flags; struct amd_svm_iommu_ir *ir; + u64 entry; /** * In some cases, the existing irte is updated and re-set, @@ -843,6 +844,18 @@ ir->data = pi->ir_data; spin_lock_irqsave(&svm->ir_list_lock, flags); + + /* + * Update the target pCPU for IOMMU doorbells if the vCPU is running. + * If the vCPU is NOT running, i.e. is blocking or scheduled out, KVM + * will update the pCPU info when the vCPU awkened and/or scheduled in. + * See also avic_vcpu_load(). + */ + entry = READ_ONCE(*(svm->avic_physical_id_cache)); + if (entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK) + amd_iommu_update_ga(entry & AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK, + true, pi->ir_data); + list_add(&ir->node, &svm->ir_list); spin_unlock_irqrestore(&svm->ir_list_lock, flags); out: @@ -1022,10 +1035,11 @@ avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, int cpu, bool r) { int ret = 0; - unsigned long flags; struct amd_svm_iommu_ir *ir; struct vcpu_svm *svm = to_svm(vcpu); + lockdep_assert_held(&svm->ir_list_lock); + if (!kvm_arch_has_assigned_device(vcpu->kvm)) return 0; @@ -1033,19 +1047,15 @@ * Here, we go through the per-vcpu ir_list to update all existing * interrupt remapping table entry targeting this vcpu. */ - spin_lock_irqsave(&svm->ir_list_lock, flags); - if (list_empty(&svm->ir_list)) - goto out; + return 0; list_for_each_entry(ir, &svm->ir_list, node) { ret = amd_iommu_update_ga(cpu, r, ir->data); if (ret) - break; + return ret; } -out: - spin_unlock_irqrestore(&svm->ir_list_lock, flags); - return ret; + return 0; } void avic_vcpu_load(struct kvm_vcpu *vcpu, int cpu) @@ -1053,6 +1063,7 @@ u64 entry; int h_physical_id = kvm_cpu_get_apicid(cpu); struct vcpu_svm *svm = to_svm(vcpu); + unsigned long flags; lockdep_assert_preemption_disabled(); @@ -1069,6 +1080,15 @@ if (kvm_vcpu_is_blocking(vcpu)) return; + /* + * Grab the per-vCPU interrupt remapping lock even if the VM doesn't + * _currently_ have assigned devices, as that can change. Holding + * ir_list_lock ensures that either svm_ir_list_add() will consume + * up-to-date entry information, or that this task will wait until + * svm_ir_list_add() completes to set the new target pCPU. + */ + spin_lock_irqsave(&svm->ir_list_lock, flags); + entry = READ_ONCE(*(svm->avic_physical_id_cache)); entry &= ~AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK; @@ -1077,25 +1097,48 @@ WRITE_ONCE(*(svm->avic_physical_id_cache), entry); avic_update_iommu_vcpu_affinity(vcpu, h_physical_id, true); + + spin_unlock_irqrestore(&svm->ir_list_lock, flags); } void avic_vcpu_put(struct kvm_vcpu *vcpu) { u64 entry; struct vcpu_svm *svm = to_svm(vcpu); + unsigned long flags; lockdep_assert_preemption_disabled(); + /* + * Note, reading the Physical ID entry outside of ir_list_lock is safe + * as only the pCPU that has loaded (or is loading) the vCPU is allowed + * to modify the entry, and preemption is disabled. I.e. the vCPU + * can't be scheduled out and thus avic_vcpu_{put,load}() can't run + * recursively. + */ entry = READ_ONCE(*(svm->avic_physical_id_cache)); /* Nothing to do if IsRunning == '0' due to vCPU blocking. */ if (!(entry & AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK)) return; + /* + * Take and hold the per-vCPU interrupt remapping lock while updating + * the Physical ID entry even though the lock doesn't protect against + * multiple writers (see above). Holding ir_list_lock ensures that + * either svm_ir_list_add() will consume up-to-date entry information, + * or that this task will wait until svm_ir_list_add() completes to + * mark the vCPU as not running. + */ + spin_lock_irqsave(&svm->ir_list_lock, flags); + avic_update_iommu_vcpu_affinity(vcpu, -1, 0); entry &= ~AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK; WRITE_ONCE(*(svm->avic_physical_id_cache), entry); + + spin_unlock_irqrestore(&svm->ir_list_lock, flags); + } void avic_refresh_virtual_apic_mode(struct kvm_vcpu *vcpu) diff -u linux-6.2.0/arch/x86/kvm/svm/sev.c linux-6.2.0/arch/x86/kvm/svm/sev.c --- linux-6.2.0/arch/x86/kvm/svm/sev.c +++ linux-6.2.0/arch/x86/kvm/svm/sev.c @@ -1723,7 +1723,7 @@ * Note, the source is not required to have the same number of * vCPUs as the destination when migrating a vanilla SEV VM. */ - src_vcpu = kvm_get_vcpu(dst_kvm, i); + src_vcpu = kvm_get_vcpu(src_kvm, i); src_svm = to_svm(src_vcpu); /* @@ -2941,6 +2941,32 @@ count, in); } +static void sev_es_vcpu_after_set_cpuid(struct vcpu_svm *svm) +{ + struct kvm_vcpu *vcpu = &svm->vcpu; + + if (boot_cpu_has(X86_FEATURE_V_TSC_AUX)) { + bool v_tsc_aux = guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP) || + guest_cpuid_has(vcpu, X86_FEATURE_RDPID); + + set_msr_interception(vcpu, svm->msrpm, MSR_TSC_AUX, v_tsc_aux, v_tsc_aux); + } +} + +void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm) +{ + struct kvm_vcpu *vcpu = &svm->vcpu; + struct kvm_cpuid_entry2 *best; + + /* For sev guests, the memory encryption bit is not reserved in CR3. */ + best = kvm_find_cpuid_entry(vcpu, 0x8000001F); + if (best) + vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f)); + + if (sev_es_guest(svm->vcpu.kvm)) + sev_es_vcpu_after_set_cpuid(svm); +} + static void sev_es_init_vmcb(struct vcpu_svm *svm) { struct kvm_vcpu *vcpu = &svm->vcpu; @@ -2951,9 +2977,12 @@ /* * An SEV-ES guest requires a VMSA area that is a separate from the * VMCB page. Do not include the encryption mask on the VMSA physical - * address since hardware will access it using the guest key. + * address since hardware will access it using the guest key. Note, + * the VMSA will be NULL if this vCPU is the destination for intrahost + * migration, and will be copied later. */ - svm->vmcb->control.vmsa_pa = __pa(svm->sev_es.vmsa); + if (svm->sev_es.vmsa) + svm->vmcb->control.vmsa_pa = __pa(svm->sev_es.vmsa); /* Can't intercept CR register access, HV can't modify CR registers */ svm_clr_intercept(svm, INTERCEPT_CR0_READ); @@ -2984,14 +3013,6 @@ set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); set_msr_interception(vcpu, svm->msrpm, MSR_IA32_LASTINTTOIP, 1, 1); - - if (boot_cpu_has(X86_FEATURE_V_TSC_AUX) && - (guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDTSCP) || - guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDPID))) { - set_msr_interception(vcpu, svm->msrpm, MSR_TSC_AUX, 1, 1); - if (guest_cpuid_has(&svm->vcpu, X86_FEATURE_RDTSCP)) - svm_clr_intercept(svm, INTERCEPT_RDTSCP); - } } void sev_init_vmcb(struct vcpu_svm *svm) diff -u linux-6.2.0/arch/x86/kvm/svm/svm.c linux-6.2.0/arch/x86/kvm/svm/svm.c --- linux-6.2.0/arch/x86/kvm/svm/svm.c +++ linux-6.2.0/arch/x86/kvm/svm/svm.c @@ -367,6 +367,8 @@ svm->vmcb->control.int_state |= SVM_INTERRUPT_SHADOW_MASK; } +static bool svm_can_emulate_instruction(struct kvm_vcpu *vcpu, int emul_type, + void *insn, int insn_len); static int __svm_skip_emulated_instruction(struct kvm_vcpu *vcpu, bool commit_side_effects) @@ -387,6 +389,14 @@ } if (!svm->next_rip) { + /* + * FIXME: Drop this when kvm_emulate_instruction() does the + * right thing and treats "can't emulate" as outright failure + * for EMULTYPE_SKIP. + */ + if (!svm_can_emulate_instruction(vcpu, EMULTYPE_SKIP, NULL, 0)) + return 0; + if (unlikely(!commit_side_effects)) old_rflags = svm->vmcb->save.rflags; @@ -4169,7 +4179,6 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); - struct kvm_cpuid_entry2 *best; vcpu->arch.xsaves_enabled = guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) && boot_cpu_has(X86_FEATURE_XSAVE) && @@ -4194,12 +4203,8 @@ svm_recalc_instruction_intercepts(vcpu, svm); - /* For sev guests, the memory encryption bit is not reserved in CR3. */ - if (sev_guest(vcpu->kvm)) { - best = kvm_find_cpuid_entry(vcpu, 0x8000001F); - if (best) - vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f)); - } + if (sev_guest(vcpu->kvm)) + sev_vcpu_after_set_cpuid(svm); init_vmcb_after_set_cpuid(vcpu); } @@ -4604,16 +4609,25 @@ * and cannot be decrypted by KVM, i.e. KVM would read cyphertext and * decode garbage. * - * Inject #UD if KVM reached this point without an instruction buffer. - * In practice, this path should never be hit by a well-behaved guest, - * e.g. KVM doesn't intercept #UD or #GP for SEV guests, but this path - * is still theoretically reachable, e.g. via unaccelerated fault-like - * AVIC access, and needs to be handled by KVM to avoid putting the - * guest into an infinite loop. Injecting #UD is somewhat arbitrary, - * but its the least awful option given lack of insight into the guest. + * If KVM is NOT trying to simply skip an instruction, inject #UD if + * KVM reached this point without an instruction buffer. In practice, + * this path should never be hit by a well-behaved guest, e.g. KVM + * doesn't intercept #UD or #GP for SEV guests, but this path is still + * theoretically reachable, e.g. via unaccelerated fault-like AVIC + * access, and needs to be handled by KVM to avoid putting the guest + * into an infinite loop. Injecting #UD is somewhat arbitrary, but + * its the least awful option given lack of insight into the guest. + * + * If KVM is trying to skip an instruction, simply resume the guest. + * If a #NPF occurs while the guest is vectoring an INT3/INTO, then KVM + * will attempt to re-inject the INT3/INTO and skip the instruction. + * In that scenario, retrying the INT3/INTO and hoping the guest will + * make forward progress is the only option that has a chance of + * success (and in practice it will work the vast majority of the time). */ if (unlikely(!insn)) { - kvm_queue_exception(vcpu, UD_VECTOR); + if (!(emul_type & EMULTYPE_SKIP)) + kvm_queue_exception(vcpu, UD_VECTOR); return false; } diff -u linux-6.2.0/arch/x86/kvm/svm/svm.h linux-6.2.0/arch/x86/kvm/svm/svm.h --- linux-6.2.0/arch/x86/kvm/svm/svm.h +++ linux-6.2.0/arch/x86/kvm/svm/svm.h @@ -677,6 +677,7 @@ void sev_hardware_unsetup(void); int sev_cpu_init(struct svm_cpu_data *sd); void sev_init_vmcb(struct vcpu_svm *svm); +void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm); void sev_free_vcpu(struct kvm_vcpu *vcpu); int sev_handle_vmgexit(struct kvm_vcpu *vcpu); int sev_es_string_io(struct vcpu_svm *svm, int size, unsigned int port, int in); diff -u linux-6.2.0/arch/x86/kvm/vmx/vmx.c linux-6.2.0/arch/x86/kvm/vmx/vmx.c --- linux-6.2.0/arch/x86/kvm/vmx/vmx.c +++ linux-6.2.0/arch/x86/kvm/vmx/vmx.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include #include #include @@ -702,7 +702,6 @@ return ret; } -#ifdef CONFIG_KEXEC_CORE static void crash_vmclear_local_loaded_vmcss(void) { int cpu = raw_smp_processor_id(); @@ -712,7 +711,6 @@ loaded_vmcss_on_cpu_link) vmcs_clear(v->vmcs); } -#endif /* CONFIG_KEXEC_CORE */ static void __loaded_vmcs_clear(void *arg) { @@ -8561,10 +8559,9 @@ { allow_smaller_maxphyaddr = false; -#ifdef CONFIG_KEXEC_CORE RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL); synchronize_rcu(); -#endif + vmx_cleanup_l1d_flush(); } @@ -8637,10 +8634,9 @@ pi_init_cpu(cpu); } -#ifdef CONFIG_KEXEC_CORE rcu_assign_pointer(crash_vmclear_loaded_vmcss, crash_vmclear_local_loaded_vmcss); -#endif + vmx_check_vmcs12_offsets(); /* diff -u linux-6.2.0/arch/x86/mm/mem_encrypt_amd.c linux-6.2.0/arch/x86/mm/mem_encrypt_amd.c --- linux-6.2.0/arch/x86/mm/mem_encrypt_amd.c +++ linux-6.2.0/arch/x86/mm/mem_encrypt_amd.c @@ -288,11 +288,10 @@ return !cpu_feature_enabled(X86_FEATURE_SME_COHERENT); } -static void enc_dec_hypercall(unsigned long vaddr, int npages, bool enc) +static void enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc) { #ifdef CONFIG_PARAVIRT - unsigned long sz = npages << PAGE_SHIFT; - unsigned long vaddr_end = vaddr + sz; + unsigned long vaddr_end = vaddr + size; while (vaddr < vaddr_end) { int psize, pmask, level; @@ -342,7 +341,7 @@ snp_set_memory_private(vaddr, npages); if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) - enc_dec_hypercall(vaddr, npages, enc); + enc_dec_hypercall(vaddr, npages << PAGE_SHIFT, enc); return true; } @@ -466,7 +465,7 @@ ret = 0; - early_set_mem_enc_dec_hypercall(start, PAGE_ALIGN(size) >> PAGE_SHIFT, enc); + early_set_mem_enc_dec_hypercall(start, size, enc); out: __flush_tlb_all(); return ret; @@ -482,9 +481,9 @@ return early_set_memory_enc_dec(vaddr, size, true); } -void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, int npages, bool enc) +void __init early_set_mem_enc_dec_hypercall(unsigned long vaddr, unsigned long size, bool enc) { - enc_dec_hypercall(vaddr, npages, enc); + enc_dec_hypercall(vaddr, size, enc); } void __init sme_early_init(void) diff -u linux-6.2.0/arch/x86/purgatory/Makefile linux-6.2.0/arch/x86/purgatory/Makefile --- linux-6.2.0/arch/x86/purgatory/Makefile +++ linux-6.2.0/arch/x86/purgatory/Makefile @@ -19,6 +19,10 @@ # optimization flags. KBUILD_CFLAGS := $(filter-out -fprofile-sample-use=% -fprofile-use=%,$(KBUILD_CFLAGS)) +# When LTO is enabled, llvm emits many text sections, which is not supported +# by kexec. Remove -flto=* flags. +KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO),$(KBUILD_CFLAGS)) + # When linking purgatory.ro with -r unresolved symbols are not checked, # also link a purgatory.chk binary without -r to check for unresolved symbols. PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib diff -u linux-6.2.0/arch/xtensa/platforms/iss/network.c linux-6.2.0/arch/xtensa/platforms/iss/network.c --- linux-6.2.0/arch/xtensa/platforms/iss/network.c +++ linux-6.2.0/arch/xtensa/platforms/iss/network.c @@ -201,7 +201,7 @@ return simc_write(lp->tp.info.tuntap.fd, (*skb)->data, (*skb)->len); } -unsigned short tuntap_protocol(struct sk_buff *skb) +static unsigned short tuntap_protocol(struct sk_buff *skb) { return eth_type_trans(skb, skb->dev); } @@ -441,7 +441,7 @@ return -EINVAL; } -void iss_net_user_timer_expire(struct timer_list *unused) +static void iss_net_user_timer_expire(struct timer_list *unused) { } diff -u linux-6.2.0/block/bio-integrity.c linux-6.2.0/block/bio-integrity.c --- linux-6.2.0/block/bio-integrity.c +++ linux-6.2.0/block/bio-integrity.c @@ -124,23 +124,18 @@ unsigned int len, unsigned int offset) { struct bio_integrity_payload *bip = bio_integrity(bio); - struct bio_vec *iv; if (bip->bip_vcnt >= bip->bip_max_vcnt) { printk(KERN_ERR "%s: bip_vec full\n", __func__); return 0; } - iv = bip->bip_vec + bip->bip_vcnt; - if (bip->bip_vcnt && bvec_gap_to_prev(&bdev_get_queue(bio->bi_bdev)->limits, &bip->bip_vec[bip->bip_vcnt - 1], offset)) return 0; - iv->bv_page = page; - iv->bv_len = len; - iv->bv_offset = offset; + bvec_set_page(&bip->bip_vec[bip->bip_vcnt], page, len, offset); bip->bip_vcnt++; return len; diff -u linux-6.2.0/block/bio.c linux-6.2.0/block/bio.c --- linux-6.2.0/block/bio.c +++ linux-6.2.0/block/bio.c @@ -1030,10 +1030,7 @@ if (bio->bi_vcnt >= queue_max_segments(q)) return 0; - bvec = &bio->bi_io_vec[bio->bi_vcnt]; - bvec->bv_page = page; - bvec->bv_len = len; - bvec->bv_offset = offset; + bvec_set_page(&bio->bi_io_vec[bio->bi_vcnt], page, len, offset); bio->bi_vcnt++; bio->bi_iter.bi_size += len; return len; @@ -1109,15 +1106,10 @@ void __bio_add_page(struct bio *bio, struct page *page, unsigned int len, unsigned int off) { - struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt]; - WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)); WARN_ON_ONCE(bio_full(bio, len)); - bv->bv_page = page; - bv->bv_offset = off; - bv->bv_len = len; - + bvec_set_page(&bio->bi_io_vec[bio->bi_vcnt], page, len, off); bio->bi_iter.bi_size += len; bio->bi_vcnt++; } diff -u linux-6.2.0/block/blk-settings.c linux-6.2.0/block/blk-settings.c --- linux-6.2.0/block/blk-settings.c +++ linux-6.2.0/block/blk-settings.c @@ -824,10 +824,13 @@ */ void blk_queue_write_cache(struct request_queue *q, bool wc, bool fua) { - if (wc) + if (wc) { + blk_queue_flag_set(QUEUE_FLAG_HW_WC, q); blk_queue_flag_set(QUEUE_FLAG_WC, q); - else + } else { + blk_queue_flag_clear(QUEUE_FLAG_HW_WC, q); blk_queue_flag_clear(QUEUE_FLAG_WC, q); + } if (fua) blk_queue_flag_set(QUEUE_FLAG_FUA, q); else diff -u linux-6.2.0/block/blk-throttle.c linux-6.2.0/block/blk-throttle.c --- linux-6.2.0/block/blk-throttle.c +++ linux-6.2.0/block/blk-throttle.c @@ -698,11 +698,41 @@ return true; } +static unsigned int calculate_io_allowed(u32 iops_limit, + unsigned long jiffy_elapsed) +{ + unsigned int io_allowed; + u64 tmp; + + /* + * jiffy_elapsed should not be a big value as minimum iops can be + * 1 then at max jiffy elapsed should be equivalent of 1 second as we + * will allow dispatch after 1 second and after that slice should + * have been trimmed. + */ + + tmp = (u64)iops_limit * jiffy_elapsed; + do_div(tmp, HZ); + + if (tmp > UINT_MAX) + io_allowed = UINT_MAX; + else + io_allowed = tmp; + + return io_allowed; +} + +static u64 calculate_bytes_allowed(u64 bps_limit, unsigned long jiffy_elapsed) +{ + return mul_u64_u64_div_u64(bps_limit, (u64)jiffy_elapsed, (u64)HZ); +} + /* Trim the used slices and adjust slice start accordingly */ static inline void throtl_trim_slice(struct throtl_grp *tg, bool rw) { - unsigned long nr_slices, time_elapsed, io_trim; - u64 bytes_trim, tmp; + unsigned long time_elapsed; + long long bytes_trim; + int io_trim; BUG_ON(time_before(tg->slice_end[rw], tg->slice_start[rw])); @@ -724,67 +754,38 @@ throtl_set_slice_end(tg, rw, jiffies + tg->td->throtl_slice); - time_elapsed = jiffies - tg->slice_start[rw]; - - nr_slices = time_elapsed / tg->td->throtl_slice; - - if (!nr_slices) + time_elapsed = rounddown(jiffies - tg->slice_start[rw], + tg->td->throtl_slice); + if (!time_elapsed) return; - tmp = tg_bps_limit(tg, rw) * tg->td->throtl_slice * nr_slices; - do_div(tmp, HZ); - bytes_trim = tmp; - - io_trim = (tg_iops_limit(tg, rw) * tg->td->throtl_slice * nr_slices) / - HZ; - if (!bytes_trim && !io_trim) + bytes_trim = calculate_bytes_allowed(tg_bps_limit(tg, rw), + time_elapsed) + + tg->carryover_bytes[rw]; + io_trim = calculate_io_allowed(tg_iops_limit(tg, rw), time_elapsed) + + tg->carryover_ios[rw]; + if (bytes_trim <= 0 && io_trim <= 0) return; - if (tg->bytes_disp[rw] >= bytes_trim) + tg->carryover_bytes[rw] = 0; + if ((long long)tg->bytes_disp[rw] >= bytes_trim) tg->bytes_disp[rw] -= bytes_trim; else tg->bytes_disp[rw] = 0; - if (tg->io_disp[rw] >= io_trim) + tg->carryover_ios[rw] = 0; + if ((int)tg->io_disp[rw] >= io_trim) tg->io_disp[rw] -= io_trim; else tg->io_disp[rw] = 0; - tg->slice_start[rw] += nr_slices * tg->td->throtl_slice; + tg->slice_start[rw] += time_elapsed; throtl_log(&tg->service_queue, - "[%c] trim slice nr=%lu bytes=%llu io=%lu start=%lu end=%lu jiffies=%lu", - rw == READ ? 'R' : 'W', nr_slices, bytes_trim, io_trim, - tg->slice_start[rw], tg->slice_end[rw], jiffies); -} - -static unsigned int calculate_io_allowed(u32 iops_limit, - unsigned long jiffy_elapsed) -{ - unsigned int io_allowed; - u64 tmp; - - /* - * jiffy_elapsed should not be a big value as minimum iops can be - * 1 then at max jiffy elapsed should be equivalent of 1 second as we - * will allow dispatch after 1 second and after that slice should - * have been trimmed. - */ - - tmp = (u64)iops_limit * jiffy_elapsed; - do_div(tmp, HZ); - - if (tmp > UINT_MAX) - io_allowed = UINT_MAX; - else - io_allowed = tmp; - - return io_allowed; -} - -static u64 calculate_bytes_allowed(u64 bps_limit, unsigned long jiffy_elapsed) -{ - return mul_u64_u64_div_u64(bps_limit, (u64)jiffy_elapsed, (u64)HZ); + "[%c] trim slice nr=%lu bytes=%lld io=%d start=%lu end=%lu jiffies=%lu", + rw == READ ? 'R' : 'W', time_elapsed / tg->td->throtl_slice, + bytes_trim, io_trim, tg->slice_start[rw], tg->slice_end[rw], + jiffies); } static void __tg_update_carryover(struct throtl_grp *tg, bool rw) diff -u linux-6.2.0/block/ioctl.c linux-6.2.0/block/ioctl.c --- linux-6.2.0/block/ioctl.c +++ linux-6.2.0/block/ioctl.c @@ -20,6 +20,8 @@ struct blkpg_partition p; long long start, length; + if (disk->flags & GENHD_FL_NO_PART) + return -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (copy_from_user(&p, upart, sizeof(struct blkpg_partition))) diff -u linux-6.2.0/crypto/algapi.c linux-6.2.0/crypto/algapi.c --- linux-6.2.0/crypto/algapi.c +++ linux-6.2.0/crypto/algapi.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "internal.h" @@ -74,15 +75,26 @@ inst->alg.cra_type->free(inst); } -static void crypto_destroy_instance(struct crypto_alg *alg) +static void crypto_destroy_instance_workfn(struct work_struct *w) { - struct crypto_instance *inst = (void *)alg; + struct crypto_instance *inst = container_of(w, struct crypto_instance, + free_work); struct crypto_template *tmpl = inst->tmpl; crypto_free_instance(inst); crypto_tmpl_put(tmpl); } +static void crypto_destroy_instance(struct crypto_alg *alg) +{ + struct crypto_instance *inst = container_of(alg, + struct crypto_instance, + alg); + + INIT_WORK(&inst->free_work, crypto_destroy_instance_workfn); + schedule_work(&inst->free_work); +} + /* * This function adds a spawn to the list secondary_spawns which * will be used at the end of crypto_remove_spawns to unregister diff -u linux-6.2.0/crypto/xts.c linux-6.2.0/crypto/xts.c --- linux-6.2.0/crypto/xts.c +++ linux-6.2.0/crypto/xts.c @@ -396,10 +396,10 @@ * cipher name. */ if (!strncmp(cipher_name, "ecb(", 4)) { - unsigned len; + int len; - len = strlcpy(ctx->name, cipher_name + 4, sizeof(ctx->name)); - if (len < 2 || len >= sizeof(ctx->name)) + len = strscpy(ctx->name, cipher_name + 4, sizeof(ctx->name)); + if (len < 2) goto err_free_inst; if (ctx->name[len - 1] != ')') diff -u linux-6.2.0/debian.master/abi/abiname linux-6.2.0/debian.master/abi/abiname --- linux-6.2.0/debian.master/abi/abiname +++ linux-6.2.0/debian.master/abi/abiname @@ -1 +1 @@ -38 +39 diff -u linux-6.2.0/debian.master/abi/armhf/generic-lpae.modules linux-6.2.0/debian.master/abi/armhf/generic-lpae.modules --- linux-6.2.0/debian.master/abi/armhf/generic-lpae.modules +++ linux-6.2.0/debian.master/abi/armhf/generic-lpae.modules @@ -3800,7 +3800,6 @@ nvmet-fc nvmet-rdma nvmet-tcp -nvsw-sn2201 nwl-dsi nxp-c45-tja11xx nxp-nci diff -u linux-6.2.0/debian.master/abi/armhf/generic.modules linux-6.2.0/debian.master/abi/armhf/generic.modules --- linux-6.2.0/debian.master/abi/armhf/generic.modules +++ linux-6.2.0/debian.master/abi/armhf/generic.modules @@ -3800,7 +3800,6 @@ nvmet-fc nvmet-rdma nvmet-tcp -nvsw-sn2201 nwl-dsi nxp-c45-tja11xx nxp-nci diff -u linux-6.2.0/debian.master/abi/version linux-6.2.0/debian.master/abi/version --- linux-6.2.0/debian.master/abi/version +++ linux-6.2.0/debian.master/abi/version @@ -1 +1 @@ -6.2.0-38.39 +6.2.0-39.40 diff -u linux-6.2.0/debian.master/changelog linux-6.2.0/debian.master/changelog --- linux-6.2.0/debian.master/changelog +++ linux-6.2.0/debian.master/changelog @@ -1,3 +1,1502 @@ +linux (6.2.0-41.42) lunar; urgency=medium + + * lunar/linux: 6.2.0-41.42 -proposed tracker (LP: #2048351) + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] resync update-dkms-versions helper + - [Packaging] remove helper scripts + - [Packaging] update annotations scripts + - debian/dkms-versions -- update from kernel-versions (main/2024.01.08) + + * [SRU][22.04.2 & 23.10] OS cannot boot successfully when enabling VMD in UEFI + setup (LP: #2020022) + - x86: don't use REP_GOOD or ERMS for small memory clearing + - x86/cpufeatures: Add macros for Intel's new fast rep string features + + * Hotplugging SCSI disk in QEMU VM fails (LP: #2047382) + - Revert "PCI: acpiphp: Reassign resources on bridge if necessary" + + * CVE-2023-6622 + - netfilter: nf_tables: bail out on mismatching dynset and set expressions + + * CVE-2023-6111 + - netfilter: nf_tables: remove catchall element in GC sync path + + * CVE-2024-0193 + - netfilter: nf_tables: skip set commit for deleted/destroyed sets + + * Sound: Add rtl quirk of M90-Gen5 (LP: #2046105) + - ALSA: hda/realtek: Enable headset on Lenovo M90 Gen5 + + * [Debian] autoreconstruct - Do not generate chmod -x for deleted files + (LP: #2045562) + - [Debian] autoreconstruct - Do not generate chmod -x for deleted files + + * CVE-2023-6932 + - ipv4: igmp: fix refcnt uaf issue when receiving igmp query packet + + * CVE-2023-6931 + - perf: Fix perf_event_validate_size() + - perf: Fix perf_event_validate_size() lockdep splat + + * CVE-2023-6531 + - io_uring/af_unix: disable sending io_uring over sockets + + * CVE-2023-6606 + - smb: client: fix OOB in smbCalcSize() + + * CVE-2023-6817 + - netfilter: nft_set_pipapo: skip inactive elements during set walk + + * Avoid using damage rectangle under hardware rotation mode when PSR is + enabled (LP: #2045958) + - drm/amd/display: fix hw rotated modes when PSR-SU is enabled + + * Lunar update: upstream stable patchset 2023-12-11 (LP: #2046197) + - NFS/pNFS: Report EINVAL errors from connect() to the server + - SUNRPC: Mark the cred for revalidation if the server rejects it + - NFSv4.1: use EXCHGID4_FLAG_USE_PNFS_DS for DS server + - NFSv4.1: fix pnfs MDS=DS session trunking + - media: v4l: Use correct dependency for camera sensor drivers + - media: via: Use correct dependency for camera sensor drivers + - netfs: Only call folio_start_fscache() one time for each folio + - dm: fix a race condition in retrieve_deps + - btrfs: improve error message after failure to add delayed dir index item + - btrfs: remove BUG() after failure to insert delayed dir index item + - ext4: replace the traditional ternary conditional operator with with + max()/min() + - ext4: move setting of trimmed bit into ext4_try_to_trim_range() + - ext4: do not let fstrim block system suspend + - netfilter: nft_set_rbtree: use read spinlock to avoid datapath contention + - netfilter: nft_set_pipapo: call nft_trans_gc_queue_sync() in catchall GC + - netfilter: nft_set_pipapo: stop GC iteration if GC transaction allocation + fails + - netfilter: nft_set_hash: try later when GC hits EAGAIN on iteration + - netfilter: nf_tables: fix memleak when more than 255 elements expired + - ASoC: meson: spdifin: start hw on dai probe + - netfilter: nf_tables: disallow element removal on anonymous sets + - bpf: Avoid deadlock when using queue and stack maps from NMI + - ASoC: rt5640: Revert "Fix sleep in atomic context" + - ASoC: rt5640: Fix IRQ not being free-ed for HDA jack detect mode + - ALSA: hda/realtek: Splitting the UX3402 into two separate models + - netfilter: conntrack: fix extension size table + - selftests: tls: swap the TX and RX sockets in some tests + - net/core: Fix ETH_P_1588 flow dissector + - ASoC: hdaudio.c: Add missing check for devm_kstrdup + - ASoC: imx-audmix: Fix return error with devm_clk_get() + - octeon_ep: fix tx dma unmap len values in SG + - iavf: do not process adminq tasks when __IAVF_IN_REMOVE_TASK is set + - ASoC: SOF: core: Only call sof_ops_free() on remove if the probe was + successful + - iavf: add iavf_schedule_aq_request() helper + - iavf: schedule a request immediately after add/delete vlan + - i40e: Fix VF VLAN offloading when port VLAN is configured + - netfilter, bpf: Adjust timeouts of non-confirmed CTs in + bpf_ct_insert_entry() + - ionic: fix 16bit math issue when PAGE_SIZE >= 64KB + - igc: Fix infinite initialization loop with early XDP redirect + - scsi: iscsi_tcp: restrict to TCP sockets + - powerpc/perf/hv-24x7: Update domain value check + - dccp: fix dccp_v4_err()/dccp_v6_err() again + - x86/mm, kexec, ima: Use memblock_free_late() from ima_free_kexec_buffer() + - net: hsr: Properly parse HSRv1 supervisor frames. + - platform/x86: intel_scu_ipc: Check status after timeout in busy_loop() + - platform/x86: intel_scu_ipc: Check status upon timeout in + ipc_wait_for_interrupt() + - platform/x86: intel_scu_ipc: Don't override scu in + intel_scu_ipc_dev_simple_command() + - platform/x86: intel_scu_ipc: Fail IPC send if still busy + - x86/srso: Fix srso_show_state() side effect + - x86/srso: Fix SBPB enablement for spec_rstack_overflow=off + - net: hns3: add cmdq check for vf periodic service task + - net: hns3: fix GRE checksum offload issue + - net: hns3: only enable unicast promisc when mac table full + - net: hns3: fix fail to delete tc flower rules during reset issue + - net: hns3: add 5ms delay before clear firmware reset irq source + - net: bridge: use DEV_STATS_INC() + - team: fix null-ptr-deref when team device type is changed + - net: rds: Fix possible NULL-pointer dereference + - netfilter: nf_tables: disable toggling dormant table state more than once + - i915/pmu: Move execlist stats initialization to execlist specific setup + - locking/seqlock: Do the lockdep annotation before locking in + do_write_seqcount_begin_nested() + - net: ena: Flush XDP packets on error. + - bnxt_en: Flush XDP for bnxt_poll_nitroa0()'s NAPI + - octeontx2-pf: Do xdp_do_flush() after redirects. + - igc: Expose tx-usecs coalesce setting to user + - proc: nommu: /proc//maps: release mmap read lock + - proc: nommu: fix empty /proc//maps + - cifs: Fix UAF in cifs_demultiplex_thread() + - gpio: tb10x: Fix an error handling path in tb10x_gpio_probe() + - i2c: mux: demux-pinctrl: check the return value of devm_kstrdup() + - i2c: mux: gpio: Add missing fwnode_handle_put() + - i2c: xiic: Correct return value check for xiic_reinit() + - ARM: dts: samsung: exynos4210-i9100: Fix LCD screen's physical size + - f2fs: get out of a repeat loop when getting a locked data page + - s390/pkey: fix PKEY_TYPE_EP11_AES handling in PKEY_CLR2SECK2 IOCTL + - arm64: dts: qcom: sdm845-db845c: Mark cont splash memory region as reserved + - wifi: ath11k: fix tx status reporting in encap offload mode + - wifi: ath11k: Cleanup mac80211 references on failure during tx_complete + - scsi: qla2xxx: Select qpair depending on which CPU post_cmd() gets called + - scsi: qla2xxx: Use raw_smp_processor_id() instead of smp_processor_id() + - drm/amdkfd: Flush TLB after unmapping for GFX v9.4.3 + - drm/amdkfd: Insert missing TLB flush on GFX10 and later + - btrfs: reset destination buffer when read_extent_buffer() gets invalid range + - vfio/mdev: Fix a null-ptr-deref bug for mdev_unregister_parent() + - MIPS: Alchemy: only build mmc support helpers if au1xmmc is enabled + - spi: spi-gxp: BUG: Correct spi write return value + - drm/bridge: ti-sn65dsi83: Do not generate HFP/HBP/HSA and EOT packet + - bus: ti-sysc: Use fsleep() instead of usleep_range() in sysc_reset() + - bus: ti-sysc: Fix missing AM35xx SoC matching + - firmware: arm_scmi: Harden perf domain info access + - firmware: arm_scmi: Fixup perf power-cost/microwatt support + - power: supply: mt6370: Fix missing error code in mt6370_chg_toggle_cfo() + - clk: sprd: Fix thm_parents incorrect configuration + - clk: tegra: fix error return case for recalc_rate + - ARM: dts: ti: omap: Fix bandgap thermal cells addressing for omap3/4 + - ARM: dts: Unify pinctrl-single pin group nodes for omap4 + - ARM: dts: ti: omap: motorola-mapphone: Fix abe_clkctrl warning on boot + - bus: ti-sysc: Fix SYSC_QUIRK_SWSUP_SIDLE_ACT handling for uart wake-up + - power: supply: ucs1002: fix error code in ucs1002_get_property() + - firmware: imx-dsp: Fix an error handling path in imx_dsp_setup_channels() + - xtensa: add default definition for XCHAL_HAVE_DIV32 + - xtensa: iss/network: make functions static + - xtensa: boot: don't add include-dirs + - xtensa: umulsidi3: fix conditional expression + - xtensa: boot/lib: fix function prototypes + - power: supply: rk817: Fix node refcount leak + - selftests/powerpc: Use CLEAN macro to fix make warning + - selftests/powerpc: Pass make context to children + - selftests/powerpc: Fix emit_tests to work with run_kselftest.sh + - soc: imx8m: Enable OCOTP clock for imx8mm before reading registers + - arm64: dts: imx: Add imx8mm-prt8mm.dtb to build + - firmware: arm_ffa: Don't set the memory region attributes for MEM_LEND + - gpio: pmic-eic-sprd: Add can_sleep flag for PMIC EIC chip + - i2c: npcm7xx: Fix callback completion ordering + - x86/reboot: VMCLEAR active VMCSes before emergency reboot + - ceph: drop messages from MDS when unmounting + - dma-debug: don't call __dma_entry_alloc_check_leak() under free_entries_lock + - bpf: Annotate bpf_long_memcpy with data_race + - spi: sun6i: reduce DMA RX transfer width to single byte + - spi: sun6i: fix race between DMA RX transfer completion and RX FIFO drain + - nvme-fc: Prevent null pointer dereference in nvme_fc_io_getuuid() + - parisc: sba: Fix compile warning wrt list of SBA devices + - parisc: iosapic.c: Fix sparse warnings + - parisc: drivers: Fix sparse warning + - parisc: irq: Make irq_stack_union static to avoid sparse warning + - scsi: qedf: Add synchronization between I/O completions and abort + - scsi: ufs: core: Move __ufshcd_send_uic_cmd() outside host_lock + - scsi: ufs: core: Poll HCS.UCRDY before issuing a UIC command + - selftests/ftrace: Correctly enable event in instance-event.tc + - ring-buffer: Avoid softlockup in ring_buffer_resize() + - btrfs: assert delayed node locked when removing delayed item + - selftests: fix dependency checker script + - ring-buffer: Do not attempt to read past "commit" + - net/smc: bugfix for smcr v2 server connect success statistic + - ata: sata_mv: Fix incorrect string length computation in mv_dump_mem() + - platform/mellanox: mlxbf-bootctl: add NET dependency into Kconfig + - platform/x86: asus-wmi: Support 2023 ROG X16 tablet mode + - thermal/of: add missing of_node_put() + - drm/amd/display: Don't check registers, if using AUX BL control + - drm/amdgpu/soc21: don't remap HDP registers for SR-IOV + - drm/amdgpu/nbio4.3: set proper rmmio_remap.reg_offset for SR-IOV + - drm/amdgpu: Handle null atom context in VBIOS info ioctl + - riscv: errata: fix T-Head dcache.cva encoding + - scsi: pm80xx: Use phy-specific SAS address when sending PHY_START command + - scsi: pm80xx: Avoid leaking tags when processing + OPC_INB_SET_CONTROLLER_CONFIG command + - smb3: correct places where ENOTSUPP is used instead of preferred EOPNOTSUPP + - ata: libata-eh: do not clear ATA_PFLAG_EH_PENDING in ata_eh_reset() + - spi: nxp-fspi: reset the FLSHxCR1 registers + - spi: stm32: add a delay before SPI disable + - ASoC: fsl: imx-pcm-rpmsg: Add SNDRV_PCM_INFO_BATCH flag + - spi: intel-pci: Add support for Granite Rapids SPI serial flash + - bpf: Clarify error expectations from bpf_clone_redirect + - ALSA: hda: intel-sdw-acpi: Use u8 type for link index + - ASoC: cs42l42: Ensure a reset pulse meets minimum pulse width. + - ASoC: cs42l42: Don't rely on GPIOD_OUT_LOW to set RESET initially low + - firmware: cirrus: cs_dsp: Only log list of algorithms in debug build + - memblock tests: fix warning: "__ALIGN_KERNEL" redefined + - memblock tests: fix warning ‘struct seq_file’ declared inside parameter list + - ASoC: imx-rpmsg: Set ignore_pmdown_time for dai_link + - media: vb2: frame_vector.c: replace WARN_ONCE with a comment + - NFSv4.1: fix zero value filehandle in post open getattr + - ASoC: SOF: Intel: MTL: Reduce the DSP init timeout + - powerpc/watchpoints: Disable preemption in thread_change_pc() + - powerpc/watchpoint: Disable pagefaults when getting user instruction + - powerpc/watchpoints: Annotate atomic context in more places + - net: hsr: Add __packed to struct hsr_sup_tlv. + - tsnep: Fix NAPI scheduling + - tsnep: Fix NAPI polling with budget 0 + - LoongArch: Set all reserved memblocks on Node#0 at initialization + - fbdev/sh7760fb: Depend on FB=y + - perf build: Define YYNOMEM as YYNOABORT for bison < 3.81 + - nvme-pci: do not set the NUMA node of device if it has none + - wifi: ath11k: Don't drop tx_status when peer cannot be found + - scsi: qla2xxx: Fix NULL pointer dereference in target mode + - smack: Record transmuting in smk_transmuted + - smack: Retrieve transmuting information in smack_inode_getsecurity() + - iommu/arm-smmu-v3: Fix soft lockup triggered by arm_smmu_mm_invalidate_range + - x86/sgx: Resolves SECS reclaim vs. page fault for EAUG race + - x86/srso: Add SRSO mitigation for Hygon processors + - KVM: SVM: INTERCEPT_RDTSCP is never intercepted anyway + - KVM: SVM: Fix TSC_AUX virtualization setup + - KVM: x86/mmu: Open code leaf invalidation from mmu_notifier + - KVM: x86/mmu: Do not filter address spaces in + for_each_tdp_mmu_root_yield_safe() + - mptcp: fix bogus receive window shrinkage with multiple subflows + - Revert "tty: n_gsm: fix UAF in gsm_cleanup_mux" + - serial: 8250_port: Check IRQ data before use + - nilfs2: fix potential use after free in nilfs_gccache_submit_read_data() + - ALSA: hda: Disable power save for solving pop issue on Lenovo ThinkCentre + M70q + - LoongArch: Define relocation types for ABI v2.10 + - LoongArch: numa: Fix high_memory calculation + - ata: libata-scsi: link ata port and scsi device + - ata: libata-scsi: ignore reserved bits for REPORT SUPPORTED OPERATION CODES + - io_uring/fs: remove sqe->rw_flags checking from LINKAT + - i2c: i801: unregister tco_pdev in i801_probe() error path + - ASoC: amd: yc: Fix non-functional mic on Lenovo 82QF and 82UG + - kernel/sched: Modify initial boot task idle setup + - sched/rt: Fix live lock between select_fallback_rq() and RT push + - Revert "SUNRPC dont update timeout value on connection reset" + - timers: Tag (hr)timer softirq as hotplug safe + - drm/tests: Fix incorrect argument in drm_test_mm_insert_range + - arm64: defconfig: remove CONFIG_COMMON_CLK_NPCM8XX=y + - mm/damon/vaddr-test: fix memory leak in damon_do_test_apply_three_regions() + - mm/slab_common: fix slab_caches list corruption after kmem_cache_destroy() + - mm: memcontrol: fix GFP_NOFS recursion in memory.high enforcement + - ring-buffer: Update "shortest_full" in polling + - btrfs: properly report 0 avail for very full file systems + - media: uvcvideo: Fix OOB read + - bpf: Add override check to kprobe multi link attach + - bpf: Fix BTF_ID symbol generation collision + - bpf: Fix BTF_ID symbol generation collision in tools/ + - net: thunderbolt: Fix TCPv6 GSO checksum calculation + - ata: libata-core: Fix ata_port_request_pm() locking + - ata: libata-core: Fix port and device removal + - ata: libata-core: Do not register PM operations for SAS ports + - ata: libata-sata: increase PMP SRST timeout to 10s + - drm/i915/gt: Fix reservation address in ggtt_reserve_guc_top + - power: supply: rk817: Add missing module alias + - power: supply: ab8500: Set typing and props + - fs: binfmt_elf_efpic: fix personality for ELF-FDPIC + - drm/amdkfd: Use gpu_offset for user queue's wptr + - drm/meson: fix memory leak on ->hpd_notify callback + - memcg: drop kmem.limit_in_bytes + - mm, memcg: reconsider kmem.limit_in_bytes deprecation + - ASoC: amd: yc: Fix a non-functional mic on Lenovo 82TL + - NFS: More fixes for nfs_direct_write_reschedule_io() + - ASoC: rt5640: Fix sleep in atomic context + - ASoC: rt5640: Do not disable/enable IRQ twice on suspend/resume + - ASoC: rt5640: Enable the IRQ on resume after configuring jack-detect + - uapi: stddef.h: Fix __DECLARE_FLEX_ARRAY for C++ + - net: microchip: sparx5: Fix memory leak for + vcap_api_rule_add_keyvalue_test() + - net: microchip: sparx5: Fix memory leak for + vcap_api_rule_add_actionvalue_test() + - net: microchip: sparx5: Fix possible memory leak in + vcap_api_encode_rule_test() + - net: microchip: sparx5: Fix possible memory leaks in + test_vcap_xn_rule_creator() + - net: microchip: sparx5: Fix possible memory leaks in vcap_api_kunit + - x86/srso: Set CPUID feature bits independently of bug or mitigation status + - x86/srso: Don't probe microcode in a guest + - vxlan: Add missing entries to vxlan_get_size() + - net: hinic: Fix warning-hinic_set_vlan_fliter() warn: variable dereferenced + before check 'hwdev' + - swiotlb: use the calculated number of areas + - i915/guc: Get runtime pm in busyness worker only if already active + - spi: zynqmp-gqspi: fix clock imbalance on probe failure + - mm: page_alloc: fix CMA and HIGHATOMIC landing on the wrong buddy list + - ring-buffer: Fix bytes info in per_cpu buffer stats + - btrfs: file_remove_privs needs an exclusive lock in direct io write + - Upstream stable to v6.1.56, v6.5.6 + - ASoC: soc-utils: Export snd_soc_dai_is_dummy() symbol + - ASoC: tegra: Fix redundant PLLA and PLLA_OUT0 updates + - mptcp: rename timer related helper to less confusing names + - mptcp: fix dangling connection hang-up + - mptcp: annotate lockless accesses to sk->sk_err + - mptcp: move __mptcp_error_report in protocol.c + - mptcp: process pending subflow error on close + - ata,scsi: do not issue START STOP UNIT on resume + - scsi: sd: Differentiate system and runtime start/stop management + - scsi: sd: Do not issue commands to suspended disks on shutdown + - scsi: core: Improve type safety of scsi_rescan_device() + - scsi: Do not attempt to rescan suspended devices + - ata: libata-scsi: Fix delayed scsi_rescan_device() execution + - NFS: Cleanup unused rpc_clnt variable + - NFS: rename nfs_client_kset to nfs_kset + - NFSv4: Fix a state manager thread deadlock regression + - mm/memory: add vm_normal_folio() + - mm/mempolicy: convert queue_pages_pmd() to queue_folios_pmd() + - mm/mempolicy: convert queue_pages_pte_range() to queue_folios_pte_range() + - mm/mempolicy: convert migrate_page_add() to migrate_folio_add() + - mm: mempolicy: keep VMA walk if both MPOL_MF_STRICT and MPOL_MF_MOVE are + specified + - ring-buffer: remove obsolete comment for free_buffer_page() + - Revert "NFSv4: Retry LOCK on OLD_STATEID during delegation return" + - arm64: Avoid repeated AA64MMFR1_EL1 register read on pagefault path + - net: add sysctl accept_ra_min_rtr_lft + - net: change accept_ra_min_rtr_lft to affect all RA lifetimes + - net: release reference to inet6_dev pointer + - arm64: cpufeature: Fix CLRBHB and BC detection + - drm/amd/display: Adjust the MST resume flow + - iommu/arm-smmu-v3: Set TTL invalidation hint better + - iommu/arm-smmu-v3: Avoid constructing invalid range commands + - rbd: move rbd_dev_refresh() definition + - rbd: decouple header read-in from updating rbd_dev->header + - rbd: decouple parent info read-in from updating rbd_dev + - rbd: take header_rwsem in rbd_dev_refresh() only when updating + - hwmon: (nzxt-smart2) Add device id + - hwmon: (nzxt-smart2) add another USB ID + - scsi: zfcp: Fix a double put in zfcp_port_enqueue() + - iommu/vt-d: Avoid memory allocation in iommu_suspend() + - net: ethernet: mediatek: disable irq before schedule napi + - mptcp: userspace pm allow creating id 0 subflow + - qed/red_ll2: Fix undefined behavior bug in struct qed_ll2_info + - Bluetooth: hci_codec: Fix leaking content of local_codecs + - Bluetooth: hci_sync: Fix handling of HCI_QUIRK_STRICT_DUPLICATE_FILTER + - wifi: mwifiex: Fix tlv_buf_left calculation + - md/raid5: release batch_last before waiting for another stripe_head + - PCI: qcom: Fix IPQ8074 enumeration + - net: replace calls to sock->ops->connect() with kernel_connect() + - net: prevent rewrite of msg_name in sock_sendmsg() + - drm/amd: Fix detection of _PR3 on the PCIe root port + - drm/amd: Fix logic error in sienna_cichlid_update_pcie_parameters() + - arm64: Add Cortex-A520 CPU part definition + - arm64: errata: Add Cortex-A520 speculative unprivileged load workaround + - [Config] updateconfigs for ARM64_ERRATUM_2966298 + - HID: sony: Fix a potential memory leak in sony_probe() + - ubi: Refuse attaching if mtd's erasesize is 0 + - erofs: fix memory leak of LZMA global compressed deduplication + - wifi: iwlwifi: dbg_ini: fix structure packing + - wifi: iwlwifi: mvm: Fix a memory corruption issue + - wifi: cfg80211: hold wiphy lock in auto-disconnect + - wifi: cfg80211: move wowlan disable under locks + - wifi: cfg80211: add a work abstraction with special semantics + - wifi: cfg80211: fix cqm_config access race + - wifi: cfg80211: add missing kernel-doc for cqm_rssi_work + - wifi: mwifiex: Fix oob check condition in mwifiex_process_rx_packet + - leds: Drop BUG_ON check for LED_COLOR_ID_MULTI + - bpf: Fix tr dereferencing + - regulator: mt6358: Drop *_SSHUB regulators + - regulator: mt6358: Use linear voltage helpers for single range regulators + - regulator: mt6358: split ops for buck and linear range LDO regulators + - Bluetooth: Delete unused hci_req_prepare_suspend() declaration + - Bluetooth: ISO: Fix handling of listen for unicast + - drivers/net: process the result of hdlc_open() and add call of hdlc_close() + in uhdlc_close() + - wifi: mt76: mt76x02: fix MT76x0 external LNA gain handling + - perf/x86/amd/core: Fix overflow reset on hotplug + - regmap: rbtree: Fix wrong register marked as in-cache when creating new node + - wifi: mac80211: fix potential key use-after-free + - perf/x86/amd: Do not WARN() on every IRQ + - iommu/mediatek: Fix share pgtable for iova over 4GB + - regulator/core: regulator_register: set device->class earlier + - ima: Finish deprecation of IMA_TRUSTED_KEYRING Kconfig + - [Config] updateconfigs for IMA_BLACKLIST_KEYRING + - scsi: target: core: Fix deadlock due to recursive locking + - ima: rework CONFIG_IMA dependency block + - NFSv4: Fix a nfs4_state_manager() race + - bpf: tcp_read_skb needs to pop skb regardless of seq + - bpf, sockmap: Do not inc copied_seq when PEEK flag set + - bpf, sockmap: Reject sk_msg egress redirects to non-TCP sockets + - modpost: add missing else to the "of" check + - net: fix possible store tearing in neigh_periodic_work() + - bpf: Add BPF_FIB_LOOKUP_SKIP_NEIGH for bpf_fib_lookup + - neighbour: annotate lockless accesses to n->nud_state + - neighbour: switch to standard rcu, instead of rcu_bh + - neighbour: fix data-races around n->output + - ipv4, ipv6: Fix handling of transhdrlen in __ip{,6}_append_data() + - ptp: ocp: Fix error handling in ptp_ocp_device_init + - net: dsa: mv88e6xxx: Avoid EEPROM timeout when EEPROM is absent + - ipv6: tcp: add a missing nf_reset_ct() in 3WHS handling + - net: usb: smsc75xx: Fix uninit-value access in __smsc75xx_read_reg + - net: nfc: llcp: Add lock when modifying device list + - net: ethernet: ti: am65-cpsw: Fix error code in + am65_cpsw_nuss_init_tx_chns() + - ibmveth: Remove condition to recompute TCP header checksum. + - netfilter: handle the connecting collision properly in + nf_conntrack_proto_sctp + - selftests: netfilter: Test nf_tables audit logging + - selftests: netfilter: Extend nft_audit.sh + - netfilter: nf_tables: Deduplicate nft_register_obj audit logs + - netfilter: nf_tables: nft_set_rbtree: fix spurious insertion failure + - ipv4: Set offload_failed flag in fibmatch results + - net: stmmac: dwmac-stm32: fix resume on STM32 MCU + - tipc: fix a potential deadlock on &tx->lock + - tcp: fix quick-ack counting to count actual ACKs of new data + - tcp: fix delayed ACKs for MSS boundary condition + - sctp: update transport state when processing a dupcook packet + - sctp: update hb timer immediately after users change hb_interval + - netlink: annotate data-races around sk->sk_err + - HID: sony: remove duplicate NULL check before calling usb_free_urb() + - HID: intel-ish-hid: ipc: Disable and reenable ACPI GPE bit + - intel_idle: add Emerald Rapids Xeon support + - smb: use kernel_connect() and kernel_bind() + - parisc: Fix crash with nr_cpus=1 option + - dm zoned: free dmz->ddev array in dmz_put_zoned_devices + - RDMA/core: Require admin capabilities to set system parameters + - of: dynamic: Fix potential memory leak in of_changeset_action() + - IB/mlx4: Fix the size of a buffer in add_port_entries() + - gpio: aspeed: fix the GPIO number passed to pinctrl_gpio_set_config() + - gpio: pxa: disable pinctrl calls for MMP_GPIO + - RDMA/cma: Initialize ib_sa_multicast structure to 0 when join + - RDMA/cma: Fix truncation compilation warning in make_cma_ports + - RDMA/uverbs: Fix typo of sizeof argument + - RDMA/srp: Do not call scsi_done() from srp_abort() + - RDMA/siw: Fix connection failure handling + - RDMA/mlx5: Fix mutex unlocking on error flow for steering anchor creation + - RDMA/mlx5: Fix NULL string error + - x86/sev: Use the GHCB protocol when available for SNP CPUID requests + - ksmbd: fix race condition between session lookup and expire + - ksmbd: fix uaf in smb20_oplock_break_ack + - parisc: Restore __ldcw_align for PA-RISC 2.0 processors + - ipv6: remove nexthop_fib6_nh_bh() + - vrf: Fix lockdep splat in output path + - ipv6: remove one read_lock()/read_unlock() pair in rt6_check_neigh() + - xen/events: replace evtchn_rwlock with RCU + - net: mana: Fix TX CQE error handling + - mptcp: fix delegated action races + - wifi: rtw88: rtw8723d: Fix MAC address offset in EEPROM + - wifi: mt76: fix lock dependency problem for wed_lock + - wifi: cfg80211/mac80211: hold link BSSes when assoc fails for MLO connection + - ice: always add legacy 32byte RXDID in supported_rxdids + - Upstream stable to v6.1.57, v6.5.7 + + * Lunar update: upstream stable patchset 2023-12-05 (LP: #2045698) + - autofs: fix memory leak of waitqueues in autofs_catatonic_mode + - btrfs: output extra debug info if we failed to find an inline backref + - locks: fix KASAN: use-after-free in trace_event_raw_event_filelock_lock + - ACPICA: Add AML_NO_OPERAND_RESOLVE flag to Timer + - kernel/fork: beware of __put_task_struct() calling context + - rcuscale: Move rcu_scale_writer() schedule_timeout_uninterruptible() to + _idle() + - scftorture: Forgive memory-allocation failure if KASAN + - ACPI: video: Add backlight=native DMI quirk for Lenovo Ideapad Z470 + - perf/smmuv3: Enable HiSilicon Erratum 162001900 quirk for HIP08/09 + - perf/imx_ddr: speed up overflow frequency of cycle + - hw_breakpoint: fix single-stepping when using bpf_overflow_handler + - ACPI: x86: s2idle: Catch multiple ACPI_TYPE_PACKAGE objects + - selftests/nolibc: fix up kernel parameters support + - devlink: remove reload failed checks in params get/set callbacks + - crypto: lrw,xts - Replace strlcpy with strscpy + - ice: Don't tx before switchdev is fully configured + - wifi: ath9k: fix fortify warnings + - wifi: ath9k: fix printk specifier + - wifi: mwifiex: fix fortify warning + - mt76: mt7921: don't assume adequate headroom for SDIO headers + - wifi: wil6210: fix fortify warnings + - can: sun4i_can: Add acceptance register quirk + - [Config] updateconfigs for CAN_SUN4I + - can: sun4i_can: Add support for the Allwinner D1 + - net: Use sockaddr_storage for getsockopt(SO_PEERNAME). + - net/ipv4: return the real errno instead of -EINVAL + - crypto: lib/mpi - avoid null pointer deref in mpi_cmp_ui() + - Bluetooth: Fix hci_suspend_sync crash + - netlink: convert nlk->flags to atomic flags + - tpm_tis: Resend command to recover from data transfer errors + - mmc: sdhci-esdhc-imx: improve ESDHC_FLAG_ERR010450 + - alx: fix OOB-read compiler warning + - wifi: mac80211: check S1G action frame size + - netfilter: ebtables: fix fortify warnings in size_entry_mwt() + - wifi: cfg80211: reject auth/assoc to AP with our address + - wifi: cfg80211: ocb: don't leave if not joined + - wifi: mac80211: check for station first in client probe + - wifi: mac80211_hwsim: drop short frames + - libbpf: Free btf_vmlinux when closing bpf_object + - drm/bridge: tc358762: Instruct DSI host to generate HSE packets + - drm/edid: Add quirk for OSVR HDK 2.0 + - arm64: dts: qcom: sm6125-pdx201: correct ramoops pmsg-size + - arm64: dts: qcom: sm6350: correct ramoops pmsg-size + - arm64: dts: qcom: sm8150-kumano: correct ramoops pmsg-size + - arm64: dts: qcom: sm8250-edo: correct ramoops pmsg-size + - samples/hw_breakpoint: Fix kernel BUG 'invalid opcode: 0000' + - drm/amd/display: Fix underflow issue on 175hz timing + - ASoC: SOF: topology: simplify code to prevent static analysis warnings + - ASoC: Intel: sof_sdw: Update BT offload config for soundwire config + - ALSA: hda: intel-dsp-cfg: add LunarLake support + - drm/amd/display: Use DTBCLK as refclk instead of DPREFCLK + - drm/amd/display: Blocking invalid 420 modes on HDMI TMDS for DCN31 + - drm/amd/display: Blocking invalid 420 modes on HDMI TMDS for DCN314 + - drm/exynos: fix a possible null-pointer dereference due to data race in + exynos_drm_crtc_atomic_disable() + - drm/mediatek: dp: Change logging to dev for mtk_dp_aux_transfer() + - bus: ti-sysc: Configure uart quirks for k3 SoC + - md: raid1: fix potential OOB in raid1_remove_disk() + - ext2: fix datatype of block number in ext2_xattr_set2() + - fs/jfs: prevent double-free in dbUnmount() after failed jfs_remount() + - jfs: fix invalid free of JFS_IP(ipimap)->i_imap in diUnmount + - PCI: dwc: Provide deinit callback for i.MX + - ARM: 9317/1: kexec: Make smp stop calls asynchronous + - powerpc/pseries: fix possible memory leak in ibmebus_bus_init() + - PCI: vmd: Disable bridge window for domain reset + - PCI: fu740: Set the number of MSI vectors + - media: mdp3: Fix resource leaks in of_find_device_by_node + - media: dvb-usb-v2: af9035: Fix null-ptr-deref in af9035_i2c_master_xfer + - media: dw2102: Fix null-ptr-deref in dw2102_i2c_transfer() + - media: af9005: Fix null-ptr-deref in af9005_i2c_xfer + - media: anysee: fix null-ptr-deref in anysee_master_xfer + - media: az6007: Fix null-ptr-deref in az6007_i2c_xfer() + - media: dvb-usb-v2: gl861: Fix null-ptr-deref in gl861_i2c_master_xfer + - scsi: lpfc: Abort outstanding ELS cmds when mailbox timeout error is + detected + - media: tuners: qt1010: replace BUG_ON with a regular error + - media: pci: cx23885: replace BUG with error return + - usb: cdns3: Put the cdns set active part outside the spin lock + - usb: gadget: fsl_qe_udc: validate endpoint index for ch9 udc + - tools: iio: iio_generic_buffer: Fix some integer type and calculation + - scsi: target: iscsi: Fix buffer overflow in lio_target_nacl_info_show() + - serial: cpm_uart: Avoid suspicious locking + - misc: open-dice: make OPEN_DICE depend on HAS_IOMEM + - usb: ehci: add workaround for chipidea PORTSC.PEC bug + - usb: chipidea: add workaround for chipidea PEC bug + - media: pci: ipu3-cio2: Initialise timing struct to avoid a compiler warning + - kobject: Add sanity check for kset->kobj.ktype in kset_register() + - interconnect: Fix locking for runpm vs reclaim + - printk: Keep non-panic-CPUs out of console lock + - printk: Consolidate console deferred printing + - btrfs: add a helper to read the superblock metadata_uuid + - btrfs: compare the correct fsid/metadata_uuid in btrfs_validate_super + - block: factor out a bvec_set_page helper + - nvmet: use bvec_set_page to initialize bvecs + - nvmet-tcp: pass iov_len instead of sg->length to bvec_set_page() + - drm: gm12u320: Fix the timeout usage for usb_bulk_msg() + - scsi: qla2xxx: Fix NULL vs IS_ERR() bug for debugfs_create_dir() + - selftests: tracing: Fix to unmount tracefs for recovering environment + - x86/ibt: Suppress spurious ENDBR + - riscv: kexec: Align the kexeced kernel entry + - scsi: target: core: Fix target_cmd_counter leak + - scsi: lpfc: Fix the NULL vs IS_ERR() bug for debugfs_create_file() + - panic: Reenable preemption in WARN slowpath + - x86/boot/compressed: Reserve more memory for page tables + - x86/purgatory: Remove LTO flags + - samples/hw_breakpoint: fix building without module unloading + - md/raid1: fix error: ISO C90 forbids mixed declarations + - Revert "SUNRPC: Fail faster on bad verifier" + - attr: block mode changes of symlinks + - ovl: fix failed copyup of fileattr on a symlink + - ovl: fix incorrect fdput() on aio completion + - io_uring/net: fix iter retargeting for selected buf + - md: Put the right device in md_seq_next + - Revert "drm/amd: Disable S/G for APUs when 64GB or more host memory" + - dm: don't attempt to queue IO under RCU protection + - btrfs: fix lockdep splat and potential deadlock after failure running + delayed items + - btrfs: fix a compilation error if DEBUG is defined in btree_dirty_folio + - btrfs: release path before inode lookup during the ino lookup ioctl + - btrfs: check for BTRFS_FS_ERROR in pending ordered assert + - tracing: Have tracing_max_latency inc the trace array ref count + - tracing: Have event inject files inc the trace array ref count + - tracing: Increase trace array ref count on enable and filter files + - tracing: Have current_trace inc the trace array ref count + - tracing: Have option files inc the trace array ref count + - selinux: fix handling of empty opts in selinux_fs_context_submount() + - nfsd: fix change_info in NFSv4 RENAME replies + - tracefs: Add missing lockdown check to tracefs_create_dir() + - i2c: aspeed: Reset the i2c controller when timeout occurs + - ata: libata: disallow dev-initiated LPM transitions to unsupported states + - ata: libahci: clear pending interrupt status + - scsi: megaraid_sas: Fix deadlock on firmware crashdump + - scsi: pm8001: Setup IRQs on resume + - ext4: fix rec_len verify error + - drm/amd/display: fix the white screen issue when >= 64GB DRAM + - drm/amdgpu: fix amdgpu_cs_p1_user_fence + - interconnect: Teach lockdep about icc_bw_lock order + - x86/ibt: Avoid duplicate ENDBR in __put_user_nocheck*() + - btrfs: fix race between finishing block group creation and its item update + - x86/alternatives: Remove faulty optimization + - x86,static_call: Fix static-call vs return-thunk + - Upstream stable to v6.1.55, v6.5.5 + + * CVE-2023-46813 + - x86/sev: Disable MMIO emulation from user mode + - x86/sev: Check IOBM for IOIO exceptions from user-space + - x86/sev: Check for user-space IOIO pointing to kernel space + + * CVE-2023-5972 + - nf_tables: fix NULL pointer dereference in nft_inner_init() + - nf_tables: fix NULL pointer dereference in nft_expr_inner_parse() + + * RTL8111EPP: Fix the network lost after resume with DASH (LP: #2043786) + - r8169: add handling DASH when DASH is disabled + - r8169: fix network lost after resume on DASH systems + + * kernel BUG: io_uring openat triggers audit reference count underflow + (LP: #2043841) + - audit, io_uring: io_uring openat triggers audit reference count underflow + + * Fix ADL: System enabled AHCI can't get into s0ix when attached ODD + (LP: #2037493) + - ata: ahci: Add Intel Alder Lake-P AHCI controller to low power chipsets list + + * [UBUNTU 23.04] Kernel config option missing for s390x PCI passthrough + (LP: #2042853) + - [Config] CONFIG_VFIO_PCI_ZDEV_KVM=y + + * Could not probe Samsung P44 30S3 PM9C1a SSD correctly: nvme nvme0: Device + not ready: aborting installation, CSTS=0x0 (LP: #2041495) + - nvme: avoid bogus CRTO values + + * Azure: Fix Azure vendor ID (LP: #2036600) + - SAUCE: (no-up) hv: Fix supply vendor ID + + * Lunar update: upstream stable patchset 2023-11-28 (LP: #2045079) + - net/ipv6: SKB symmetric hash should incorporate transport ports + - mm: multi-gen LRU: rename lrugen->lists[] to lrugen->folios[] + - Multi-gen LRU: fix per-zone reclaim + - io_uring/net: don't overflow multishot accept + - io_uring: break out of iowq iopoll on teardown + - io_uring/sqpoll: fix io-wq affinity when IORING_SETUP_SQPOLL is used + - io_uring: Don't set affinity on a dying sqpoll thread + - drm/virtio: Conditionally allocate virtio_gpu_fence + - scsi: qla2xxx: Adjust IOCB resource on qpair create + - scsi: qla2xxx: Limit TMF to 8 per function + - scsi: qla2xxx: Fix deletion race condition + - scsi: qla2xxx: fix inconsistent TMF timeout + - scsi: qla2xxx: Fix command flush during TMF + - scsi: qla2xxx: Fix erroneous link up failure + - scsi: qla2xxx: Turn off noisy message log + - scsi: qla2xxx: Fix session hang in gnl + - scsi: qla2xxx: Fix TMF leak through + - scsi: qla2xxx: Remove unsupported ql2xenabledif option + - scsi: qla2xxx: Flush mailbox commands on chip reset + - scsi: qla2xxx: Fix smatch warn for qla_init_iocb_limit() + - scsi: qla2xxx: Error code did not return to upper layer + - scsi: qla2xxx: Fix firmware resource tracking + - null_blk: fix poll request timeout handling + - fbdev/ep93xx-fb: Do not assign to struct fb_info.dev + - clk: qcom: camcc-sc7180: fix async resume during probe + - drm/ast: Fix DRAM init on AST2200 + - ASoC: tegra: Fix SFC conversion for few rates + - clk: qcom: turingcc-qcs404: fix missing resume during probe + - arm64: dts: renesas: rzg2l: Fix txdv-skew-psec typos + - send channel sequence number in SMB3 requests after reconnects + - mm: hugetlb_vmemmap: fix a race between vmemmap pmd split + - lib/test_meminit: allocate pages up to order MAX_ORDER + - parisc: led: Fix LAN receive and transmit LEDs + - parisc: led: Reduce CPU overhead for disk & lan LED computation + - cifs: update desired access while requesting for directory lease + - pinctrl: cherryview: fix address_space_handler() argument + - dt-bindings: clock: xlnx,versal-clk: drop select:false + - clk: imx: pll14xx: dynamically configure PLL for 393216000/361267200Hz + - clk: imx: pll14xx: align pdiv with reference manual + - clk: qcom: gcc-mdm9615: use proper parent for pll0_vote clock + - soc: qcom: qmi_encdec: Restrict string length in decode + - clk: qcom: dispcc-sm8450: fix runtime PM imbalance on probe errors + - clk: qcom: lpasscc-sc7280: fix missing resume during probe + - clk: qcom: q6sstop-qcs404: fix missing resume during probe + - clk: qcom: mss-sc7180: fix missing resume during probe + - NFS: Fix a potential data corruption + - NFSv4/pnfs: minor fix for cleanup path in nfs4_get_device_info + - bus: mhi: host: Skip MHI reset if device is in RDDM + - kbuild: rpm-pkg: define _arch conditionally + - kbuild: do not run depmod for 'make modules_sign' + - tpm_crb: Fix an error handling path in crb_acpi_add() + - gfs2: Switch to wait_event in gfs2_logd + - gfs2: low-memory forced flush fixes + - mailbox: qcom-ipcc: fix incorrect num_chans counting + - kconfig: fix possible buffer overflow + - Input: iqs7222 - configure power mode before triggering ATI + - perf trace: Use zfree() to reduce chances of use after free + - perf trace: Really free the evsel->priv area + - pwm: atmel-tcb: Convert to platform remove callback returning void + - pwm: atmel-tcb: Harmonize resource allocation order + - pwm: atmel-tcb: Fix resource freeing in error path and remove + - backlight: gpio_backlight: Drop output GPIO direction check for initial + power state + - Input: tca6416-keypad - always expect proper IRQ number in i2c client + - Input: tca6416-keypad - fix interrupt enable disbalance + - perf annotate bpf: Don't enclose non-debug code with an assert() + - x86/virt: Drop unnecessary check on extended CPUID level in cpu_has_svm() + - perf vendor events: Update the JSON/events descriptions for power10 platform + - perf vendor events: Drop some of the JSON/events for power10 platform + - perf vendor events: Drop STORES_PER_INST metric event for power10 platform + - perf top: Don't pass an ERR_PTR() directly to perf_session__delete() + - watchdog: intel-mid_wdt: add MODULE_ALIAS() to allow auto-load + - pwm: lpc32xx: Remove handling of PWM channels + - perf test stat_bpf_counters_cgrp: Fix shellcheck issue about logical + operators + - perf test stat_bpf_counters_cgrp: Enhance perf stat cgroup BPF counter test + - drm/i915: mark requests for GuC virtual engines to avoid use-after-free + - blk-throttle: use calculate_io/bytes_allowed() for throtl_trim_slice() + - blk-throttle: consider 'carryover_ios/bytes' in throtl_trim_slice() + - smb: propagate error code of extract_sharename() + - net/sched: fq_pie: avoid stalls in fq_pie_timer() + - sctp: annotate data-races around sk->sk_wmem_queued + - ipv4: annotate data-races around fi->fib_dead + - net: read sk->sk_family once in sk_mc_loop() + - net: fib: avoid warn splat in flow dissector + - xsk: Fix xsk_diag use-after-free error during socket cleanup + - drm/i915/gvt: Verify pfn is "valid" before dereferencing "struct page" + - drm/i915/gvt: Put the page reference obtained by KVM's gfn_to_pfn() + - drm/i915/gvt: Drop unused helper intel_vgpu_reset_gtt() + - net: use sk_forward_alloc_get() in sk_get_meminfo() + - net: annotate data-races around sk->sk_forward_alloc + - mptcp: annotate data-races around msk->rmem_fwd_alloc + - ipv4: ignore dst hint for multipath routes + - ipv6: ignore dst hint for multipath routes + - igb: disable virtualization features on 82580 + - gve: fix frag_list chaining + - veth: Fixing transmit return status for dropped packets + - net: ipv6/addrconf: avoid integer underflow in ipv6_create_tempaddr + - net: phy: micrel: Correct bit assignments for phy_device flags + - bpf, sockmap: Fix skb refcnt race after locking changes + - af_unix: Fix data-races around user->unix_inflight. + - af_unix: Fix data-race around unix_tot_inflight. + - af_unix: Fix data-races around sk->sk_shutdown. + - af_unix: Fix data race around sk->sk_err. + - kcm: Destroy mutex in kcm_exit_net() + - octeontx2-af: Fix truncation of smq in CN10K NIX AQ enqueue mbox handler + - igc: Change IGC_MIN to allow set rx/tx value between 64 and 80 + - igbvf: Change IGBVF_MIN to allow set rx/tx value between 64 and 80 + - igb: Change IGB_MIN to allow set rx/tx value between 64 and 80 + - s390/zcrypt: don't leak memory if dev_set_name() fails + - idr: fix param name in idr_alloc_cyclic() doc + - ip_tunnels: use DEV_STATS_INC() + - net: dsa: sja1105: fix bandwidth discrepancy between tc-cbs software and + offload + - net: dsa: sja1105: fix -ENOSPC when replacing the same tc-cbs too many times + - net: dsa: sja1105: complete tc-cbs offload support on SJA1110 + - bpf: Invoke __bpf_prog_exit_sleepable_recur() on recursion in + kern_sys_bpf(). + - bpf: Assign bpf_tramp_run_ctx::saved_run_ctx before recursion check. + - net: hns3: fix tx timeout issue + - net: hns3: fix byte order conversion issue in hclge_dbg_fd_tcam_read() + - net: hns3: fix debugfs concurrency issue between kfree buffer and read + - net: hns3: fix invalid mutex between tc qdisc and dcb ets command issue + - net: hns3: fix the port information display when sfp is absent + - net: hns3: remove GSO partial feature bit + - sh: boards: Fix CEU buffer size passed to dma_declare_coherent_memory() + - Multi-gen LRU: avoid race in inc_min_seq() + - net/mlx5: Free IRQ rmap and notifier on kernel shutdown + - ARC: atomics: Add compiler barrier to atomic operations... + - clocksource/drivers/arm_arch_timer: Disable timer before programming CVAL + - dmaengine: sh: rz-dmac: Fix destination and source data size setting + - jbd2: fix checkpoint cleanup performance regression + - jbd2: check 'jh->b_transaction' before removing it from checkpoint + - jbd2: correct the end of the journal recovery scan range + - ext4: add correct group descriptors and reserved GDT blocks to system zone + - ext4: fix memory leaks in ext4_fname_{setup_filename,prepare_lookup} + - f2fs: flush inode if atomic file is aborted + - f2fs: avoid false alarm of circular locking + - lib: test_scanf: Add explicit type cast to result initialization in + test_number_prefix() + - hwspinlock: qcom: add missing regmap config for SFPB MMIO implementation + - ata: ahci: Add Elkhart Lake AHCI controller + - ata: pata_falcon: fix IO base selection for Q40 + - ata: sata_gemini: Add missing MODULE_DESCRIPTION + - ata: pata_ftide010: Add missing MODULE_DESCRIPTION + - fuse: nlookup missing decrement in fuse_direntplus_link + - btrfs: zoned: do not zone finish data relocation block group + - btrfs: fix start transaction qgroup rsv double free + - btrfs: free qgroup rsv on io failure + - btrfs: don't start transaction when joining with TRANS_JOIN_NOSTART + - btrfs: set page extent mapped after read_folio in relocate_one_page + - btrfs: zoned: re-enable metadata over-commit for zoned mode + - btrfs: use the correct superblock to compare fsid in btrfs_validate_super + - drm/mxsfb: Disable overlay plane in mxsfb_plane_overlay_atomic_disable() + - mtd: rawnand: brcmnand: Fix crash during the panic_write + - mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write + - mtd: spi-nor: Correct flags for Winbond w25q128 + - mtd: rawnand: brcmnand: Fix potential false time out warning + - mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller + - drm/amd/display: enable cursor degamma for DCN3+ DRM legacy gamma + - drm/amd/display: prevent potential division by zero errors + - KVM: SVM: Take and hold ir_list_lock when updating vCPU's Physical ID entry + - KVM: SVM: Don't inject #UD if KVM attempts to skip SEV guest insn + - KVM: SVM: Get source vCPUs from source VM for SEV-ES intrahost migration + - KVM: nSVM: Check instead of asserting on nested TSC scaling support + - KVM: nSVM: Load L1's TSC multiplier based on L1 state, not L2 state + - KVM: SVM: Set target pCPU during IRTE update if target vCPU is running + - KVM: SVM: Skip VMSA init in sev_es_init_vmcb() if pointer is NULL + - MIPS: Fix CONFIG_CPU_DADDI_WORKAROUNDS `modules_install' regression + - perf hists browser: Fix hierarchy mode header + - perf test shell stat_bpf_counters: Fix test on Intel + - perf tools: Handle old data in PERF_RECORD_ATTR + - perf hists browser: Fix the number of entries for 'e' key + - drm/amd/display: always switch off ODM before committing more streams + - drm/amd/display: Remove wait while locked + - drm/amdgpu: register a dirty framebuffer callback for fbcon + - kunit: Fix wild-memory-access bug in kunit_free_suite_set() + - net: ipv4: fix one memleak in __inet_del_ifa() + - kselftest/runner.sh: Propagate SIGTERM to runner child + - selftests: Keep symlinks, when possible + - net/smc: use smc_lgr_list.lock to protect smc_lgr_list.list iterate in + smcr_port_add + - net: stmmac: fix handling of zero coalescing tx-usecs + - net: ethernet: mvpp2_main: fix possible OOB write in + mvpp2_ethtool_get_rxnfc() + - net: ethernet: mtk_eth_soc: fix possible NULL pointer dereference in + mtk_hwlro_get_fdir_all() + - hsr: Fix uninit-value access in fill_frame_info() + - net: ethernet: adi: adin1110: use eth_broadcast_addr() to assign broadcast + address + - net:ethernet:adi:adin1110: Fix forwarding offload + - net: dsa: sja1105: hide all multicast addresses from "bridge fdb show" + - net: dsa: sja1105: propagate exact error code from + sja1105_dynamic_config_poll_valid() + - net: dsa: sja1105: fix multicast forwarding working only for last added mdb + entry + - net: dsa: sja1105: serialize sja1105_port_mcast_flood() with other FDB + accesses + - net: dsa: sja1105: block FDB accesses that are concurrent with a switch + reset + - r8152: check budget for r8152_poll() + - kcm: Fix memory leak in error path of kcm_sendmsg() + - platform/mellanox: mlxbf-tmfifo: Drop the Rx packet if no more descriptors + - platform/mellanox: mlxbf-tmfifo: Drop jumbo frames + - platform/mellanox: mlxbf-pmc: Fix potential buffer overflows + - platform/mellanox: mlxbf-pmc: Fix reading of unprogrammed events + - [Config] updateconfigs for NVSW_SN2201 + - platform/mellanox: NVSW_SN2201 should depend on ACPI + - net: macb: Enable PTP unicast + - net: macb: fix sleep inside spinlock + - ipv6: fix ip6_sock_set_addr_preferences() typo + - ipv6: Remove in6addr_any alternatives. + - tcp: Factorise sk_family-independent comparison in + inet_bind2_bucket_match(_addr_any). + - tcp: Fix bind() regression for v4-mapped-v6 wildcard address. + - tcp: Fix bind() regression for v4-mapped-v6 non-wildcard address. + - ixgbe: fix timestamp configuration code + - kcm: Fix error handling for SOCK_DGRAM in kcm_sendmsg(). + - MIPS: Only fiddle with CHECKFLAGS if `need-compiler' + - drm/amd/display: Fix a bug when searching for insert_above_mpcc + - arm64: tegra: Update AHUB clock parent and rate on Tegra234 + - arm64: tegra: Update AHUB clock parent and rate + - ARM: dts: qcom: msm8974pro-castor: correct inverted X of touchscreen + - ARM: dts: qcom: msm8974pro-castor: correct touchscreen function names + - ARM: dts: qcom: msm8974pro-castor: correct touchscreen syna,nosleep-mode + - ARM: dts: BCM5301X: Extend RAM to full 256MB for Linksys EA6500 V2 + - net: annotate data-races around sk->sk_tsflags + - net: annotate data-races around sk->sk_bind_phc + - sh: push-switch: Reorder cleanup operations to avoid use-after-free bug + - misc: fastrpc: Fix remote heap allocation request + - misc: fastrpc: Fix incorrect DMA mapping unmap request + - net: renesas: rswitch: Fix unmasking irq condition + - Upstream stable to v6.1.54, v6.5.4 + + * Lunar update: upstream stable patchset 2023-11-06 (LP: #2042884) + - Partially revert "drm/amd/display: Fix possible underflow for displays with + large vblank" + - Revert "Revert drm/amd/display: Enable Freesync Video Mode by default" + - powerpc/boot: Disable power10 features after BOOTAFLAGS assignment + - media: uapi: HEVC: Add num_delta_pocs_of_ref_rps_idx field + - Revert "MIPS: unhide PATA_PLATFORM" + - phy: qcom-snps-femto-v2: use qcom_snps_hsphy_suspend/resume error code + - media: amphion: use dev_err_probe + - media: pulse8-cec: handle possible ping error + - media: pci: cx23885: fix error handling for cx23885 ATSC boards + - 9p: virtio: fix unlikely null pointer deref in handle_rerror + - 9p: virtio: make sure 'offs' is initialized in zc_request + - ksmbd: fix out of bounds in smb3_decrypt_req() + - ksmbd: validate session id and tree id in compound request + - ksmbd: no response from compound read + - ksmbd: fix out of bounds in init_smb2_rsp_hdr() + - ASoC: da7219: Flush pending AAD IRQ when suspending + - ASoC: da7219: Check for failure reading AAD IRQ events + - ASoC: nau8821: Add DMI quirk mechanism for active-high jack-detect + - ethernet: atheros: fix return value check in atl1c_tso_csum() + - m68k: Fix invalid .section syntax + - s390/dasd: use correct number of retries for ERP requests + - s390/dasd: fix hanging device after request requeue + - fs/nls: make load_nls() take a const parameter + - ASoC: rt5682-sdw: fix for JD event handling in ClockStop Mode0 + - ASoc: codecs: ES8316: Fix DMIC config + - ASoC: rt711: fix for JD event handling in ClockStop Mode0 + - ASoC: rt711-sdca: fix for JD event handling in ClockStop Mode0 + - ASoC: atmel: Fix the 8K sample parameter in I2SC master + - ALSA: usb-audio: Add quirk for Microsoft Modern Wireless Headset + - platform/x86: intel: hid: Always call BTNL ACPI method + - platform/x86/intel/hid: Add HP Dragonfly G2 to VGBS DMI quirks + - platform/x86: think-lmi: Use kfree_sensitive instead of kfree + - platform/x86: asus-wmi: Fix setting RGB mode on some TUF laptops + - platform/x86: huawei-wmi: Silence ambient light sensor + - drm/amd/smu: use AverageGfxclkFrequency* to replace previous GFX Curr Clock + - drm/amd/display: Guard DCN31 PHYD32CLK logic against chip family + - drm/amd/display: Exit idle optimizations before attempt to access PHY + - ovl: Always reevaluate the file signature for IMA + - ata: pata_arasan_cf: Use dev_err_probe() instead dev_err() in data_xfer() + - ALSA: usb-audio: Update for native DSD support quirks + - staging: fbtft: ili9341: use macro FBTFT_REGISTER_SPI_DRIVER + - security: keys: perform capable check only on privileged operations + - kprobes: Prohibit probing on CFI preamble symbol + - clk: fixed-mmio: make COMMON_CLK_FIXED_MMIO depend on HAS_IOMEM + - vmbus_testing: fix wrong python syntax for integer value comparison + - Revert "wifi: ath6k: silence false positive -Wno-dangling-pointer warning on + GCC 12" + - net: dsa: microchip: KSZ9477 register regmap alignment to 32 bit boundaries + - net: annotate data-races around sk->sk_{rcv|snd}timeo + - net: usb: qmi_wwan: add Quectel EM05GV2 + - wifi: brcmfmac: Fix field-spanning write in brcmf_scan_params_v2_to_v1() + - powerpc/powermac: Use early_* IO variants in via_calibrate_decr() + - idmaengine: make FSL_EDMA and INTEL_IDMA64 depends on HAS_IOMEM + - platform/x86/amd/pmf: Fix unsigned comparison with less than zero + - scsi: lpfc: Remove reftag check in DIF paths + - scsi: qedi: Fix potential deadlock on &qedi_percpu->p_work_lock + - net: hns3: restore user pause configure when disable autoneg + - drm/amdgpu: Match against exact bootloader status + - wifi: cfg80211: remove links only on AP + - wifi: mac80211: Use active_links instead of valid_links in Tx + - netlabel: fix shift wrapping bug in netlbl_catmap_setlong() + - bnx2x: fix page fault following EEH recovery + - cifs: fix sockaddr comparison in iface_cmp + - cifs: fix max_credits implementation + - sctp: handle invalid error codes without calling BUG() + - scsi: aacraid: Reply queue mapping to CPUs based on IRQ affinity + - scsi: storvsc: Always set no_report_opcodes + - scsi: lpfc: Fix incorrect big endian type assignment in bsg loopback path + - LoongArch: Let pmd_present() return true when splitting pmd + - LoongArch: Fix the write_fcsr() macro + - ALSA: seq: oss: Fix racy open/close of MIDI devices + - net: sfp: handle 100G/25G active optical cables in sfp_parse_support + - tracing: Introduce pipe_cpumask to avoid race on trace_pipes + - platform/mellanox: Fix mlxbf-tmfifo not handling all virtio CONSOLE + notifications + - of: property: Simplify of_link_to_phandle() + - cpufreq: intel_pstate: set stale CPU frequency to minimum + - tpm: Enable hwrng only for Pluton on AMD CPUs + - KVM: x86/mmu: Use kstrtobool() instead of strtobool() + - KVM: x86/mmu: Add "never" option to allow sticky disabling of nx_huge_pages + - drm/amd/display: ensure async flips are only accepted for fast updates + - udf: Check consistency of Space Bitmap Descriptor + - udf: Handle error when adding extent to a file + - Input: i8042 - add quirk for TUXEDO Gemini 17 Gen1/Clevo PD70PN + - Revert "PCI: tegra194: Enable support for 256 Byte payload" + - Revert "net: macsec: preserve ingress frame ordering" + - tools/resolve_btfids: Use pkg-config to locate libelf + - tools/resolve_btfids: Install subcmd headers + - tools/resolve_btfids: Alter how HOSTCC is forced + - tools/resolve_btfids: Compile resolve_btfids as host program + - tools/resolve_btfids: Tidy HOST_OVERRIDES + - tools/resolve_btfids: Pass HOSTCFLAGS as EXTRA_CFLAGS to prepare targets + - tools/resolve_btfids: Fix setting HOSTCFLAGS + - reiserfs: Check the return value from __getblk() + - eventfd: prevent underflow for eventfd semaphores + - fs: Fix error checking for d_hash_and_lookup() + - iomap: Remove large folio handling in iomap_invalidate_folio() + - tmpfs: verify {g,u}id mount options correctly + - selftests/harness: Actually report SKIP for signal tests + - vfs, security: Fix automount superblock LSM init problem, preventing NFS sb + sharing + - ARM: ptrace: Restore syscall restart tracing + - ARM: ptrace: Restore syscall skipping for tracers + - refscale: Fix uninitalized use of wait_queue_head_t + - OPP: Fix passing 0 to PTR_ERR in _opp_attach_genpd() + - selftests/resctrl: Add resctrl.h into build deps + - selftests/resctrl: Don't leak buffer in fill_cache() + - selftests/resctrl: Unmount resctrl FS if child fails to run benchmark + - selftests/resctrl: Close perf value read fd on errors + - arm64/ptrace: Clean up error handling path in sve_set_common() + - sched/psi: Select KERNFS as needed + - x86/decompressor: Don't rely on upper 32 bits of GPRs being preserved + - arm64/sme: Don't use streaming mode to probe the maximum SME VL + - arm64/fpsimd: Only provide the length to cpufeature for xCR registers + - sched/rt: Fix sysctl_sched_rr_timeslice intial value + - perf/imx_ddr: don't enable counter0 if none of 4 counters are used + - selftests/futex: Order calls to futex_lock_pi + - s390/pkey: fix/harmonize internal keyblob headers + - s390/pkey: fix PKEY_TYPE_EP11_AES handling in PKEY_GENSECK2 IOCTL + - s390/pkey: fix PKEY_TYPE_EP11_AES handling for sysfs attributes + - s390/paes: fix PKEY_TYPE_EP11_AES handling for secure keyblobs + - irqchip/loongson-eiointc: Fix return value checking of eiointc_index + - ACPI: x86: s2idle: Post-increment variables when getting constraints + - ACPI: x86: s2idle: Fix a logic error parsing AMD constraints table + - thermal/of: Fix potential uninitialized value access + - cpufreq: amd-pstate-ut: Remove module parameter access + - cpufreq: amd-pstate-ut: Fix kernel panic when loading the driver + - x86/efistub: Fix PCI ROM preservation in mixed mode + - cpufreq: powernow-k8: Use related_cpus instead of cpus in driver.exit() + - selftests/bpf: Fix bpf_nf failure upon test rerun + - bpftool: use a local copy of perf_event to fix accessing :: Bpf_cookie + - bpftool: Define a local bpf_perf_link to fix accessing its fields + - bpftool: Use a local copy of BPF_LINK_TYPE_PERF_EVENT in pid_iter.bpf.c + - bpftool: Use a local bpf_perf_event_value to fix accessing its fields + - libbpf: Fix realloc API handling in zero-sized edge cases + - bpf: Clear the probe_addr for uprobe + - bpf: Fix an error in verifying a field in a union + - crypto: qat - change value of default idle filter + - tcp: tcp_enter_quickack_mode() should be static + - hwrng: nomadik - keep clock enabled while hwrng is registered + - hwrng: pic32 - use devm_clk_get_enabled + - regmap: rbtree: Use alloc_flags for memory allocations + - wifi: rtw89: debug: Fix error handling in rtw89_debug_priv_btc_manual_set() + - wifi: mt76: mt7921: fix non-PSC channel scan fail + - udp: re-score reuseport groups when connected sockets are present + - bpf: reject unhashed sockets in bpf_sk_assign + - wifi: mt76: testmode: add nla_policy for MT76_TM_ATTR_TX_LENGTH + - spi: tegra20-sflash: fix to check return value of platform_get_irq() in + tegra_sflash_probe() + - can: gs_usb: gs_usb_receive_bulk_callback(): count RX overflow errors also + in case of OOM + - wifi: mt76: mt7915: fix power-limits while chan_switch + - wifi: mwifiex: Fix OOB and integer underflow when rx packets + - wifi: mwifiex: fix error recovery in PCIE buffer descriptor management + - kbuild: rust_is_available: remove -v option + - kbuild: rust_is_available: fix version check when CC has multiple arguments + - kbuild: rust_is_available: add check for `bindgen` invocation + - kbuild: rust_is_available: fix confusion when a version appears in the path + - crypto: stm32 - Properly handle pm_runtime_get failing + - crypto: api - Use work queue in crypto_destroy_instance + - Bluetooth: nokia: fix value check in nokia_bluetooth_serdev_probe() + - Bluetooth: Fix potential use-after-free when clear keys + - Bluetooth: hci_sync: Don't double print name in add/remove adv_monitor + - Bluetooth: hci_sync: Avoid use-after-free in dbg for hci_add_adv_monitor() + - net: tcp: fix unexcepted socket die when snd_wnd is 0 + - selftests/bpf: Fix repeat option when kfunc_call verification fails + - selftests/bpf: Clean up fmod_ret in bench_rename test script + - net-memcg: Fix scope of sockmem pressure indicators + - ice: ice_aq_check_events: fix off-by-one check when filling buffer + - crypto: caam - fix unchecked return value error + - hwrng: iproc-rng200 - Implement suspend and resume calls + - lwt: Fix return values of BPF xmit ops + - lwt: Check LWTUNNEL_XMIT_CONTINUE strictly + - fs: ocfs2: namei: check return value of ocfs2_add_entry() + - net: annotate data-races around sk->sk_lingertime + - wifi: mwifiex: fix memory leak in mwifiex_histogram_read() + - wifi: mwifiex: Fix missed return in oob checks failed path + - ARM: dts: Add .dts files missing from the build + - samples/bpf: fix bio latency check with tracepoint + - samples/bpf: fix broken map lookup probe + - wifi: ath9k: fix races between ath9k_wmi_cmd and ath9k_wmi_ctrl_rx + - wifi: ath9k: protect WMI command response buffer replacement with a lock + - wifi: nl80211/cfg80211: add forgotten nla_policy for BSS color attribute + - mac80211: make ieee80211_tx_info padding explicit + - wifi: mwifiex: avoid possible NULL skb pointer dereference + - Bluetooth: btusb: Do not call kfree_skb() under spin_lock_irqsave() + - arm64: mm: use ptep_clear() instead of pte_clear() in clear_flush() + - wifi: ath9k: use IS_ERR() with debugfs_create_dir() + - ice: avoid executing commands on other ports when driving sync + - net: arcnet: Do not call kfree_skb() under local_irq_disable() + - mlxsw: i2c: Fix chunk size setting in output mailbox buffer + - mlxsw: i2c: Limit single transaction buffer size + - mlxsw: core_hwmon: Adjust module label names based on MTCAP sensor counter + - hwmon: (tmp513) Fix the channel number in tmp51x_is_visible() + - octeontx2-pf: Refactor schedular queue alloc/free calls + - octeontx2-pf: Fix PFC TX scheduler free + - cteonxt2-pf: Fix backpressure config for multiple PFC priorities to work + simultaneously + - sfc: Check firmware supports Ethernet PTP filter + - netrom: Deny concurrent connect(). + - drm/bridge: tc358764: Fix debug print parameter order + - ASoC: cs43130: Fix numerator/denominator mixup + - quota: factor out dquot_write_dquot() + - quota: rename dquot_active() to inode_quota_active() + - quota: add new helper dquot_active() + - quota: fix dqput() to follow the guarantees dquot_srcu should provide + - drm/amd/display: Do not set drr on pipe commit + - drm/hyperv: Fix a compilation issue because of not including screen_info.h + - ASoC: stac9766: fix build errors with REGMAP_AC97 + - soc: qcom: ocmem: Add OCMEM hardware version print + - soc: qcom: ocmem: Fix NUM_PORTS & NUM_MACROS macros + - arm64: dts: qcom: sm6350: Fix ZAP region + - arm64: dts: qcom: sm8250: correct dynamic power coefficients + - arm64: dts: qcom: msm8916-l8150: correct light sensor VDDIO supply + - arm64: dts: qcom: sm8250-edo: Add gpio line names for TLMM + - arm64: dts: qcom: sm8250-edo: Add GPIO line names for PMIC GPIOs + - arm64: dts: qcom: sm8250-edo: Rectify gpio-keys + - arm64: dts: qcom: sc8280xp-crd: Correct vreg_misc_3p3 GPIO + - arm64: dts: qcom: sc8280xp: Add missing SCM interconnect + - arm64: dts: qcom: msm8996: Add missing interrupt to the USB2 controller + - arm64: dts: qcom: sdm845-tama: Set serial indices and stdout-path + - arm64: dts: qcom: sm8350: Fix CPU idle state residency times + - arm64: dts: qcom: sm8350: Add missing LMH interrupts to cpufreq + - arm64: dts: qcom: sm8350: Use proper CPU compatibles + - arm64: dts: qcom: pm8350: fix thermal zone name + - arm64: dts: qcom: pm8350b: fix thermal zone name + - arm64: dts: qcom: pmr735b: fix thermal zone name + - arm64: dts: qcom: pmk8350: fix ADC-TM compatible string + - arm64: dts: qcom: sm8250: Mark PCIe hosts as DMA coherent + - ARM: dts: stm32: YAML validation fails for Argon Boards + - ARM: dts: stm32: adopt generic iio bindings for adc channels on emstamp- + argon + - ARM: dts: stm32: Add missing detach mailbox for emtrion emSBC-Argon + - ARM: dts: stm32: YAML validation fails for Odyssey Boards + - ARM: dts: stm32: Add missing detach mailbox for Odyssey SoM + - ARM: dts: stm32: Update to generic ADC channel binding on DHSOM systems + - ARM: dts: stm32: Add missing detach mailbox for DHCOM SoM + - firmware: ti_sci: Use system_state to determine polling + - drm/amdgpu: avoid integer overflow warning in amdgpu_device_resize_fb_bar() + - ARM: dts: BCM53573: Drop nonexistent #usb-cells + - ARM: dts: BCM53573: Add cells sizes to PCIe node + - ARM: dts: BCM53573: Use updated "spi-gpio" binding properties + - arm64: tegra: Fix HSUART for Jetson AGX Orin + - arm64: dts: qcom: sm8250-sony-xperia: correct GPIO keys wakeup again + - arm64: dts: qcom: pm6150l: Add missing short interrupt + - arm64: dts: qcom: pm660l: Add missing short interrupt + - arm64: dts: qcom: pmi8994: Add missing OVP interrupt + - arm64: tegra: Fix HSUART for Smaug + - drm/etnaviv: fix dumping of active MMU context + - block: cleanup queue_wc_store + - block: don't allow enabling a cache on devices that don't support it + - x86/mm: Fix PAT bit missing from page protection modify mask + - drm/bridge: anx7625: Use common macros for DP power sequencing commands + - drm/bridge: anx7625: Use common macros for HDCP capabilities + - ARM: dts: samsung: s3c6410-mini6410: correct ethernet reg addresses (split) + - ARM: dts: s5pv210: add dummy 5V regulator for backlight on SMDKv210 + - ARM: dts: samsung: s5pv210-smdkv210: correct ethernet reg addresses (split) + - drm: adv7511: Fix low refresh rate register for ADV7533/5 + - ARM: dts: BCM53573: Fix Ethernet info for Luxul devices + - arm64: dts: qcom: sdm845: Add missing RPMh power domain to GCC + - arm64: dts: qcom: sdm845: Fix the min frequency of "ice_core_clk" + - arm64: dts: qcom: msm8996-gemini: fix touchscreen VIO supply + - drm/amdgpu: Update min() to min_t() in 'amdgpu_info_ioctl' + - md: Factor out is_md_suspended helper + - md: Change active_io to percpu + - md: restore 'noio_flag' for the last mddev_resume() + - md/raid10: factor out dereference_rdev_and_rrdev() + - md/raid10: use dereference_rdev_and_rrdev() to get devices + - md/md-bitmap: remove unnecessary local variable in backlog_store() + - md/md-bitmap: hold 'reconfig_mutex' in backlog_store() + - drm/msm: Update dev core dump to not print backwards + - drm/tegra: dpaux: Fix incorrect return value of platform_get_irq + - of: unittest: fix null pointer dereferencing in + of_unittest_find_node_by_name() + - arm64: dts: qcom: sm8150: Fix the I2C7 interrupt + - ARM: dts: BCM53573: Fix Tenda AC9 switch CPU port + - drm/armada: Fix off-by-one error in armada_overlay_get_property() + - drm/repaper: Reduce temporary buffer size in repaper_fb_dirty() + - drm/panel: simple: Add missing connector type and pixel format for AUO + T215HVN01 + - ima: Remove deprecated IMA_TRUSTED_KEYRING Kconfig + - [Config] updateconfigs for IMA_TRUSTED_KEYRING + - drm: xlnx: zynqmp_dpsub: Add missing check for dma_set_mask + - soc: qcom: smem: Fix incompatible types in comparison + - drm/msm/mdp5: Don't leak some plane state + - firmware: meson_sm: fix to avoid potential NULL pointer dereference + - drm/msm/dpu: fix the irq index in dpu_encoder_phys_wb_wait_for_commit_done + - smackfs: Prevent underflow in smk_set_cipso() + - drm/amd/pm: fix variable dereferenced issue in amdgpu_device_attr_create() + - drm/msm/a2xx: Call adreno_gpu_init() earlier + - audit: fix possible soft lockup in __audit_inode_child() + - block/mq-deadline: use correct way to throttling write requests + - io_uring: fix drain stalls by invalid SQE + - drm/mediatek: dp: Add missing error checks in mtk_dp_parse_capabilities + - bus: ti-sysc: Fix build warning for 64-bit build + - drm/mediatek: Remove freeing not dynamic allocated memory + - ARM: dts: qcom: ipq4019: correct SDHCI XO clock + - drm/mediatek: Fix potential memory leak if vmap() fail + - arm64: dts: qcom: apq8016-sbc: Fix ov5640 regulator supply names + - arm64: dts: qcom: msm8998: Drop bus clock reference from MMSS SMMU + - arm64: dts: qcom: msm8998: Add missing power domain to MMSS SMMU + - arm64: dts: qcom: msm8996: Fix dsi1 interrupts + - arm64: dts: qcom: sc8280xp-x13s: Unreserve NC pins + - bus: ti-sysc: Fix cast to enum warning + - md/raid5-cache: fix a deadlock in r5l_exit_log() + - md/raid5-cache: fix null-ptr-deref for r5l_flush_stripe_to_raid() + - firmware: cs_dsp: Fix new control name check + - md: add error_handlers for raid0 and linear + - md/raid0: Factor out helper for mapping and submitting a bio + - md/raid0: Fix performance regression for large sequential writes + - md: raid0: account for split bio in iostat accounting + - ASoC: SOF: amd: clear dsp to host interrupt status + - of: overlay: Call of_changeset_init() early + - of: unittest: Fix overlay type in apply/revert check + - ALSA: ac97: Fix possible error value of *rac97 + - ipmi:ssif: Add check for kstrdup + - ipmi:ssif: Fix a memory leak when scanning for an adapter + - clk: qcom: gpucc-sm6350: Introduce index-based clk lookup + - clk: qcom: gpucc-sm6350: Fix clock source names + - clk: qcom: gcc-sc8280xp: Add EMAC GDSCs + - clk: qcom: gcc-sc8280xp: Add missing GDSC flags + - dt-bindings: clock: qcom,gcc-sc8280xp: Add missing GDSCs + - clk: qcom: gcc-sc8280xp: Add missing GDSCs + - clk: rockchip: rk3568: Fix PLL rate setting for 78.75MHz + - PCI: apple: Initialize pcie->nvecs before use + - PCI: qcom-ep: Switch MHI bus master clock off during L1SS + - drivers: clk: keystone: Fix parameter judgment in _of_pll_clk_init() + - PCI/DOE: Fix destroy_work_on_stack() race + - clk: sunxi-ng: Modify mismatched function name + - clk: qcom: gcc-sc7180: Fix up gcc_sdcc2_apps_clk_src + - EDAC/igen6: Fix the issue of no error events + - ext4: correct grp validation in ext4_mb_good_group + - ext4: avoid potential data overflow in next_linear_group + - clk: qcom: gcc-sm8250: Fix gcc_sdcc2_apps_clk_src + - kvm/vfio: Prepare for accepting vfio device fd + - kvm/vfio: ensure kvg instance stays around in kvm_vfio_group_add() + - clk: qcom: reset: Use the correct type of sleep/delay based on length + - clk: qcom: gcc-sm6350: Fix gcc_sdcc2_apps_clk_src + - PCI: microchip: Correct the DED and SEC interrupt bit offsets + - PCI: Mark NVIDIA T4 GPUs to avoid bus reset + - pinctrl: mcp23s08: check return value of devm_kasprintf() + - PCI: Add locking to RMW PCI Express Capability Register accessors + - PCI: pciehp: Use RMW accessors for changing LNKCTL + - PCI/ASPM: Use RMW accessors for changing LNKCTL + - clk: qcom: gcc-sm8450: Use floor ops for SDCC RCGs + - clk: imx: pllv4: Fix SPLL2 MULT range + - clk: imx: imx8ulp: update SPLL2 type + - clk: imx8mp: fix sai4 clock + - clk: imx: composite-8m: fix clock pauses when set_rate would be a no-op + - powerpc/radix: Move some functions into #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + - vfio/type1: fix cap_migration information leak + - nvdimm: Fix memleak of pmu attr_groups in unregister_nvdimm_pmu() + - nvdimm: Fix dereference after free in register_nvdimm_pmu() + - powerpc/fadump: reset dump area size if fadump memory reserve fails + - powerpc/perf: Convert fsl_emb notifier to state machine callbacks + - drm/amdgpu: Use RMW accessors for changing LNKCTL + - drm/radeon: Use RMW accessors for changing LNKCTL + - net/mlx5: Use RMW accessors for changing LNKCTL + - wifi: ath11k: Use RMW accessors for changing LNKCTL + - wifi: ath10k: Use RMW accessors for changing LNKCTL + - NFSv4.2: Rework scratch handling for READ_PLUS + - NFSv4.2: Fix READ_PLUS smatch warnings + - NFSv4.2: Fix READ_PLUS size calculations + - powerpc: Don't include lppaca.h in paca.h + - powerpc/pseries: Rework lppaca_shared_proc() to avoid DEBUG_PREEMPT + - nfs/blocklayout: Use the passed in gfp flags + - powerpc/pseries: Fix hcall tracepoints with JUMP_LABEL=n + - powerpc/mpc5xxx: Add missing fwnode_handle_put() + - powerpc/iommu: Fix notifiers being shared by PCI and VIO buses + - ext4: fix unttached inode after power cut with orphan file feature enabled + - jfs: validate max amount of blocks before allocation. + - fs: lockd: avoid possible wrong NULL parameter + - NFSD: da_addr_body field missing in some GETDEVICEINFO replies + - NFS: Guard against READDIR loop when entry names exceed MAXNAMELEN + - NFSv4.2: fix handling of COPY ERR_OFFLOAD_NO_REQ + - pNFS: Fix assignment of xprtdata.cred + - cgroup/cpuset: Inherit parent's load balance state in v2 + - RDMA/qedr: Remove a duplicate assignment in irdma_query_ah() + - media: ov5640: fix low resolution image abnormal issue + - media: ad5820: Drop unsupported ad5823 from i2c_ and of_device_id tables + - media: i2c: tvp5150: check return value of devm_kasprintf() + - media: v4l2-core: Fix a potential resource leak in v4l2_fwnode_parse_link() + - iommu/amd/iommu_v2: Fix pasid_state refcount dec hit 0 warning on pasid + unbind + - iommu: rockchip: Fix directory table address encoding + - drivers: usb: smsusb: fix error handling code in smsusb_init_device + - media: dib7000p: Fix potential division by zero + - media: dvb-usb: m920x: Fix a potential memory leak in m920x_i2c_xfer() + - media: cx24120: Add retval check for cx24120_message_send() + - RDMA/siw: Fabricate a GID on tun and loopback devices + - scsi: hisi_sas: Fix warnings detected by sparse + - scsi: hisi_sas: Fix normally completed I/O analysed as failed + - dt-bindings: extcon: maxim,max77843: restrict connector properties + - media: amphion: reinit vpu if reqbufs output 0 + - media: amphion: add helper function to get id name + - media: mtk-jpeg: Fix use after free bug due to uncanceled work + - media: rkvdec: increase max supported height for H.264 + - media: amphion: fix CHECKED_RETURN issues reported by coverity + - media: amphion: fix REVERSE_INULL issues reported by coverity + - media: amphion: fix UNINIT issues reported by coverity + - media: amphion: fix UNUSED_VALUE issue reported by coverity + - media: amphion: ensure the bitops don't cross boundaries + - media: mediatek: vcodec: Return NULL if no vdec_fb is found + - media: mediatek: vcodec: fix potential double free + - media: mediatek: vcodec: fix resource leaks in vdec_msg_queue_init() + - usb: phy: mxs: fix getting wrong state with mxs_phy_is_otg_host() + - scsi: RDMA/srp: Fix residual handling + - scsi: iscsi: Add length check for nlattr payload + - scsi: iscsi: Add strlen() check in iscsi_if_set{_host}_param() + - scsi: be2iscsi: Add length check when parsing nlattrs + - scsi: qla4xxx: Add length check when parsing nlattrs + - iio: accel: adxl313: Fix adxl313_i2c_id[] table + - serial: sprd: Assign sprd_port after initialized to avoid wrong access + - serial: sprd: Fix DMA buffer leak issue + - x86/APM: drop the duplicate APM_MINOR_DEV macro + - RDMA/rxe: Fix incomplete state save in rxe_requester + - scsi: qedf: Do not touch __user pointer in + qedf_dbg_stop_io_on_error_cmd_read() directly + - scsi: qedf: Do not touch __user pointer in qedf_dbg_debug_cmd_read() + directly + - scsi: qedf: Do not touch __user pointer in qedf_dbg_fp_int_cmd_read() + directly + - RDMA/irdma: Replace one-element array with flexible-array member + - coresight: tmc: Explicit type conversions to prevent integer overflow + - interconnect: qcom: qcm2290: Enable sync state + - dma-buf/sync_file: Fix docs syntax + - driver core: test_async: fix an error code + - driver core: Call dma_cleanup() on the test_remove path + - kernfs: add stub helper for kernfs_generic_poll() + - extcon: cht_wc: add POWER_SUPPLY dependency + - iommu/mediatek: Fix two IOMMU share pagetable issue + - iommu/sprd: Add missing force_aperture + - RDMA/hns: Fix port active speed + - RDMA/hns: Fix incorrect post-send with direct wqe of wr-list + - RDMA/hns: Fix inaccurate error label name in init instance + - RDMA/hns: Fix CQ and QP cache affinity + - IB/uverbs: Fix an potential error pointer dereference + - fsi: aspeed: Reset master errors after CFAM reset + - iommu/qcom: Disable and reset context bank before programming + - iommu/vt-d: Fix to flush cache of PASID directory table + - platform/x86: dell-sysman: Fix reference leak + - media: cec: core: add adap_nb_transmit_canceled() callback + - media: cec: core: add adap_unconfigured() callback + - media: go7007: Remove redundant if statement + - media: venus: hfi_venus: Only consider sys_idle_indicator on V1 + - docs: ABI: fix spelling/grammar in SBEFIFO timeout interface + - USB: gadget: core: Add missing kerneldoc for vbus_work + - USB: gadget: f_mass_storage: Fix unused variable warning + - drivers: base: Free devm resources when unregistering a device + - HID: input: Support devices sending Eraser without Invert + - media: ov5640: Enable MIPI interface in ov5640_set_power_mipi() + - media: ov5640: Fix initial RESETB state and annotate timings + - media: ov2680: Remove auto-gain and auto-exposure controls + - media: ov2680: Fix ov2680_bayer_order() + - media: ov2680: Fix vflip / hflip set functions + - media: ov2680: Remove VIDEO_V4L2_SUBDEV_API ifdef-s + - media: ov2680: Don't take the lock for try_fmt calls + - media: ov2680: Add ov2680_fill_format() helper function + - media: ov2680: Fix ov2680_set_fmt() which == V4L2_SUBDEV_FORMAT_TRY not + working + - media: ov2680: Fix regulators being left enabled on ov2680_power_on() errors + - media: i2c: rdacm21: Fix uninitialized value + - f2fs: fix to avoid mmap vs set_compress_option case + - f2fs: judge whether discard_unit is section only when have + CONFIG_BLK_DEV_ZONED + - f2fs: Only lfs mode is allowed with zoned block device feature + - Revert "f2fs: fix to do sanity check on extent cache correctly" + - cgroup:namespace: Remove unused cgroup_namespaces_init() + - coresight: trbe: Fix TRBE potential sleep in atomic context + - scsi: core: Use 32-bit hostnum in scsi_host_lookup() + - scsi: fcoe: Fix potential deadlock on &fip->ctlr_lock + - interconnect: qcom: sm8450: Enable sync_state + - interconnect: qcom: bcm-voter: Improve enable_mask handling + - interconnect: qcom: bcm-voter: Use enable_maks for keepalive voting + - serial: tegra: handle clk prepare error in tegra_uart_hw_init() + - amba: bus: fix refcount leak + - Revert "IB/isert: Fix incorrect release of isert connection" + - RDMA/siw: Balance the reference of cep->kref in the error path + - RDMA/siw: Correct wrong debug message + - RDMA/efa: Fix wrong resources deallocation order + - HID: logitech-dj: Fix error handling in logi_dj_recv_switch_to_dj_mode() + - HID: uclogic: Correct devm device reference for hidinput input_dev name + - HID: multitouch: Correct devm device reference for hidinput input_dev name + - platform/x86/amd/pmf: Fix a missing cleanup path + - tick/rcu: Fix false positive "softirq work is pending" messages + - x86/speculation: Mark all Skylake CPUs as vulnerable to GDS + - tracing: Remove extra space at the end of hwlat_detector/mode + - tracing: Fix race issue between cpu buffer write and swap + - mtd: rawnand: brcmnand: Fix mtd oobsize + - dmaengine: idxd: Modify the dependence of attribute pasid_enabled + - phy/rockchip: inno-hdmi: use correct vco_div_5 macro on rk3328 + - phy/rockchip: inno-hdmi: round fractal pixclock in rk3328 recalc_rate + - phy/rockchip: inno-hdmi: do not power on rk3328 post pll on reg write + - rpmsg: glink: Add check for kstrdup + - leds: pwm: Fix error code in led_pwm_create_fwnode() + - leds: multicolor: Use rounded division when calculating color components + - leds: Fix BUG_ON check for LED_COLOR_ID_MULTI that is always false + - leds: trigger: tty: Do not use LED_ON/OFF constants, use + led_blink_set_oneshot instead + - mtd: spi-nor: Check bus width while setting QE bit + - mtd: rawnand: fsmc: handle clk prepare error in fsmc_nand_resume() + - um: Fix hostaudio build errors + - dmaengine: ste_dma40: Add missing IRQ check in d40_probe + - Drivers: hv: vmbus: Don't dereference ACPI root object handle + - cpufreq: Fix the race condition while updating the transition_task of policy + - virtio_ring: fix avail_wrap_counter in virtqueue_add_packed + - netfilter: nft_exthdr: Fix non-linear header modification + - skbuff: skb_segment, Call zero copy functions before using skbuff frags + - PM / devfreq: Fix leak in devfreq_dev_release() + - ALSA: pcm: Fix missing fixup call in compat hw_refine ioctl + - rcu: dump vmalloc memory info safely + - printk: ringbuffer: Fix truncating buffer size min_t cast + - scsi: core: Fix the scsi_set_resid() documentation + - mm/vmalloc: add a safer version of find_vm_area() for debug + - cpu/hotplug: Prevent self deadlock on CPU hot-unplug + - media: i2c: ccs: Check rules is non-NULL + - [Config] updateconfigs for VIDEO_CAMERA_SENSOR + - media: i2c: Add a camera sensor top level menu + - PCI: rockchip: Use 64-bit mask on MSI 64-bit PCI address + - ipmi_si: fix a memleak in try_smi_init() + - ARM: OMAP2+: Fix -Warray-bounds warning in _pwrdm_state_switch() + - XArray: Do not return sibling entries from xa_load() + - io_uring: break iopolling on signal + - backlight/gpio_backlight: Compare against struct fb_info.device + - backlight/bd6107: Compare against struct fb_info.device + - backlight/lv5207lp: Compare against struct fb_info.device + - drm/amd/display: register edp_backlight_control() for DCN301 + - xtensa: PMU: fix base address for the newer hardware + - LoongArch: mm: Add p?d_leaf() definitions + - i3c: master: svc: fix probe failure when no i3c device exist + - arm64: csum: Fix OoB access in IP checksum code for negative lengths + - ALSA: hda/cirrus: Fix broken audio on hardware with two CS42L42 codecs. + - media: dvb: symbol fixup for dvb_attach() + - media: venus: hfi_venus: Write to VIDC_CTRL_INIT after unmasking interrupts + - scsi: mpt3sas: Perform additional retries if doorbell read returns 0 + - PCI: Free released resource after coalescing + - PCI: hv: Fix a crash in hv_pci_restore_msi_msg() during hibernation + - PCI/PM: Only read PCI_PM_CTRL register when available + - ntb: Drop packets when qp link is down + - ntb: Clean up tx tail index on link down + - ntb: Fix calculation ntb_transport_tx_free_entry() + - Revert "PCI: Mark NVIDIA T4 GPUs to avoid bus reset" + - block: don't add or resize partition on the disk with GENHD_FL_NO_PART + - procfs: block chmod on /proc/thread-self/comm + - parisc: Fix /proc/cpuinfo output for lscpu + - drm/amd/display: Add smu write msg id fail retry process + - bpf: Fix issue in verifying allow_ptr_leaks + - dlm: fix plock lookup when using multiple lockspaces + - dccp: Fix out of bounds access in DCCP error handler + - x86/sev: Make enc_dec_hypercall() accept a size instead of npages + - X.509: if signature is unsupported skip validation + - net: handle ARPHRD_PPP in dev_is_mac_header_xmit() + - fsverity: skip PKCS#7 parser when keyring is empty + - x86/MCE: Always save CS register on AMD Zen IF Poison errors + - platform/chrome: chromeos_acpi: print hex string for ACPI_TYPE_BUFFER + - mmc: renesas_sdhi: register irqs before registering controller + - pstore/ram: Check start of empty przs during init + - arm64: sdei: abort running SDEI handlers during crash + - s390/dcssblk: fix kernel crash with list_add corruption + - s390/ipl: add missing secure/has_secure file to ipl type 'unknown' + - s390/dasd: fix string length handling + - crypto: stm32 - fix loop iterating through scatterlist for DMA + - cpufreq: brcmstb-avs-cpufreq: Fix -Warray-bounds bug + - of: property: fw_devlink: Add a devlink for panel followers + - usb: typec: tcpm: set initial svdm version based on pd revision + - usb: typec: bus: verify partner exists in typec_altmode_attention + - x86/sgx: Break up long non-preemptible delays in sgx_vepc_release() + - perf/x86/uncore: Correct the number of CHAs on EMR + - serial: sc16is7xx: remove obsolete out_thread label + - serial: sc16is7xx: fix regression with GPIO configuration + - tracing: Zero the pipe cpumask on alloc to avoid spurious -EBUSY + - Revert "drm/amd/display: Do not set drr on pipe commit" + - md: Free resources in __md_stop + - NFSv4.2: Fix a potential double free with READ_PLUS + - NFSv4.2: Rework scratch handling for READ_PLUS (again) + - md: fix regression for null-ptr-deference in __md_stop() + - clk: Mark a fwnode as initialized when using CLK_OF_DECLARE() macro + - treewide: Fix probing of devices in DT overlays + - clk: Avoid invalid function names in CLK_OF_DECLARE() + - powercap: arm_scmi: Remove recursion while parsing zones + - wifi: mt76: mt7915: rework tx packets counting when WED is active + - wifi: mt76: mt7915: rework tx bytes counting when WED is active + - wifi: mt76: mt7996: fix bss wlan_idx when sending bss_info command + - wifi: mt76: mt7996: use correct phy for background radar event + - wifi: mt76: mt7996: fix WA event ring size + - can: tcan4x5x: Remove reserved register 0x814 from writable table + - net: lan966x: Fix return value check for vcap_get_rule() + - wifi: rtw89: 8852b: rfk: fine tune IQK parameters to improve performance on + 2GHz band + - bpf: Fix check_func_arg_reg_off bug for graph root/node + - octeontx2-af: CN10KB: fix PFC configuration + - drm: bridge: dw-mipi-dsi: Fix enable/disable of DSI controller + - ARM: dts: stm32: Add missing detach mailbox for DHCOR SoM + - arm64: dts: qcom: pmi8950: Add missing OVP interrupt + - ARM: dts: qcom: sdx65-mtp: Update the pmic used in sdx65 + - iommufd: Fix locking around hwpt allocation + - clk: qcom: dispcc-sc8280xp: Use ret registers on GDSCs + - PCI: Mark NVIDIA T4 GPUs to avoid bus reset + - pinctrl: mediatek: assign functions to configure pin bias on MT7986 + - media: amphion: decoder support display delay for all formats + - RDMA/rxe: Move work queue code to subroutines + - RDMA/rxe: Fix rxe_modify_srq + - iommu: Remove kernel-doc warnings + - arm64: defconfig: Drop CONFIG_VIDEO_IMX_MEDIA + - media: ipu-bridge: Fix null pointer deref on SSDB/PLD parsing warnings + - thermal/drivers/imx8mm: Suppress log message on probe deferral + - dmaengine: idxd: Allow ATS disable update only for configurable devices + - powerpc/ftrace: Fix dropping weak symbols with older toolchains + - crypto: af_alg - Decrement struct key.usage in alg_set_by_key_serial() + - x86/build: Fix linker fill bytes quirk/incompatibility for ld.lld + - Upstream stable to v6.1.53, v6.4.16 + + * CVE-2023-6176 + - net/tls: do not free tls_rec on async operation in bpf_exec_tx_verdict() + + -- Roxana Nicolescu Mon, 08 Jan 2024 14:11:39 +0100 + linux (6.2.0-39.40) lunar; urgency=medium * lunar/linux: 6.2.0-39.40 -proposed tracker (LP: #2043451) diff -u linux-6.2.0/debian.master/config/annotations linux-6.2.0/debian.master/config/annotations --- linux-6.2.0/debian.master/config/annotations +++ linux-6.2.0/debian.master/config/annotations @@ -258,15 +258,9 @@ CONFIG_IMA_APPRAISE policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}> CONFIG_IMA_APPRAISE note<'LP: #1643652'> -CONFIG_IMA_APPRAISE_SIGNED_INIT policy<{'amd64': '-', 'arm64': '-', 'armhf': '-', 'ppc64el': 'n', 's390x': '-'}> -CONFIG_IMA_APPRAISE_SIGNED_INIT note<'LP: #1667490'> - CONFIG_IMA_ARCH_POLICY policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}> CONFIG_IMA_ARCH_POLICY note<'LP: #1866909'> -CONFIG_IMA_BLACKLIST_KEYRING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}> -CONFIG_IMA_BLACKLIST_KEYRING note<'LP: #1667490'> - CONFIG_IMA_DEFAULT_HASH_SHA256 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'n'}> CONFIG_IMA_DEFAULT_HASH_SHA256 note<'LP: #1643652'> @@ -276,24 +270,15 @@ CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}> CONFIG_IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY note<'LP: #1667490'> -CONFIG_IMA_LOAD_X509 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'n'}> -CONFIG_IMA_LOAD_X509 note<'LP: #1643652'> - CONFIG_IMA_READ_POLICY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'n'}> CONFIG_IMA_READ_POLICY note<'LP: #1866909'> CONFIG_IMA_SIG_TEMPLATE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'y', 'riscv64': 'n', 's390x': 'n'}> CONFIG_IMA_SIG_TEMPLATE note<'LP: #1643652'> -CONFIG_IMA_TRUSTED_KEYRING policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}> -CONFIG_IMA_TRUSTED_KEYRING note<'LP: #1643652'> - CONFIG_IMA_WRITE_POLICY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}> CONFIG_IMA_WRITE_POLICY note<'LP: #1667490'> -CONFIG_IMA_X509_PATH policy<{'ppc64el': '"/etc/keys/x509_ima.der"'}> -CONFIG_IMA_X509_PATH note<'LP: #1643652'> - CONFIG_INPUT_UINPUT policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}> CONFIG_INPUT_UINPUT note<'LP: #584812'> @@ -732,6 +717,9 @@ CONFIG_VFIO_PCI policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}> CONFIG_VFIO_PCI note<'LP: #1636733'> +CONFIG_VFIO_PCI_ZDEV_KVM policy<{'s390x': 'y'}> +CONFIG_VFIO_PCI_ZDEV_KVM note<'LP: #2042853'> + CONFIG_VIDEO_VIMC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_VIDEO_VIMC note<'LP: #1831482'> @@ -1532,6 +1520,7 @@ CONFIG_ARM64_ERRATUM_2457168 policy<{'arm64': 'y'}> CONFIG_ARM64_ERRATUM_2645198 policy<{'arm64': 'y'}> CONFIG_ARM64_ERRATUM_2658417 policy<{'arm64': 'y'}> +CONFIG_ARM64_ERRATUM_2966298 policy<{'arm64': 'y'}> CONFIG_ARM64_ERRATUM_819472 policy<{'arm64': 'y'}> CONFIG_ARM64_ERRATUM_824069 policy<{'arm64': 'y'}> CONFIG_ARM64_ERRATUM_826319 policy<{'arm64': 'y'}> @@ -2394,6 +2383,7 @@ CONFIG_CAN_SLCAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_CAN_SOFTING policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_CAN_SOFTING_CS policy<{'amd64': 'm'}> +CONFIG_CAN_SUN4I policy<{'riscv64': 'm'}> CONFIG_CAN_TI_HECC policy<{'armhf': 'm'}> CONFIG_CAN_UCAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_CAN_VCAN policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> @@ -6017,11 +6007,13 @@ CONFIG_IMA_APPRAISE_BOOTPARAM policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}> CONFIG_IMA_APPRAISE_BUILD_POLICY policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}> CONFIG_IMA_APPRAISE_MODSIG policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}> +CONFIG_IMA_BLACKLIST_KEYRING policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}> CONFIG_IMA_DEFAULT_HASH policy<{'amd64': '"sha1"', 'arm64': '"sha1"', 'armhf': '"sha1"', 'ppc64el': '"sha256"', 'riscv64': '"sha1"', 's390x': '"sha1"'}> CONFIG_IMA_DEFAULT_HASH_SHA1 policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'n', 'riscv64': 'y', 's390x': 'y'}> CONFIG_IMA_DEFAULT_HASH_SHA512 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}> CONFIG_IMA_DEFAULT_TEMPLATE policy<{'amd64': '"ima-ng"', 'arm64': '"ima-ng"', 'armhf': '"ima-ng"', 'ppc64el': '"ima-sig"', 'riscv64': '"ima-ng"', 's390x': '"ima-ng"'}> CONFIG_IMA_DISABLE_HTABLE policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}> +CONFIG_IMA_LOAD_X509 policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}> CONFIG_IMA_LSM_RULES policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}> CONFIG_IMA_MEASURE_ASYMMETRIC_KEYS policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y', 's390x': 'y'}> CONFIG_IMA_MEASURE_PCR_IDX policy<{'amd64': '10', 'arm64': '10', 'armhf': '10', 'ppc64el': '10', 'riscv64': '10', 's390x': '10'}> @@ -8888,7 +8880,7 @@ CONFIG_NVME_TARGET_TCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}> CONFIG_NVME_TCP policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'm'}> CONFIG_NVME_VERBOSE_ERRORS policy<{'amd64': 'n', 'arm64': 'n', 'armhf': 'n', 'ppc64el': 'n', 'riscv64': 'n', 's390x': 'n'}> -CONFIG_NVSW_SN2201 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm'}> +CONFIG_NVSW_SN2201 policy<{'amd64': 'm', 'arm64': 'm', 'armhf': '-'}> CONFIG_NV_TCO policy<{'amd64': 'm'}> CONFIG_NXP_C45_TJA11XX_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': 'n'}> CONFIG_NXP_TJA11XX_PHY policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm', 's390x': '-'}> @@ -14036,7 +14028,6 @@ CONFIG_VFIO_PCI_INTX policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}> CONFIG_VFIO_PCI_MMAP policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}> CONFIG_VFIO_PCI_VGA policy<{'amd64': 'y'}> -CONFIG_VFIO_PCI_ZDEV_KVM policy<{'s390x': 'n'}> CONFIG_VFIO_PLATFORM policy<{'arm64': 'm', 'armhf': 'm'}> CONFIG_VFIO_PLATFORM_AMDXGBE_RESET policy<{'arm64': 'm', 'armhf': 'm'}> CONFIG_VFIO_PLATFORM_CALXEDAXGMAC_RESET policy<{'arm64': 'm', 'armhf': 'm'}> @@ -14108,6 +14099,7 @@ CONFIG_VIDEO_CADENCE_CSI2RX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_VIDEO_CADENCE_CSI2TX policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_VIDEO_CAFE_CCIC policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> +CONFIG_VIDEO_CAMERA_SENSOR policy<{'amd64': 'y', 'arm64': 'y', 'armhf': 'y', 'ppc64el': 'y', 'riscv64': 'y'}> CONFIG_VIDEO_CCS policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_VIDEO_CCS_PLL policy<{'amd64': 'm', 'arm64': 'm', 'armhf': 'm', 'ppc64el': 'm', 'riscv64': 'm'}> CONFIG_VIDEO_COBALT policy<{'amd64': 'm'}> diff -u linux-6.2.0/debian.master/reconstruct linux-6.2.0/debian.master/reconstruct --- linux-6.2.0/debian.master/reconstruct +++ linux-6.2.0/debian.master/reconstruct @@ -1,4 +1,53 @@ # Recreate any symlinks created since the orig. +chmod +x 'debian/cloud-tools/hv_get_dhcp_info' +chmod +x 'debian/cloud-tools/hv_get_dns_info' +chmod +x 'debian/cloud-tools/hv_set_ifconfig' +chmod +x 'debian/rules' +chmod +x 'debian/scripts/checks/abi-check' +chmod +x 'debian/scripts/checks/config-check' +chmod +x 'debian/scripts/checks/final-checks' +chmod +x 'debian/scripts/checks/module-check' +chmod +x 'debian/scripts/checks/module-signature-check' +chmod +x 'debian/scripts/checks/retpoline-check' +chmod +x 'debian/scripts/control-create' +chmod +x 'debian/scripts/dkms-build' +chmod +x 'debian/scripts/dkms-build--nvidia-N' +chmod +x 'debian/scripts/dkms-build-configure--zfs' +chmod +x 'debian/scripts/file-downloader' +chmod +x 'debian/scripts/link-headers' +chmod +x 'debian/scripts/link-lib-rust' +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/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' +chmod +x 'debian/scripts/misc/insert-ubuntu-changes' +chmod +x 'debian/scripts/misc/kernelconfig' +chmod +x 'debian/scripts/misc/migrate-annotations' +chmod +x 'debian/scripts/misc/retag' +chmod +x 'debian/scripts/misc/splitconfig.pl' +chmod +x 'debian/scripts/misc/update-aufs.sh' +chmod +x 'debian/scripts/module-inclusion' +chmod +x 'debian/scripts/retpoline-extract' +chmod +x 'debian/scripts/retpoline-extract-one' +chmod +x 'debian/scripts/sign-module' +chmod +x 'debian/templates/extra.postinst.in' +chmod +x 'debian/templates/extra.postrm.in' +chmod +x 'debian/templates/headers.postinst.in' +chmod +x 'debian/templates/image.postinst.in' +chmod +x 'debian/templates/image.postrm.in' +chmod +x 'debian/templates/image.preinst.in' +chmod +x 'debian/templates/image.prerm.in' +chmod +x 'debian/tests-build/check-aliases' +chmod +x 'debian/tests/rebuild' +chmod +x 'debian/tests/ubuntu-regression-suite' +chmod +x 'drivers/watchdog/f71808e_wdt.c' +chmod +x 'tools/testing/selftests/netfilter/nft_audit.sh' +chmod +x 'update-dkms-versions' # Remove any files deleted from the orig. rm -f 'arch/alpha/include/asm/bugs.h' rm -f 'arch/ia64/include/asm/bugs.h' @@ -164,58 +213,7 @@ rm -f 'scripts/is_rust_module.sh' +rm -f 'tools/perf/pmu-events/arch/powerpc/power10/floating_point.json' rm -f 'tools/testing/selftests/net/bpf/Makefile' rm -f 'tools/testing/selftests/net/bpf/nat6to4.c' rm -f 'tools/testing/selftests/tc-testing/tc-tests/filters/rsvp.json' rm -f 'tools/testing/selftests/tc-testing/tc-tests/filters/tcindex.json' -chmod +x 'debian/cloud-tools/hv_get_dhcp_info' -chmod +x 'debian/cloud-tools/hv_get_dns_info' -chmod +x 'debian/cloud-tools/hv_set_ifconfig' -chmod +x 'debian/rules' -chmod +x 'debian/scripts/checks/abi-check' -chmod +x 'debian/scripts/checks/config-check' -chmod +x 'debian/scripts/checks/final-checks' -chmod +x 'debian/scripts/checks/module-check' -chmod +x 'debian/scripts/checks/module-signature-check' -chmod +x 'debian/scripts/checks/retpoline-check' -chmod +x 'debian/scripts/control-create' -chmod +x 'debian/scripts/dkms-build' -chmod +x 'debian/scripts/dkms-build--nvidia-N' -chmod +x 'debian/scripts/dkms-build-configure--zfs' -chmod +x 'debian/scripts/file-downloader' -chmod +x 'debian/scripts/helpers/close' -chmod +x 'debian/scripts/helpers/open' -chmod +x 'debian/scripts/helpers/rebase' -chmod +x 'debian/scripts/link-headers' -chmod +x 'debian/scripts/link-lib-rust' -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/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' -chmod +x 'debian/scripts/misc/insert-ubuntu-changes' -chmod +x 'debian/scripts/misc/kernelconfig' -chmod +x 'debian/scripts/misc/migrate-annotations' -chmod +x 'debian/scripts/misc/retag' -chmod +x 'debian/scripts/misc/splitconfig.pl' -chmod +x 'debian/scripts/misc/update-aufs.sh' -chmod +x 'debian/scripts/module-inclusion' -chmod +x 'debian/scripts/retpoline-extract' -chmod +x 'debian/scripts/retpoline-extract-one' -chmod +x 'debian/scripts/sign-module' -chmod +x 'debian/templates/extra.postinst.in' -chmod +x 'debian/templates/extra.postrm.in' -chmod +x 'debian/templates/headers.postinst.in' -chmod +x 'debian/templates/image.postinst.in' -chmod +x 'debian/templates/image.postrm.in' -chmod +x 'debian/templates/image.preinst.in' -chmod +x 'debian/templates/image.prerm.in' -chmod +x 'debian/tests-build/check-aliases' -chmod +x 'debian/tests/rebuild' -chmod +x 'debian/tests/ubuntu-regression-suite' -chmod +x 'drivers/watchdog/f71808e_wdt.c' -chmod -x 'scripts/is_rust_module.sh' -chmod +x 'update-dkms-versions' exit 0 diff -u linux-6.2.0/debian.master/tracking-bug linux-6.2.0/debian.master/tracking-bug --- linux-6.2.0/debian.master/tracking-bug +++ linux-6.2.0/debian.master/tracking-bug @@ -1 +1 @@ -2043451 2023.10.30-3 +2048351 2024.01.08-1 diff -u linux-6.2.0/debian.master/upstream-stable linux-6.2.0/debian.master/upstream-stable --- linux-6.2.0/debian.master/upstream-stable +++ linux-6.2.0/debian.master/upstream-stable @@ -3,4 +3,5 @@ - linux-6.1.y = v6.1.52 + linux-6.1.y = v6.1.57 linux-6.2.y = v6.2.16 linux-6.3.y = v6.3.13 - linux-6.4.y = v6.4.15 + linux-6.4.y = v6.4.16 + linux-6.5.y = v6.5.7 diff -u linux-6.2.0/debian/changelog linux-6.2.0/debian/changelog --- linux-6.2.0/debian/changelog +++ linux-6.2.0/debian/changelog @@ -1,3 +1,1502 @@ +linux (6.2.0-41.42) lunar; urgency=medium + + * lunar/linux: 6.2.0-41.42 -proposed tracker (LP: #2048351) + + * Packaging resync (LP: #1786013) + - [Packaging] resync git-ubuntu-log + - [Packaging] resync update-dkms-versions helper + - [Packaging] remove helper scripts + - [Packaging] update annotations scripts + - debian/dkms-versions -- update from kernel-versions (main/2024.01.08) + + * [SRU][22.04.2 & 23.10] OS cannot boot successfully when enabling VMD in UEFI + setup (LP: #2020022) + - x86: don't use REP_GOOD or ERMS for small memory clearing + - x86/cpufeatures: Add macros for Intel's new fast rep string features + + * Hotplugging SCSI disk in QEMU VM fails (LP: #2047382) + - Revert "PCI: acpiphp: Reassign resources on bridge if necessary" + + * CVE-2023-6622 + - netfilter: nf_tables: bail out on mismatching dynset and set expressions + + * CVE-2023-6111 + - netfilter: nf_tables: remove catchall element in GC sync path + + * CVE-2024-0193 + - netfilter: nf_tables: skip set commit for deleted/destroyed sets + + * Sound: Add rtl quirk of M90-Gen5 (LP: #2046105) + - ALSA: hda/realtek: Enable headset on Lenovo M90 Gen5 + + * [Debian] autoreconstruct - Do not generate chmod -x for deleted files + (LP: #2045562) + - [Debian] autoreconstruct - Do not generate chmod -x for deleted files + + * CVE-2023-6932 + - ipv4: igmp: fix refcnt uaf issue when receiving igmp query packet + + * CVE-2023-6931 + - perf: Fix perf_event_validate_size() + - perf: Fix perf_event_validate_size() lockdep splat + + * CVE-2023-6531 + - io_uring/af_unix: disable sending io_uring over sockets + + * CVE-2023-6606 + - smb: client: fix OOB in smbCalcSize() + + * CVE-2023-6817 + - netfilter: nft_set_pipapo: skip inactive elements during set walk + + * Avoid using damage rectangle under hardware rotation mode when PSR is + enabled (LP: #2045958) + - drm/amd/display: fix hw rotated modes when PSR-SU is enabled + + * Lunar update: upstream stable patchset 2023-12-11 (LP: #2046197) + - NFS/pNFS: Report EINVAL errors from connect() to the server + - SUNRPC: Mark the cred for revalidation if the server rejects it + - NFSv4.1: use EXCHGID4_FLAG_USE_PNFS_DS for DS server + - NFSv4.1: fix pnfs MDS=DS session trunking + - media: v4l: Use correct dependency for camera sensor drivers + - media: via: Use correct dependency for camera sensor drivers + - netfs: Only call folio_start_fscache() one time for each folio + - dm: fix a race condition in retrieve_deps + - btrfs: improve error message after failure to add delayed dir index item + - btrfs: remove BUG() after failure to insert delayed dir index item + - ext4: replace the traditional ternary conditional operator with with + max()/min() + - ext4: move setting of trimmed bit into ext4_try_to_trim_range() + - ext4: do not let fstrim block system suspend + - netfilter: nft_set_rbtree: use read spinlock to avoid datapath contention + - netfilter: nft_set_pipapo: call nft_trans_gc_queue_sync() in catchall GC + - netfilter: nft_set_pipapo: stop GC iteration if GC transaction allocation + fails + - netfilter: nft_set_hash: try later when GC hits EAGAIN on iteration + - netfilter: nf_tables: fix memleak when more than 255 elements expired + - ASoC: meson: spdifin: start hw on dai probe + - netfilter: nf_tables: disallow element removal on anonymous sets + - bpf: Avoid deadlock when using queue and stack maps from NMI + - ASoC: rt5640: Revert "Fix sleep in atomic context" + - ASoC: rt5640: Fix IRQ not being free-ed for HDA jack detect mode + - ALSA: hda/realtek: Splitting the UX3402 into two separate models + - netfilter: conntrack: fix extension size table + - selftests: tls: swap the TX and RX sockets in some tests + - net/core: Fix ETH_P_1588 flow dissector + - ASoC: hdaudio.c: Add missing check for devm_kstrdup + - ASoC: imx-audmix: Fix return error with devm_clk_get() + - octeon_ep: fix tx dma unmap len values in SG + - iavf: do not process adminq tasks when __IAVF_IN_REMOVE_TASK is set + - ASoC: SOF: core: Only call sof_ops_free() on remove if the probe was + successful + - iavf: add iavf_schedule_aq_request() helper + - iavf: schedule a request immediately after add/delete vlan + - i40e: Fix VF VLAN offloading when port VLAN is configured + - netfilter, bpf: Adjust timeouts of non-confirmed CTs in + bpf_ct_insert_entry() + - ionic: fix 16bit math issue when PAGE_SIZE >= 64KB + - igc: Fix infinite initialization loop with early XDP redirect + - scsi: iscsi_tcp: restrict to TCP sockets + - powerpc/perf/hv-24x7: Update domain value check + - dccp: fix dccp_v4_err()/dccp_v6_err() again + - x86/mm, kexec, ima: Use memblock_free_late() from ima_free_kexec_buffer() + - net: hsr: Properly parse HSRv1 supervisor frames. + - platform/x86: intel_scu_ipc: Check status after timeout in busy_loop() + - platform/x86: intel_scu_ipc: Check status upon timeout in + ipc_wait_for_interrupt() + - platform/x86: intel_scu_ipc: Don't override scu in + intel_scu_ipc_dev_simple_command() + - platform/x86: intel_scu_ipc: Fail IPC send if still busy + - x86/srso: Fix srso_show_state() side effect + - x86/srso: Fix SBPB enablement for spec_rstack_overflow=off + - net: hns3: add cmdq check for vf periodic service task + - net: hns3: fix GRE checksum offload issue + - net: hns3: only enable unicast promisc when mac table full + - net: hns3: fix fail to delete tc flower rules during reset issue + - net: hns3: add 5ms delay before clear firmware reset irq source + - net: bridge: use DEV_STATS_INC() + - team: fix null-ptr-deref when team device type is changed + - net: rds: Fix possible NULL-pointer dereference + - netfilter: nf_tables: disable toggling dormant table state more than once + - i915/pmu: Move execlist stats initialization to execlist specific setup + - locking/seqlock: Do the lockdep annotation before locking in + do_write_seqcount_begin_nested() + - net: ena: Flush XDP packets on error. + - bnxt_en: Flush XDP for bnxt_poll_nitroa0()'s NAPI + - octeontx2-pf: Do xdp_do_flush() after redirects. + - igc: Expose tx-usecs coalesce setting to user + - proc: nommu: /proc//maps: release mmap read lock + - proc: nommu: fix empty /proc//maps + - cifs: Fix UAF in cifs_demultiplex_thread() + - gpio: tb10x: Fix an error handling path in tb10x_gpio_probe() + - i2c: mux: demux-pinctrl: check the return value of devm_kstrdup() + - i2c: mux: gpio: Add missing fwnode_handle_put() + - i2c: xiic: Correct return value check for xiic_reinit() + - ARM: dts: samsung: exynos4210-i9100: Fix LCD screen's physical size + - f2fs: get out of a repeat loop when getting a locked data page + - s390/pkey: fix PKEY_TYPE_EP11_AES handling in PKEY_CLR2SECK2 IOCTL + - arm64: dts: qcom: sdm845-db845c: Mark cont splash memory region as reserved + - wifi: ath11k: fix tx status reporting in encap offload mode + - wifi: ath11k: Cleanup mac80211 references on failure during tx_complete + - scsi: qla2xxx: Select qpair depending on which CPU post_cmd() gets called + - scsi: qla2xxx: Use raw_smp_processor_id() instead of smp_processor_id() + - drm/amdkfd: Flush TLB after unmapping for GFX v9.4.3 + - drm/amdkfd: Insert missing TLB flush on GFX10 and later + - btrfs: reset destination buffer when read_extent_buffer() gets invalid range + - vfio/mdev: Fix a null-ptr-deref bug for mdev_unregister_parent() + - MIPS: Alchemy: only build mmc support helpers if au1xmmc is enabled + - spi: spi-gxp: BUG: Correct spi write return value + - drm/bridge: ti-sn65dsi83: Do not generate HFP/HBP/HSA and EOT packet + - bus: ti-sysc: Use fsleep() instead of usleep_range() in sysc_reset() + - bus: ti-sysc: Fix missing AM35xx SoC matching + - firmware: arm_scmi: Harden perf domain info access + - firmware: arm_scmi: Fixup perf power-cost/microwatt support + - power: supply: mt6370: Fix missing error code in mt6370_chg_toggle_cfo() + - clk: sprd: Fix thm_parents incorrect configuration + - clk: tegra: fix error return case for recalc_rate + - ARM: dts: ti: omap: Fix bandgap thermal cells addressing for omap3/4 + - ARM: dts: Unify pinctrl-single pin group nodes for omap4 + - ARM: dts: ti: omap: motorola-mapphone: Fix abe_clkctrl warning on boot + - bus: ti-sysc: Fix SYSC_QUIRK_SWSUP_SIDLE_ACT handling for uart wake-up + - power: supply: ucs1002: fix error code in ucs1002_get_property() + - firmware: imx-dsp: Fix an error handling path in imx_dsp_setup_channels() + - xtensa: add default definition for XCHAL_HAVE_DIV32 + - xtensa: iss/network: make functions static + - xtensa: boot: don't add include-dirs + - xtensa: umulsidi3: fix conditional expression + - xtensa: boot/lib: fix function prototypes + - power: supply: rk817: Fix node refcount leak + - selftests/powerpc: Use CLEAN macro to fix make warning + - selftests/powerpc: Pass make context to children + - selftests/powerpc: Fix emit_tests to work with run_kselftest.sh + - soc: imx8m: Enable OCOTP clock for imx8mm before reading registers + - arm64: dts: imx: Add imx8mm-prt8mm.dtb to build + - firmware: arm_ffa: Don't set the memory region attributes for MEM_LEND + - gpio: pmic-eic-sprd: Add can_sleep flag for PMIC EIC chip + - i2c: npcm7xx: Fix callback completion ordering + - x86/reboot: VMCLEAR active VMCSes before emergency reboot + - ceph: drop messages from MDS when unmounting + - dma-debug: don't call __dma_entry_alloc_check_leak() under free_entries_lock + - bpf: Annotate bpf_long_memcpy with data_race + - spi: sun6i: reduce DMA RX transfer width to single byte + - spi: sun6i: fix race between DMA RX transfer completion and RX FIFO drain + - nvme-fc: Prevent null pointer dereference in nvme_fc_io_getuuid() + - parisc: sba: Fix compile warning wrt list of SBA devices + - parisc: iosapic.c: Fix sparse warnings + - parisc: drivers: Fix sparse warning + - parisc: irq: Make irq_stack_union static to avoid sparse warning + - scsi: qedf: Add synchronization between I/O completions and abort + - scsi: ufs: core: Move __ufshcd_send_uic_cmd() outside host_lock + - scsi: ufs: core: Poll HCS.UCRDY before issuing a UIC command + - selftests/ftrace: Correctly enable event in instance-event.tc + - ring-buffer: Avoid softlockup in ring_buffer_resize() + - btrfs: assert delayed node locked when removing delayed item + - selftests: fix dependency checker script + - ring-buffer: Do not attempt to read past "commit" + - net/smc: bugfix for smcr v2 server connect success statistic + - ata: sata_mv: Fix incorrect string length computation in mv_dump_mem() + - platform/mellanox: mlxbf-bootctl: add NET dependency into Kconfig + - platform/x86: asus-wmi: Support 2023 ROG X16 tablet mode + - thermal/of: add missing of_node_put() + - drm/amd/display: Don't check registers, if using AUX BL control + - drm/amdgpu/soc21: don't remap HDP registers for SR-IOV + - drm/amdgpu/nbio4.3: set proper rmmio_remap.reg_offset for SR-IOV + - drm/amdgpu: Handle null atom context in VBIOS info ioctl + - riscv: errata: fix T-Head dcache.cva encoding + - scsi: pm80xx: Use phy-specific SAS address when sending PHY_START command + - scsi: pm80xx: Avoid leaking tags when processing + OPC_INB_SET_CONTROLLER_CONFIG command + - smb3: correct places where ENOTSUPP is used instead of preferred EOPNOTSUPP + - ata: libata-eh: do not clear ATA_PFLAG_EH_PENDING in ata_eh_reset() + - spi: nxp-fspi: reset the FLSHxCR1 registers + - spi: stm32: add a delay before SPI disable + - ASoC: fsl: imx-pcm-rpmsg: Add SNDRV_PCM_INFO_BATCH flag + - spi: intel-pci: Add support for Granite Rapids SPI serial flash + - bpf: Clarify error expectations from bpf_clone_redirect + - ALSA: hda: intel-sdw-acpi: Use u8 type for link index + - ASoC: cs42l42: Ensure a reset pulse meets minimum pulse width. + - ASoC: cs42l42: Don't rely on GPIOD_OUT_LOW to set RESET initially low + - firmware: cirrus: cs_dsp: Only log list of algorithms in debug build + - memblock tests: fix warning: "__ALIGN_KERNEL" redefined + - memblock tests: fix warning ‘struct seq_file’ declared inside parameter list + - ASoC: imx-rpmsg: Set ignore_pmdown_time for dai_link + - media: vb2: frame_vector.c: replace WARN_ONCE with a comment + - NFSv4.1: fix zero value filehandle in post open getattr + - ASoC: SOF: Intel: MTL: Reduce the DSP init timeout + - powerpc/watchpoints: Disable preemption in thread_change_pc() + - powerpc/watchpoint: Disable pagefaults when getting user instruction + - powerpc/watchpoints: Annotate atomic context in more places + - net: hsr: Add __packed to struct hsr_sup_tlv. + - tsnep: Fix NAPI scheduling + - tsnep: Fix NAPI polling with budget 0 + - LoongArch: Set all reserved memblocks on Node#0 at initialization + - fbdev/sh7760fb: Depend on FB=y + - perf build: Define YYNOMEM as YYNOABORT for bison < 3.81 + - nvme-pci: do not set the NUMA node of device if it has none + - wifi: ath11k: Don't drop tx_status when peer cannot be found + - scsi: qla2xxx: Fix NULL pointer dereference in target mode + - smack: Record transmuting in smk_transmuted + - smack: Retrieve transmuting information in smack_inode_getsecurity() + - iommu/arm-smmu-v3: Fix soft lockup triggered by arm_smmu_mm_invalidate_range + - x86/sgx: Resolves SECS reclaim vs. page fault for EAUG race + - x86/srso: Add SRSO mitigation for Hygon processors + - KVM: SVM: INTERCEPT_RDTSCP is never intercepted anyway + - KVM: SVM: Fix TSC_AUX virtualization setup + - KVM: x86/mmu: Open code leaf invalidation from mmu_notifier + - KVM: x86/mmu: Do not filter address spaces in + for_each_tdp_mmu_root_yield_safe() + - mptcp: fix bogus receive window shrinkage with multiple subflows + - Revert "tty: n_gsm: fix UAF in gsm_cleanup_mux" + - serial: 8250_port: Check IRQ data before use + - nilfs2: fix potential use after free in nilfs_gccache_submit_read_data() + - ALSA: hda: Disable power save for solving pop issue on Lenovo ThinkCentre + M70q + - LoongArch: Define relocation types for ABI v2.10 + - LoongArch: numa: Fix high_memory calculation + - ata: libata-scsi: link ata port and scsi device + - ata: libata-scsi: ignore reserved bits for REPORT SUPPORTED OPERATION CODES + - io_uring/fs: remove sqe->rw_flags checking from LINKAT + - i2c: i801: unregister tco_pdev in i801_probe() error path + - ASoC: amd: yc: Fix non-functional mic on Lenovo 82QF and 82UG + - kernel/sched: Modify initial boot task idle setup + - sched/rt: Fix live lock between select_fallback_rq() and RT push + - Revert "SUNRPC dont update timeout value on connection reset" + - timers: Tag (hr)timer softirq as hotplug safe + - drm/tests: Fix incorrect argument in drm_test_mm_insert_range + - arm64: defconfig: remove CONFIG_COMMON_CLK_NPCM8XX=y + - mm/damon/vaddr-test: fix memory leak in damon_do_test_apply_three_regions() + - mm/slab_common: fix slab_caches list corruption after kmem_cache_destroy() + - mm: memcontrol: fix GFP_NOFS recursion in memory.high enforcement + - ring-buffer: Update "shortest_full" in polling + - btrfs: properly report 0 avail for very full file systems + - media: uvcvideo: Fix OOB read + - bpf: Add override check to kprobe multi link attach + - bpf: Fix BTF_ID symbol generation collision + - bpf: Fix BTF_ID symbol generation collision in tools/ + - net: thunderbolt: Fix TCPv6 GSO checksum calculation + - ata: libata-core: Fix ata_port_request_pm() locking + - ata: libata-core: Fix port and device removal + - ata: libata-core: Do not register PM operations for SAS ports + - ata: libata-sata: increase PMP SRST timeout to 10s + - drm/i915/gt: Fix reservation address in ggtt_reserve_guc_top + - power: supply: rk817: Add missing module alias + - power: supply: ab8500: Set typing and props + - fs: binfmt_elf_efpic: fix personality for ELF-FDPIC + - drm/amdkfd: Use gpu_offset for user queue's wptr + - drm/meson: fix memory leak on ->hpd_notify callback + - memcg: drop kmem.limit_in_bytes + - mm, memcg: reconsider kmem.limit_in_bytes deprecation + - ASoC: amd: yc: Fix a non-functional mic on Lenovo 82TL + - NFS: More fixes for nfs_direct_write_reschedule_io() + - ASoC: rt5640: Fix sleep in atomic context + - ASoC: rt5640: Do not disable/enable IRQ twice on suspend/resume + - ASoC: rt5640: Enable the IRQ on resume after configuring jack-detect + - uapi: stddef.h: Fix __DECLARE_FLEX_ARRAY for C++ + - net: microchip: sparx5: Fix memory leak for + vcap_api_rule_add_keyvalue_test() + - net: microchip: sparx5: Fix memory leak for + vcap_api_rule_add_actionvalue_test() + - net: microchip: sparx5: Fix possible memory leak in + vcap_api_encode_rule_test() + - net: microchip: sparx5: Fix possible memory leaks in + test_vcap_xn_rule_creator() + - net: microchip: sparx5: Fix possible memory leaks in vcap_api_kunit + - x86/srso: Set CPUID feature bits independently of bug or mitigation status + - x86/srso: Don't probe microcode in a guest + - vxlan: Add missing entries to vxlan_get_size() + - net: hinic: Fix warning-hinic_set_vlan_fliter() warn: variable dereferenced + before check 'hwdev' + - swiotlb: use the calculated number of areas + - i915/guc: Get runtime pm in busyness worker only if already active + - spi: zynqmp-gqspi: fix clock imbalance on probe failure + - mm: page_alloc: fix CMA and HIGHATOMIC landing on the wrong buddy list + - ring-buffer: Fix bytes info in per_cpu buffer stats + - btrfs: file_remove_privs needs an exclusive lock in direct io write + - Upstream stable to v6.1.56, v6.5.6 + - ASoC: soc-utils: Export snd_soc_dai_is_dummy() symbol + - ASoC: tegra: Fix redundant PLLA and PLLA_OUT0 updates + - mptcp: rename timer related helper to less confusing names + - mptcp: fix dangling connection hang-up + - mptcp: annotate lockless accesses to sk->sk_err + - mptcp: move __mptcp_error_report in protocol.c + - mptcp: process pending subflow error on close + - ata,scsi: do not issue START STOP UNIT on resume + - scsi: sd: Differentiate system and runtime start/stop management + - scsi: sd: Do not issue commands to suspended disks on shutdown + - scsi: core: Improve type safety of scsi_rescan_device() + - scsi: Do not attempt to rescan suspended devices + - ata: libata-scsi: Fix delayed scsi_rescan_device() execution + - NFS: Cleanup unused rpc_clnt variable + - NFS: rename nfs_client_kset to nfs_kset + - NFSv4: Fix a state manager thread deadlock regression + - mm/memory: add vm_normal_folio() + - mm/mempolicy: convert queue_pages_pmd() to queue_folios_pmd() + - mm/mempolicy: convert queue_pages_pte_range() to queue_folios_pte_range() + - mm/mempolicy: convert migrate_page_add() to migrate_folio_add() + - mm: mempolicy: keep VMA walk if both MPOL_MF_STRICT and MPOL_MF_MOVE are + specified + - ring-buffer: remove obsolete comment for free_buffer_page() + - Revert "NFSv4: Retry LOCK on OLD_STATEID during delegation return" + - arm64: Avoid repeated AA64MMFR1_EL1 register read on pagefault path + - net: add sysctl accept_ra_min_rtr_lft + - net: change accept_ra_min_rtr_lft to affect all RA lifetimes + - net: release reference to inet6_dev pointer + - arm64: cpufeature: Fix CLRBHB and BC detection + - drm/amd/display: Adjust the MST resume flow + - iommu/arm-smmu-v3: Set TTL invalidation hint better + - iommu/arm-smmu-v3: Avoid constructing invalid range commands + - rbd: move rbd_dev_refresh() definition + - rbd: decouple header read-in from updating rbd_dev->header + - rbd: decouple parent info read-in from updating rbd_dev + - rbd: take header_rwsem in rbd_dev_refresh() only when updating + - hwmon: (nzxt-smart2) Add device id + - hwmon: (nzxt-smart2) add another USB ID + - scsi: zfcp: Fix a double put in zfcp_port_enqueue() + - iommu/vt-d: Avoid memory allocation in iommu_suspend() + - net: ethernet: mediatek: disable irq before schedule napi + - mptcp: userspace pm allow creating id 0 subflow + - qed/red_ll2: Fix undefined behavior bug in struct qed_ll2_info + - Bluetooth: hci_codec: Fix leaking content of local_codecs + - Bluetooth: hci_sync: Fix handling of HCI_QUIRK_STRICT_DUPLICATE_FILTER + - wifi: mwifiex: Fix tlv_buf_left calculation + - md/raid5: release batch_last before waiting for another stripe_head + - PCI: qcom: Fix IPQ8074 enumeration + - net: replace calls to sock->ops->connect() with kernel_connect() + - net: prevent rewrite of msg_name in sock_sendmsg() + - drm/amd: Fix detection of _PR3 on the PCIe root port + - drm/amd: Fix logic error in sienna_cichlid_update_pcie_parameters() + - arm64: Add Cortex-A520 CPU part definition + - arm64: errata: Add Cortex-A520 speculative unprivileged load workaround + - [Config] updateconfigs for ARM64_ERRATUM_2966298 + - HID: sony: Fix a potential memory leak in sony_probe() + - ubi: Refuse attaching if mtd's erasesize is 0 + - erofs: fix memory leak of LZMA global compressed deduplication + - wifi: iwlwifi: dbg_ini: fix structure packing + - wifi: iwlwifi: mvm: Fix a memory corruption issue + - wifi: cfg80211: hold wiphy lock in auto-disconnect + - wifi: cfg80211: move wowlan disable under locks + - wifi: cfg80211: add a work abstraction with special semantics + - wifi: cfg80211: fix cqm_config access race + - wifi: cfg80211: add missing kernel-doc for cqm_rssi_work + - wifi: mwifiex: Fix oob check condition in mwifiex_process_rx_packet + - leds: Drop BUG_ON check for LED_COLOR_ID_MULTI + - bpf: Fix tr dereferencing + - regulator: mt6358: Drop *_SSHUB regulators + - regulator: mt6358: Use linear voltage helpers for single range regulators + - regulator: mt6358: split ops for buck and linear range LDO regulators + - Bluetooth: Delete unused hci_req_prepare_suspend() declaration + - Bluetooth: ISO: Fix handling of listen for unicast + - drivers/net: process the result of hdlc_open() and add call of hdlc_close() + in uhdlc_close() + - wifi: mt76: mt76x02: fix MT76x0 external LNA gain handling + - perf/x86/amd/core: Fix overflow reset on hotplug + - regmap: rbtree: Fix wrong register marked as in-cache when creating new node + - wifi: mac80211: fix potential key use-after-free + - perf/x86/amd: Do not WARN() on every IRQ + - iommu/mediatek: Fix share pgtable for iova over 4GB + - regulator/core: regulator_register: set device->class earlier + - ima: Finish deprecation of IMA_TRUSTED_KEYRING Kconfig + - [Config] updateconfigs for IMA_BLACKLIST_KEYRING + - scsi: target: core: Fix deadlock due to recursive locking + - ima: rework CONFIG_IMA dependency block + - NFSv4: Fix a nfs4_state_manager() race + - bpf: tcp_read_skb needs to pop skb regardless of seq + - bpf, sockmap: Do not inc copied_seq when PEEK flag set + - bpf, sockmap: Reject sk_msg egress redirects to non-TCP sockets + - modpost: add missing else to the "of" check + - net: fix possible store tearing in neigh_periodic_work() + - bpf: Add BPF_FIB_LOOKUP_SKIP_NEIGH for bpf_fib_lookup + - neighbour: annotate lockless accesses to n->nud_state + - neighbour: switch to standard rcu, instead of rcu_bh + - neighbour: fix data-races around n->output + - ipv4, ipv6: Fix handling of transhdrlen in __ip{,6}_append_data() + - ptp: ocp: Fix error handling in ptp_ocp_device_init + - net: dsa: mv88e6xxx: Avoid EEPROM timeout when EEPROM is absent + - ipv6: tcp: add a missing nf_reset_ct() in 3WHS handling + - net: usb: smsc75xx: Fix uninit-value access in __smsc75xx_read_reg + - net: nfc: llcp: Add lock when modifying device list + - net: ethernet: ti: am65-cpsw: Fix error code in + am65_cpsw_nuss_init_tx_chns() + - ibmveth: Remove condition to recompute TCP header checksum. + - netfilter: handle the connecting collision properly in + nf_conntrack_proto_sctp + - selftests: netfilter: Test nf_tables audit logging + - selftests: netfilter: Extend nft_audit.sh + - netfilter: nf_tables: Deduplicate nft_register_obj audit logs + - netfilter: nf_tables: nft_set_rbtree: fix spurious insertion failure + - ipv4: Set offload_failed flag in fibmatch results + - net: stmmac: dwmac-stm32: fix resume on STM32 MCU + - tipc: fix a potential deadlock on &tx->lock + - tcp: fix quick-ack counting to count actual ACKs of new data + - tcp: fix delayed ACKs for MSS boundary condition + - sctp: update transport state when processing a dupcook packet + - sctp: update hb timer immediately after users change hb_interval + - netlink: annotate data-races around sk->sk_err + - HID: sony: remove duplicate NULL check before calling usb_free_urb() + - HID: intel-ish-hid: ipc: Disable and reenable ACPI GPE bit + - intel_idle: add Emerald Rapids Xeon support + - smb: use kernel_connect() and kernel_bind() + - parisc: Fix crash with nr_cpus=1 option + - dm zoned: free dmz->ddev array in dmz_put_zoned_devices + - RDMA/core: Require admin capabilities to set system parameters + - of: dynamic: Fix potential memory leak in of_changeset_action() + - IB/mlx4: Fix the size of a buffer in add_port_entries() + - gpio: aspeed: fix the GPIO number passed to pinctrl_gpio_set_config() + - gpio: pxa: disable pinctrl calls for MMP_GPIO + - RDMA/cma: Initialize ib_sa_multicast structure to 0 when join + - RDMA/cma: Fix truncation compilation warning in make_cma_ports + - RDMA/uverbs: Fix typo of sizeof argument + - RDMA/srp: Do not call scsi_done() from srp_abort() + - RDMA/siw: Fix connection failure handling + - RDMA/mlx5: Fix mutex unlocking on error flow for steering anchor creation + - RDMA/mlx5: Fix NULL string error + - x86/sev: Use the GHCB protocol when available for SNP CPUID requests + - ksmbd: fix race condition between session lookup and expire + - ksmbd: fix uaf in smb20_oplock_break_ack + - parisc: Restore __ldcw_align for PA-RISC 2.0 processors + - ipv6: remove nexthop_fib6_nh_bh() + - vrf: Fix lockdep splat in output path + - ipv6: remove one read_lock()/read_unlock() pair in rt6_check_neigh() + - xen/events: replace evtchn_rwlock with RCU + - net: mana: Fix TX CQE error handling + - mptcp: fix delegated action races + - wifi: rtw88: rtw8723d: Fix MAC address offset in EEPROM + - wifi: mt76: fix lock dependency problem for wed_lock + - wifi: cfg80211/mac80211: hold link BSSes when assoc fails for MLO connection + - ice: always add legacy 32byte RXDID in supported_rxdids + - Upstream stable to v6.1.57, v6.5.7 + + * Lunar update: upstream stable patchset 2023-12-05 (LP: #2045698) + - autofs: fix memory leak of waitqueues in autofs_catatonic_mode + - btrfs: output extra debug info if we failed to find an inline backref + - locks: fix KASAN: use-after-free in trace_event_raw_event_filelock_lock + - ACPICA: Add AML_NO_OPERAND_RESOLVE flag to Timer + - kernel/fork: beware of __put_task_struct() calling context + - rcuscale: Move rcu_scale_writer() schedule_timeout_uninterruptible() to + _idle() + - scftorture: Forgive memory-allocation failure if KASAN + - ACPI: video: Add backlight=native DMI quirk for Lenovo Ideapad Z470 + - perf/smmuv3: Enable HiSilicon Erratum 162001900 quirk for HIP08/09 + - perf/imx_ddr: speed up overflow frequency of cycle + - hw_breakpoint: fix single-stepping when using bpf_overflow_handler + - ACPI: x86: s2idle: Catch multiple ACPI_TYPE_PACKAGE objects + - selftests/nolibc: fix up kernel parameters support + - devlink: remove reload failed checks in params get/set callbacks + - crypto: lrw,xts - Replace strlcpy with strscpy + - ice: Don't tx before switchdev is fully configured + - wifi: ath9k: fix fortify warnings + - wifi: ath9k: fix printk specifier + - wifi: mwifiex: fix fortify warning + - mt76: mt7921: don't assume adequate headroom for SDIO headers + - wifi: wil6210: fix fortify warnings + - can: sun4i_can: Add acceptance register quirk + - [Config] updateconfigs for CAN_SUN4I + - can: sun4i_can: Add support for the Allwinner D1 + - net: Use sockaddr_storage for getsockopt(SO_PEERNAME). + - net/ipv4: return the real errno instead of -EINVAL + - crypto: lib/mpi - avoid null pointer deref in mpi_cmp_ui() + - Bluetooth: Fix hci_suspend_sync crash + - netlink: convert nlk->flags to atomic flags + - tpm_tis: Resend command to recover from data transfer errors + - mmc: sdhci-esdhc-imx: improve ESDHC_FLAG_ERR010450 + - alx: fix OOB-read compiler warning + - wifi: mac80211: check S1G action frame size + - netfilter: ebtables: fix fortify warnings in size_entry_mwt() + - wifi: cfg80211: reject auth/assoc to AP with our address + - wifi: cfg80211: ocb: don't leave if not joined + - wifi: mac80211: check for station first in client probe + - wifi: mac80211_hwsim: drop short frames + - libbpf: Free btf_vmlinux when closing bpf_object + - drm/bridge: tc358762: Instruct DSI host to generate HSE packets + - drm/edid: Add quirk for OSVR HDK 2.0 + - arm64: dts: qcom: sm6125-pdx201: correct ramoops pmsg-size + - arm64: dts: qcom: sm6350: correct ramoops pmsg-size + - arm64: dts: qcom: sm8150-kumano: correct ramoops pmsg-size + - arm64: dts: qcom: sm8250-edo: correct ramoops pmsg-size + - samples/hw_breakpoint: Fix kernel BUG 'invalid opcode: 0000' + - drm/amd/display: Fix underflow issue on 175hz timing + - ASoC: SOF: topology: simplify code to prevent static analysis warnings + - ASoC: Intel: sof_sdw: Update BT offload config for soundwire config + - ALSA: hda: intel-dsp-cfg: add LunarLake support + - drm/amd/display: Use DTBCLK as refclk instead of DPREFCLK + - drm/amd/display: Blocking invalid 420 modes on HDMI TMDS for DCN31 + - drm/amd/display: Blocking invalid 420 modes on HDMI TMDS for DCN314 + - drm/exynos: fix a possible null-pointer dereference due to data race in + exynos_drm_crtc_atomic_disable() + - drm/mediatek: dp: Change logging to dev for mtk_dp_aux_transfer() + - bus: ti-sysc: Configure uart quirks for k3 SoC + - md: raid1: fix potential OOB in raid1_remove_disk() + - ext2: fix datatype of block number in ext2_xattr_set2() + - fs/jfs: prevent double-free in dbUnmount() after failed jfs_remount() + - jfs: fix invalid free of JFS_IP(ipimap)->i_imap in diUnmount + - PCI: dwc: Provide deinit callback for i.MX + - ARM: 9317/1: kexec: Make smp stop calls asynchronous + - powerpc/pseries: fix possible memory leak in ibmebus_bus_init() + - PCI: vmd: Disable bridge window for domain reset + - PCI: fu740: Set the number of MSI vectors + - media: mdp3: Fix resource leaks in of_find_device_by_node + - media: dvb-usb-v2: af9035: Fix null-ptr-deref in af9035_i2c_master_xfer + - media: dw2102: Fix null-ptr-deref in dw2102_i2c_transfer() + - media: af9005: Fix null-ptr-deref in af9005_i2c_xfer + - media: anysee: fix null-ptr-deref in anysee_master_xfer + - media: az6007: Fix null-ptr-deref in az6007_i2c_xfer() + - media: dvb-usb-v2: gl861: Fix null-ptr-deref in gl861_i2c_master_xfer + - scsi: lpfc: Abort outstanding ELS cmds when mailbox timeout error is + detected + - media: tuners: qt1010: replace BUG_ON with a regular error + - media: pci: cx23885: replace BUG with error return + - usb: cdns3: Put the cdns set active part outside the spin lock + - usb: gadget: fsl_qe_udc: validate endpoint index for ch9 udc + - tools: iio: iio_generic_buffer: Fix some integer type and calculation + - scsi: target: iscsi: Fix buffer overflow in lio_target_nacl_info_show() + - serial: cpm_uart: Avoid suspicious locking + - misc: open-dice: make OPEN_DICE depend on HAS_IOMEM + - usb: ehci: add workaround for chipidea PORTSC.PEC bug + - usb: chipidea: add workaround for chipidea PEC bug + - media: pci: ipu3-cio2: Initialise timing struct to avoid a compiler warning + - kobject: Add sanity check for kset->kobj.ktype in kset_register() + - interconnect: Fix locking for runpm vs reclaim + - printk: Keep non-panic-CPUs out of console lock + - printk: Consolidate console deferred printing + - btrfs: add a helper to read the superblock metadata_uuid + - btrfs: compare the correct fsid/metadata_uuid in btrfs_validate_super + - block: factor out a bvec_set_page helper + - nvmet: use bvec_set_page to initialize bvecs + - nvmet-tcp: pass iov_len instead of sg->length to bvec_set_page() + - drm: gm12u320: Fix the timeout usage for usb_bulk_msg() + - scsi: qla2xxx: Fix NULL vs IS_ERR() bug for debugfs_create_dir() + - selftests: tracing: Fix to unmount tracefs for recovering environment + - x86/ibt: Suppress spurious ENDBR + - riscv: kexec: Align the kexeced kernel entry + - scsi: target: core: Fix target_cmd_counter leak + - scsi: lpfc: Fix the NULL vs IS_ERR() bug for debugfs_create_file() + - panic: Reenable preemption in WARN slowpath + - x86/boot/compressed: Reserve more memory for page tables + - x86/purgatory: Remove LTO flags + - samples/hw_breakpoint: fix building without module unloading + - md/raid1: fix error: ISO C90 forbids mixed declarations + - Revert "SUNRPC: Fail faster on bad verifier" + - attr: block mode changes of symlinks + - ovl: fix failed copyup of fileattr on a symlink + - ovl: fix incorrect fdput() on aio completion + - io_uring/net: fix iter retargeting for selected buf + - md: Put the right device in md_seq_next + - Revert "drm/amd: Disable S/G for APUs when 64GB or more host memory" + - dm: don't attempt to queue IO under RCU protection + - btrfs: fix lockdep splat and potential deadlock after failure running + delayed items + - btrfs: fix a compilation error if DEBUG is defined in btree_dirty_folio + - btrfs: release path before inode lookup during the ino lookup ioctl + - btrfs: check for BTRFS_FS_ERROR in pending ordered assert + - tracing: Have tracing_max_latency inc the trace array ref count + - tracing: Have event inject files inc the trace array ref count + - tracing: Increase trace array ref count on enable and filter files + - tracing: Have current_trace inc the trace array ref count + - tracing: Have option files inc the trace array ref count + - selinux: fix handling of empty opts in selinux_fs_context_submount() + - nfsd: fix change_info in NFSv4 RENAME replies + - tracefs: Add missing lockdown check to tracefs_create_dir() + - i2c: aspeed: Reset the i2c controller when timeout occurs + - ata: libata: disallow dev-initiated LPM transitions to unsupported states + - ata: libahci: clear pending interrupt status + - scsi: megaraid_sas: Fix deadlock on firmware crashdump + - scsi: pm8001: Setup IRQs on resume + - ext4: fix rec_len verify error + - drm/amd/display: fix the white screen issue when >= 64GB DRAM + - drm/amdgpu: fix amdgpu_cs_p1_user_fence + - interconnect: Teach lockdep about icc_bw_lock order + - x86/ibt: Avoid duplicate ENDBR in __put_user_nocheck*() + - btrfs: fix race between finishing block group creation and its item update + - x86/alternatives: Remove faulty optimization + - x86,static_call: Fix static-call vs return-thunk + - Upstream stable to v6.1.55, v6.5.5 + + * CVE-2023-46813 + - x86/sev: Disable MMIO emulation from user mode + - x86/sev: Check IOBM for IOIO exceptions from user-space + - x86/sev: Check for user-space IOIO pointing to kernel space + + * CVE-2023-5972 + - nf_tables: fix NULL pointer dereference in nft_inner_init() + - nf_tables: fix NULL pointer dereference in nft_expr_inner_parse() + + * RTL8111EPP: Fix the network lost after resume with DASH (LP: #2043786) + - r8169: add handling DASH when DASH is disabled + - r8169: fix network lost after resume on DASH systems + + * kernel BUG: io_uring openat triggers audit reference count underflow + (LP: #2043841) + - audit, io_uring: io_uring openat triggers audit reference count underflow + + * Fix ADL: System enabled AHCI can't get into s0ix when attached ODD + (LP: #2037493) + - ata: ahci: Add Intel Alder Lake-P AHCI controller to low power chipsets list + + * [UBUNTU 23.04] Kernel config option missing for s390x PCI passthrough + (LP: #2042853) + - [Config] CONFIG_VFIO_PCI_ZDEV_KVM=y + + * Could not probe Samsung P44 30S3 PM9C1a SSD correctly: nvme nvme0: Device + not ready: aborting installation, CSTS=0x0 (LP: #2041495) + - nvme: avoid bogus CRTO values + + * Azure: Fix Azure vendor ID (LP: #2036600) + - SAUCE: (no-up) hv: Fix supply vendor ID + + * Lunar update: upstream stable patchset 2023-11-28 (LP: #2045079) + - net/ipv6: SKB symmetric hash should incorporate transport ports + - mm: multi-gen LRU: rename lrugen->lists[] to lrugen->folios[] + - Multi-gen LRU: fix per-zone reclaim + - io_uring/net: don't overflow multishot accept + - io_uring: break out of iowq iopoll on teardown + - io_uring/sqpoll: fix io-wq affinity when IORING_SETUP_SQPOLL is used + - io_uring: Don't set affinity on a dying sqpoll thread + - drm/virtio: Conditionally allocate virtio_gpu_fence + - scsi: qla2xxx: Adjust IOCB resource on qpair create + - scsi: qla2xxx: Limit TMF to 8 per function + - scsi: qla2xxx: Fix deletion race condition + - scsi: qla2xxx: fix inconsistent TMF timeout + - scsi: qla2xxx: Fix command flush during TMF + - scsi: qla2xxx: Fix erroneous link up failure + - scsi: qla2xxx: Turn off noisy message log + - scsi: qla2xxx: Fix session hang in gnl + - scsi: qla2xxx: Fix TMF leak through + - scsi: qla2xxx: Remove unsupported ql2xenabledif option + - scsi: qla2xxx: Flush mailbox commands on chip reset + - scsi: qla2xxx: Fix smatch warn for qla_init_iocb_limit() + - scsi: qla2xxx: Error code did not return to upper layer + - scsi: qla2xxx: Fix firmware resource tracking + - null_blk: fix poll request timeout handling + - fbdev/ep93xx-fb: Do not assign to struct fb_info.dev + - clk: qcom: camcc-sc7180: fix async resume during probe + - drm/ast: Fix DRAM init on AST2200 + - ASoC: tegra: Fix SFC conversion for few rates + - clk: qcom: turingcc-qcs404: fix missing resume during probe + - arm64: dts: renesas: rzg2l: Fix txdv-skew-psec typos + - send channel sequence number in SMB3 requests after reconnects + - mm: hugetlb_vmemmap: fix a race between vmemmap pmd split + - lib/test_meminit: allocate pages up to order MAX_ORDER + - parisc: led: Fix LAN receive and transmit LEDs + - parisc: led: Reduce CPU overhead for disk & lan LED computation + - cifs: update desired access while requesting for directory lease + - pinctrl: cherryview: fix address_space_handler() argument + - dt-bindings: clock: xlnx,versal-clk: drop select:false + - clk: imx: pll14xx: dynamically configure PLL for 393216000/361267200Hz + - clk: imx: pll14xx: align pdiv with reference manual + - clk: qcom: gcc-mdm9615: use proper parent for pll0_vote clock + - soc: qcom: qmi_encdec: Restrict string length in decode + - clk: qcom: dispcc-sm8450: fix runtime PM imbalance on probe errors + - clk: qcom: lpasscc-sc7280: fix missing resume during probe + - clk: qcom: q6sstop-qcs404: fix missing resume during probe + - clk: qcom: mss-sc7180: fix missing resume during probe + - NFS: Fix a potential data corruption + - NFSv4/pnfs: minor fix for cleanup path in nfs4_get_device_info + - bus: mhi: host: Skip MHI reset if device is in RDDM + - kbuild: rpm-pkg: define _arch conditionally + - kbuild: do not run depmod for 'make modules_sign' + - tpm_crb: Fix an error handling path in crb_acpi_add() + - gfs2: Switch to wait_event in gfs2_logd + - gfs2: low-memory forced flush fixes + - mailbox: qcom-ipcc: fix incorrect num_chans counting + - kconfig: fix possible buffer overflow + - Input: iqs7222 - configure power mode before triggering ATI + - perf trace: Use zfree() to reduce chances of use after free + - perf trace: Really free the evsel->priv area + - pwm: atmel-tcb: Convert to platform remove callback returning void + - pwm: atmel-tcb: Harmonize resource allocation order + - pwm: atmel-tcb: Fix resource freeing in error path and remove + - backlight: gpio_backlight: Drop output GPIO direction check for initial + power state + - Input: tca6416-keypad - always expect proper IRQ number in i2c client + - Input: tca6416-keypad - fix interrupt enable disbalance + - perf annotate bpf: Don't enclose non-debug code with an assert() + - x86/virt: Drop unnecessary check on extended CPUID level in cpu_has_svm() + - perf vendor events: Update the JSON/events descriptions for power10 platform + - perf vendor events: Drop some of the JSON/events for power10 platform + - perf vendor events: Drop STORES_PER_INST metric event for power10 platform + - perf top: Don't pass an ERR_PTR() directly to perf_session__delete() + - watchdog: intel-mid_wdt: add MODULE_ALIAS() to allow auto-load + - pwm: lpc32xx: Remove handling of PWM channels + - perf test stat_bpf_counters_cgrp: Fix shellcheck issue about logical + operators + - perf test stat_bpf_counters_cgrp: Enhance perf stat cgroup BPF counter test + - drm/i915: mark requests for GuC virtual engines to avoid use-after-free + - blk-throttle: use calculate_io/bytes_allowed() for throtl_trim_slice() + - blk-throttle: consider 'carryover_ios/bytes' in throtl_trim_slice() + - smb: propagate error code of extract_sharename() + - net/sched: fq_pie: avoid stalls in fq_pie_timer() + - sctp: annotate data-races around sk->sk_wmem_queued + - ipv4: annotate data-races around fi->fib_dead + - net: read sk->sk_family once in sk_mc_loop() + - net: fib: avoid warn splat in flow dissector + - xsk: Fix xsk_diag use-after-free error during socket cleanup + - drm/i915/gvt: Verify pfn is "valid" before dereferencing "struct page" + - drm/i915/gvt: Put the page reference obtained by KVM's gfn_to_pfn() + - drm/i915/gvt: Drop unused helper intel_vgpu_reset_gtt() + - net: use sk_forward_alloc_get() in sk_get_meminfo() + - net: annotate data-races around sk->sk_forward_alloc + - mptcp: annotate data-races around msk->rmem_fwd_alloc + - ipv4: ignore dst hint for multipath routes + - ipv6: ignore dst hint for multipath routes + - igb: disable virtualization features on 82580 + - gve: fix frag_list chaining + - veth: Fixing transmit return status for dropped packets + - net: ipv6/addrconf: avoid integer underflow in ipv6_create_tempaddr + - net: phy: micrel: Correct bit assignments for phy_device flags + - bpf, sockmap: Fix skb refcnt race after locking changes + - af_unix: Fix data-races around user->unix_inflight. + - af_unix: Fix data-race around unix_tot_inflight. + - af_unix: Fix data-races around sk->sk_shutdown. + - af_unix: Fix data race around sk->sk_err. + - kcm: Destroy mutex in kcm_exit_net() + - octeontx2-af: Fix truncation of smq in CN10K NIX AQ enqueue mbox handler + - igc: Change IGC_MIN to allow set rx/tx value between 64 and 80 + - igbvf: Change IGBVF_MIN to allow set rx/tx value between 64 and 80 + - igb: Change IGB_MIN to allow set rx/tx value between 64 and 80 + - s390/zcrypt: don't leak memory if dev_set_name() fails + - idr: fix param name in idr_alloc_cyclic() doc + - ip_tunnels: use DEV_STATS_INC() + - net: dsa: sja1105: fix bandwidth discrepancy between tc-cbs software and + offload + - net: dsa: sja1105: fix -ENOSPC when replacing the same tc-cbs too many times + - net: dsa: sja1105: complete tc-cbs offload support on SJA1110 + - bpf: Invoke __bpf_prog_exit_sleepable_recur() on recursion in + kern_sys_bpf(). + - bpf: Assign bpf_tramp_run_ctx::saved_run_ctx before recursion check. + - net: hns3: fix tx timeout issue + - net: hns3: fix byte order conversion issue in hclge_dbg_fd_tcam_read() + - net: hns3: fix debugfs concurrency issue between kfree buffer and read + - net: hns3: fix invalid mutex between tc qdisc and dcb ets command issue + - net: hns3: fix the port information display when sfp is absent + - net: hns3: remove GSO partial feature bit + - sh: boards: Fix CEU buffer size passed to dma_declare_coherent_memory() + - Multi-gen LRU: avoid race in inc_min_seq() + - net/mlx5: Free IRQ rmap and notifier on kernel shutdown + - ARC: atomics: Add compiler barrier to atomic operations... + - clocksource/drivers/arm_arch_timer: Disable timer before programming CVAL + - dmaengine: sh: rz-dmac: Fix destination and source data size setting + - jbd2: fix checkpoint cleanup performance regression + - jbd2: check 'jh->b_transaction' before removing it from checkpoint + - jbd2: correct the end of the journal recovery scan range + - ext4: add correct group descriptors and reserved GDT blocks to system zone + - ext4: fix memory leaks in ext4_fname_{setup_filename,prepare_lookup} + - f2fs: flush inode if atomic file is aborted + - f2fs: avoid false alarm of circular locking + - lib: test_scanf: Add explicit type cast to result initialization in + test_number_prefix() + - hwspinlock: qcom: add missing regmap config for SFPB MMIO implementation + - ata: ahci: Add Elkhart Lake AHCI controller + - ata: pata_falcon: fix IO base selection for Q40 + - ata: sata_gemini: Add missing MODULE_DESCRIPTION + - ata: pata_ftide010: Add missing MODULE_DESCRIPTION + - fuse: nlookup missing decrement in fuse_direntplus_link + - btrfs: zoned: do not zone finish data relocation block group + - btrfs: fix start transaction qgroup rsv double free + - btrfs: free qgroup rsv on io failure + - btrfs: don't start transaction when joining with TRANS_JOIN_NOSTART + - btrfs: set page extent mapped after read_folio in relocate_one_page + - btrfs: zoned: re-enable metadata over-commit for zoned mode + - btrfs: use the correct superblock to compare fsid in btrfs_validate_super + - drm/mxsfb: Disable overlay plane in mxsfb_plane_overlay_atomic_disable() + - mtd: rawnand: brcmnand: Fix crash during the panic_write + - mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write + - mtd: spi-nor: Correct flags for Winbond w25q128 + - mtd: rawnand: brcmnand: Fix potential false time out warning + - mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller + - drm/amd/display: enable cursor degamma for DCN3+ DRM legacy gamma + - drm/amd/display: prevent potential division by zero errors + - KVM: SVM: Take and hold ir_list_lock when updating vCPU's Physical ID entry + - KVM: SVM: Don't inject #UD if KVM attempts to skip SEV guest insn + - KVM: SVM: Get source vCPUs from source VM for SEV-ES intrahost migration + - KVM: nSVM: Check instead of asserting on nested TSC scaling support + - KVM: nSVM: Load L1's TSC multiplier based on L1 state, not L2 state + - KVM: SVM: Set target pCPU during IRTE update if target vCPU is running + - KVM: SVM: Skip VMSA init in sev_es_init_vmcb() if pointer is NULL + - MIPS: Fix CONFIG_CPU_DADDI_WORKAROUNDS `modules_install' regression + - perf hists browser: Fix hierarchy mode header + - perf test shell stat_bpf_counters: Fix test on Intel + - perf tools: Handle old data in PERF_RECORD_ATTR + - perf hists browser: Fix the number of entries for 'e' key + - drm/amd/display: always switch off ODM before committing more streams + - drm/amd/display: Remove wait while locked + - drm/amdgpu: register a dirty framebuffer callback for fbcon + - kunit: Fix wild-memory-access bug in kunit_free_suite_set() + - net: ipv4: fix one memleak in __inet_del_ifa() + - kselftest/runner.sh: Propagate SIGTERM to runner child + - selftests: Keep symlinks, when possible + - net/smc: use smc_lgr_list.lock to protect smc_lgr_list.list iterate in + smcr_port_add + - net: stmmac: fix handling of zero coalescing tx-usecs + - net: ethernet: mvpp2_main: fix possible OOB write in + mvpp2_ethtool_get_rxnfc() + - net: ethernet: mtk_eth_soc: fix possible NULL pointer dereference in + mtk_hwlro_get_fdir_all() + - hsr: Fix uninit-value access in fill_frame_info() + - net: ethernet: adi: adin1110: use eth_broadcast_addr() to assign broadcast + address + - net:ethernet:adi:adin1110: Fix forwarding offload + - net: dsa: sja1105: hide all multicast addresses from "bridge fdb show" + - net: dsa: sja1105: propagate exact error code from + sja1105_dynamic_config_poll_valid() + - net: dsa: sja1105: fix multicast forwarding working only for last added mdb + entry + - net: dsa: sja1105: serialize sja1105_port_mcast_flood() with other FDB + accesses + - net: dsa: sja1105: block FDB accesses that are concurrent with a switch + reset + - r8152: check budget for r8152_poll() + - kcm: Fix memory leak in error path of kcm_sendmsg() + - platform/mellanox: mlxbf-tmfifo: Drop the Rx packet if no more descriptors + - platform/mellanox: mlxbf-tmfifo: Drop jumbo frames + - platform/mellanox: mlxbf-pmc: Fix potential buffer overflows + - platform/mellanox: mlxbf-pmc: Fix reading of unprogrammed events + - [Config] updateconfigs for NVSW_SN2201 + - platform/mellanox: NVSW_SN2201 should depend on ACPI + - net: macb: Enable PTP unicast + - net: macb: fix sleep inside spinlock + - ipv6: fix ip6_sock_set_addr_preferences() typo + - ipv6: Remove in6addr_any alternatives. + - tcp: Factorise sk_family-independent comparison in + inet_bind2_bucket_match(_addr_any). + - tcp: Fix bind() regression for v4-mapped-v6 wildcard address. + - tcp: Fix bind() regression for v4-mapped-v6 non-wildcard address. + - ixgbe: fix timestamp configuration code + - kcm: Fix error handling for SOCK_DGRAM in kcm_sendmsg(). + - MIPS: Only fiddle with CHECKFLAGS if `need-compiler' + - drm/amd/display: Fix a bug when searching for insert_above_mpcc + - arm64: tegra: Update AHUB clock parent and rate on Tegra234 + - arm64: tegra: Update AHUB clock parent and rate + - ARM: dts: qcom: msm8974pro-castor: correct inverted X of touchscreen + - ARM: dts: qcom: msm8974pro-castor: correct touchscreen function names + - ARM: dts: qcom: msm8974pro-castor: correct touchscreen syna,nosleep-mode + - ARM: dts: BCM5301X: Extend RAM to full 256MB for Linksys EA6500 V2 + - net: annotate data-races around sk->sk_tsflags + - net: annotate data-races around sk->sk_bind_phc + - sh: push-switch: Reorder cleanup operations to avoid use-after-free bug + - misc: fastrpc: Fix remote heap allocation request + - misc: fastrpc: Fix incorrect DMA mapping unmap request + - net: renesas: rswitch: Fix unmasking irq condition + - Upstream stable to v6.1.54, v6.5.4 + + * Lunar update: upstream stable patchset 2023-11-06 (LP: #2042884) + - Partially revert "drm/amd/display: Fix possible underflow for displays with + large vblank" + - Revert "Revert drm/amd/display: Enable Freesync Video Mode by default" + - powerpc/boot: Disable power10 features after BOOTAFLAGS assignment + - media: uapi: HEVC: Add num_delta_pocs_of_ref_rps_idx field + - Revert "MIPS: unhide PATA_PLATFORM" + - phy: qcom-snps-femto-v2: use qcom_snps_hsphy_suspend/resume error code + - media: amphion: use dev_err_probe + - media: pulse8-cec: handle possible ping error + - media: pci: cx23885: fix error handling for cx23885 ATSC boards + - 9p: virtio: fix unlikely null pointer deref in handle_rerror + - 9p: virtio: make sure 'offs' is initialized in zc_request + - ksmbd: fix out of bounds in smb3_decrypt_req() + - ksmbd: validate session id and tree id in compound request + - ksmbd: no response from compound read + - ksmbd: fix out of bounds in init_smb2_rsp_hdr() + - ASoC: da7219: Flush pending AAD IRQ when suspending + - ASoC: da7219: Check for failure reading AAD IRQ events + - ASoC: nau8821: Add DMI quirk mechanism for active-high jack-detect + - ethernet: atheros: fix return value check in atl1c_tso_csum() + - m68k: Fix invalid .section syntax + - s390/dasd: use correct number of retries for ERP requests + - s390/dasd: fix hanging device after request requeue + - fs/nls: make load_nls() take a const parameter + - ASoC: rt5682-sdw: fix for JD event handling in ClockStop Mode0 + - ASoc: codecs: ES8316: Fix DMIC config + - ASoC: rt711: fix for JD event handling in ClockStop Mode0 + - ASoC: rt711-sdca: fix for JD event handling in ClockStop Mode0 + - ASoC: atmel: Fix the 8K sample parameter in I2SC master + - ALSA: usb-audio: Add quirk for Microsoft Modern Wireless Headset + - platform/x86: intel: hid: Always call BTNL ACPI method + - platform/x86/intel/hid: Add HP Dragonfly G2 to VGBS DMI quirks + - platform/x86: think-lmi: Use kfree_sensitive instead of kfree + - platform/x86: asus-wmi: Fix setting RGB mode on some TUF laptops + - platform/x86: huawei-wmi: Silence ambient light sensor + - drm/amd/smu: use AverageGfxclkFrequency* to replace previous GFX Curr Clock + - drm/amd/display: Guard DCN31 PHYD32CLK logic against chip family + - drm/amd/display: Exit idle optimizations before attempt to access PHY + - ovl: Always reevaluate the file signature for IMA + - ata: pata_arasan_cf: Use dev_err_probe() instead dev_err() in data_xfer() + - ALSA: usb-audio: Update for native DSD support quirks + - staging: fbtft: ili9341: use macro FBTFT_REGISTER_SPI_DRIVER + - security: keys: perform capable check only on privileged operations + - kprobes: Prohibit probing on CFI preamble symbol + - clk: fixed-mmio: make COMMON_CLK_FIXED_MMIO depend on HAS_IOMEM + - vmbus_testing: fix wrong python syntax for integer value comparison + - Revert "wifi: ath6k: silence false positive -Wno-dangling-pointer warning on + GCC 12" + - net: dsa: microchip: KSZ9477 register regmap alignment to 32 bit boundaries + - net: annotate data-races around sk->sk_{rcv|snd}timeo + - net: usb: qmi_wwan: add Quectel EM05GV2 + - wifi: brcmfmac: Fix field-spanning write in brcmf_scan_params_v2_to_v1() + - powerpc/powermac: Use early_* IO variants in via_calibrate_decr() + - idmaengine: make FSL_EDMA and INTEL_IDMA64 depends on HAS_IOMEM + - platform/x86/amd/pmf: Fix unsigned comparison with less than zero + - scsi: lpfc: Remove reftag check in DIF paths + - scsi: qedi: Fix potential deadlock on &qedi_percpu->p_work_lock + - net: hns3: restore user pause configure when disable autoneg + - drm/amdgpu: Match against exact bootloader status + - wifi: cfg80211: remove links only on AP + - wifi: mac80211: Use active_links instead of valid_links in Tx + - netlabel: fix shift wrapping bug in netlbl_catmap_setlong() + - bnx2x: fix page fault following EEH recovery + - cifs: fix sockaddr comparison in iface_cmp + - cifs: fix max_credits implementation + - sctp: handle invalid error codes without calling BUG() + - scsi: aacraid: Reply queue mapping to CPUs based on IRQ affinity + - scsi: storvsc: Always set no_report_opcodes + - scsi: lpfc: Fix incorrect big endian type assignment in bsg loopback path + - LoongArch: Let pmd_present() return true when splitting pmd + - LoongArch: Fix the write_fcsr() macro + - ALSA: seq: oss: Fix racy open/close of MIDI devices + - net: sfp: handle 100G/25G active optical cables in sfp_parse_support + - tracing: Introduce pipe_cpumask to avoid race on trace_pipes + - platform/mellanox: Fix mlxbf-tmfifo not handling all virtio CONSOLE + notifications + - of: property: Simplify of_link_to_phandle() + - cpufreq: intel_pstate: set stale CPU frequency to minimum + - tpm: Enable hwrng only for Pluton on AMD CPUs + - KVM: x86/mmu: Use kstrtobool() instead of strtobool() + - KVM: x86/mmu: Add "never" option to allow sticky disabling of nx_huge_pages + - drm/amd/display: ensure async flips are only accepted for fast updates + - udf: Check consistency of Space Bitmap Descriptor + - udf: Handle error when adding extent to a file + - Input: i8042 - add quirk for TUXEDO Gemini 17 Gen1/Clevo PD70PN + - Revert "PCI: tegra194: Enable support for 256 Byte payload" + - Revert "net: macsec: preserve ingress frame ordering" + - tools/resolve_btfids: Use pkg-config to locate libelf + - tools/resolve_btfids: Install subcmd headers + - tools/resolve_btfids: Alter how HOSTCC is forced + - tools/resolve_btfids: Compile resolve_btfids as host program + - tools/resolve_btfids: Tidy HOST_OVERRIDES + - tools/resolve_btfids: Pass HOSTCFLAGS as EXTRA_CFLAGS to prepare targets + - tools/resolve_btfids: Fix setting HOSTCFLAGS + - reiserfs: Check the return value from __getblk() + - eventfd: prevent underflow for eventfd semaphores + - fs: Fix error checking for d_hash_and_lookup() + - iomap: Remove large folio handling in iomap_invalidate_folio() + - tmpfs: verify {g,u}id mount options correctly + - selftests/harness: Actually report SKIP for signal tests + - vfs, security: Fix automount superblock LSM init problem, preventing NFS sb + sharing + - ARM: ptrace: Restore syscall restart tracing + - ARM: ptrace: Restore syscall skipping for tracers + - refscale: Fix uninitalized use of wait_queue_head_t + - OPP: Fix passing 0 to PTR_ERR in _opp_attach_genpd() + - selftests/resctrl: Add resctrl.h into build deps + - selftests/resctrl: Don't leak buffer in fill_cache() + - selftests/resctrl: Unmount resctrl FS if child fails to run benchmark + - selftests/resctrl: Close perf value read fd on errors + - arm64/ptrace: Clean up error handling path in sve_set_common() + - sched/psi: Select KERNFS as needed + - x86/decompressor: Don't rely on upper 32 bits of GPRs being preserved + - arm64/sme: Don't use streaming mode to probe the maximum SME VL + - arm64/fpsimd: Only provide the length to cpufeature for xCR registers + - sched/rt: Fix sysctl_sched_rr_timeslice intial value + - perf/imx_ddr: don't enable counter0 if none of 4 counters are used + - selftests/futex: Order calls to futex_lock_pi + - s390/pkey: fix/harmonize internal keyblob headers + - s390/pkey: fix PKEY_TYPE_EP11_AES handling in PKEY_GENSECK2 IOCTL + - s390/pkey: fix PKEY_TYPE_EP11_AES handling for sysfs attributes + - s390/paes: fix PKEY_TYPE_EP11_AES handling for secure keyblobs + - irqchip/loongson-eiointc: Fix return value checking of eiointc_index + - ACPI: x86: s2idle: Post-increment variables when getting constraints + - ACPI: x86: s2idle: Fix a logic error parsing AMD constraints table + - thermal/of: Fix potential uninitialized value access + - cpufreq: amd-pstate-ut: Remove module parameter access + - cpufreq: amd-pstate-ut: Fix kernel panic when loading the driver + - x86/efistub: Fix PCI ROM preservation in mixed mode + - cpufreq: powernow-k8: Use related_cpus instead of cpus in driver.exit() + - selftests/bpf: Fix bpf_nf failure upon test rerun + - bpftool: use a local copy of perf_event to fix accessing :: Bpf_cookie + - bpftool: Define a local bpf_perf_link to fix accessing its fields + - bpftool: Use a local copy of BPF_LINK_TYPE_PERF_EVENT in pid_iter.bpf.c + - bpftool: Use a local bpf_perf_event_value to fix accessing its fields + - libbpf: Fix realloc API handling in zero-sized edge cases + - bpf: Clear the probe_addr for uprobe + - bpf: Fix an error in verifying a field in a union + - crypto: qat - change value of default idle filter + - tcp: tcp_enter_quickack_mode() should be static + - hwrng: nomadik - keep clock enabled while hwrng is registered + - hwrng: pic32 - use devm_clk_get_enabled + - regmap: rbtree: Use alloc_flags for memory allocations + - wifi: rtw89: debug: Fix error handling in rtw89_debug_priv_btc_manual_set() + - wifi: mt76: mt7921: fix non-PSC channel scan fail + - udp: re-score reuseport groups when connected sockets are present + - bpf: reject unhashed sockets in bpf_sk_assign + - wifi: mt76: testmode: add nla_policy for MT76_TM_ATTR_TX_LENGTH + - spi: tegra20-sflash: fix to check return value of platform_get_irq() in + tegra_sflash_probe() + - can: gs_usb: gs_usb_receive_bulk_callback(): count RX overflow errors also + in case of OOM + - wifi: mt76: mt7915: fix power-limits while chan_switch + - wifi: mwifiex: Fix OOB and integer underflow when rx packets + - wifi: mwifiex: fix error recovery in PCIE buffer descriptor management + - kbuild: rust_is_available: remove -v option + - kbuild: rust_is_available: fix version check when CC has multiple arguments + - kbuild: rust_is_available: add check for `bindgen` invocation + - kbuild: rust_is_available: fix confusion when a version appears in the path + - crypto: stm32 - Properly handle pm_runtime_get failing + - crypto: api - Use work queue in crypto_destroy_instance + - Bluetooth: nokia: fix value check in nokia_bluetooth_serdev_probe() + - Bluetooth: Fix potential use-after-free when clear keys + - Bluetooth: hci_sync: Don't double print name in add/remove adv_monitor + - Bluetooth: hci_sync: Avoid use-after-free in dbg for hci_add_adv_monitor() + - net: tcp: fix unexcepted socket die when snd_wnd is 0 + - selftests/bpf: Fix repeat option when kfunc_call verification fails + - selftests/bpf: Clean up fmod_ret in bench_rename test script + - net-memcg: Fix scope of sockmem pressure indicators + - ice: ice_aq_check_events: fix off-by-one check when filling buffer + - crypto: caam - fix unchecked return value error + - hwrng: iproc-rng200 - Implement suspend and resume calls + - lwt: Fix return values of BPF xmit ops + - lwt: Check LWTUNNEL_XMIT_CONTINUE strictly + - fs: ocfs2: namei: check return value of ocfs2_add_entry() + - net: annotate data-races around sk->sk_lingertime + - wifi: mwifiex: fix memory leak in mwifiex_histogram_read() + - wifi: mwifiex: Fix missed return in oob checks failed path + - ARM: dts: Add .dts files missing from the build + - samples/bpf: fix bio latency check with tracepoint + - samples/bpf: fix broken map lookup probe + - wifi: ath9k: fix races between ath9k_wmi_cmd and ath9k_wmi_ctrl_rx + - wifi: ath9k: protect WMI command response buffer replacement with a lock + - wifi: nl80211/cfg80211: add forgotten nla_policy for BSS color attribute + - mac80211: make ieee80211_tx_info padding explicit + - wifi: mwifiex: avoid possible NULL skb pointer dereference + - Bluetooth: btusb: Do not call kfree_skb() under spin_lock_irqsave() + - arm64: mm: use ptep_clear() instead of pte_clear() in clear_flush() + - wifi: ath9k: use IS_ERR() with debugfs_create_dir() + - ice: avoid executing commands on other ports when driving sync + - net: arcnet: Do not call kfree_skb() under local_irq_disable() + - mlxsw: i2c: Fix chunk size setting in output mailbox buffer + - mlxsw: i2c: Limit single transaction buffer size + - mlxsw: core_hwmon: Adjust module label names based on MTCAP sensor counter + - hwmon: (tmp513) Fix the channel number in tmp51x_is_visible() + - octeontx2-pf: Refactor schedular queue alloc/free calls + - octeontx2-pf: Fix PFC TX scheduler free + - cteonxt2-pf: Fix backpressure config for multiple PFC priorities to work + simultaneously + - sfc: Check firmware supports Ethernet PTP filter + - netrom: Deny concurrent connect(). + - drm/bridge: tc358764: Fix debug print parameter order + - ASoC: cs43130: Fix numerator/denominator mixup + - quota: factor out dquot_write_dquot() + - quota: rename dquot_active() to inode_quota_active() + - quota: add new helper dquot_active() + - quota: fix dqput() to follow the guarantees dquot_srcu should provide + - drm/amd/display: Do not set drr on pipe commit + - drm/hyperv: Fix a compilation issue because of not including screen_info.h + - ASoC: stac9766: fix build errors with REGMAP_AC97 + - soc: qcom: ocmem: Add OCMEM hardware version print + - soc: qcom: ocmem: Fix NUM_PORTS & NUM_MACROS macros + - arm64: dts: qcom: sm6350: Fix ZAP region + - arm64: dts: qcom: sm8250: correct dynamic power coefficients + - arm64: dts: qcom: msm8916-l8150: correct light sensor VDDIO supply + - arm64: dts: qcom: sm8250-edo: Add gpio line names for TLMM + - arm64: dts: qcom: sm8250-edo: Add GPIO line names for PMIC GPIOs + - arm64: dts: qcom: sm8250-edo: Rectify gpio-keys + - arm64: dts: qcom: sc8280xp-crd: Correct vreg_misc_3p3 GPIO + - arm64: dts: qcom: sc8280xp: Add missing SCM interconnect + - arm64: dts: qcom: msm8996: Add missing interrupt to the USB2 controller + - arm64: dts: qcom: sdm845-tama: Set serial indices and stdout-path + - arm64: dts: qcom: sm8350: Fix CPU idle state residency times + - arm64: dts: qcom: sm8350: Add missing LMH interrupts to cpufreq + - arm64: dts: qcom: sm8350: Use proper CPU compatibles + - arm64: dts: qcom: pm8350: fix thermal zone name + - arm64: dts: qcom: pm8350b: fix thermal zone name + - arm64: dts: qcom: pmr735b: fix thermal zone name + - arm64: dts: qcom: pmk8350: fix ADC-TM compatible string + - arm64: dts: qcom: sm8250: Mark PCIe hosts as DMA coherent + - ARM: dts: stm32: YAML validation fails for Argon Boards + - ARM: dts: stm32: adopt generic iio bindings for adc channels on emstamp- + argon + - ARM: dts: stm32: Add missing detach mailbox for emtrion emSBC-Argon + - ARM: dts: stm32: YAML validation fails for Odyssey Boards + - ARM: dts: stm32: Add missing detach mailbox for Odyssey SoM + - ARM: dts: stm32: Update to generic ADC channel binding on DHSOM systems + - ARM: dts: stm32: Add missing detach mailbox for DHCOM SoM + - firmware: ti_sci: Use system_state to determine polling + - drm/amdgpu: avoid integer overflow warning in amdgpu_device_resize_fb_bar() + - ARM: dts: BCM53573: Drop nonexistent #usb-cells + - ARM: dts: BCM53573: Add cells sizes to PCIe node + - ARM: dts: BCM53573: Use updated "spi-gpio" binding properties + - arm64: tegra: Fix HSUART for Jetson AGX Orin + - arm64: dts: qcom: sm8250-sony-xperia: correct GPIO keys wakeup again + - arm64: dts: qcom: pm6150l: Add missing short interrupt + - arm64: dts: qcom: pm660l: Add missing short interrupt + - arm64: dts: qcom: pmi8994: Add missing OVP interrupt + - arm64: tegra: Fix HSUART for Smaug + - drm/etnaviv: fix dumping of active MMU context + - block: cleanup queue_wc_store + - block: don't allow enabling a cache on devices that don't support it + - x86/mm: Fix PAT bit missing from page protection modify mask + - drm/bridge: anx7625: Use common macros for DP power sequencing commands + - drm/bridge: anx7625: Use common macros for HDCP capabilities + - ARM: dts: samsung: s3c6410-mini6410: correct ethernet reg addresses (split) + - ARM: dts: s5pv210: add dummy 5V regulator for backlight on SMDKv210 + - ARM: dts: samsung: s5pv210-smdkv210: correct ethernet reg addresses (split) + - drm: adv7511: Fix low refresh rate register for ADV7533/5 + - ARM: dts: BCM53573: Fix Ethernet info for Luxul devices + - arm64: dts: qcom: sdm845: Add missing RPMh power domain to GCC + - arm64: dts: qcom: sdm845: Fix the min frequency of "ice_core_clk" + - arm64: dts: qcom: msm8996-gemini: fix touchscreen VIO supply + - drm/amdgpu: Update min() to min_t() in 'amdgpu_info_ioctl' + - md: Factor out is_md_suspended helper + - md: Change active_io to percpu + - md: restore 'noio_flag' for the last mddev_resume() + - md/raid10: factor out dereference_rdev_and_rrdev() + - md/raid10: use dereference_rdev_and_rrdev() to get devices + - md/md-bitmap: remove unnecessary local variable in backlog_store() + - md/md-bitmap: hold 'reconfig_mutex' in backlog_store() + - drm/msm: Update dev core dump to not print backwards + - drm/tegra: dpaux: Fix incorrect return value of platform_get_irq + - of: unittest: fix null pointer dereferencing in + of_unittest_find_node_by_name() + - arm64: dts: qcom: sm8150: Fix the I2C7 interrupt + - ARM: dts: BCM53573: Fix Tenda AC9 switch CPU port + - drm/armada: Fix off-by-one error in armada_overlay_get_property() + - drm/repaper: Reduce temporary buffer size in repaper_fb_dirty() + - drm/panel: simple: Add missing connector type and pixel format for AUO + T215HVN01 + - ima: Remove deprecated IMA_TRUSTED_KEYRING Kconfig + - [Config] updateconfigs for IMA_TRUSTED_KEYRING + - drm: xlnx: zynqmp_dpsub: Add missing check for dma_set_mask + - soc: qcom: smem: Fix incompatible types in comparison + - drm/msm/mdp5: Don't leak some plane state + - firmware: meson_sm: fix to avoid potential NULL pointer dereference + - drm/msm/dpu: fix the irq index in dpu_encoder_phys_wb_wait_for_commit_done + - smackfs: Prevent underflow in smk_set_cipso() + - drm/amd/pm: fix variable dereferenced issue in amdgpu_device_attr_create() + - drm/msm/a2xx: Call adreno_gpu_init() earlier + - audit: fix possible soft lockup in __audit_inode_child() + - block/mq-deadline: use correct way to throttling write requests + - io_uring: fix drain stalls by invalid SQE + - drm/mediatek: dp: Add missing error checks in mtk_dp_parse_capabilities + - bus: ti-sysc: Fix build warning for 64-bit build + - drm/mediatek: Remove freeing not dynamic allocated memory + - ARM: dts: qcom: ipq4019: correct SDHCI XO clock + - drm/mediatek: Fix potential memory leak if vmap() fail + - arm64: dts: qcom: apq8016-sbc: Fix ov5640 regulator supply names + - arm64: dts: qcom: msm8998: Drop bus clock reference from MMSS SMMU + - arm64: dts: qcom: msm8998: Add missing power domain to MMSS SMMU + - arm64: dts: qcom: msm8996: Fix dsi1 interrupts + - arm64: dts: qcom: sc8280xp-x13s: Unreserve NC pins + - bus: ti-sysc: Fix cast to enum warning + - md/raid5-cache: fix a deadlock in r5l_exit_log() + - md/raid5-cache: fix null-ptr-deref for r5l_flush_stripe_to_raid() + - firmware: cs_dsp: Fix new control name check + - md: add error_handlers for raid0 and linear + - md/raid0: Factor out helper for mapping and submitting a bio + - md/raid0: Fix performance regression for large sequential writes + - md: raid0: account for split bio in iostat accounting + - ASoC: SOF: amd: clear dsp to host interrupt status + - of: overlay: Call of_changeset_init() early + - of: unittest: Fix overlay type in apply/revert check + - ALSA: ac97: Fix possible error value of *rac97 + - ipmi:ssif: Add check for kstrdup + - ipmi:ssif: Fix a memory leak when scanning for an adapter + - clk: qcom: gpucc-sm6350: Introduce index-based clk lookup + - clk: qcom: gpucc-sm6350: Fix clock source names + - clk: qcom: gcc-sc8280xp: Add EMAC GDSCs + - clk: qcom: gcc-sc8280xp: Add missing GDSC flags + - dt-bindings: clock: qcom,gcc-sc8280xp: Add missing GDSCs + - clk: qcom: gcc-sc8280xp: Add missing GDSCs + - clk: rockchip: rk3568: Fix PLL rate setting for 78.75MHz + - PCI: apple: Initialize pcie->nvecs before use + - PCI: qcom-ep: Switch MHI bus master clock off during L1SS + - drivers: clk: keystone: Fix parameter judgment in _of_pll_clk_init() + - PCI/DOE: Fix destroy_work_on_stack() race + - clk: sunxi-ng: Modify mismatched function name + - clk: qcom: gcc-sc7180: Fix up gcc_sdcc2_apps_clk_src + - EDAC/igen6: Fix the issue of no error events + - ext4: correct grp validation in ext4_mb_good_group + - ext4: avoid potential data overflow in next_linear_group + - clk: qcom: gcc-sm8250: Fix gcc_sdcc2_apps_clk_src + - kvm/vfio: Prepare for accepting vfio device fd + - kvm/vfio: ensure kvg instance stays around in kvm_vfio_group_add() + - clk: qcom: reset: Use the correct type of sleep/delay based on length + - clk: qcom: gcc-sm6350: Fix gcc_sdcc2_apps_clk_src + - PCI: microchip: Correct the DED and SEC interrupt bit offsets + - PCI: Mark NVIDIA T4 GPUs to avoid bus reset + - pinctrl: mcp23s08: check return value of devm_kasprintf() + - PCI: Add locking to RMW PCI Express Capability Register accessors + - PCI: pciehp: Use RMW accessors for changing LNKCTL + - PCI/ASPM: Use RMW accessors for changing LNKCTL + - clk: qcom: gcc-sm8450: Use floor ops for SDCC RCGs + - clk: imx: pllv4: Fix SPLL2 MULT range + - clk: imx: imx8ulp: update SPLL2 type + - clk: imx8mp: fix sai4 clock + - clk: imx: composite-8m: fix clock pauses when set_rate would be a no-op + - powerpc/radix: Move some functions into #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE + - vfio/type1: fix cap_migration information leak + - nvdimm: Fix memleak of pmu attr_groups in unregister_nvdimm_pmu() + - nvdimm: Fix dereference after free in register_nvdimm_pmu() + - powerpc/fadump: reset dump area size if fadump memory reserve fails + - powerpc/perf: Convert fsl_emb notifier to state machine callbacks + - drm/amdgpu: Use RMW accessors for changing LNKCTL + - drm/radeon: Use RMW accessors for changing LNKCTL + - net/mlx5: Use RMW accessors for changing LNKCTL + - wifi: ath11k: Use RMW accessors for changing LNKCTL + - wifi: ath10k: Use RMW accessors for changing LNKCTL + - NFSv4.2: Rework scratch handling for READ_PLUS + - NFSv4.2: Fix READ_PLUS smatch warnings + - NFSv4.2: Fix READ_PLUS size calculations + - powerpc: Don't include lppaca.h in paca.h + - powerpc/pseries: Rework lppaca_shared_proc() to avoid DEBUG_PREEMPT + - nfs/blocklayout: Use the passed in gfp flags + - powerpc/pseries: Fix hcall tracepoints with JUMP_LABEL=n + - powerpc/mpc5xxx: Add missing fwnode_handle_put() + - powerpc/iommu: Fix notifiers being shared by PCI and VIO buses + - ext4: fix unttached inode after power cut with orphan file feature enabled + - jfs: validate max amount of blocks before allocation. + - fs: lockd: avoid possible wrong NULL parameter + - NFSD: da_addr_body field missing in some GETDEVICEINFO replies + - NFS: Guard against READDIR loop when entry names exceed MAXNAMELEN + - NFSv4.2: fix handling of COPY ERR_OFFLOAD_NO_REQ + - pNFS: Fix assignment of xprtdata.cred + - cgroup/cpuset: Inherit parent's load balance state in v2 + - RDMA/qedr: Remove a duplicate assignment in irdma_query_ah() + - media: ov5640: fix low resolution image abnormal issue + - media: ad5820: Drop unsupported ad5823 from i2c_ and of_device_id tables + - media: i2c: tvp5150: check return value of devm_kasprintf() + - media: v4l2-core: Fix a potential resource leak in v4l2_fwnode_parse_link() + - iommu/amd/iommu_v2: Fix pasid_state refcount dec hit 0 warning on pasid + unbind + - iommu: rockchip: Fix directory table address encoding + - drivers: usb: smsusb: fix error handling code in smsusb_init_device + - media: dib7000p: Fix potential division by zero + - media: dvb-usb: m920x: Fix a potential memory leak in m920x_i2c_xfer() + - media: cx24120: Add retval check for cx24120_message_send() + - RDMA/siw: Fabricate a GID on tun and loopback devices + - scsi: hisi_sas: Fix warnings detected by sparse + - scsi: hisi_sas: Fix normally completed I/O analysed as failed + - dt-bindings: extcon: maxim,max77843: restrict connector properties + - media: amphion: reinit vpu if reqbufs output 0 + - media: amphion: add helper function to get id name + - media: mtk-jpeg: Fix use after free bug due to uncanceled work + - media: rkvdec: increase max supported height for H.264 + - media: amphion: fix CHECKED_RETURN issues reported by coverity + - media: amphion: fix REVERSE_INULL issues reported by coverity + - media: amphion: fix UNINIT issues reported by coverity + - media: amphion: fix UNUSED_VALUE issue reported by coverity + - media: amphion: ensure the bitops don't cross boundaries + - media: mediatek: vcodec: Return NULL if no vdec_fb is found + - media: mediatek: vcodec: fix potential double free + - media: mediatek: vcodec: fix resource leaks in vdec_msg_queue_init() + - usb: phy: mxs: fix getting wrong state with mxs_phy_is_otg_host() + - scsi: RDMA/srp: Fix residual handling + - scsi: iscsi: Add length check for nlattr payload + - scsi: iscsi: Add strlen() check in iscsi_if_set{_host}_param() + - scsi: be2iscsi: Add length check when parsing nlattrs + - scsi: qla4xxx: Add length check when parsing nlattrs + - iio: accel: adxl313: Fix adxl313_i2c_id[] table + - serial: sprd: Assign sprd_port after initialized to avoid wrong access + - serial: sprd: Fix DMA buffer leak issue + - x86/APM: drop the duplicate APM_MINOR_DEV macro + - RDMA/rxe: Fix incomplete state save in rxe_requester + - scsi: qedf: Do not touch __user pointer in + qedf_dbg_stop_io_on_error_cmd_read() directly + - scsi: qedf: Do not touch __user pointer in qedf_dbg_debug_cmd_read() + directly + - scsi: qedf: Do not touch __user pointer in qedf_dbg_fp_int_cmd_read() + directly + - RDMA/irdma: Replace one-element array with flexible-array member + - coresight: tmc: Explicit type conversions to prevent integer overflow + - interconnect: qcom: qcm2290: Enable sync state + - dma-buf/sync_file: Fix docs syntax + - driver core: test_async: fix an error code + - driver core: Call dma_cleanup() on the test_remove path + - kernfs: add stub helper for kernfs_generic_poll() + - extcon: cht_wc: add POWER_SUPPLY dependency + - iommu/mediatek: Fix two IOMMU share pagetable issue + - iommu/sprd: Add missing force_aperture + - RDMA/hns: Fix port active speed + - RDMA/hns: Fix incorrect post-send with direct wqe of wr-list + - RDMA/hns: Fix inaccurate error label name in init instance + - RDMA/hns: Fix CQ and QP cache affinity + - IB/uverbs: Fix an potential error pointer dereference + - fsi: aspeed: Reset master errors after CFAM reset + - iommu/qcom: Disable and reset context bank before programming + - iommu/vt-d: Fix to flush cache of PASID directory table + - platform/x86: dell-sysman: Fix reference leak + - media: cec: core: add adap_nb_transmit_canceled() callback + - media: cec: core: add adap_unconfigured() callback + - media: go7007: Remove redundant if statement + - media: venus: hfi_venus: Only consider sys_idle_indicator on V1 + - docs: ABI: fix spelling/grammar in SBEFIFO timeout interface + - USB: gadget: core: Add missing kerneldoc for vbus_work + - USB: gadget: f_mass_storage: Fix unused variable warning + - drivers: base: Free devm resources when unregistering a device + - HID: input: Support devices sending Eraser without Invert + - media: ov5640: Enable MIPI interface in ov5640_set_power_mipi() + - media: ov5640: Fix initial RESETB state and annotate timings + - media: ov2680: Remove auto-gain and auto-exposure controls + - media: ov2680: Fix ov2680_bayer_order() + - media: ov2680: Fix vflip / hflip set functions + - media: ov2680: Remove VIDEO_V4L2_SUBDEV_API ifdef-s + - media: ov2680: Don't take the lock for try_fmt calls + - media: ov2680: Add ov2680_fill_format() helper function + - media: ov2680: Fix ov2680_set_fmt() which == V4L2_SUBDEV_FORMAT_TRY not + working + - media: ov2680: Fix regulators being left enabled on ov2680_power_on() errors + - media: i2c: rdacm21: Fix uninitialized value + - f2fs: fix to avoid mmap vs set_compress_option case + - f2fs: judge whether discard_unit is section only when have + CONFIG_BLK_DEV_ZONED + - f2fs: Only lfs mode is allowed with zoned block device feature + - Revert "f2fs: fix to do sanity check on extent cache correctly" + - cgroup:namespace: Remove unused cgroup_namespaces_init() + - coresight: trbe: Fix TRBE potential sleep in atomic context + - scsi: core: Use 32-bit hostnum in scsi_host_lookup() + - scsi: fcoe: Fix potential deadlock on &fip->ctlr_lock + - interconnect: qcom: sm8450: Enable sync_state + - interconnect: qcom: bcm-voter: Improve enable_mask handling + - interconnect: qcom: bcm-voter: Use enable_maks for keepalive voting + - serial: tegra: handle clk prepare error in tegra_uart_hw_init() + - amba: bus: fix refcount leak + - Revert "IB/isert: Fix incorrect release of isert connection" + - RDMA/siw: Balance the reference of cep->kref in the error path + - RDMA/siw: Correct wrong debug message + - RDMA/efa: Fix wrong resources deallocation order + - HID: logitech-dj: Fix error handling in logi_dj_recv_switch_to_dj_mode() + - HID: uclogic: Correct devm device reference for hidinput input_dev name + - HID: multitouch: Correct devm device reference for hidinput input_dev name + - platform/x86/amd/pmf: Fix a missing cleanup path + - tick/rcu: Fix false positive "softirq work is pending" messages + - x86/speculation: Mark all Skylake CPUs as vulnerable to GDS + - tracing: Remove extra space at the end of hwlat_detector/mode + - tracing: Fix race issue between cpu buffer write and swap + - mtd: rawnand: brcmnand: Fix mtd oobsize + - dmaengine: idxd: Modify the dependence of attribute pasid_enabled + - phy/rockchip: inno-hdmi: use correct vco_div_5 macro on rk3328 + - phy/rockchip: inno-hdmi: round fractal pixclock in rk3328 recalc_rate + - phy/rockchip: inno-hdmi: do not power on rk3328 post pll on reg write + - rpmsg: glink: Add check for kstrdup + - leds: pwm: Fix error code in led_pwm_create_fwnode() + - leds: multicolor: Use rounded division when calculating color components + - leds: Fix BUG_ON check for LED_COLOR_ID_MULTI that is always false + - leds: trigger: tty: Do not use LED_ON/OFF constants, use + led_blink_set_oneshot instead + - mtd: spi-nor: Check bus width while setting QE bit + - mtd: rawnand: fsmc: handle clk prepare error in fsmc_nand_resume() + - um: Fix hostaudio build errors + - dmaengine: ste_dma40: Add missing IRQ check in d40_probe + - Drivers: hv: vmbus: Don't dereference ACPI root object handle + - cpufreq: Fix the race condition while updating the transition_task of policy + - virtio_ring: fix avail_wrap_counter in virtqueue_add_packed + - netfilter: nft_exthdr: Fix non-linear header modification + - skbuff: skb_segment, Call zero copy functions before using skbuff frags + - PM / devfreq: Fix leak in devfreq_dev_release() + - ALSA: pcm: Fix missing fixup call in compat hw_refine ioctl + - rcu: dump vmalloc memory info safely + - printk: ringbuffer: Fix truncating buffer size min_t cast + - scsi: core: Fix the scsi_set_resid() documentation + - mm/vmalloc: add a safer version of find_vm_area() for debug + - cpu/hotplug: Prevent self deadlock on CPU hot-unplug + - media: i2c: ccs: Check rules is non-NULL + - [Config] updateconfigs for VIDEO_CAMERA_SENSOR + - media: i2c: Add a camera sensor top level menu + - PCI: rockchip: Use 64-bit mask on MSI 64-bit PCI address + - ipmi_si: fix a memleak in try_smi_init() + - ARM: OMAP2+: Fix -Warray-bounds warning in _pwrdm_state_switch() + - XArray: Do not return sibling entries from xa_load() + - io_uring: break iopolling on signal + - backlight/gpio_backlight: Compare against struct fb_info.device + - backlight/bd6107: Compare against struct fb_info.device + - backlight/lv5207lp: Compare against struct fb_info.device + - drm/amd/display: register edp_backlight_control() for DCN301 + - xtensa: PMU: fix base address for the newer hardware + - LoongArch: mm: Add p?d_leaf() definitions + - i3c: master: svc: fix probe failure when no i3c device exist + - arm64: csum: Fix OoB access in IP checksum code for negative lengths + - ALSA: hda/cirrus: Fix broken audio on hardware with two CS42L42 codecs. + - media: dvb: symbol fixup for dvb_attach() + - media: venus: hfi_venus: Write to VIDC_CTRL_INIT after unmasking interrupts + - scsi: mpt3sas: Perform additional retries if doorbell read returns 0 + - PCI: Free released resource after coalescing + - PCI: hv: Fix a crash in hv_pci_restore_msi_msg() during hibernation + - PCI/PM: Only read PCI_PM_CTRL register when available + - ntb: Drop packets when qp link is down + - ntb: Clean up tx tail index on link down + - ntb: Fix calculation ntb_transport_tx_free_entry() + - Revert "PCI: Mark NVIDIA T4 GPUs to avoid bus reset" + - block: don't add or resize partition on the disk with GENHD_FL_NO_PART + - procfs: block chmod on /proc/thread-self/comm + - parisc: Fix /proc/cpuinfo output for lscpu + - drm/amd/display: Add smu write msg id fail retry process + - bpf: Fix issue in verifying allow_ptr_leaks + - dlm: fix plock lookup when using multiple lockspaces + - dccp: Fix out of bounds access in DCCP error handler + - x86/sev: Make enc_dec_hypercall() accept a size instead of npages + - X.509: if signature is unsupported skip validation + - net: handle ARPHRD_PPP in dev_is_mac_header_xmit() + - fsverity: skip PKCS#7 parser when keyring is empty + - x86/MCE: Always save CS register on AMD Zen IF Poison errors + - platform/chrome: chromeos_acpi: print hex string for ACPI_TYPE_BUFFER + - mmc: renesas_sdhi: register irqs before registering controller + - pstore/ram: Check start of empty przs during init + - arm64: sdei: abort running SDEI handlers during crash + - s390/dcssblk: fix kernel crash with list_add corruption + - s390/ipl: add missing secure/has_secure file to ipl type 'unknown' + - s390/dasd: fix string length handling + - crypto: stm32 - fix loop iterating through scatterlist for DMA + - cpufreq: brcmstb-avs-cpufreq: Fix -Warray-bounds bug + - of: property: fw_devlink: Add a devlink for panel followers + - usb: typec: tcpm: set initial svdm version based on pd revision + - usb: typec: bus: verify partner exists in typec_altmode_attention + - x86/sgx: Break up long non-preemptible delays in sgx_vepc_release() + - perf/x86/uncore: Correct the number of CHAs on EMR + - serial: sc16is7xx: remove obsolete out_thread label + - serial: sc16is7xx: fix regression with GPIO configuration + - tracing: Zero the pipe cpumask on alloc to avoid spurious -EBUSY + - Revert "drm/amd/display: Do not set drr on pipe commit" + - md: Free resources in __md_stop + - NFSv4.2: Fix a potential double free with READ_PLUS + - NFSv4.2: Rework scratch handling for READ_PLUS (again) + - md: fix regression for null-ptr-deference in __md_stop() + - clk: Mark a fwnode as initialized when using CLK_OF_DECLARE() macro + - treewide: Fix probing of devices in DT overlays + - clk: Avoid invalid function names in CLK_OF_DECLARE() + - powercap: arm_scmi: Remove recursion while parsing zones + - wifi: mt76: mt7915: rework tx packets counting when WED is active + - wifi: mt76: mt7915: rework tx bytes counting when WED is active + - wifi: mt76: mt7996: fix bss wlan_idx when sending bss_info command + - wifi: mt76: mt7996: use correct phy for background radar event + - wifi: mt76: mt7996: fix WA event ring size + - can: tcan4x5x: Remove reserved register 0x814 from writable table + - net: lan966x: Fix return value check for vcap_get_rule() + - wifi: rtw89: 8852b: rfk: fine tune IQK parameters to improve performance on + 2GHz band + - bpf: Fix check_func_arg_reg_off bug for graph root/node + - octeontx2-af: CN10KB: fix PFC configuration + - drm: bridge: dw-mipi-dsi: Fix enable/disable of DSI controller + - ARM: dts: stm32: Add missing detach mailbox for DHCOR SoM + - arm64: dts: qcom: pmi8950: Add missing OVP interrupt + - ARM: dts: qcom: sdx65-mtp: Update the pmic used in sdx65 + - iommufd: Fix locking around hwpt allocation + - clk: qcom: dispcc-sc8280xp: Use ret registers on GDSCs + - PCI: Mark NVIDIA T4 GPUs to avoid bus reset + - pinctrl: mediatek: assign functions to configure pin bias on MT7986 + - media: amphion: decoder support display delay for all formats + - RDMA/rxe: Move work queue code to subroutines + - RDMA/rxe: Fix rxe_modify_srq + - iommu: Remove kernel-doc warnings + - arm64: defconfig: Drop CONFIG_VIDEO_IMX_MEDIA + - media: ipu-bridge: Fix null pointer deref on SSDB/PLD parsing warnings + - thermal/drivers/imx8mm: Suppress log message on probe deferral + - dmaengine: idxd: Allow ATS disable update only for configurable devices + - powerpc/ftrace: Fix dropping weak symbols with older toolchains + - crypto: af_alg - Decrement struct key.usage in alg_set_by_key_serial() + - x86/build: Fix linker fill bytes quirk/incompatibility for ld.lld + - Upstream stable to v6.1.53, v6.4.16 + + * CVE-2023-6176 + - net/tls: do not free tls_rec on async operation in bpf_exec_tx_verdict() + + -- Roxana Nicolescu Mon, 08 Jan 2024 14:11:39 +0100 + linux (6.2.0-39.40) lunar; urgency=medium * lunar/linux: 6.2.0-39.40 -proposed tracker (LP: #2043451) diff -u linux-6.2.0/debian/control linux-6.2.0/debian/control --- linux-6.2.0/debian/control +++ linux-6.2.0/debian/control @@ -93,7 +93,7 @@ you do not want this package. Install the appropriate linux-headers package instead. -Package: linux-headers-6.2.0-39 +Package: linux-headers-6.2.0-41 Build-Profiles: Architecture: all Multi-Arch: foreign @@ -103,7 +103,7 @@ Description: Header files related to Linux kernel version 6.2.0 This package provides kernel header files for version 6.2.0, for sites that want the latest kernel headers. Please read - /usr/share/doc/linux-headers-6.2.0-39/debian.README.gz for details + /usr/share/doc/linux-headers-6.2.0-41/debian.README.gz for details Package: linux-tools-common Build-Profiles: @@ -118,18 +118,18 @@ version locked tools (such as perf and x86_energy_perf_policy) for version 6.2.0. -Package: linux-tools-6.2.0-39 +Package: linux-tools-6.2.0-41 Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: devel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends}, linux-tools-common -Description: Linux kernel version specific tools for version 6.2.0-39 +Description: Linux kernel version specific tools for version 6.2.0-41 This package provides the architecture dependant parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.2.0-39 on + version 6.2.0-41 on 64 bit x86. - You probably want to install linux-tools-6.2.0-39-. + You probably want to install linux-tools-6.2.0-41-. Package: linux-cloud-tools-common Build-Profiles: @@ -142,17 +142,17 @@ This package provides the architecture independent parts for kernel version locked tools for cloud tools for version 6.2.0. -Package: linux-cloud-tools-6.2.0-39 +Package: linux-cloud-tools-6.2.0-41 Build-Profiles: Architecture: amd64 armhf Section: devel Priority: optional Depends: ${misc:Depends}, ${shlibs:Depends}, linux-cloud-tools-common -Description: Linux kernel version specific cloud tools for version 6.2.0-39 +Description: Linux kernel version specific cloud tools for version 6.2.0-41 This package provides the architecture dependant parts for kernel - version locked tools for cloud tools for version 6.2.0-39 on + version locked tools for cloud tools for version 6.2.0-41 on 64 bit x86. - You probably want to install linux-cloud-tools-6.2.0-39-. + You probably want to install linux-cloud-tools-6.2.0-41-. Package: linux-tools-host Build-Profiles: @@ -192,17 +192,17 @@ contained in each file. -Package: linux-image-unsigned-6.2.0-39-generic +Package: linux-image-unsigned-6.2.0-41-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x 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.2.0-39-generic +Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.2.0-41-generic 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] | grub-ieee1275 [ppc64el], initramfs-tools | linux-initramfs-tool Breaks: flash-kernel (<< 3.90ubuntu2) [arm64 armhf], s390-tools (<< 2.3.0-0ubuntu3) [s390x] -Conflicts: linux-image-6.2.0-39-generic -Suggests: fdutils, linux-doc | linux-source-6.2.0, linux-tools, linux-headers-6.2.0-39-generic, linux-modules-extra-6.2.0-39-generic +Conflicts: linux-image-6.2.0-41-generic +Suggests: fdutils, linux-doc | linux-source-6.2.0, linux-tools, linux-headers-6.2.0-41-generic, linux-modules-extra-6.2.0-41-generic Description: Linux kernel image for version 6.2.0 on 64 bit x86 SMP This package contains the unsigned Linux kernel image for version 6.2.0 on 64 bit x86 SMP. @@ -215,7 +215,7 @@ the linux-generic meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-6.2.0-39-generic +Package: linux-modules-6.2.0-41-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: kernel @@ -235,12 +235,12 @@ the linux-generic meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-extra-6.2.0-39-generic +Package: linux-modules-extra-6.2.0-41-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: kernel Priority: optional -Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.2.0-39-generic, wireless-regdb +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.2.0-41-generic, wireless-regdb Description: Linux kernel extra modules for version 6.2.0 on 64 bit x86 SMP This package contains the Linux kernel extra modules for version 6.2.0 on 64 bit x86 SMP. @@ -257,21 +257,21 @@ the linux-generic meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-headers-6.2.0-39-generic +Package: linux-headers-6.2.0-41-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: devel Priority: optional -Depends: ${misc:Depends}, linux-headers-6.2.0-39, ${shlibs:Depends} +Depends: ${misc:Depends}, linux-headers-6.2.0-41, ${shlibs:Depends} Provides: linux-headers, linux-headers-3.0 Description: Linux kernel headers for version 6.2.0 on 64 bit x86 SMP This package provides kernel header files for version 6.2.0 on 64 bit x86 SMP. . This is for sites that want the latest kernel headers. Please read - /usr/share/doc/linux-headers-6.2.0-39/debian.README.gz for details. + /usr/share/doc/linux-headers-6.2.0-41/debian.README.gz for details. -Package: linux-lib-rust-6.2.0-39-generic +Package: linux-lib-rust-6.2.0-41-generic Build-Profiles: Architecture: amd64 Multi-Arch: foreign @@ -282,7 +282,7 @@ This package provides kernel library files for version 6.2.0, that allow to compile out-of-tree kernel modules written in Rust. -Package: linux-image-unsigned-6.2.0-39-generic-dbgsym +Package: linux-image-unsigned-6.2.0-41-generic-dbgsym Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: devel @@ -299,31 +299,31 @@ is uncompressed, and unstripped. This package also includes the unstripped modules. -Package: linux-tools-6.2.0-39-generic +Package: linux-tools-6.2.0-41-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: devel Priority: optional -Depends: ${misc:Depends}, linux-tools-6.2.0-39 -Description: Linux kernel version specific tools for version 6.2.0-39 +Depends: ${misc:Depends}, linux-tools-6.2.0-41 +Description: Linux kernel version specific tools for version 6.2.0-41 This package provides the architecture dependant parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.2.0-39 on + version 6.2.0-41 on 64 bit x86. -Package: linux-cloud-tools-6.2.0-39-generic +Package: linux-cloud-tools-6.2.0-41-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: devel Priority: optional -Depends: ${misc:Depends}, linux-cloud-tools-6.2.0-39 -Description: Linux kernel version specific cloud tools for version 6.2.0-39 +Depends: ${misc:Depends}, linux-cloud-tools-6.2.0-41 +Description: Linux kernel version specific cloud tools for version 6.2.0-41 This package provides the architecture dependant parts for kernel - version locked tools for cloud for version 6.2.0-39 on + version locked tools for cloud for version 6.2.0-41 on 64 bit x86. -Package: linux-buildinfo-6.2.0-39-generic +Package: linux-buildinfo-6.2.0-41-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: kernel @@ -337,18 +337,18 @@ You likely do not want to install this package. -Package: linux-modules-ipu6-6.2.0-39-generic +Package: linux-modules-ipu6-6.2.0-41-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: kernel Priority: optional Depends: ${misc:Depends}, - linux-image-6.2.0-39-generic | linux-image-unsigned-6.2.0-39-generic, + linux-image-6.2.0-41-generic | linux-image-unsigned-6.2.0-41-generic, Built-Using: ${linux:BuiltUsing} -Description: Linux kernel ipu6 modules for version 6.2.0-39 +Description: Linux kernel ipu6 modules for version 6.2.0-41 This package provides the Linux kernel ipu6 modules for version - 6.2.0-39. + 6.2.0-41. . You likely do not want to install this package directly. Instead, install the one of the linux-modules-ipu6-generic* meta-packages, @@ -356,18 +356,18 @@ also installed. -Package: linux-modules-ivsc-6.2.0-39-generic +Package: linux-modules-ivsc-6.2.0-41-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: kernel Priority: optional Depends: ${misc:Depends}, - linux-image-6.2.0-39-generic | linux-image-unsigned-6.2.0-39-generic, + linux-image-6.2.0-41-generic | linux-image-unsigned-6.2.0-41-generic, Built-Using: ${linux:BuiltUsing} -Description: Linux kernel ivsc modules for version 6.2.0-39 +Description: Linux kernel ivsc modules for version 6.2.0-41 This package provides the Linux kernel ivsc modules for version - 6.2.0-39. + 6.2.0-41. . You likely do not want to install this package directly. Instead, install the one of the linux-modules-ivsc-generic* meta-packages, @@ -375,18 +375,18 @@ also installed. -Package: linux-modules-iwlwifi-6.2.0-39-generic +Package: linux-modules-iwlwifi-6.2.0-41-generic Build-Profiles: Architecture: amd64 armhf arm64 ppc64el s390x Section: kernel Priority: optional Depends: ${misc:Depends}, - linux-image-6.2.0-39-generic | linux-image-unsigned-6.2.0-39-generic, + linux-image-6.2.0-41-generic | linux-image-unsigned-6.2.0-41-generic, Built-Using: ${linux:BuiltUsing} -Description: Linux kernel iwlwifi modules for version 6.2.0-39 +Description: Linux kernel iwlwifi modules for version 6.2.0-41 This package provides the Linux kernel iwlwifi modules for version - 6.2.0-39. + 6.2.0-41. . You likely do not want to install this package directly. Instead, install the one of the linux-modules-iwlwifi-generic* meta-packages, @@ -394,17 +394,17 @@ also installed. -Package: linux-image-unsigned-6.2.0-39-generic-64k +Package: linux-image-unsigned-6.2.0-41-generic-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.2.0-39-generic-64k +Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.2.0-41-generic-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.2.0-39-generic-64k -Suggests: fdutils, linux-doc | linux-source-6.2.0, linux-tools, linux-headers-6.2.0-39-generic-64k, linux-modules-extra-6.2.0-39-generic-64k +Conflicts: linux-image-6.2.0-41-generic-64k +Suggests: fdutils, linux-doc | linux-source-6.2.0, linux-tools, linux-headers-6.2.0-41-generic-64k, linux-modules-extra-6.2.0-41-generic-64k Description: Linux kernel image for version 6.2.0 on 64 bit x86 SMP This package contains the unsigned Linux kernel image for version 6.2.0 on 64 bit x86 SMP. @@ -417,7 +417,7 @@ the linux-generic-64k meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-6.2.0-39-generic-64k +Package: linux-modules-6.2.0-41-generic-64k Build-Profiles: Architecture: arm64 Section: kernel @@ -437,12 +437,12 @@ the linux-generic-64k meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-extra-6.2.0-39-generic-64k +Package: linux-modules-extra-6.2.0-41-generic-64k Build-Profiles: Architecture: arm64 Section: kernel Priority: optional -Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.2.0-39-generic-64k, wireless-regdb +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.2.0-41-generic-64k, wireless-regdb Description: Linux kernel extra modules for version 6.2.0 on 64 bit x86 SMP This package contains the Linux kernel extra modules for version 6.2.0 on 64 bit x86 SMP. @@ -459,21 +459,21 @@ the linux-generic-64k meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-headers-6.2.0-39-generic-64k +Package: linux-headers-6.2.0-41-generic-64k Build-Profiles: Architecture: arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-headers-6.2.0-39, ${shlibs:Depends} +Depends: ${misc:Depends}, linux-headers-6.2.0-41, ${shlibs:Depends} Provides: linux-headers, linux-headers-3.0 Description: Linux kernel headers for version 6.2.0 on 64 bit x86 SMP This package provides kernel header files for version 6.2.0 on 64 bit x86 SMP. . This is for sites that want the latest kernel headers. Please read - /usr/share/doc/linux-headers-6.2.0-39/debian.README.gz for details. + /usr/share/doc/linux-headers-6.2.0-41/debian.README.gz for details. -Package: linux-lib-rust-6.2.0-39-generic-64k +Package: linux-lib-rust-6.2.0-41-generic-64k Build-Profiles: Architecture: amd64 Multi-Arch: foreign @@ -484,7 +484,7 @@ This package provides kernel library files for version 6.2.0, that allow to compile out-of-tree kernel modules written in Rust. -Package: linux-image-unsigned-6.2.0-39-generic-64k-dbgsym +Package: linux-image-unsigned-6.2.0-41-generic-64k-dbgsym Build-Profiles: Architecture: arm64 Section: devel @@ -501,31 +501,31 @@ is uncompressed, and unstripped. This package also includes the unstripped modules. -Package: linux-tools-6.2.0-39-generic-64k +Package: linux-tools-6.2.0-41-generic-64k Build-Profiles: Architecture: arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-tools-6.2.0-39 -Description: Linux kernel version specific tools for version 6.2.0-39 +Depends: ${misc:Depends}, linux-tools-6.2.0-41 +Description: Linux kernel version specific tools for version 6.2.0-41 This package provides the architecture dependant parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.2.0-39 on + version 6.2.0-41 on 64 bit x86. -Package: linux-cloud-tools-6.2.0-39-generic-64k +Package: linux-cloud-tools-6.2.0-41-generic-64k Build-Profiles: Architecture: arm64 Section: devel Priority: optional -Depends: ${misc:Depends}, linux-cloud-tools-6.2.0-39 -Description: Linux kernel version specific cloud tools for version 6.2.0-39 +Depends: ${misc:Depends}, linux-cloud-tools-6.2.0-41 +Description: Linux kernel version specific cloud tools for version 6.2.0-41 This package provides the architecture dependant parts for kernel - version locked tools for cloud for version 6.2.0-39 on + version locked tools for cloud for version 6.2.0-41 on 64 bit x86. -Package: linux-buildinfo-6.2.0-39-generic-64k +Package: linux-buildinfo-6.2.0-41-generic-64k Build-Profiles: Architecture: arm64 Section: kernel @@ -539,18 +539,18 @@ You likely do not want to install this package. -Package: linux-modules-ipu6-6.2.0-39-generic-64k +Package: linux-modules-ipu6-6.2.0-41-generic-64k Build-Profiles: Architecture: arm64 Section: kernel Priority: optional Depends: ${misc:Depends}, - linux-image-6.2.0-39-generic-64k | linux-image-unsigned-6.2.0-39-generic-64k, + linux-image-6.2.0-41-generic-64k | linux-image-unsigned-6.2.0-41-generic-64k, Built-Using: ${linux:BuiltUsing} -Description: Linux kernel ipu6 modules for version 6.2.0-39 +Description: Linux kernel ipu6 modules for version 6.2.0-41 This package provides the Linux kernel ipu6 modules for version - 6.2.0-39. + 6.2.0-41. . You likely do not want to install this package directly. Instead, install the one of the linux-modules-ipu6-generic-64k* meta-packages, @@ -558,18 +558,18 @@ also installed. -Package: linux-modules-ivsc-6.2.0-39-generic-64k +Package: linux-modules-ivsc-6.2.0-41-generic-64k Build-Profiles: Architecture: arm64 Section: kernel Priority: optional Depends: ${misc:Depends}, - linux-image-6.2.0-39-generic-64k | linux-image-unsigned-6.2.0-39-generic-64k, + linux-image-6.2.0-41-generic-64k | linux-image-unsigned-6.2.0-41-generic-64k, Built-Using: ${linux:BuiltUsing} -Description: Linux kernel ivsc modules for version 6.2.0-39 +Description: Linux kernel ivsc modules for version 6.2.0-41 This package provides the Linux kernel ivsc modules for version - 6.2.0-39. + 6.2.0-41. . You likely do not want to install this package directly. Instead, install the one of the linux-modules-ivsc-generic-64k* meta-packages, @@ -577,18 +577,18 @@ also installed. -Package: linux-modules-iwlwifi-6.2.0-39-generic-64k +Package: linux-modules-iwlwifi-6.2.0-41-generic-64k Build-Profiles: Architecture: arm64 Section: kernel Priority: optional Depends: ${misc:Depends}, - linux-image-6.2.0-39-generic-64k | linux-image-unsigned-6.2.0-39-generic-64k, + linux-image-6.2.0-41-generic-64k | linux-image-unsigned-6.2.0-41-generic-64k, Built-Using: ${linux:BuiltUsing} -Description: Linux kernel iwlwifi modules for version 6.2.0-39 +Description: Linux kernel iwlwifi modules for version 6.2.0-41 This package provides the Linux kernel iwlwifi modules for version - 6.2.0-39. + 6.2.0-41. . You likely do not want to install this package directly. Instead, install the one of the linux-modules-iwlwifi-generic-64k* meta-packages, @@ -596,17 +596,17 @@ also installed. -Package: linux-image-unsigned-6.2.0-39-generic-lpae +Package: linux-image-unsigned-6.2.0-41-generic-lpae Build-Profiles: Architecture: armhf 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.2.0-39-generic-lpae +Depends: ${misc:Depends}, ${shlibs:Depends}, kmod, linux-base (>= 4.5ubuntu1~16.04.1), linux-modules-6.2.0-41-generic-lpae Recommends: flash-kernel [armhf] | 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.2.0-39-generic-lpae -Suggests: fdutils, linux-doc | linux-source-6.2.0, linux-tools, linux-headers-6.2.0-39-generic-lpae, linux-modules-extra-6.2.0-39-generic-lpae +Conflicts: linux-image-6.2.0-41-generic-lpae +Suggests: fdutils, linux-doc | linux-source-6.2.0, linux-tools, linux-headers-6.2.0-41-generic-lpae, linux-modules-extra-6.2.0-41-generic-lpae Description: Linux kernel image for version 6.2.0 on 64 bit x86 SMP This package contains the unsigned Linux kernel image for version 6.2.0 on 64 bit x86 SMP. @@ -619,7 +619,7 @@ the linux-generic-lpae meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-6.2.0-39-generic-lpae +Package: linux-modules-6.2.0-41-generic-lpae Build-Profiles: Architecture: armhf Section: kernel @@ -639,12 +639,12 @@ the linux-generic-lpae meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-modules-extra-6.2.0-39-generic-lpae +Package: linux-modules-extra-6.2.0-41-generic-lpae Build-Profiles: Architecture: armhf Section: kernel Priority: optional -Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.2.0-39-generic-lpae, wireless-regdb +Depends: ${misc:Depends}, ${shlibs:Depends}, linux-modules-6.2.0-41-generic-lpae, wireless-regdb Description: Linux kernel extra modules for version 6.2.0 on 64 bit x86 SMP This package contains the Linux kernel extra modules for version 6.2.0 on 64 bit x86 SMP. @@ -661,21 +661,21 @@ the linux-generic-lpae meta-package, which will ensure that upgrades work correctly, and that supporting packages are also installed. -Package: linux-headers-6.2.0-39-generic-lpae +Package: linux-headers-6.2.0-41-generic-lpae Build-Profiles: Architecture: armhf Section: devel Priority: optional -Depends: ${misc:Depends}, linux-headers-6.2.0-39, ${shlibs:Depends} +Depends: ${misc:Depends}, linux-headers-6.2.0-41, ${shlibs:Depends} Provides: linux-headers, linux-headers-3.0 Description: Linux kernel headers for version 6.2.0 on 64 bit x86 SMP This package provides kernel header files for version 6.2.0 on 64 bit x86 SMP. . This is for sites that want the latest kernel headers. Please read - /usr/share/doc/linux-headers-6.2.0-39/debian.README.gz for details. + /usr/share/doc/linux-headers-6.2.0-41/debian.README.gz for details. -Package: linux-lib-rust-6.2.0-39-generic-lpae +Package: linux-lib-rust-6.2.0-41-generic-lpae Build-Profiles: Architecture: amd64 Multi-Arch: foreign @@ -686,7 +686,7 @@ This package provides kernel library files for version 6.2.0, that allow to compile out-of-tree kernel modules written in Rust. -Package: linux-image-unsigned-6.2.0-39-generic-lpae-dbgsym +Package: linux-image-unsigned-6.2.0-41-generic-lpae-dbgsym Build-Profiles: Architecture: armhf Section: devel @@ -703,31 +703,31 @@ is uncompressed, and unstripped. This package also includes the unstripped modules. -Package: linux-tools-6.2.0-39-generic-lpae +Package: linux-tools-6.2.0-41-generic-lpae Build-Profiles: Architecture: armhf Section: devel Priority: optional -Depends: ${misc:Depends}, linux-tools-6.2.0-39 -Description: Linux kernel version specific tools for version 6.2.0-39 +Depends: ${misc:Depends}, linux-tools-6.2.0-41 +Description: Linux kernel version specific tools for version 6.2.0-41 This package provides the architecture dependant parts for kernel version locked tools (such as perf and x86_energy_perf_policy) for - version 6.2.0-39 on + version 6.2.0-41 on 64 bit x86. -Package: linux-cloud-tools-6.2.0-39-generic-lpae +Package: linux-cloud-tools-6.2.0-41-generic-lpae Build-Profiles: Architecture: armhf Section: devel Priority: optional -Depends: ${misc:Depends}, linux-cloud-tools-6.2.0-39 -Description: Linux kernel version specific cloud tools for version 6.2.0-39 +Depends: ${misc:Depends}, linux-cloud-tools-6.2.0-41 +Description: Linux kernel version specific cloud tools for version 6.2.0-41 This package provides the architecture dependant parts for kernel - version locked tools for cloud for version 6.2.0-39 on + version locked tools for cloud for version 6.2.0-41 on 64 bit x86. -Package: linux-buildinfo-6.2.0-39-generic-lpae +Package: linux-buildinfo-6.2.0-41-generic-lpae Build-Profiles: Architecture: armhf Section: kernel @@ -741,18 +741,18 @@ You likely do not want to install this package. -Package: linux-modules-ipu6-6.2.0-39-generic-lpae +Package: linux-modules-ipu6-6.2.0-41-generic-lpae Build-Profiles: Architecture: armhf Section: kernel Priority: optional Depends: ${misc:Depends}, - linux-image-6.2.0-39-generic-lpae | linux-image-unsigned-6.2.0-39-generic-lpae, + linux-image-6.2.0-41-generic-lpae | linux-image-unsigned-6.2.0-41-generic-lpae, Built-Using: ${linux:BuiltUsing} -Description: Linux kernel ipu6 modules for version 6.2.0-39 +Description: Linux kernel ipu6 modules for version 6.2.0-41 This package provides the Linux kernel ipu6 modules for version - 6.2.0-39. + 6.2.0-41. . You likely do not want to install this package directly. Instead, install the one of the linux-modules-ipu6-generic-lpae* meta-packages, @@ -760,18 +760,18 @@ also installed. -Package: linux-modules-ivsc-6.2.0-39-generic-lpae +Package: linux-modules-ivsc-6.2.0-41-generic-lpae Build-Profiles: Architecture: armhf Section: kernel Priority: optional Depends: ${misc:Depends}, - linux-image-6.2.0-39-generic-lpae | linux-image-unsigned-6.2.0-39-generic-lpae, + linux-image-6.2.0-41-generic-lpae | linux-image-unsigned-6.2.0-41-generic-lpae, Built-Using: ${linux:BuiltUsing} -Description: Linux kernel ivsc modules for version 6.2.0-39 +Description: Linux kernel ivsc modules for version 6.2.0-41 This package provides the Linux kernel ivsc modules for version - 6.2.0-39. + 6.2.0-41. . You likely do not want to install this package directly. Instead, install the one of the linux-modules-ivsc-generic-lpae* meta-packages, @@ -779,18 +779,18 @@ also installed. -Package: linux-modules-iwlwifi-6.2.0-39-generic-lpae +Package: linux-modules-iwlwifi-6.2.0-41-generic-lpae Build-Profiles: Architecture: armhf Section: kernel Priority: optional Depends: ${misc:Depends}, - linux-image-6.2.0-39-generic-lpae | linux-image-unsigned-6.2.0-39-generic-lpae, + linux-image-6.2.0-41-generic-lpae | linux-image-unsigned-6.2.0-41-generic-lpae, Built-Using: ${linux:BuiltUsing} -Description: Linux kernel iwlwifi modules for version 6.2.0-39 +Description: Linux kernel iwlwifi modules for version 6.2.0-41 This package provides the Linux kernel iwlwifi modules for version - 6.2.0-39. + 6.2.0-41. . You likely do not want to install this package directly. Instead, install the one of the linux-modules-iwlwifi-generic-lpae* meta-packages, diff -u linux-6.2.0/debian/dkms-versions linux-6.2.0/debian/dkms-versions --- linux-6.2.0/debian/dkms-versions +++ linux-6.2.0/debian/dkms-versions @@ -1,4 +1,4 @@ -zfs-linux 2.1.9-2ubuntu1.1 modulename=zfs debpath=pool/universe/z/%package%/zfs-dkms_%version%_all.deb arch=amd64 arch=arm64 arch=ppc64el arch=s390x rprovides=spl-modules rprovides=spl-dkms rprovides=zfs-modules rprovides=zfs-dkms +zfs-linux 2.1.9-2ubuntu1.2 modulename=zfs debpath=pool/universe/z/%package%/zfs-dkms_%version%_all.deb arch=amd64 arch=arm64 arch=ppc64el arch=s390x rprovides=spl-modules rprovides=spl-dkms rprovides=zfs-modules rprovides=zfs-dkms ipu6-drivers 0~git202211220708.278b7e3d-0ubuntu0.23.04.1 modulename=ipu6 debpath=pool/universe/i/%package%/intel-ipu6-dkms_%version%_amd64.deb arch=amd64 rprovides=ipu6-modules rprovides=intel-ipu6-dkms type=standalone ivsc-driver 0~git202211241536.70d95269-0ubuntu0.23.04.1 modulename=ivsc debpath=pool/universe/i/%package%/intel-vsc-dkms_%version%_amd64.deb arch=amd64 rprovides=ivsc-modules rprovides=intel-vsc-dkms type=standalone backport-iwlwifi-dkms 9904-0ubuntu5 modulename=iwlwifi debpath=pool/universe/b/%package%/backport-iwlwifi-dkms_%version%_all.deb arch=amd64 rprovides=iwlwifi-modules rprovides=backport-iwlwifi-dkms type=standalone reverted: --- linux-6.2.0/debian/scripts/helpers/close +++ linux-6.2.0.orig/debian/scripts/helpers/close @@ -1,195 +0,0 @@ -#!/bin/bash -eu -export LC_ALL=C.UTF-8 - -usage() { - cat << EOF -Usage: ${P:-$(basename "$0")} [-h|--help] [-d|--dry-run] [-c|--include-config] [-s|--skip-master] [-b BASE_VERSION] - -Prepare the closing release commit. Include all the changelog entries -in the current release, including the changes from the base -kernel. Also close the changelog entry and check for config changes. - -Optional arguments: - -d, --dry-run Perform a trial run with no changes made - printing the commands instead. - -c, --include-config Include config changes in the closing commit. - -s, --skip-master Skip master kernel changelog entries (used when - bootstraping new kernels). - -b BASE_VERSION For derivatives and backports, force the changelog - entries to have the base version as provided (used - when changing the base derivative version of a - backport). - -h, --help Show this help message and exit. - -Examples: - Simply close a release: - \$ cranky close - - Also include any config changes to the closing commit: - \$ cranky close -c - -EOF -} - -dry_run=0 -commit_configs=0 -skip_master_entries=0 -base_version= -while [ "$#" -gt 0 ]; do - case "$1" in - -h|--help) - usage - exit 0 - ;; - -d|--dry-run) - dry_run=1 - ;; - -c|--include-config) - commit_configs=1 - ;; - -s|--skip-master) - skip_master_entries=1 - ;; - -b) - shift - base_version="$1" - ;; - *) - usage - exit 1 - ;; - esac - shift -done - -hl() { echo -e "\e[1m$*\e[0m"; } - -run() { - # Quote args for echo or eval - local quoted=() - for token; do - quoted+=( "$(printf '%q' "$token")" ) - done - # Run - if [ "$dry_run" -eq 1 ]; then - hl "DRY RUN: ${quoted[*]}" - else - hl "${quoted[*]}" - "$@" - echo - fi -} - -# Trick shellcheck so it doesn't complain every time it's necessary to -# use `run $CHROOT`. Use `chroot_run` instead. -shopt -s expand_aliases -alias chroot_run='run ${CHROOT:-}' - -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 - # shellcheck disable=SC1090 - . "$CONF" -fi - -# Check if changelog is open -series=$(dpkg-parsechangelog -l"$DEBIAN/changelog" -SDistribution) -if [ "$series" != 'UNRELEASED' ]; then - echo "The last entry of the changelog is already released." - exit 1 -fi - -# Update configs -if [ -d "$DEBIAN/config" ]; then - chroot_run fakeroot debian/rules clean updateconfigs - changes=$(git diff HEAD -- "./$DEBIAN/config/") - if [ "$commit_configs" -eq 0 ] && [ -n "$changes" ]; then - echo "Config has changed! please, review it and commit." - exit 1 - fi -fi - -# For normal trees the fact that the update.conf file exists means that they are rebase -# kernels. There are some special trees which started with uc20-efi, which have that -# file because they logically depend on another source but do not have the directory -# which DEBIAN_MASTER points to. -# Skip inserting parent source entries if this is not a rebase tree. -if [ ! -f "$DEBIAN/etc/update.conf" ]; then - skip_master_entries=1 -elif [ "$DEBIAN_MASTER" != "" -a ! -d "$DEBIAN_MASTER" ]; then - skip_master_entries=1 -fi -if [ $skip_master_entries == 0 ]; then - if [ "$DEBIAN_MASTER" = "" ]; then - echo "DEBIAN_MASTER should be defined either in $DEBIAN/etc/update.conf or the environment" - exit 1 - fi - - if [ -z "${base_version}" ]; then - offset=0 - # If not provided as an option, 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 - base_version=$(echo "$changes" | sed -n -r -e '/^\s.*\[ Ubuntu: ([~0-9.-]*) \]$/{s//\1/p;q}') - [ "$base_version" ] && break - offset=$(( offset + 1 )) - done - fi - - master_version=$(dpkg-parsechangelog -l${DEBIAN_MASTER}/changelog -SVersion) - if ! [ "$master_version" ]; then - echo "Failed to retrieve current master version from changelog: $DEBIAN/changelog" - exit 1 - fi - run ./debian/scripts/misc/insert-ubuntu-changes "$DEBIAN/changelog" "$base_version" "$master_version" \ - "$DEBIAN_MASTER/changelog" -fi - -# Insert local changes -run fakeroot debian/rules insertchanges - -# This should be the last step. If there were no changes to the -# changelog, there is nothing to release, so nothing to commit. -changes=$(git diff HEAD) -if [ -z "$changes" ] && [ "$dry_run" -eq 0 ]; then - hl "No changes to commit." - exit 1 -fi - -# Find the current series from previous changelog entries: -series='' -offset=0 -while true; do - series=$(dpkg-parsechangelog -l"$DEBIAN/changelog" -SDistribution -c1 -o"$offset") - if [ "$series" ] && [ "$series" != 'UNRELEASED' ]; then - break - fi - offset=$(( offset + 1 )) -done -if ! [ "$series" ]; then - echo "Failed to retrieve the package series from changelog: $DEBIAN/changelog" - exit 1 -fi -# Close the changelog -run dch --nomultimaint -c "$DEBIAN/changelog" -r -D "$series" '' - -# Commit changes -package=$(dpkg-parsechangelog -l"$DEBIAN/changelog" -SSource) -prefix="Ubuntu$(echo "$package" | sed -r -e 's/linux(-?)/\1/')-" -version=$(dpkg-parsechangelog -l"$DEBIAN/changelog" -SVersion) -run git commit -sam "UBUNTU: $prefix$version" reverted: --- linux-6.2.0/debian/scripts/helpers/open +++ linux-6.2.0.orig/debian/scripts/helpers/open @@ -1,234 +0,0 @@ -#!/bin/bash -eu -export LC_ALL=C.UTF-8 - -out() -{ - local rc=${?} - - trap - EXIT INT TERM HUP - [ "${rc}" -eq 0 ] || echo "Error: Script failed" >&2 - - exit "${rc}" -} - -hl() { - echo -e "\e[1m$*\e[0m" -} - -run() { - # Quote args for echo or eval - local quoted=() - for token; do - quoted+=("$(printf '%q' "$token")") - done - # Run - if [ "$dry_run" -eq 1 ]; then - hl "DRY RUN: ${quoted[*]}" - else - hl "${quoted[*]}" - "$@" - echo - fi -} - -usage() { - cat << EOF -Usage: ${P:-$(basename "$0")} [-h|--help] [-d|--dry-run] [-r|--reuse-abi] - -Create a "start new release" commit. The new commit will contain ABI -changes and any customization required by backport kernels. - -Optional arguments: - -d, --dry-run Perform a trial run with no changes made - printing the commands instead. - -r, --reuse-abi Do not download the previous release ABI files - for the new release and just rename the - current ABI directory. This might cause the - build to fail if the module list or the - retpoline information has changed. - -h, --help Show this help message and exit. - -Environment variable: - CRANKY_MAILENFORCE Regular expression used to validate \$DEBEMAIL. If not - set, it defaults to "@canonical.com$". - -Examples: - Simply start a new release (that will fetch the ABI files from the - archieve repositories): - \$ cranky open - - Start a new release re-using the ABI files already present in the - tree: - \$ cranky open --reuse-abi - -EOF -} - -dry_run=0 -reuse_abi=0 -while [ "$#" -gt 0 ]; do - case "$1" in - -h|--help) - usage - exit 0 - ;; - -d|--dry-run) - dry_run=1 - ;; - -r|--reuse-abi) - reuse_abi=1 - ;; - *) - usage - exit 1 - ;; - esac - shift -done - -trap out EXIT INT TERM HUP - -# Trick shellcheck so it doesn't complain every time it's necessary to -# use `run $CHROOT`. Use `chroot_run` instead. -shopt -s expand_aliases -alias chroot_run='run ${CHROOT:-}' - -# Check DEBEMAIL (used to create the new changelog stanza): -DEBEMAIL="${DEBEMAIL:-}" -CRANKY_MAILENFORCE="${CRANKY_MAILENFORCE:-@canonical.com\$}" -if [ -z "$DEBEMAIL" ] || ! echo "$DEBEMAIL" | grep -qE "$CRANKY_MAILENFORCE"; then - echo "DEBEMAIL is unset, or does not contain \"$CRANKY_MAILENFORCE\": $DEBEMAIL" >&2 - exit 1 -fi - -# Requires a git repo -if [ ! -e .git ]; then - echo "Not a git repository!" >&2 - exit 1 -fi - -# Check the debian directory -if [ ! -e debian/debian.env ]; then - echo "Cannot find debian/debian.env!" >&2 - exit 1 -fi -DEBIAN= -# shellcheck disable=SC1091 -. debian/debian.env -if [ -z "$DEBIAN" ] || [ ! -d "$DEBIAN" ]; then - echo "Invalid DEBIAN directory: $DEBIAN" >&2 - exit 1 -fi - -# Abort if changes or untracked files are found in the debian -# directory (ie, in "debian.master/"). cranky open is expected to -# change and commit files in this directory. -if ! git diff-index --quiet HEAD -- "$DEBIAN/" || \ - [ -n "$(git ls-files --others -- "$DEBIAN/")" ]; then - echo "\"$DEBIAN/\" is not clean!" >&2 - exit 1 -fi - -# Check changelog -series=$(dpkg-parsechangelog -l"$DEBIAN/changelog" -SDistribution) -if [ "$series" == 'UNRELEASED' ]; then - echo "$DEBIAN/changelog is not closed!" >&2 - exit 1 -fi - -# Load the info about derivative -BACKPORT_SUFFIX= -BACKPORT_NO_SUFFIX= -derivative_conf="$DEBIAN/etc/update.conf" -if [ -f "$derivative_conf" ]; then - # shellcheck disable=SC1090 - . "$derivative_conf" -fi - -# Run the update script used for backport kernels -if [ -n "$BACKPORT_SUFFIX" ] || [ -n "$BACKPORT_NO_SUFFIX" ]; then - update_from_master_script="$DEBIAN/scripts/helpers/copy-files" - if [ ! -x "$update_from_master_script" ]; then - echo "Backport kernel is missing the"\ - "\"$update_from_master_script\" script!"; - exit 1 - fi - # The tree should be clean at this point, since that is enforced at - # the beginning of the script. Because of that, it's safe to git add - # "$DEBIAN/". - run env CHROOT="$CHROOT" "$update_from_master_script" - run git add "$DEBIAN" - # Update configs after the necessary files were copied from - # the base kernel. It's not expected that `fdr updateconfigs` - # will fail at this point, because the base kernel's - # configuration and annotations file are expected to be in a - # correct state. `fdr updateconfigs` should only change a few - # configuration options that depend on the userspace tooling - # version, such as gcc. - if ! chroot_run fakeroot debian/rules clean updateconfigs; then - echo "Failed to update configs. Please review the previous" \ - "rebase operation and \"$update_from_master_script\""; - exit 1 - fi - run git add "$DEBIAN/config" -fi - -# fdr clean should be called after copy-files, that way we can git add -# any changes in "debian./" (`fdr clean` in trusty will -# usually generate changes in "debian./). Also, fdr clean -# removes an ABI that matches the current version in the -# changelog. Since `fdr startnewrelease` requires `fdr clean`, we need -# to call it before getabis. -chroot_run fakeroot debian/rules clean - -# Update ABI -if [ -d "$DEBIAN/abi" ]; then - # The new ABI directory should use the current version in the - # changelog since `fdr startnewrelease` was't called at this - # point yet: - new=$(dpkg-parsechangelog -l"$DEBIAN/changelog" -SVersion) - - if [ "$reuse_abi" -ne 0 ]; then - if [ -f "$DEBIAN/abi/version" ]; then - # This is an unversioned ABI directory, so simply update the - # version file - echo "$new" | run tee "$DEBIAN/abi/version" >/dev/null - run git add "$DEBIAN/abi/version" - else - # Get the old ABI directory: - old=$(find "$DEBIAN/abi/" -mindepth 1 -maxdepth 1 -type d | \ - grep -P '/abi/[0-9]+\.[0-9]+\.[0-9]+-[0-9]+\.[0-9]+') - if [ -z "${old}" ] ; then - echo "Failed to find the previous ABI directory." \ - "Please check \"$DEBIAN/abi/\"!" >&2 - exit 1 - elif [ "$(echo "$old" | wc -l)" -gt 1 ]; then - echo "Failed to rename the current ABI directory." \ - "Multiple directories found. Please check \"$DEBIAN/abi/\"!" >&2 - exit 1 - fi - new="$DEBIAN/abi/$new" - # Rename the ABI directory - run git mv "$old" "$new" - fi - else - # Call in-tree getabis: - # Use the single argument form since getabis is now - # updated by cranky fix. - run debian/scripts/misc/getabis "${new}" - # getabis already handles the necessary git add/rm calls. - fi -fi - -# Create the new changelog entry: -run fakeroot debian/rules startnewrelease -run git add "$DEBIAN/changelog" - -# Create the commit -run git commit -s -F debian/commit-templates/newrelease - -# Mimic maint-startnewrelease -[ "$dry_run" -eq 0 ] && \ - hl "\n***** Now please inspect the commit before pushing *****" - -exit 0 reverted: --- linux-6.2.0/debian/scripts/helpers/rebase +++ linux-6.2.0.orig/debian/scripts/helpers/rebase @@ -1,159 +0,0 @@ -#!/bin/bash -e -# -# This script is intended as a helper when rebasing from its master branch. -# - -LOCAL_BRANCH= -RELEASE_REPO= -SOURCE_RELEASE_BRANCH= -OWN= - -function out() -{ - local rc="${?}" - trap - EXIT INT TERM HUP - [ "${rc}" -eq 0 ] || echo "Error: Script failed" - exit "${rc}" -} - -trap out EXIT INT TERM HUP - -if [ -f debian/debian.env ]; then - # shellcheck disable=SC1091 - . debian/debian.env -fi - -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 - # shellcheck disable=SC1090 - . "${CONF}" -fi - -usage="$0 [-r RELEASE_REPO] [ -b REMOTE_BRANCH ] [-l LOCAL_BRANCH] [-d]"$'\n\n' -usage+="-r RELEASE_REPO Git repository to fetch the reference branch from."$'\n' -usage+="-b REMOTE_BRANCH Remote branch to fetch from."$'\n' -usage+="-l LOCAL_BRANCH Use LOCAL_BRANCH as the reference branch."$'\n' -usage+="-o Rebase against own kernel."$'\n' -usage+="-d,--dry-run Dry run (do not rebase)." - -# Convert long options to short options -for arg in "$@" -do - shift - case "$arg" in - '--dry-run') set -- "$@" '-d' ;; - '--'*) echo "usage: ${usage}"; exit ;; - *) set -- "$@" "$arg" ;; - esac -done - -# -# command line options: -# [-r RELEASE_REPO] - override default git repository. -# [-b REMOTE_BRANCH] - override default remote branch. -# [-l LOCAL_BRANCH] - do not fetch from remote repo, use a local branch. - -while getopts "r:b:l:od" opt; do - case $opt in - r ) RELEASE_REPO="$OPTARG" ;; - b ) SOURCE_RELEASE_BRANCH="$OPTARG" ;; - l ) LOCAL_BRANCH="$OPTARG" ;; - d ) DRY_RUN=1 ;; - o ) OWN=1 ;; - \? ) echo "usage: ${usage}"; exit ;; - esac -done -shift $((OPTIND - 1)) - -# For normal trees the fact that the update.conf file exists means that they are rebase -# kernels. There are some special trees which started with uc20-efi, which have that -# file because they logically depend on another source but do not have the directory -# which DEBIAN_MASTER points to. -IS_REBASE_KERNEL=true -if [ ! -f "$DEBIAN/etc/update.conf" ]; then - IS_REBASE_KERNEL=false -elif [ "$DEBIAN_MASTER" != "" -a ! -d "$DEBIAN_MASTER" ]; then - IS_REBASE_KERNEL=false -fi -if ! $IS_REBASE_KERNEL && [ -z "$OWN" ]; then - echo "This is not a rebase kernel, no rebase should be needed, please report if otherwise" - exit 0 -fi - -if [ "${OWN}" ] ; then - DEBIAN_MASTER="${DEBIAN}" -fi - -if [ "$DEBIAN_MASTER" = "" ]; then - echo "DEBIAN_MASTER should be defined either in ${DEBIAN}/etc/update.conf or the environment" - exit 1 -fi - -if [ -z "${LOCAL_BRANCH}" ]; then - if [ -z "${RELEASE_REPO}" ] || [ -z "${SOURCE_RELEASE_BRANCH}" ]; then - echo Missing update.conf or missing parameters for remote repo and branch. - exit 1 - fi - # - # Fetch the upstream branch. - # - git fetch "${RELEASE_REPO}" - git fetch "${RELEASE_REPO}" "${SOURCE_RELEASE_BRANCH}" - LOCAL_BRANCH=FETCH_HEAD -fi - -# -# Find the most recent tag on given upstream branch, then -# rebase against it. This avoids the case where there have been some -# commits since the last official tag. -# -MASTER_COMMIT=$(git log --pretty=one "${LOCAL_BRANCH}" "${DEBIAN_MASTER}" | \ - awk ' - /Ubuntu-/ { - if (match($0, /UBUNTU: Ubuntu-/)) { - print $1 - exit - } - } - ' -) -# -# Find the current merge point where current branch was based. -# -BASE_COMMIT=$(git log --pretty=one "${DEBIAN_MASTER}" | \ - awk ' - /Ubuntu-/ { - if (match($0, /UBUNTU: Ubuntu-/)) { - print $1 - exit - } - } - ' -) -if [ "${MASTER_COMMIT}" = "${BASE_COMMIT}" ]; then - echo Already up to date. - exit 0 -fi - -if [ -z "${MASTER_COMMIT}" ] || [ -z "${BASE_COMMIT}" ]; then - echo "Could not find either master or base commit." - echo "master commit: ${MASTER_COMMIT}" - echo "base commit: ${BASE_COMMIT}" - exit 1 -fi - -MASTER_VERSION=$(git show --format=%s -s "$MASTER_COMMIT" | sed 's/^UBUNTU: //') -BASE_VERSION=$(git show --format=%s -s "$BASE_COMMIT" | sed 's/^UBUNTU: //') -echo "Rebase still needed between $BASE_VERSION and $MASTER_VERSION." - -if [ "${DRY_RUN}" ]; then - echo "DRY RUN: git rebase --onto ${MASTER_COMMIT} ${BASE_COMMIT}" - exit 0 -fi - -git rebase --onto "${MASTER_COMMIT}" "${BASE_COMMIT}" diff -u linux-6.2.0/debian/scripts/misc/annotations linux-6.2.0/debian/scripts/misc/annotations --- linux-6.2.0/debian/scripts/misc/annotations +++ linux-6.2.0/debian/scripts/misc/annotations @@ -3,272 +3,32 @@ -# Manage Ubuntu kernel .config and annotations -# Copyright © 2022 Canonical Ltd. -import sys -sys.dont_write_bytecode = True -import os -import argparse -import json -from signal import signal, SIGPIPE, SIG_DFL - -from kconfig.annotations import Annotation, KConfig - -VERSION = '0.1' - -SKIP_CONFIGS = ( - # CONFIG_VERSION_SIGNATURE is dynamically set during the build - 'CONFIG_VERSION_SIGNATURE', - # Allow to use a different versions of toolchain tools - 'CONFIG_GCC_VERSION', - 'CONFIG_CC_VERSION_TEXT', - 'CONFIG_AS_VERSION', - 'CONFIG_LD_VERSION', - 'CONFIG_LLD_VERSION', - 'CONFIG_CLANG_VERSION', - 'CONFIG_PAHOLE_VERSION', - 'CONFIG_RUSTC_VERSION_TEXT', - 'CONFIG_BINDGEN_VERSION_TEXT', -) - - -def make_parser(): - parser = argparse.ArgumentParser( - description='Manage Ubuntu kernel .config and annotations', - ) - parser.add_argument('--version', '-v', action='version', version=f'%(prog)s {VERSION}') - - parser.add_argument('--file', '-f', action='store', - help='Pass annotations or .config file to be parsed') - parser.add_argument('--arch', '-a', action='store', - help='Select architecture') - parser.add_argument('--flavour', '-l', action='store', - help='Select flavour (default is "generic")') - parser.add_argument('--config', '-c', action='store', - help='Select a specific config option') - parser.add_argument('--query', '-q', action='store_true', - help='Query annotations') - parser.add_argument('--note', '-n', action='store', - help='Write a specific note to a config option in annotations') - parser.add_argument('--autocomplete', action='store_true', - help='Enable config bash autocomplete: `source <(annotations --autocomplete)`') - parser.add_argument('--source', '-t', action='store_true', - help='Jump to a config definition in the kernel source code') - - ga = parser.add_argument_group(title='Action').add_mutually_exclusive_group(required=False) - ga.add_argument('--write', '-w', action='store', - metavar='VALUE', dest='value', - help='Set a specific config value in annotations (use \'null\' to remove)') - ga.add_argument('--export', '-e', action='store_true', - help='Convert annotations to .config format') - ga.add_argument('--import', '-i', action='store', - metavar="FILE", dest='import_file', - help='Import a full .config for a specific arch and flavour into annotations') - ga.add_argument('--update', '-u', action='store', - metavar="FILE", dest='update_file', - help='Import a partial .config into annotations (only resync configs specified in FILE)') - ga.add_argument('--check', '-k', action='store', - metavar="FILE", dest='check_file', - help='Validate kernel .config with annotations') - return parser - - -_ARGPARSER = make_parser() - - -def arg_fail(message): - print(message) - _ARGPARSER.print_usage() - sys.exit(1) - - -def print_result(config, res): - if res is not None and config not in res: - res = {config or '*': res} - print(json.dumps(res, indent=4)) - - -def do_query(args): - if args.arch is None and args.flavour is not None: - arg_fail('error: --flavour requires --arch') - a = Annotation(args.file) - res = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour) - print_result(args.config, res) - - -def do_autocomplete(args): - a = Annotation(args.file) - res = (c.removeprefix('CONFIG_') for c in a.search_config()) - res_str = ' '.join(res) - print(f'complete -W "{res_str}" annotations') - - -def do_source(args): - if args.config is None: - arg_fail('error: --source requires --config') - if not os.path.exists('tags'): - print('tags not found in the current directory, try: `make tags`') - sys.exit(1) - os.system(f'vim -t {args.config}') - - -def do_note(args): - if args.config is None: - arg_fail('error: --note requires --config') - - # Set the note in annotations - a = Annotation(args.file) - a.set(args.config, note=args.note) - - # Save back to annotations - a.save(args.file) - - # Query and print back the value - a = Annotation(args.file) - res = a.search_config(config=args.config) - print_result(args.config, res) - - -def do_write(args): - if args.config is None: - arg_fail('error: --write requires --config') - - # Set the value in annotations ('null' means remove) - a = Annotation(args.file) - if args.value == 'null': - a.remove(args.config, arch=args.arch, flavour=args.flavour) - else: - a.set(args.config, arch=args.arch, flavour=args.flavour, value=args.value, note=args.note) - - # Save back to annotations - a.save(args.file) - - # Query and print back the value - a = Annotation(args.file) - res = a.search_config(config=args.config) - print_result(args.config, res) - - -def do_export(args): - if args.arch is None: - arg_fail('error: --export requires --arch') - a = Annotation(args.file) - conf = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour) - if conf: - print(a.to_config(conf)) - - -def do_import(args): - if args.arch is None: - arg_fail('error: --arch is required with --import') - if args.flavour is None: - arg_fail('error: --flavour is required with --import') - if args.config is not None: - arg_fail('error: --config cannot be used with --import (try --update)') - - # Merge with the current annotations - a = Annotation(args.file) - c = KConfig(args.import_file) - a.update(c, arch=args.arch, flavour=args.flavour) - - # Save back to annotations - a.save(args.file) - - -def do_update(args): - if args.arch is None: - arg_fail('error: --arch is required with --update') - - # Merge with the current annotations - a = Annotation(args.file) - c = KConfig(args.update_file) - if args.config is None: - configs = list(set(c.config.keys()) - set(SKIP_CONFIGS)) - if configs: - a.update(c, arch=args.arch, flavour=args.flavour, configs=configs) - - # Save back to annotations - a.save(args.file) - - -def do_check(args): - # Determine arch and flavour - if args.arch is None: - arg_fail('error: --arch is required with --check') - - print(f"check-config: loading annotations from {args.file}") - total = good = ret = 0 - - # Load annotations settings - a = Annotation(args.file) - a_configs = a.search_config(arch=args.arch, flavour=args.flavour).keys() - - # Parse target .config - c = KConfig(args.check_file) - c_configs = c.config.keys() - - # Validate .config against annotations - for conf in sorted(a_configs | c_configs): - if conf in SKIP_CONFIGS: - continue - entry = a.search_config(config=conf, arch=args.arch, flavour=args.flavour) - expected = entry[conf] if entry else '-' - value = c.config[conf] if conf in c.config else '-' - if value != expected: - policy = a.config[conf] if conf in a.config else 'undefined' - if 'policy' in policy: - policy = f"policy<{policy['policy']}>" - print(f"check-config: FAIL: ({value} != {expected}): {conf} {policy})") - ret = 1 - else: - good += 1 - total += 1 - - print(f"check-config: {good}/{total} checks passed -- exit {ret}") - sys.exit(ret) - - -def autodetect_annotations(args): - if args.file: - return - # If --file/-f isn't specified try to automatically determine the right - # location of the annotations file looking at debian/debian.env. - try: - with open('debian/debian.env', 'rt', encoding='utf-8') as fd: - args.file = fd.read().rstrip().split('=')[1] + '/config/annotations' - except (FileNotFoundError, IndexError): - arg_fail('error: could not determine DEBDIR, try using: --file/-f') +# This file is not installed; it's just to run annotations from inside a source +# distribution without installing it in the system. +import sys -def main(): - # Prevent broken pipe errors when showing output in pipe to other tools - # (less for example) - signal(SIGPIPE, SIG_DFL) +# Prevent generating .pyc files on import +# +# We may end up adding these files to our git repos by mistake, so simply +# prevent generating them in advance. +# +# There's a tiny performance penalty with this, because python needs to +# re-generate the bytecode on-the-fly every time the script is executed, but +# this overhead is absolutely negligible compared the rest of the kernel build +# time. +sys.dont_write_bytecode = True - # Main annotations program - args = _ARGPARSER.parse_args() - autodetect_annotations(args) +import os # noqa: E402 Import not at top of file +from kconfig import run # noqa: E402 Import not at top of file - if args.config and not args.config.startswith('CONFIG_'): - args.config = 'CONFIG_' + args.config - if args.value: - do_write(args) - elif args.note: - do_note(args) - elif args.export: - do_export(args) - elif args.import_file: - do_import(args) - elif args.update_file: - do_update(args) - elif args.check_file: - do_check(args) - elif args.autocomplete: - do_autocomplete(args) - elif args.source: - do_source(args) - else: - do_query(args) +# Update PATH to make sure that annotations can be executed directly from the +# source directory. +def update_path(): + script_dir = os.path.dirname(os.path.abspath(__file__)) + current_path = os.environ.get("PATH", "") + new_path = f"{script_dir}:{current_path}" + os.environ["PATH"] = new_path -if __name__ == '__main__': - main() +update_path() +exit(run.main()) diff -u linux-6.2.0/debian/scripts/misc/gen-auto-reconstruct linux-6.2.0/debian/scripts/misc/gen-auto-reconstruct --- linux-6.2.0/debian/scripts/misc/gen-auto-reconstruct +++ linux-6.2.0/debian/scripts/misc/gen-auto-reconstruct @@ -34,14 +34,6 @@ echo "[ ! -L '$name' ] && ln -sf '$link' '$name'" done - # Identify all removed files since the proffered tag. - echo "# Remove any files deleted from the orig." - git diff "$tag.." --raw --no-renames | awk '(/^:/ && $5 == "D") { print $NF }' | \ - while read name - do - echo "rm -f '$name'" - done - # Identify files with execute permissions added since the proffered tag. git diff "$tag.." --raw --no-renames | awk -F '[: \t]' '{print $2, $3, $NF }' | \ while IFS=" " read old new name @@ -53,12 +45,20 @@ added=$(( new & 0111 )) if [ "$added" -ne 0 ]; then echo "chmod +x '$name'" - else + elif [ "$new" -ne 0 ]; then echo "chmod -x '$name'" fi fi done + # Identify all removed files since the proffered tag. + echo "# Remove any files deleted from the orig." + git diff "$tag.." --raw --no-renames | awk '(/^:/ && $5 == "D") { print $NF }' | \ + while read name + do + echo "rm -f '$name'" + done + # All done, make sure this does not complete in error. echo "exit 0" ) >"$reconstruct" diff -u linux-6.2.0/debian/scripts/misc/git-ubuntu-log linux-6.2.0/debian/scripts/misc/git-ubuntu-log --- linux-6.2.0/debian/scripts/misc/git-ubuntu-log +++ linux-6.2.0/debian/scripts/misc/git-ubuntu-log @@ -120,7 +120,7 @@ try: # urllib.request.urlcleanup() request = urllib.request.Request('https://api.launchpad.net/devel/bugs/' + bug) - request.add_header('Cache-Control', 'max-age=0') + request.add_header('Cache-Control', 'no-cache') with urllib.request.urlopen(request) as response: data = response.read() bug_info = json.loads(data.decode('utf-8')) diff -u linux-6.2.0/debian/scripts/misc/kconfig/annotations.py linux-6.2.0/debian/scripts/misc/kconfig/annotations.py --- linux-6.2.0/debian/scripts/misc/kconfig/annotations.py +++ linux-6.2.0/debian/scripts/misc/kconfig/annotations.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python # -*- mode: python -*- # python module to manage Ubuntu kernel .config and annotations # Copyright © 2022 Canonical Ltd. @@ -12,26 +11,29 @@ from ast import literal_eval from os.path import dirname, abspath +from kconfig.version import ANNOTATIONS_FORMAT_VERSION -class Config(): - def __init__(self, fname): + +class Config: + def __init__(self, fname, do_include=True): """ Basic configuration file object """ self.fname = fname self.config = {} + self.do_include = do_include raw_data = self._load(fname) self._parse(raw_data) @staticmethod def _load(fname: str) -> str: - with open(fname, 'rt', encoding='utf-8') as fd: + with open(fname, "rt", encoding="utf-8") as fd: data = fd.read() return data.rstrip() def __str__(self): - """ Return a JSON representation of the config """ + """Return a JSON representation of the config""" return json.dumps(self.config, indent=4) @abstractmethod @@ -44,14 +46,15 @@ Parse a .config file, individual config options can be accessed via .config[] """ + def _parse(self, data: str): self.config = {} for line in data.splitlines(): - m = re.match(r'^# (CONFIG_.*) is not set$', line) + m = re.match(r"^# (CONFIG_.*) is not set$", line) if m: self.config[m.group(1)] = literal_eval("'n'") continue - m = re.match(r'^(CONFIG_[A-Za-z0-9_]+)=(.*)$', line) + m = re.match(r"^(CONFIG_[A-Za-z0-9_]+)=(.*)$", line) if m: self.config[m.group(1)] = literal_eval("'" + m.group(2) + "'") continue @@ -61,12 +64,13 @@ """ Parse body of annotations file """ + def _parse_body(self, data: str, parent=True): for line in data.splitlines(): # Replace tabs with spaces, squeeze multiple into singles and # remove leading and trailing spaces - line = line.replace('\t', ' ') - line = re.sub(r' +', ' ', line) + line = line.replace("\t", " ") + line = re.sub(r" +", " ", line) line = line.strip() # Ignore empty lines @@ -74,12 +78,12 @@ continue # Catpure flavors of included files - if line.startswith('# FLAVOUR: '): - self.include_flavour += line.split(' ')[2:] + if line.startswith("# FLAVOUR: "): + self.include_flavour += line.split(" ")[2:] continue # Ignore comments - if line.startswith('#'): + if line.startswith("#"): continue # Handle includes (recursively) @@ -87,46 +91,59 @@ if m: if parent: self.include.append(m.group(1)) - include_fname = dirname(abspath(self.fname)) + '/' + m.group(1) - include_data = self._load(include_fname) - self._parse_body(include_data, parent=False) + if self.do_include: + include_fname = dirname(abspath(self.fname)) + "/" + m.group(1) + include_data = self._load(include_fname) + self._parse_body(include_data, parent=False) continue # Handle policy and note lines - if re.match(r'.* (policy|note)<', line): + if re.match(r".* (policy|note)<", line): try: - conf = line.split(' ')[0] + conf = line.split(" ")[0] if conf in self.config: entry = self.config[conf] else: - entry = {'policy': {}} + entry = {"policy": {}} match = False - m = re.match(r'.* policy<(.*?)>', line) + m = re.match(r".* policy<(.*?)>", line) if m: match = True - try: - entry['policy'] |= literal_eval(m.group(1)) - except TypeError: - entry['policy'] = {**entry['policy'], **literal_eval(m.group(1))} + # Update the previous entry considering potential overrides: + # - if the new entry is adding a rule for a new + # arch/flavour, simply add that + # - if the new entry is overriding a previous + # arch-flavour item, then overwrite that item + # - if the new entry is overriding a whole arch, then + # remove all the previous flavour rules of that arch + new_entry = literal_eval(m.group(1)) + for key in new_entry: + if key in self.arch: + for flavour_key in list(entry["policy"].keys()): + if flavour_key.startswith(key): + del entry["policy"][flavour_key] + entry["policy"][key] = new_entry[key] + else: + entry["policy"][key] = new_entry[key] - m = re.match(r'.* note<(.*?)>', line) + m = re.match(r".* note<(.*?)>", line) if m: - entry['oneline'] = match + entry["oneline"] = match match = True - entry['note'] = "'" + m.group(1).replace("'", '') + "'" + entry["note"] = "'" + m.group(1).replace("'", "") + "'" if not match: - raise SyntaxError('syntax error') + raise SyntaxError("syntax error") self.config[conf] = entry except Exception as e: - raise SyntaxError(str(e) + f', line = {line}') from e + raise SyntaxError(str(e) + f", line = {line}") from e continue # Invalid line - raise SyntaxError(f'invalid line: {line}') + raise SyntaxError(f"invalid line: {line}") - def _parse(self, data: str): + def _legacy_parse(self, data: str): """ Parse main annotations file, individual config options can be accessed via self.config[] @@ -136,35 +153,86 @@ self.flavour = [] self.flavour_dep = {} self.include = [] - self.header = '' + self.header = "" self.include_flavour = [] # Parse header (only main header will considered, headers in includes # will be treated as comments) for line in data.splitlines(): - if re.match(r'^#.*', line): - m = re.match(r'^# ARCH: (.*)', line) + if re.match(r"^#.*", line): + m = re.match(r"^# ARCH: (.*)", line) if m: - self.arch = list(m.group(1).split(' ')) - m = re.match(r'^# FLAVOUR: (.*)', line) + self.arch = list(m.group(1).split(" ")) + m = re.match(r"^# FLAVOUR: (.*)", line) if m: - self.flavour = list(m.group(1).split(' ')) - m = re.match(r'^# FLAVOUR_DEP: (.*)', line) + self.flavour = list(m.group(1).split(" ")) + m = re.match(r"^# FLAVOUR_DEP: (.*)", line) if m: self.flavour_dep = literal_eval(m.group(1)) self.header += line + "\n" else: break - # Parse body (handle includes recursively) + # Return an error if architectures are not defined + if not self.arch: + raise SyntaxError("ARCH not defined in annotations") + # Return an error if flavours are not defined + if not self.flavour: + raise SyntaxError("FLAVOUR not defined in annotations") + + # Parse body self._parse_body(data) # Sanity check: Verify that all FLAVOUR_DEP flavors are valid - for src, tgt in self.flavour_dep.items(): - if src not in self.flavour: - raise SyntaxError(f'Invalid source flavour in FLAVOUR_DEP: {src}') - if tgt not in self.include_flavour: - raise SyntaxError(f'Invalid target flavour in FLAVOUR_DEP: {tgt}') + if self.do_include: + for src, tgt in self.flavour_dep.items(): + if src not in self.flavour: + raise SyntaxError(f"Invalid source flavour in FLAVOUR_DEP: {src}") + if tgt not in self.include_flavour: + raise SyntaxError(f"Invalid target flavour in FLAVOUR_DEP: {tgt}") + + def _json_parse(self, data, is_included=False): + data = json.loads(data) + + # Check if version is supported + version = data["attributes"]["_version"] + if version > ANNOTATIONS_FORMAT_VERSION: + raise SyntaxError(f"annotations format version {version} not supported") + + # Check for top-level annotations vs imported annotations + if not is_included: + self.config = data["config"] + self.arch = data["attributes"]["arch"] + self.flavour = data["attributes"]["flavour"] + self.flavour_dep = data["attributes"]["flavour_dep"] + self.include = data["attributes"]["include"] + self.include_flavour = [] + else: + # We are procesing an imported annotations, so merge all the + # configs and attributes. + try: + self.config = data["config"] | self.config + except TypeError: + self.config = {**self.config, **data["config"]} + self.arch = list(set(self.arch) | set(data["attributes"]["arch"])) + self.flavour = list(set(self.flavour) | set(data["attributes"]["flavour"])) + self.include_flavour = list(set(self.include_flavour) | set(data["attributes"]["flavour"])) + self.flavour_dep = self.flavour_dep | data["attributes"]["flavour_dep"] + + # Handle recursive inclusions + if self.do_include: + for f in data["attributes"]["include"]: + include_fname = dirname(abspath(self.fname)) + "/" + f + data = self._load(include_fname) + self._json_parse(data, is_included=True) + + def _parse(self, data: str): + # Try to parse the legacy format first, otherwise use the new JSON + # format. + try: + self._legacy_parse(data) + except SyntaxError: + self._json_parse(data, is_included=False) def _remove_entry(self, config: str): if self.config[config]: @@ -175,34 +243,40 @@ return if arch is not None: if flavour is not None: - flavour = f'{arch}-{flavour}' + flavour = f"{arch}-{flavour}" else: flavour = arch - del self.config[config]['policy'][flavour] - if not self.config[config]['policy']: + del self.config[config]["policy"][flavour] + if not self.config[config]["policy"]: self._remove_entry(config) else: self._remove_entry(config) - def set(self, config: str, arch: str = None, flavour: str = None, - value: str = None, note: str = None): + def set( + self, + config: str, + arch: str = None, + flavour: str = None, + value: str = None, + note: str = None, + ): if value is not None: if config not in self.config: - self.config[config] = {'policy': {}} + self.config[config] = {"policy": {}} if arch is not None: if flavour is not None: - flavour = f'{arch}-{flavour}' + flavour = f"{arch}-{flavour}" else: flavour = arch - self.config[config]['policy'][flavour] = value + self.config[config]["policy"][flavour] = value else: for a in self.arch: - self.config[config]['policy'][a] = value + self.config[config]["policy"][a] = value if note is not None: - self.config[config]['note'] = "'" + note.replace("'", '') + "'" + self.config[config]["note"] = "'" + note.replace("'", "") + "'" def update(self, c: KConfig, arch: str, flavour: str = None, configs: list = None): - """ Merge configs from a Kconfig object into Annotation object """ + """Merge configs from a Kconfig object into Annotation object""" # Determine if we need to import all configs or a single config if not configs: @@ -210,63 +284,75 @@ try: configs |= self.search_config(arch=arch, flavour=flavour).keys() except TypeError: - configs = {**configs, **self.search_config(arch=arch, flavour=flavour).keys()} + configs = { + **configs, + **self.search_config(arch=arch, flavour=flavour).keys(), + } # Import configs from the Kconfig object into Annotations + flavour_arg = flavour if flavour is not None: - flavour = arch + f'-{flavour}' + flavour = arch + f"-{flavour}" else: flavour = arch for conf in configs: if conf in c.config: val = c.config[conf] else: - val = '-' + val = "-" if conf in self.config: - if 'policy' in self.config[conf]: - self.config[conf]['policy'][flavour] = val + if "policy" in self.config[conf]: + # Add a TODO if a config with a note is changing and print + # a warning + old_val = self.search_config(config=conf, arch=arch, flavour=flavour_arg) + if old_val: + old_val = old_val[conf] + if val != old_val and "note" in self.config[conf]: + self.config[conf]["note"] = "TODO: update note" + print(f"WARNING: {conf} changed from {old_val} to {val}, updating note") + self.config[conf]["policy"][flavour] = val else: - self.config[conf]['policy'] = {flavour: val} + self.config[conf]["policy"] = {flavour: val} else: - self.config[conf] = {'policy': {flavour: val}} + self.config[conf] = {"policy": {flavour: val}} def _compact(self): # Try to remove redundant settings: if the config value of a flavour is # the same as the one of the main arch simply drop it. for conf in self.config.copy(): - if 'policy' not in self.config[conf]: + if "policy" not in self.config[conf]: continue for flavour in self.flavour: - if flavour not in self.config[conf]['policy']: + if flavour not in self.config[conf]["policy"]: continue - m = re.match(r'^(.*?)-(.*)$', flavour) + m = re.match(r"^(.*?)-(.*)$", flavour) if not m: continue arch = m.group(1) - if arch in self.config[conf]['policy']: - if self.config[conf]['policy'][flavour] == self.config[conf]['policy'][arch]: - del self.config[conf]['policy'][flavour] + if arch in self.config[conf]["policy"]: + if self.config[conf]["policy"][flavour] == self.config[conf]["policy"][arch]: + del self.config[conf]["policy"][flavour] continue if flavour not in self.flavour_dep: continue generic = self.flavour_dep[flavour] - if generic in self.config[conf]['policy']: - if self.config[conf]['policy'][flavour] == self.config[conf]['policy'][generic]: - del self.config[conf]['policy'][flavour] + if generic in self.config[conf]["policy"]: + if self.config[conf]["policy"][flavour] == self.config[conf]["policy"][generic]: + del self.config[conf]["policy"][flavour] continue # Remove rules for flavours / arches that are not supported (not # listed in the annotations header). - for flavour in self.config[conf]['policy'].copy(): + for flavour in self.config[conf]["policy"].copy(): if flavour not in list(set(self.arch + self.flavour)): - del self.config[conf]['policy'][flavour] + del self.config[conf]["policy"][flavour] # Remove configs that are all undefined across all arches/flavours # (unless we have includes) if not self.include: - if 'policy' in self.config[conf]: - if list(set(self.config[conf]['policy'].values())) == ['-']: - self.config[conf]['policy'] = {} + if "policy" in self.config[conf]: + if list(set(self.config[conf]["policy"].values())) == ["-"]: + self.config[conf]["policy"] = {} # Drop empty rules - if not self.config[conf]['policy']: + if not self.config[conf]["policy"]: del self.config[conf] else: # Compact same value across all flavour within the same arch @@ -274,16 +360,16 @@ arch_flavours = [i for i in self.flavour if i.startswith(arch)] value = None for flavour in arch_flavours: - if flavour not in self.config[conf]['policy']: + if flavour not in self.config[conf]["policy"]: break if value is None: - value = self.config[conf]['policy'][flavour] - elif value != self.config[conf]['policy'][flavour]: + value = self.config[conf]["policy"][flavour] + elif value != self.config[conf]["policy"][flavour]: break else: for flavour in arch_flavours: - del self.config[conf]['policy'][flavour] - self.config[conf]['policy'][arch] = value + del self.config[conf]["policy"][flavour] + self.config[conf]["policy"][arch] = value # After the first round of compaction we may end up having configs that # are undefined across all arches, so do another round of compaction to # drop these settings that are not needed anymore @@ -291,34 +377,34 @@ if not self.include: for conf in self.config.copy(): # Remove configs that are all undefined across all arches/flavours - if 'policy' in self.config[conf]: - if list(set(self.config[conf]['policy'].values())) == ['-']: - self.config[conf]['policy'] = {} + if "policy" in self.config[conf]: + if list(set(self.config[conf]["policy"].values())) == ["-"]: + self.config[conf]["policy"] = {} # Drop empty rules - if not self.config[conf]['policy']: + if not self.config[conf]["policy"]: del self.config[conf] @staticmethod def _sorted(config): - """ Sort configs alphabetically but return configs with a note first """ + """Sort configs alphabetically but return configs with a note first""" w_note = [] wo_note = [] for c in sorted(config): - if 'note' in config[c]: + if "note" in config[c]: w_note.append(c) else: wo_note.append(c) return w_note + wo_note def save(self, fname: str): - """ Save annotations data to the annotation file """ + """Save annotations data to the annotation file""" # Compact annotations structure self._compact() # Save annotations to disk - with tempfile.NamedTemporaryFile(mode='w+t', delete=False) as tmp: + with tempfile.NamedTemporaryFile(mode="w+t", delete=False) as tmp: # Write header - tmp.write(self.header + '\n') + tmp.write(self.header + "\n") # Write includes for i in self.include: @@ -335,40 +421,43 @@ marker = False for conf in self._sorted(self.config): new_val = self.config[conf] - if 'policy' not in new_val: + if "policy" not in new_val: continue # If new_val is a subset of old_val, skip it unless there are # new notes that are different than the old ones. old_val = tmp_a.config.get(conf) - if old_val and 'policy' in old_val: + if old_val and "policy" in old_val: try: - can_skip = old_val['policy'] == old_val['policy'] | new_val['policy'] + can_skip = old_val["policy"] == old_val["policy"] | new_val["policy"] except TypeError: - can_skip = old_val['policy'] == {**old_val['policy'], **new_val['policy']} + can_skip = old_val["policy"] == { + **old_val["policy"], + **new_val["policy"], + } if can_skip: - if 'note' not in new_val: + if "note" not in new_val: continue - if 'note' in old_val and 'note' in new_val: - if old_val['note'] == new_val['note']: + if "note" in old_val and "note" in new_val: + if old_val["note"] == new_val["note"]: continue # Write out the policy (and note) line(s) - val = dict(sorted(new_val['policy'].items())) + val = dict(sorted(new_val["policy"].items())) line = f"{conf : <47} policy<{val}>" - if 'note' in new_val: - val = new_val['note'] - if new_val.get('oneline', False): + if "note" in new_val: + val = new_val["note"] + if new_val.get("oneline", False): # Single line - line += f' note<{val}>' + line += f" note<{val}>" else: # Separate policy and note lines, # followed by an empty line - line += f'\n{conf : <47} note<{val}>\n' + line += f"\n{conf : <47} note<{val}>\n" elif not marker: # Write out a marker indicating the start of annotations # without notes - tmp.write('\n# ---- Annotations without notes ----\n\n') + tmp.write("\n# ---- Annotations without notes ----\n\n") marker = True tmp.write(line + "\n") @@ -377,10 +466,10 @@ shutil.move(tmp.name, fname) def search_config(self, config: str = None, arch: str = None, flavour: str = None) -> dict: - """ Return config value of a specific config option or architecture """ + """Return config value of a specific config option or architecture""" if flavour is None: - flavour = 'generic' - flavour = f'{arch}-{flavour}' + flavour = "generic" + flavour = f"{arch}-{flavour}" if flavour in self.flavour_dep: generic = self.flavour_dep[flavour] else: @@ -392,14 +481,14 @@ # Get config options of a specific architecture ret = {} for c, val in self.config.items(): - if 'policy' not in val: + if "policy" not in val: continue - if flavour in val['policy']: - ret[c] = val['policy'][flavour] - elif generic != flavour and generic in val['policy']: - ret[c] = val['policy'][generic] - elif arch in val['policy']: - ret[c] = val['policy'][arch] + if flavour in val["policy"]: + ret[c] = val["policy"][flavour] + elif generic != flavour and generic in val["policy"]: + ret[c] = val["policy"][generic] + elif arch in val["policy"]: + ret[c] = val["policy"][arch] return ret if config is not None and arch is None: # Get a specific config option for all architectures @@ -407,24 +496,24 @@ if config is not None and arch is not None: # Get a specific config option for a specific architecture if config in self.config: - if 'policy' in self.config[config]: - if flavour in self.config[config]['policy']: - return {config: self.config[config]['policy'][flavour]} - if generic != flavour and generic in self.config[config]['policy']: - return {config: self.config[config]['policy'][generic]} - if arch in self.config[config]['policy']: - return {config: self.config[config]['policy'][arch]} + if "policy" in self.config[config]: + if flavour in self.config[config]["policy"]: + return {config: self.config[config]["policy"][flavour]} + if generic != flavour and generic in self.config[config]["policy"]: + return {config: self.config[config]["policy"][generic]} + if arch in self.config[config]["policy"]: + return {config: self.config[config]["policy"][arch]} return None @staticmethod def to_config(data: dict) -> str: - """ Convert annotations data to .config format """ - s = '' + """Convert annotations data to .config format""" + s = "" for c in data: v = data[c] - if v == 'n': + if v == "n": s += f"# {c} is not set\n" - elif v == '-': + elif v == "-": pass else: s += f"{c}={v}\n" diff -u linux-6.2.0/drivers/acpi/arm64/iort.c linux-6.2.0/drivers/acpi/arm64/iort.c --- linux-6.2.0/drivers/acpi/arm64/iort.c +++ linux-6.2.0/drivers/acpi/arm64/iort.c @@ -1707,7 +1707,10 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = { /* HiSilicon Hip08 Platform */ {"HISI ", "HIP08 ", 0, ACPI_SIG_IORT, greater_than_or_equal, - "Erratum #162001800", IORT_SMMU_V3_PMCG_HISI_HIP08}, + "Erratum #162001800, Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP08}, + /* HiSilicon Hip09 Platform */ + {"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal, + "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, { } }; diff -u linux-6.2.0/drivers/acpi/video_detect.c linux-6.2.0/drivers/acpi/video_detect.c --- linux-6.2.0/drivers/acpi/video_detect.c +++ linux-6.2.0/drivers/acpi/video_detect.c @@ -446,6 +446,15 @@ }, }, { + /* https://bugzilla.suse.com/show_bug.cgi?id=1208724 */ + .callback = video_detect_force_native, + /* Lenovo Ideapad Z470 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_VERSION, "IdeaPad Z470"), + }, + }, + { /* https://bugzilla.redhat.com/show_bug.cgi?id=1187004 */ .callback = video_detect_force_native, /* Lenovo Ideapad Z570 */ diff -u linux-6.2.0/drivers/acpi/x86/s2idle.c linux-6.2.0/drivers/acpi/x86/s2idle.c --- linux-6.2.0/drivers/acpi/x86/s2idle.c +++ linux-6.2.0/drivers/acpi/x86/s2idle.c @@ -112,6 +112,12 @@ union acpi_object *package = &out_obj->package.elements[i]; if (package->type == ACPI_TYPE_PACKAGE) { + if (lpi_constraints_table) { + acpi_handle_err(lps0_device_handle, + "Duplicate constraints list\n"); + goto free_acpi_buffer; + } + lpi_constraints_table = kcalloc(package->package.count, sizeof(*lpi_constraints_table), GFP_KERNEL); @@ -122,17 +128,16 @@ acpi_handle_debug(lps0_device_handle, "LPI: constraints list begin:\n"); - for (j = 0; j < package->package.count; ++j) { + for (j = 0; j < package->package.count; j++) { union acpi_object *info_obj = &package->package.elements[j]; struct lpi_device_constraint_amd dev_info = {}; struct lpi_constraints *list; acpi_status status; - for (k = 0; k < info_obj->package.count; ++k) { - union acpi_object *obj = &info_obj->package.elements[k]; + list = &lpi_constraints_table[lpi_constraints_table_size]; - list = &lpi_constraints_table[lpi_constraints_table_size]; - list->min_dstate = -1; + for (k = 0; k < info_obj->package.count; k++) { + union acpi_object *obj = &info_obj->package.elements[k]; switch (k) { case 0: @@ -148,27 +153,21 @@ dev_info.min_dstate = obj->integer.value; break; } - - if (!dev_info.enabled || !dev_info.name || - !dev_info.min_dstate) - continue; - - status = acpi_get_handle(NULL, dev_info.name, - &list->handle); - if (ACPI_FAILURE(status)) - continue; - - acpi_handle_debug(lps0_device_handle, - "Name:%s\n", dev_info.name); - - list->min_dstate = dev_info.min_dstate; - - if (list->min_dstate < 0) { - acpi_handle_debug(lps0_device_handle, - "Incomplete constraint defined\n"); - continue; - } } + + if (!dev_info.enabled || !dev_info.name || + !dev_info.min_dstate) + continue; + + status = acpi_get_handle(NULL, dev_info.name, &list->handle); + if (ACPI_FAILURE(status)) + continue; + + acpi_handle_debug(lps0_device_handle, + "Name:%s\n", dev_info.name); + + list->min_dstate = dev_info.min_dstate; + lpi_constraints_table_size++; } } @@ -213,7 +212,7 @@ if (!package) continue; - for (j = 0; j < package->package.count; ++j) { + for (j = 0; j < package->package.count; j++) { union acpi_object *element = &(package->package.elements[j]); @@ -245,7 +244,7 @@ constraint->min_dstate = -1; - for (j = 0; j < package_count; ++j) { + for (j = 0; j < package_count; j++) { union acpi_object *info_obj = &info.package[j]; union acpi_object *cnstr_pkg; union acpi_object *obj; diff -u linux-6.2.0/drivers/ata/ahci.c linux-6.2.0/drivers/ata/ahci.c --- linux-6.2.0/drivers/ata/ahci.c +++ linux-6.2.0/drivers/ata/ahci.c @@ -421,6 +421,9 @@ { PCI_VDEVICE(INTEL, 0x34d3), board_ahci_low_power }, /* Ice Lake LP AHCI */ { PCI_VDEVICE(INTEL, 0x02d3), board_ahci_low_power }, /* Comet Lake PCH-U AHCI */ { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */ + /* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */ + { PCI_VDEVICE(INTEL, 0x4b63), board_ahci_low_power }, /* Elkhart Lake AHCI */ + { PCI_VDEVICE(INTEL, 0x7ae2), board_ahci_low_power }, /* Alder Lake-P AHCI */ /* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, @@ -1881,6 +1884,15 @@ else dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n"); + if (!(hpriv->cap & HOST_CAP_PART)) + host->flags |= ATA_HOST_NO_PART; + + if (!(hpriv->cap & HOST_CAP_SSC)) + host->flags |= ATA_HOST_NO_SSC; + + if (!(hpriv->cap2 & HOST_CAP2_SDS)) + host->flags |= ATA_HOST_NO_DEVSLP; + if (pi.flags & ATA_FLAG_EM) ahci_reset_em(host); diff -u linux-6.2.0/drivers/ata/libata-core.c linux-6.2.0/drivers/ata/libata-core.c --- linux-6.2.0/drivers/ata/libata-core.c +++ linux-6.2.0/drivers/ata/libata-core.c @@ -4982,17 +4982,19 @@ struct ata_link *link; unsigned long flags; - /* Previous resume operation might still be in - * progress. Wait for PM_PENDING to clear. + spin_lock_irqsave(ap->lock, flags); + + /* + * A previous PM operation might still be in progress. Wait for + * ATA_PFLAG_PM_PENDING to clear. */ if (ap->pflags & ATA_PFLAG_PM_PENDING) { + spin_unlock_irqrestore(ap->lock, flags); ata_port_wait_eh(ap); - WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); + spin_lock_irqsave(ap->lock, flags); } - /* request PM ops to EH */ - spin_lock_irqsave(ap->lock, flags); - + /* Request PM operation to EH */ ap->pm_mesg = mesg; ap->pflags |= ATA_PFLAG_PM_PENDING; ata_for_each_link(link, ap, HOST_FIRST) { @@ -5004,10 +5006,8 @@ spin_unlock_irqrestore(ap->lock, flags); - if (!async) { + if (!async) ata_port_wait_eh(ap); - WARN_ON(ap->pflags & ATA_PFLAG_PM_PENDING); - } } /* @@ -5023,11 +5023,27 @@ static void ata_port_suspend(struct ata_port *ap, pm_message_t mesg) { + /* + * We are about to suspend the port, so we do not care about + * scsi_rescan_device() calls scheduled by previous resume operations. + * The next resume will schedule the rescan again. So cancel any rescan + * that is not done yet. + */ + cancel_delayed_work_sync(&ap->scsi_rescan_task); + ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, false); } static void ata_port_suspend_async(struct ata_port *ap, pm_message_t mesg) { + /* + * We are about to suspend the port, so we do not care about + * scsi_rescan_device() calls scheduled by previous resume operations. + * The next resume will schedule the rescan again. So cancel any rescan + * that is not done yet. + */ + cancel_delayed_work_sync(&ap->scsi_rescan_task); + ata_port_request_pm(ap, mesg, 0, ata_port_suspend_ehi, true); } @@ -5174,7 +5190,7 @@ #endif const struct device_type ata_port_type = { - .name = "ata_port", + .name = ATA_PORT_TYPE_NAME, #ifdef CONFIG_PM .pm = &ata_port_pm_ops, #endif @@ -5907,11 +5923,30 @@ if (!ap->ops->error_handler) goto skip_eh; - /* tell EH we're leaving & flush EH */ + /* Wait for any ongoing EH */ + ata_port_wait_eh(ap); + + mutex_lock(&ap->scsi_scan_mutex); spin_lock_irqsave(ap->lock, flags); + + /* Remove scsi devices */ + ata_for_each_link(link, ap, HOST_FIRST) { + ata_for_each_dev(dev, link, ALL) { + if (dev->sdev) { + spin_unlock_irqrestore(ap->lock, flags); + scsi_remove_device(dev->sdev); + spin_lock_irqsave(ap->lock, flags); + dev->sdev = NULL; + } + } + } + + /* Tell EH to disable all devices */ ap->pflags |= ATA_PFLAG_UNLOADING; ata_port_schedule_eh(ap); + spin_unlock_irqrestore(ap->lock, flags); + mutex_unlock(&ap->scsi_scan_mutex); /* wait till EH commits suicide */ ata_port_wait_eh(ap); diff -u linux-6.2.0/drivers/ata/libata-eh.c linux-6.2.0/drivers/ata/libata-eh.c --- linux-6.2.0/drivers/ata/libata-eh.c +++ linux-6.2.0/drivers/ata/libata-eh.c @@ -2712,18 +2712,11 @@ } } - /* - * Some controllers can't be frozen very well and may set spurious - * error conditions during reset. Clear accumulated error - * information and re-thaw the port if frozen. As reset is the - * final recovery action and we cross check link onlineness against - * device classification later, no hotplug event is lost by this. - */ + /* clear cached SError */ spin_lock_irqsave(link->ap->lock, flags); - memset(&link->eh_info, 0, sizeof(link->eh_info)); + link->eh_info.serror = 0; if (slave) - memset(&slave->eh_info, 0, sizeof(link->eh_info)); - ap->pflags &= ~ATA_PFLAG_EH_PENDING; + slave->eh_info.serror = 0; spin_unlock_irqrestore(link->ap->lock, flags); if (ata_port_is_frozen(ap)) diff -u linux-6.2.0/drivers/ata/libata-scsi.c linux-6.2.0/drivers/ata/libata-scsi.c --- linux-6.2.0/drivers/ata/libata-scsi.c +++ linux-6.2.0/drivers/ata/libata-scsi.c @@ -1097,7 +1097,15 @@ } } else { sdev->sector_size = ata_id_logical_sector_size(dev->id); - sdev->manage_start_stop = 1; + /* + * Stop the drive on suspend but do not issue START STOP UNIT + * on resume as this is not necessary and may fail: the device + * will be woken up by ata_port_pm_resume() with a port reset + * and device revalidation. + */ + sdev->manage_system_start_stop = true; + sdev->manage_runtime_start_stop = true; + sdev->no_start_on_resume = 1; } /* @@ -1130,6 +1138,42 @@ } /** + * ata_scsi_slave_alloc - Early setup of SCSI device + * @sdev: SCSI device to examine + * + * This is called from scsi_alloc_sdev() when the scsi device + * associated with an ATA device is scanned on a port. + * + * LOCKING: + * Defined by SCSI layer. We don't really care. + */ + +int ata_scsi_slave_alloc(struct scsi_device *sdev) +{ + struct ata_port *ap = ata_shost_to_port(sdev->host); + struct device_link *link; + + ata_scsi_sdev_config(sdev); + + /* + * Create a link from the ata_port device to the scsi device to ensure + * that PM does suspend/resume in the correct order: the scsi device is + * consumer (child) and the ata port the supplier (parent). + */ + link = device_link_add(&sdev->sdev_gendev, &ap->tdev, + DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); + if (!link) { + ata_port_err(ap, "Failed to create link to scsi device %s\n", + dev_name(&sdev->sdev_gendev)); + return -ENODEV; + } + + return 0; +} +EXPORT_SYMBOL_GPL(ata_scsi_slave_alloc); + +/** * ata_scsi_slave_config - Set SCSI device attributes * @sdev: SCSI device to examine * @@ -1145,14 +1189,11 @@ { struct ata_port *ap = ata_shost_to_port(sdev->host); struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); - int rc = 0; - - ata_scsi_sdev_config(sdev); if (dev) - rc = ata_scsi_dev_config(sdev, dev); + return ata_scsi_dev_config(sdev, dev); - return rc; + return 0; } EXPORT_SYMBOL_GPL(ata_scsi_slave_config); @@ -1179,6 +1220,8 @@ if (!ap->ops->error_handler) return; + device_link_remove(&sdev->sdev_gendev, &ap->tdev); + spin_lock_irqsave(ap->lock, flags); dev = __ata_scsi_find_dev(ap, sdev); if (dev && dev->sdev) { @@ -4208,7 +4251,7 @@ break; case MAINTENANCE_IN: - if (scsicmd[1] == MI_REPORT_SUPPORTED_OPERATION_CODES) + if ((scsicmd[1] & 0x1f) == MI_REPORT_SUPPORTED_OPERATION_CODES) ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in); else ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); @@ -4621,7 +4664,7 @@ struct ata_link *link; struct ata_device *dev; unsigned long flags; - bool delay_rescan = false; + int ret = 0; mutex_lock(&ap->scsi_scan_mutex); spin_lock_irqsave(ap->lock, flags); @@ -4630,37 +4673,34 @@ ata_for_each_dev(dev, link, ENABLED) { struct scsi_device *sdev = dev->sdev; + /* + * If the port was suspended before this was scheduled, + * bail out. + */ + if (ap->pflags & ATA_PFLAG_SUSPENDED) + goto unlock; + if (!sdev) continue; if (scsi_device_get(sdev)) continue; - /* - * If the rescan work was scheduled because of a resume - * event, the port is already fully resumed, but the - * SCSI device may not yet be fully resumed. In such - * case, executing scsi_rescan_device() may cause a - * deadlock with the PM code on device_lock(). Prevent - * this by giving up and retrying rescan after a short - * delay. - */ - delay_rescan = sdev->sdev_gendev.power.is_suspended; - if (delay_rescan) { - scsi_device_put(sdev); - break; - } - spin_unlock_irqrestore(ap->lock, flags); - scsi_rescan_device(&(sdev->sdev_gendev)); + ret = scsi_rescan_device(sdev); scsi_device_put(sdev); spin_lock_irqsave(ap->lock, flags); + + if (ret) + goto unlock; } } +unlock: spin_unlock_irqrestore(ap->lock, flags); mutex_unlock(&ap->scsi_scan_mutex); - if (delay_rescan) + /* Reschedule with a delay if scsi_rescan_device() returned an error */ + if (ret) schedule_delayed_work(&ap->scsi_rescan_task, msecs_to_jiffies(5)); } diff -u linux-6.2.0/drivers/base/core.c linux-6.2.0/drivers/base/core.c --- linux-6.2.0/drivers/base/core.c +++ linux-6.2.0/drivers/base/core.c @@ -3817,6 +3817,17 @@ device_platform_notify_remove(dev); device_links_purge(dev); + /* + * If a device does not have a driver attached, we need to clean + * up any managed resources. We do this in device_release(), but + * it's never called (and we leak the device) if a managed + * resource holds a reference to the device. So release all + * managed resources here, like we do in driver_detach(). We + * still need to do so again in device_release() in case someone + * adds a new resource after this point, though. + */ + devres_release_all(dev); + if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_REMOVED_DEVICE, dev); diff -u linux-6.2.0/drivers/base/dd.c linux-6.2.0/drivers/base/dd.c --- linux-6.2.0/drivers/base/dd.c +++ linux-6.2.0/drivers/base/dd.c @@ -674,6 +674,8 @@ device_remove(dev); driver_sysfs_remove(dev); + if (dev->bus && dev->bus->dma_cleanup) + dev->bus->dma_cleanup(dev); device_unbind_cleanup(dev); goto re_probe; diff -u linux-6.2.0/drivers/block/null_blk/main.c linux-6.2.0/drivers/block/null_blk/main.c --- linux-6.2.0/drivers/block/null_blk/main.c +++ linux-6.2.0/drivers/block/null_blk/main.c @@ -1605,9 +1605,12 @@ struct nullb_queue *nq = hctx->driver_data; LIST_HEAD(list); int nr = 0; + struct request *rq; spin_lock(&nq->poll_lock); list_splice_init(&nq->poll_list, &list); + list_for_each_entry(rq, &list, queuelist) + blk_mq_set_request_complete(rq); spin_unlock(&nq->poll_lock); while (!list_empty(&list)) { @@ -1633,16 +1636,21 @@ struct blk_mq_hw_ctx *hctx = rq->mq_hctx; struct nullb_cmd *cmd = blk_mq_rq_to_pdu(rq); - pr_info("rq %p timed out\n", rq); - if (hctx->type == HCTX_TYPE_POLL) { struct nullb_queue *nq = hctx->driver_data; spin_lock(&nq->poll_lock); + /* The request may have completed meanwhile. */ + if (blk_mq_request_completed(rq)) { + spin_unlock(&nq->poll_lock); + return BLK_EH_DONE; + } list_del_init(&rq->queuelist); spin_unlock(&nq->poll_lock); } + pr_info("rq %p timed out\n", rq); + /* * If the device is marked as blocking (i.e. memory backed or zoned * device), the submission path may be blocked waiting for resources diff -u linux-6.2.0/drivers/block/rbd.c linux-6.2.0/drivers/block/rbd.c --- linux-6.2.0/drivers/block/rbd.c +++ linux-6.2.0/drivers/block/rbd.c @@ -632,9 +632,8 @@ static void rbd_dev_remove_parent(struct rbd_device *rbd_dev); static int rbd_dev_refresh(struct rbd_device *rbd_dev); -static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev); -static int rbd_dev_header_info(struct rbd_device *rbd_dev); -static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev); +static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, + struct rbd_image_header *header); static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, u64 snap_id); static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, @@ -995,15 +994,24 @@ RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); } +static void rbd_image_header_cleanup(struct rbd_image_header *header) +{ + kfree(header->object_prefix); + ceph_put_snap_context(header->snapc); + kfree(header->snap_sizes); + kfree(header->snap_names); + + memset(header, 0, sizeof(*header)); +} + /* * Fill an rbd image header with information from the given format 1 * on-disk header. */ -static int rbd_header_from_disk(struct rbd_device *rbd_dev, - struct rbd_image_header_ondisk *ondisk) +static int rbd_header_from_disk(struct rbd_image_header *header, + struct rbd_image_header_ondisk *ondisk, + bool first_time) { - struct rbd_image_header *header = &rbd_dev->header; - bool first_time = header->object_prefix == NULL; struct ceph_snap_context *snapc; char *object_prefix = NULL; char *snap_names = NULL; @@ -1070,11 +1078,6 @@ if (first_time) { header->object_prefix = object_prefix; header->obj_order = ondisk->options.order; - rbd_init_layout(rbd_dev); - } else { - ceph_put_snap_context(header->snapc); - kfree(header->snap_names); - kfree(header->snap_sizes); } /* The remaining fields always get updated (when we refresh) */ @@ -4860,7 +4863,9 @@ * return, the rbd_dev->header field will contain up-to-date * information about the image. */ -static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) +static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev, + struct rbd_image_header *header, + bool first_time) { struct rbd_image_header_ondisk *ondisk = NULL; u32 snap_count = 0; @@ -4908,7 +4913,7 @@ snap_count = le32_to_cpu(ondisk->snap_count); } while (snap_count != want_count); - ret = rbd_header_from_disk(rbd_dev, ondisk); + ret = rbd_header_from_disk(header, ondisk, first_time); out: kfree(ondisk); @@ -4932,39 +4937,6 @@ } } -static int rbd_dev_refresh(struct rbd_device *rbd_dev) -{ - u64 mapping_size; - int ret; - - down_write(&rbd_dev->header_rwsem); - mapping_size = rbd_dev->mapping.size; - - ret = rbd_dev_header_info(rbd_dev); - if (ret) - goto out; - - /* - * If there is a parent, see if it has disappeared due to the - * mapped image getting flattened. - */ - if (rbd_dev->parent) { - ret = rbd_dev_v2_parent_info(rbd_dev); - if (ret) - goto out; - } - - rbd_assert(!rbd_is_snap(rbd_dev)); - rbd_dev->mapping.size = rbd_dev->header.image_size; - -out: - up_write(&rbd_dev->header_rwsem); - if (!ret && mapping_size != rbd_dev->mapping.size) - rbd_dev_update_size(rbd_dev); - - return ret; -} - static const struct blk_mq_ops rbd_mq_ops = { .queue_rq = rbd_queue_rq, }; @@ -5504,17 +5476,12 @@ return 0; } -static int rbd_dev_v2_image_size(struct rbd_device *rbd_dev) -{ - return _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, - &rbd_dev->header.obj_order, - &rbd_dev->header.image_size); -} - -static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) +static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev, + char **pobject_prefix) { size_t size; void *reply_buf; + char *object_prefix; int ret; void *p; @@ -5532,16 +5499,16 @@ goto out; p = reply_buf; - rbd_dev->header.object_prefix = ceph_extract_encoded_string(&p, - p + ret, NULL, GFP_NOIO); + object_prefix = ceph_extract_encoded_string(&p, p + ret, NULL, + GFP_NOIO); + if (IS_ERR(object_prefix)) { + ret = PTR_ERR(object_prefix); + goto out; + } ret = 0; - if (IS_ERR(rbd_dev->header.object_prefix)) { - ret = PTR_ERR(rbd_dev->header.object_prefix); - rbd_dev->header.object_prefix = NULL; - } else { - dout(" object_prefix = %s\n", rbd_dev->header.object_prefix); - } + *pobject_prefix = object_prefix; + dout(" object_prefix = %s\n", object_prefix); out: kfree(reply_buf); @@ -5592,13 +5559,6 @@ return 0; } -static int rbd_dev_v2_features(struct rbd_device *rbd_dev) -{ - return _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, - rbd_is_ro(rbd_dev), - &rbd_dev->header.features); -} - /* * These are generic image flags, but since they are used only for * object map, store them in rbd_dev->object_map_flags. @@ -5635,6 +5595,14 @@ u64 overlap; }; +static void rbd_parent_info_cleanup(struct parent_image_info *pii) +{ + kfree(pii->pool_ns); + kfree(pii->image_id); + + memset(pii, 0, sizeof(*pii)); +} + /* * The caller is responsible for @pii. */ @@ -5704,6 +5672,9 @@ if (pii->has_overlap) ceph_decode_64_safe(&p, end, pii->overlap, e_inval); + dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", + __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, + pii->has_overlap, pii->overlap); return 0; e_inval: @@ -5742,14 +5713,17 @@ pii->has_overlap = true; ceph_decode_64_safe(&p, end, pii->overlap, e_inval); + dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", + __func__, pii->pool_id, pii->pool_ns, pii->image_id, pii->snap_id, + pii->has_overlap, pii->overlap); return 0; e_inval: return -EINVAL; } -static int get_parent_info(struct rbd_device *rbd_dev, - struct parent_image_info *pii) +static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev, + struct parent_image_info *pii) { struct page *req_page, *reply_page; void *p; @@ -5777,7 +5751,7 @@ return ret; } -static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) +static int rbd_dev_setup_parent(struct rbd_device *rbd_dev) { struct rbd_spec *parent_spec; struct parent_image_info pii = { 0 }; @@ -5787,37 +5761,12 @@ if (!parent_spec) return -ENOMEM; - ret = get_parent_info(rbd_dev, &pii); + ret = rbd_dev_v2_parent_info(rbd_dev, &pii); if (ret) goto out_err; - dout("%s pool_id %llu pool_ns %s image_id %s snap_id %llu has_overlap %d overlap %llu\n", - __func__, pii.pool_id, pii.pool_ns, pii.image_id, pii.snap_id, - pii.has_overlap, pii.overlap); - - if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) { - /* - * Either the parent never existed, or we have - * record of it but the image got flattened so it no - * longer has a parent. When the parent of a - * layered image disappears we immediately set the - * overlap to 0. The effect of this is that all new - * requests will be treated as if the image had no - * parent. - * - * If !pii.has_overlap, the parent image spec is not - * applicable. It's there to avoid duplication in each - * snapshot record. - */ - if (rbd_dev->parent_overlap) { - rbd_dev->parent_overlap = 0; - rbd_dev_parent_put(rbd_dev); - pr_info("%s: clone image has been flattened\n", - rbd_dev->disk->disk_name); - } - + if (pii.pool_id == CEPH_NOPOOL || !pii.has_overlap) goto out; /* No parent? No problem. */ - } /* The ceph file layout needs to fit pool id in 32 bits */ @@ -5829,58 +5778,46 @@ } /* - * The parent won't change (except when the clone is - * flattened, already handled that). So we only need to - * record the parent spec we have not already done so. + * The parent won't change except when the clone is flattened, + * so we only need to record the parent image spec once. */ - if (!rbd_dev->parent_spec) { - parent_spec->pool_id = pii.pool_id; - if (pii.pool_ns && *pii.pool_ns) { - parent_spec->pool_ns = pii.pool_ns; - pii.pool_ns = NULL; - } - parent_spec->image_id = pii.image_id; - pii.image_id = NULL; - parent_spec->snap_id = pii.snap_id; - - rbd_dev->parent_spec = parent_spec; - parent_spec = NULL; /* rbd_dev now owns this */ + parent_spec->pool_id = pii.pool_id; + if (pii.pool_ns && *pii.pool_ns) { + parent_spec->pool_ns = pii.pool_ns; + pii.pool_ns = NULL; } + parent_spec->image_id = pii.image_id; + pii.image_id = NULL; + parent_spec->snap_id = pii.snap_id; + + rbd_assert(!rbd_dev->parent_spec); + rbd_dev->parent_spec = parent_spec; + parent_spec = NULL; /* rbd_dev now owns this */ /* - * We always update the parent overlap. If it's zero we issue - * a warning, as we will proceed as if there was no parent. + * Record the parent overlap. If it's zero, issue a warning as + * we will proceed as if there is no parent. */ - if (!pii.overlap) { - if (parent_spec) { - /* refresh, careful to warn just once */ - if (rbd_dev->parent_overlap) - rbd_warn(rbd_dev, - "clone now standalone (overlap became 0)"); - } else { - /* initial probe */ - rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); - } - } + if (!pii.overlap) + rbd_warn(rbd_dev, "clone is standalone (overlap 0)"); rbd_dev->parent_overlap = pii.overlap; out: ret = 0; out_err: - kfree(pii.pool_ns); - kfree(pii.image_id); + rbd_parent_info_cleanup(&pii); rbd_spec_put(parent_spec); return ret; } -static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) +static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev, + u64 *stripe_unit, u64 *stripe_count) { struct { __le64 stripe_unit; __le64 stripe_count; } __attribute__ ((packed)) striping_info_buf = { 0 }; size_t size = sizeof (striping_info_buf); - void *p; int ret; ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, @@ -5892,27 +5829,33 @@ if (ret < size) return -ERANGE; - p = &striping_info_buf; - rbd_dev->header.stripe_unit = ceph_decode_64(&p); - rbd_dev->header.stripe_count = ceph_decode_64(&p); + *stripe_unit = le64_to_cpu(striping_info_buf.stripe_unit); + *stripe_count = le64_to_cpu(striping_info_buf.stripe_count); + dout(" stripe_unit = %llu stripe_count = %llu\n", *stripe_unit, + *stripe_count); + return 0; } -static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev) +static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev, s64 *data_pool_id) { - __le64 data_pool_id; + __le64 data_pool_buf; int ret; ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, &rbd_dev->header_oloc, "get_data_pool", - NULL, 0, &data_pool_id, sizeof(data_pool_id)); + NULL, 0, &data_pool_buf, + sizeof(data_pool_buf)); + dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) return ret; - if (ret < sizeof(data_pool_id)) + if (ret < sizeof(data_pool_buf)) return -EBADMSG; - rbd_dev->header.data_pool_id = le64_to_cpu(data_pool_id); - WARN_ON(rbd_dev->header.data_pool_id == CEPH_NOPOOL); + *data_pool_id = le64_to_cpu(data_pool_buf); + dout(" data_pool_id = %lld\n", *data_pool_id); + WARN_ON(*data_pool_id == CEPH_NOPOOL); + return 0; } @@ -6104,7 +6047,8 @@ return ret; } -static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) +static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev, + struct ceph_snap_context **psnapc) { size_t size; int ret; @@ -6165,9 +6109,7 @@ for (i = 0; i < snap_count; i++) snapc->snaps[i] = ceph_decode_64(&p); - ceph_put_snap_context(rbd_dev->header.snapc); - rbd_dev->header.snapc = snapc; - + *psnapc = snapc; dout(" snap context seq = %llu, snap_count = %u\n", (unsigned long long)seq, (unsigned int)snap_count); out: @@ -6216,38 +6158,42 @@ return snap_name; } -static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev) +static int rbd_dev_v2_header_info(struct rbd_device *rbd_dev, + struct rbd_image_header *header, + bool first_time) { - bool first_time = rbd_dev->header.object_prefix == NULL; int ret; - ret = rbd_dev_v2_image_size(rbd_dev); + ret = _rbd_dev_v2_snap_size(rbd_dev, CEPH_NOSNAP, + first_time ? &header->obj_order : NULL, + &header->image_size); if (ret) return ret; if (first_time) { - ret = rbd_dev_v2_header_onetime(rbd_dev); + ret = rbd_dev_v2_header_onetime(rbd_dev, header); if (ret) return ret; } - ret = rbd_dev_v2_snap_context(rbd_dev); - if (ret && first_time) { - kfree(rbd_dev->header.object_prefix); - rbd_dev->header.object_prefix = NULL; - } + ret = rbd_dev_v2_snap_context(rbd_dev, &header->snapc); + if (ret) + return ret; - return ret; + return 0; } -static int rbd_dev_header_info(struct rbd_device *rbd_dev) +static int rbd_dev_header_info(struct rbd_device *rbd_dev, + struct rbd_image_header *header, + bool first_time) { rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); + rbd_assert(!header->object_prefix && !header->snapc); if (rbd_dev->image_format == 1) - return rbd_dev_v1_header_info(rbd_dev); + return rbd_dev_v1_header_info(rbd_dev, header, first_time); - return rbd_dev_v2_header_info(rbd_dev); + return rbd_dev_v2_header_info(rbd_dev, header, first_time); } /* @@ -6735,60 +6681,49 @@ */ static void rbd_dev_unprobe(struct rbd_device *rbd_dev) { - struct rbd_image_header *header; - rbd_dev_parent_put(rbd_dev); rbd_object_map_free(rbd_dev); rbd_dev_mapping_clear(rbd_dev); /* Free dynamic fields from the header, then zero it out */ - header = &rbd_dev->header; - ceph_put_snap_context(header->snapc); - kfree(header->snap_sizes); - kfree(header->snap_names); - kfree(header->object_prefix); - memset(header, 0, sizeof (*header)); + rbd_image_header_cleanup(&rbd_dev->header); } -static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev) +static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev, + struct rbd_image_header *header) { int ret; - ret = rbd_dev_v2_object_prefix(rbd_dev); + ret = rbd_dev_v2_object_prefix(rbd_dev, &header->object_prefix); if (ret) - goto out_err; + return ret; /* * Get the and check features for the image. Currently the * features are assumed to never change. */ - ret = rbd_dev_v2_features(rbd_dev); + ret = _rbd_dev_v2_snap_features(rbd_dev, CEPH_NOSNAP, + rbd_is_ro(rbd_dev), &header->features); if (ret) - goto out_err; + return ret; /* If the image supports fancy striping, get its parameters */ - if (rbd_dev->header.features & RBD_FEATURE_STRIPINGV2) { - ret = rbd_dev_v2_striping_info(rbd_dev); - if (ret < 0) - goto out_err; + if (header->features & RBD_FEATURE_STRIPINGV2) { + ret = rbd_dev_v2_striping_info(rbd_dev, &header->stripe_unit, + &header->stripe_count); + if (ret) + return ret; } - if (rbd_dev->header.features & RBD_FEATURE_DATA_POOL) { - ret = rbd_dev_v2_data_pool(rbd_dev); + if (header->features & RBD_FEATURE_DATA_POOL) { + ret = rbd_dev_v2_data_pool(rbd_dev, &header->data_pool_id); if (ret) - goto out_err; + return ret; } - rbd_init_layout(rbd_dev); return 0; - -out_err: - rbd_dev->header.features = 0; - kfree(rbd_dev->header.object_prefix); - rbd_dev->header.object_prefix = NULL; - return ret; } /* @@ -6983,13 +6918,15 @@ if (!depth) down_write(&rbd_dev->header_rwsem); - ret = rbd_dev_header_info(rbd_dev); + ret = rbd_dev_header_info(rbd_dev, &rbd_dev->header, true); if (ret) { if (ret == -ENOENT && !need_watch) rbd_print_dne(rbd_dev, false); goto err_out_probe; } + rbd_init_layout(rbd_dev); + /* * If this image is the one being mapped, we have pool name and * id, image name and id, and snap name - need to fill snap id. @@ -7018,7 +6955,7 @@ } if (rbd_dev->header.features & RBD_FEATURE_LAYERING) { - ret = rbd_dev_v2_parent_info(rbd_dev); + ret = rbd_dev_setup_parent(rbd_dev); if (ret) goto err_out_probe; } @@ -7044,6 +6981,107 @@ return ret; } +static void rbd_dev_update_header(struct rbd_device *rbd_dev, + struct rbd_image_header *header) +{ + rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); + rbd_assert(rbd_dev->header.object_prefix); /* !first_time */ + + if (rbd_dev->header.image_size != header->image_size) { + rbd_dev->header.image_size = header->image_size; + + if (!rbd_is_snap(rbd_dev)) { + rbd_dev->mapping.size = header->image_size; + rbd_dev_update_size(rbd_dev); + } + } + + ceph_put_snap_context(rbd_dev->header.snapc); + rbd_dev->header.snapc = header->snapc; + header->snapc = NULL; + + if (rbd_dev->image_format == 1) { + kfree(rbd_dev->header.snap_names); + rbd_dev->header.snap_names = header->snap_names; + header->snap_names = NULL; + + kfree(rbd_dev->header.snap_sizes); + rbd_dev->header.snap_sizes = header->snap_sizes; + header->snap_sizes = NULL; + } +} + +static void rbd_dev_update_parent(struct rbd_device *rbd_dev, + struct parent_image_info *pii) +{ + if (pii->pool_id == CEPH_NOPOOL || !pii->has_overlap) { + /* + * Either the parent never existed, or we have + * record of it but the image got flattened so it no + * longer has a parent. When the parent of a + * layered image disappears we immediately set the + * overlap to 0. The effect of this is that all new + * requests will be treated as if the image had no + * parent. + * + * If !pii.has_overlap, the parent image spec is not + * applicable. It's there to avoid duplication in each + * snapshot record. + */ + if (rbd_dev->parent_overlap) { + rbd_dev->parent_overlap = 0; + rbd_dev_parent_put(rbd_dev); + pr_info("%s: clone has been flattened\n", + rbd_dev->disk->disk_name); + } + } else { + rbd_assert(rbd_dev->parent_spec); + + /* + * Update the parent overlap. If it became zero, issue + * a warning as we will proceed as if there is no parent. + */ + if (!pii->overlap && rbd_dev->parent_overlap) + rbd_warn(rbd_dev, + "clone has become standalone (overlap 0)"); + rbd_dev->parent_overlap = pii->overlap; + } +} + +static int rbd_dev_refresh(struct rbd_device *rbd_dev) +{ + struct rbd_image_header header = { 0 }; + struct parent_image_info pii = { 0 }; + int ret; + + dout("%s rbd_dev %p\n", __func__, rbd_dev); + + ret = rbd_dev_header_info(rbd_dev, &header, false); + if (ret) + goto out; + + /* + * If there is a parent, see if it has disappeared due to the + * mapped image getting flattened. + */ + if (rbd_dev->parent) { + ret = rbd_dev_v2_parent_info(rbd_dev, &pii); + if (ret) + goto out; + } + + down_write(&rbd_dev->header_rwsem); + rbd_dev_update_header(rbd_dev, &header); + if (rbd_dev->parent) + rbd_dev_update_parent(rbd_dev, &pii); + up_write(&rbd_dev->header_rwsem); + +out: + rbd_parent_info_cleanup(&pii); + rbd_image_header_cleanup(&header); + return ret; +} + static ssize_t do_rbd_add(struct bus_type *bus, const char *buf, size_t count) diff -u linux-6.2.0/drivers/bluetooth/btusb.c linux-6.2.0/drivers/bluetooth/btusb.c --- linux-6.2.0/drivers/bluetooth/btusb.c +++ linux-6.2.0/drivers/bluetooth/btusb.c @@ -2064,7 +2064,7 @@ * alternate setting. */ spin_lock_irqsave(&data->rxlock, flags); - kfree_skb(data->sco_skb); + dev_kfree_skb_irq(data->sco_skb); data->sco_skb = NULL; spin_unlock_irqrestore(&data->rxlock, flags); diff -u linux-6.2.0/drivers/bus/imx-weim.c linux-6.2.0/drivers/bus/imx-weim.c --- linux-6.2.0/drivers/bus/imx-weim.c +++ linux-6.2.0/drivers/bus/imx-weim.c @@ -331,6 +331,12 @@ "Failed to setup timing for '%pOF'\n", rd->dn); if (!of_node_check_flag(rd->dn, OF_POPULATED)) { + /* + * Clear the flag before adding the device so that + * fw_devlink doesn't skip adding consumers to this + * device. + */ + rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE; if (!of_platform_device_create(rd->dn, NULL, &pdev->dev)) { dev_err(&pdev->dev, "Failed to create child device '%pOF'\n", diff -u linux-6.2.0/drivers/bus/ti-sysc.c linux-6.2.0/drivers/bus/ti-sysc.c --- linux-6.2.0/drivers/bus/ti-sysc.c +++ linux-6.2.0/drivers/bus/ti-sysc.c @@ -38,6 +38,7 @@ SOC_2420, SOC_2430, SOC_3430, + SOC_AM35, SOC_3630, SOC_4430, SOC_4460, @@ -1119,6 +1120,11 @@ if (ddata->cfg.quirks & (SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_SWSUP_SIDLE_ACT)) { best_mode = SYSC_IDLE_NO; + + /* Clear WAKEUP */ + if (regbits->enwkup_shift >= 0 && + ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) + reg &= ~BIT(regbits->enwkup_shift); } else { best_mode = fls(ddata->cfg.sidlemodes) - 1; if (best_mode > SYSC_IDLE_MASK) { @@ -1246,6 +1252,13 @@ } } + if (ddata->cfg.quirks & SYSC_QUIRK_SWSUP_SIDLE_ACT) { + /* Set WAKEUP */ + if (regbits->enwkup_shift >= 0 && + ddata->cfg.sysc_val & BIT(regbits->enwkup_shift)) + reg |= BIT(regbits->enwkup_shift); + } + reg &= ~(SYSC_IDLE_MASK << regbits->sidle_shift); reg |= best_mode << regbits->sidle_shift; if (regbits->autoidle_shift >= 0 && @@ -1540,14 +1553,16 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = { /* These drivers need to be fixed to not use pm_runtime_irq_safe() */ SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000046, 0xffffffff, - SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x00000052, 0xffffffff, - SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), /* Uarts on omap4 and later */ SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x50411e03, 0xffff00ff, - SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47422e03, 0xffffffff, - SYSC_QUIRK_SWSUP_SIDLE | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), + SYSC_QUIRK("uart", 0, 0x50, 0x54, 0x58, 0x47424e03, 0xffffffff, + SYSC_QUIRK_SWSUP_SIDLE_ACT | SYSC_QUIRK_LEGACY_IDLE), /* Quirks that need to be set based on the module address */ SYSC_QUIRK("mcpdm", 0x40132000, 0, 0x10, -ENODEV, 0x50000800, 0xffffffff, @@ -1882,7 +1897,7 @@ dev_warn(ddata->dev, "%s: timed out %08x !+ %08x\n", __func__, val, irq_mask); - if (sysc_soc->soc == SOC_3430) { + if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) { /* Clear DSS_SDI_CONTROL */ sysc_write(ddata, 0x44, 0); @@ -2170,8 +2185,7 @@ } if (ddata->cfg.srst_udelay) - usleep_range(ddata->cfg.srst_udelay, - ddata->cfg.srst_udelay * 2); + fsleep(ddata->cfg.srst_udelay); if (ddata->post_reset_quirk) ddata->post_reset_quirk(ddata); @@ -3047,6 +3061,7 @@ static const struct soc_device_attribute sysc_soc_match[] = { SOC_FLAG("OMAP242*", SOC_2420), SOC_FLAG("OMAP243*", SOC_2430), + SOC_FLAG("AM35*", SOC_AM35), SOC_FLAG("OMAP3[45]*", SOC_3430), SOC_FLAG("OMAP3[67]*", SOC_3630), SOC_FLAG("OMAP443*", SOC_4430), @@ -3131,7 +3146,7 @@ match = soc_device_match(sysc_soc_match); if (match && match->data) - sysc_soc->soc = (int)match->data; + sysc_soc->soc = (enum sysc_soc)(uintptr_t)match->data; /* * Check and warn about possible old incomplete dtb. We now want to see @@ -3253,7 +3268,7 @@ * can be dropped if we stop supporting old beagleboard revisions * A to B4 at some point. */ - if (sysc_soc->soc == SOC_3430) + if (sysc_soc->soc == SOC_3430 || sysc_soc->soc == SOC_AM35) error = -ENXIO; else error = -EBUSY; diff -u linux-6.2.0/drivers/char/agp/parisc-agp.c linux-6.2.0/drivers/char/agp/parisc-agp.c --- linux-6.2.0/drivers/char/agp/parisc-agp.c +++ linux-6.2.0/drivers/char/agp/parisc-agp.c @@ -394,8 +394,6 @@ static int __init parisc_agp_init(void) { - extern struct sba_device *sba_list; - int err = -1; struct parisc_device *sba = NULL, *lba = NULL; struct lba_device *lbadev = NULL; diff -u linux-6.2.0/drivers/char/ipmi/ipmi_ssif.c linux-6.2.0/drivers/char/ipmi/ipmi_ssif.c --- linux-6.2.0/drivers/char/ipmi/ipmi_ssif.c +++ linux-6.2.0/drivers/char/ipmi/ipmi_ssif.c @@ -1412,7 +1412,7 @@ restart: list_for_each_entry(info, &ssif_infos, link) { if (info->binfo.addr == addr) { - if (info->addr_src == SI_SMBIOS) + if (info->addr_src == SI_SMBIOS && !info->adapter_name) info->adapter_name = kstrdup(adapter_name, GFP_KERNEL); @@ -1612,6 +1612,11 @@ info->addr_src = SI_ACPI; info->client = client; info->adapter_name = kstrdup(client->adapter->name, GFP_KERNEL); + if (!info->adapter_name) { + kfree(info); + return -ENOMEM; + } + info->binfo.addr = client->addr; list_add_tail(&info->link, &ssif_infos); return 0; diff -u linux-6.2.0/drivers/char/tpm/tpm_crb.c linux-6.2.0/drivers/char/tpm/tpm_crb.c --- linux-6.2.0/drivers/char/tpm/tpm_crb.c +++ linux-6.2.0/drivers/char/tpm/tpm_crb.c @@ -463,28 +463,6 @@ return (cancel & CRB_CANCEL_INVOKE) == CRB_CANCEL_INVOKE; } -static int crb_check_flags(struct tpm_chip *chip) -{ - u32 val; - int ret; - - ret = crb_request_locality(chip, 0); - if (ret) - return ret; - - ret = tpm2_get_tpm_pt(chip, TPM2_PT_MANUFACTURER, &val, NULL); - if (ret) - goto release; - - if (val == 0x414D4400U /* AMD */) - chip->flags |= TPM_CHIP_FLAG_HWRNG_DISABLED; - -release: - crb_relinquish_locality(chip, 0); - - return ret; -} - static const struct tpm_class_ops tpm_crb = { .flags = TPM_OPS_AUTO_STARTUP, .status = crb_status, @@ -797,12 +775,13 @@ FW_BUG "TPM2 ACPI table has wrong size %u for start method type %d\n", buf->header.length, ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON); - return -EINVAL; + rc = -EINVAL; + goto out; } crb_pluton = ACPI_ADD_PTR(struct tpm2_crb_pluton, buf, sizeof(*buf)); rc = crb_map_pluton(dev, priv, buf, crb_pluton); if (rc) - return rc; + goto out; } priv->sm = sm; @@ -826,9 +805,14 @@ if (rc) goto out; - rc = crb_check_flags(chip); - if (rc) - goto out; +#ifdef CONFIG_X86 + /* A quirk for https://www.amd.com/en/support/kb/faq/pa-410 */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + priv->sm != ACPI_TPM2_COMMAND_BUFFER_WITH_PLUTON) { + dev_info(dev, "Disabling hwrng\n"); + chip->flags |= TPM_CHIP_FLAG_HWRNG_DISABLED; + } +#endif /* CONFIG_X86 */ rc = tpm_chip_register(chip); diff -u linux-6.2.0/drivers/char/tpm/tpm_tis_core.c linux-6.2.0/drivers/char/tpm/tpm_tis_core.c --- linux-6.2.0/drivers/char/tpm/tpm_tis_core.c +++ linux-6.2.0/drivers/char/tpm/tpm_tis_core.c @@ -498,10 +498,17 @@ int rc; u32 ordinal; unsigned long dur; + unsigned int try; - rc = tpm_tis_send_data(chip, buf, len); - if (rc < 0) - return rc; + for (try = 0; try < TPM_RETRY; try++) { + rc = tpm_tis_send_data(chip, buf, len); + if (rc >= 0) + /* Data transfer done successfully */ + break; + else if (rc != -EIO) + /* Data transfer failed, not recoverable */ + return rc; + } rc = tpm_tis_verify_crc(priv, len, buf); if (rc < 0) { diff -u linux-6.2.0/drivers/clk/Kconfig linux-6.2.0/drivers/clk/Kconfig --- linux-6.2.0/drivers/clk/Kconfig +++ linux-6.2.0/drivers/clk/Kconfig @@ -427,6 +427,7 @@ config COMMON_CLK_FIXED_MMIO bool "Clock driver for Memory Mapped Fixed values" depends on COMMON_CLK && OF + depends on HAS_IOMEM help Support for Memory Mapped IO Fixed clocks diff -u linux-6.2.0/drivers/clk/imx/clk-imx8mp.c linux-6.2.0/drivers/clk/imx/clk-imx8mp.c --- linux-6.2.0/drivers/clk/imx/clk-imx8mp.c +++ linux-6.2.0/drivers/clk/imx/clk-imx8mp.c @@ -178,10 +178,6 @@ "video_pll1_out", "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", }; -static const char * const imx8mp_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", - "video_pll1_out", "sys_pll1_133m", "osc_hdmi", - "clk_ext1", "clk_ext2", }; - static const char * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", }; @@ -567,7 +563,6 @@ hws[IMX8MP_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mp_sai1_sels, ccm_base + 0xa580); hws[IMX8MP_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mp_sai2_sels, ccm_base + 0xa600); hws[IMX8MP_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mp_sai3_sels, ccm_base + 0xa680); - hws[IMX8MP_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mp_sai4_sels, ccm_base + 0xa700); hws[IMX8MP_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mp_sai5_sels, ccm_base + 0xa780); hws[IMX8MP_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mp_sai6_sels, ccm_base + 0xa800); hws[IMX8MP_CLK_ENET_QOS] = imx8m_clk_hw_composite("enet_qos", imx8mp_enet_qos_sels, ccm_base + 0xa880); diff -u linux-6.2.0/drivers/clk/imx/clk-imx8ulp.c linux-6.2.0/drivers/clk/imx/clk-imx8ulp.c --- linux-6.2.0/drivers/clk/imx/clk-imx8ulp.c +++ linux-6.2.0/drivers/clk/imx/clk-imx8ulp.c @@ -167,7 +167,7 @@ clks[IMX8ULP_CLK_SPLL2_PRE_SEL] = imx_clk_hw_mux_flags("spll2_pre_sel", base + 0x510, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); clks[IMX8ULP_CLK_SPLL3_PRE_SEL] = imx_clk_hw_mux_flags("spll3_pre_sel", base + 0x610, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE); - clks[IMX8ULP_CLK_SPLL2] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "spll2", "spll2_pre_sel", base + 0x500); + clks[IMX8ULP_CLK_SPLL2] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP_1GHZ, "spll2", "spll2_pre_sel", base + 0x500); clks[IMX8ULP_CLK_SPLL3] = imx_clk_hw_pllv4(IMX_PLLV4_IMX8ULP, "spll3", "spll3_pre_sel", base + 0x600); clks[IMX8ULP_CLK_SPLL3_VCODIV] = imx_clk_hw_divider("spll3_vcodiv", "spll3", base + 0x604, 0, 6); diff -u linux-6.2.0/drivers/clk/qcom/camcc-sc7180.c linux-6.2.0/drivers/clk/qcom/camcc-sc7180.c --- linux-6.2.0/drivers/clk/qcom/camcc-sc7180.c +++ linux-6.2.0/drivers/clk/qcom/camcc-sc7180.c @@ -1664,7 +1664,7 @@ return ret; } - ret = pm_runtime_get(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret) return ret; diff -u linux-6.2.0/drivers/clk/qcom/lpasscc-sc7280.c linux-6.2.0/drivers/clk/qcom/lpasscc-sc7280.c --- linux-6.2.0/drivers/clk/qcom/lpasscc-sc7280.c +++ linux-6.2.0/drivers/clk/qcom/lpasscc-sc7280.c @@ -115,9 +115,13 @@ ret = pm_clk_add(&pdev->dev, "iface"); if (ret < 0) { dev_err(&pdev->dev, "failed to acquire iface clock\n"); - goto destroy_pm_clk; + goto err_destroy_pm_clk; } + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + goto err_destroy_pm_clk; + if (!of_property_read_bool(pdev->dev.of_node, "qcom,adsp-pil-mode")) { lpass_regmap_config.name = "qdsp6ss"; lpass_regmap_config.max_register = 0x3f; @@ -125,7 +129,7 @@ ret = qcom_cc_probe_by_index(pdev, 0, desc); if (ret) - goto destroy_pm_clk; + goto err_put_rpm; } lpass_regmap_config.name = "top_cc"; @@ -134,11 +138,15 @@ ret = qcom_cc_probe_by_index(pdev, 1, desc); if (ret) - goto destroy_pm_clk; + goto err_put_rpm; + + pm_runtime_put(&pdev->dev); return 0; -destroy_pm_clk: +err_put_rpm: + pm_runtime_put_sync(&pdev->dev); +err_destroy_pm_clk: pm_clk_destroy(&pdev->dev); disable_pm_runtime: diff -u linux-6.2.0/drivers/cpufreq/cpufreq.c linux-6.2.0/drivers/cpufreq/cpufreq.c --- linux-6.2.0/drivers/cpufreq/cpufreq.c +++ linux-6.2.0/drivers/cpufreq/cpufreq.c @@ -450,8 +450,10 @@ policy->cur, policy->cpuinfo.max_freq); + spin_lock(&policy->transition_lock); policy->transition_ongoing = false; policy->transition_task = NULL; + spin_unlock(&policy->transition_lock); wake_up(&policy->transition_wait); } diff -u linux-6.2.0/drivers/cpufreq/intel_pstate.c linux-6.2.0/drivers/cpufreq/intel_pstate.c --- linux-6.2.0/drivers/cpufreq/intel_pstate.c +++ linux-6.2.0/drivers/cpufreq/intel_pstate.c @@ -2615,6 +2615,11 @@ intel_pstate_clear_update_util_hook(policy->cpu); intel_pstate_hwp_set(policy->cpu); } + /* + * policy->cur is never updated with the intel_pstate driver, but it + * is used as a stale frequency value. So, keep it within limits. + */ + policy->cur = policy->min; mutex_unlock(&intel_pstate_limits_lock); diff -u linux-6.2.0/drivers/dma/Kconfig linux-6.2.0/drivers/dma/Kconfig --- linux-6.2.0/drivers/dma/Kconfig +++ linux-6.2.0/drivers/dma/Kconfig @@ -211,6 +211,7 @@ config FSL_EDMA tristate "Freescale eDMA engine support" depends on OF + depends on HAS_IOMEM select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help @@ -280,6 +281,7 @@ config INTEL_IDMA64 tristate "Intel integrated DMA 64-bit support" + depends on HAS_IOMEM select DMA_ENGINE select DMA_VIRTUAL_CHANNELS help diff -u linux-6.2.0/drivers/dma/idxd/sysfs.c linux-6.2.0/drivers/dma/idxd/sysfs.c --- linux-6.2.0/drivers/dma/idxd/sysfs.c +++ linux-6.2.0/drivers/dma/idxd/sysfs.c @@ -1091,6 +1091,9 @@ if (wq->state != IDXD_WQ_DISABLED) return -EPERM; + if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags)) + return -EPERM; + if (!idxd->hw.wq_cap.wq_ats_support) return -EOPNOTSUPP; @@ -1426,7 +1429,7 @@ { struct idxd_device *idxd = confdev_to_idxd(dev); - return sysfs_emit(buf, "%u\n", device_pasid_enabled(idxd)); + return sysfs_emit(buf, "%u\n", device_user_pasid_enabled(idxd)); } static DEVICE_ATTR_RO(pasid_enabled); diff -u linux-6.2.0/drivers/firmware/arm_ffa/driver.c linux-6.2.0/drivers/firmware/arm_ffa/driver.c --- linux-6.2.0/drivers/firmware/arm_ffa/driver.c +++ linux-6.2.0/drivers/firmware/arm_ffa/driver.c @@ -397,6 +397,19 @@ return num_pages; } +static u8 ffa_memory_attributes_get(u32 func_id) +{ + /* + * For the memory lend or donate operation, if the receiver is a PE or + * a proxy endpoint, the owner/sender must not specify the attributes + */ + if (func_id == FFA_FN_NATIVE(MEM_LEND) || + func_id == FFA_MEM_LEND) + return 0; + + return FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | FFA_MEM_INNER_SHAREABLE; +} + static int ffa_setup_and_transmit(u32 func_id, void *buffer, u32 max_fragsize, struct ffa_mem_ops_args *args) @@ -413,8 +426,7 @@ mem_region->tag = args->tag; mem_region->flags = args->flags; mem_region->sender_id = drv_info->vm_id; - mem_region->attributes = FFA_MEM_NORMAL | FFA_MEM_WRITE_BACK | - FFA_MEM_INNER_SHAREABLE; + mem_region->attributes = ffa_memory_attributes_get(func_id); ep_mem_access = &mem_region->ep_mem_access[0]; for (idx = 0; idx < args->nattrs; idx++, ep_mem_access++) { diff -u linux-6.2.0/drivers/firmware/arm_sdei.c linux-6.2.0/drivers/firmware/arm_sdei.c --- linux-6.2.0/drivers/firmware/arm_sdei.c +++ linux-6.2.0/drivers/firmware/arm_sdei.c @@ -1097,0 +1098,19 @@ + +void sdei_handler_abort(void) +{ + /* + * If the crash happened in an SDEI event handler then we need to + * finish the handler with the firmware so that we can have working + * interrupts in the crash kernel. + */ + if (__this_cpu_read(sdei_active_critical_event)) { + pr_warn("still in SDEI critical event context, attempting to finish handler.\n"); + __sdei_handler_abort(); + __this_cpu_write(sdei_active_critical_event, NULL); + } + if (__this_cpu_read(sdei_active_normal_event)) { + pr_warn("still in SDEI normal event context, attempting to finish handler.\n"); + __sdei_handler_abort(); + __this_cpu_write(sdei_active_normal_event, NULL); + } +} diff -u linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu.h linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu.h --- linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1270,7 +1270,6 @@ void amdgpu_device_pci_config_reset(struct amdgpu_device *adev); int amdgpu_device_pci_reset(struct amdgpu_device *adev); bool amdgpu_device_need_post(struct amdgpu_device *adev); -bool amdgpu_sg_display_supported(struct amdgpu_device *adev); bool amdgpu_device_pcie_dynamic_switching_supported(void); bool amdgpu_device_should_use_aspm(struct amdgpu_device *adev); bool amdgpu_device_aspm_support_quirk(void); diff -u linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c --- linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -122,7 +122,6 @@ struct drm_gem_object *gobj; struct amdgpu_bo *bo; unsigned long size; - int r; gobj = drm_gem_object_lookup(p->filp, data->handle); if (gobj == NULL) @@ -134,23 +133,14 @@ drm_gem_object_put(gobj); size = amdgpu_bo_size(bo); - if (size != PAGE_SIZE || (data->offset + 8) > size) { - r = -EINVAL; - goto error_unref; - } + if (size != PAGE_SIZE || data->offset > (size - 8)) + return -EINVAL; - if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) { - r = -EINVAL; - goto error_unref; - } + if (amdgpu_ttm_tt_get_usermm(bo->tbo.ttm)) + return -EINVAL; *offset = data->offset; - return 0; - -error_unref: - amdgpu_bo_unref(&bo); - return r; } static int amdgpu_cs_p1_bo_handles(struct amdgpu_cs_parser *p, diff -u linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c --- linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1213,6 +1213,9 @@ u16 cmd; int r; + if (!IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT)) + return 0; + /* Bypass for VF */ if (amdgpu_sriov_vf(adev)) return 0; @@ -1335,32 +1338,6 @@ } /* - * On APUs with >= 64GB white flickering has been observed w/ SG enabled. - * Disable S/G on such systems until we have a proper fix. - * https://gitlab.freedesktop.org/drm/amd/-/issues/2354 - * https://gitlab.freedesktop.org/drm/amd/-/issues/2735 - */ -bool amdgpu_sg_display_supported(struct amdgpu_device *adev) -{ - switch (amdgpu_sg_display) { - case -1: - break; - case 0: - return false; - case 1: - return true; - default: - return false; - } - if ((totalram_pages() << (PAGE_SHIFT - 10)) + - (adev->gmc.real_vram_size / 1024) >= 64000000) { - DRM_WARN("Disabling S/G due to >=64GB RAM\n"); - return false; - } - return true; -} - -/* * Intel hosts such as Raptor Lake and Sapphire Rapids don't support dynamic * speed switching. Until we have confirmation from Intel that a specific host * supports it, it's safer that we keep it disabled for all. @@ -2213,7 +2190,7 @@ adev->flags |= AMD_IS_PX; if (!(adev->flags & AMD_IS_APU)) { - parent = pci_upstream_bridge(adev->pdev); + parent = pcie_find_root_port(adev->pdev); adev->has_pr3 = parent ? pci_pr3_present(parent) : false; } diff -u linux-6.2.0/drivers/gpu/drm/amd/amdgpu/soc21.c linux-6.2.0/drivers/gpu/drm/amd/amdgpu/soc21.c --- linux-6.2.0/drivers/gpu/drm/amd/amdgpu/soc21.c +++ linux-6.2.0/drivers/gpu/drm/amd/amdgpu/soc21.c @@ -847,7 +847,7 @@ * for the purpose of expose those registers * to process space */ - if (adev->nbio.funcs->remap_hdp_registers) + if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev)) adev->nbio.funcs->remap_hdp_registers(adev); /* enable the doorbell aperture */ soc21_enable_doorbell_aperture(adev, true); diff -u linux-6.2.0/drivers/gpu/drm/amd/amdkfd/kfd_priv.h linux-6.2.0/drivers/gpu/drm/amd/amdkfd/kfd_priv.h --- linux-6.2.0/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ linux-6.2.0/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -1347,9 +1347,8 @@ static inline bool kfd_flush_tlb_after_unmap(struct kfd_dev *dev) { - return KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 2) || - (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 1) && - dev->adev->sdma.instance[0].fw_version >= 18) || + return KFD_GC_VERSION(dev) > IP_VERSION(9, 4, 2) || + (KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 1) && dev->sdma_fw_version >= 18) || KFD_GC_VERSION(dev) == IP_VERSION(9, 4, 0); } diff -u linux-6.2.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c linux-6.2.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c --- linux-6.2.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1265,11 +1265,15 @@ pt_base = amdgpu_gmc_pd_addr(adev->gart.bo); - page_table_start.high_part = (u32)(adev->gmc.gart_start >> 44) & 0xF; - page_table_start.low_part = (u32)(adev->gmc.gart_start >> 12); - page_table_end.high_part = (u32)(adev->gmc.gart_end >> 44) & 0xF; - page_table_end.low_part = (u32)(adev->gmc.gart_end >> 12); - page_table_base.high_part = upper_32_bits(pt_base) & 0xF; + page_table_start.high_part = upper_32_bits(adev->gmc.gart_start >> + AMDGPU_GPU_PAGE_SHIFT); + page_table_start.low_part = lower_32_bits(adev->gmc.gart_start >> + AMDGPU_GPU_PAGE_SHIFT); + page_table_end.high_part = upper_32_bits(adev->gmc.gart_end >> + AMDGPU_GPU_PAGE_SHIFT); + page_table_end.low_part = lower_32_bits(adev->gmc.gart_end >> + AMDGPU_GPU_PAGE_SHIFT); + page_table_base.high_part = upper_32_bits(pt_base); page_table_base.low_part = lower_32_bits(pt_base); pa_config->system_aperture.start_addr = (uint64_t)logical_addr_low << 18; @@ -1635,8 +1639,9 @@ } break; } - if (init_data.flags.gpu_vm_support) - init_data.flags.gpu_vm_support = amdgpu_sg_display_supported(adev); + if (init_data.flags.gpu_vm_support && + (amdgpu_sg_display == 0)) + init_data.flags.gpu_vm_support = false; if (init_data.flags.gpu_vm_support) adev->mode_info.gpu_vm_support = true; @@ -2345,14 +2350,62 @@ return detect_mst_link_for_all_connectors(adev_to_drm(adev)); } +static void resume_mst_branch_status(struct drm_dp_mst_topology_mgr *mgr) +{ + int ret; + u8 guid[16]; + u64 tmp64; + + mutex_lock(&mgr->lock); + if (!mgr->mst_primary) + goto out_fail; + + if (drm_dp_read_dpcd_caps(mgr->aux, mgr->dpcd) < 0) { + drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n"); + goto out_fail; + } + + ret = drm_dp_dpcd_writeb(mgr->aux, DP_MSTM_CTRL, + DP_MST_EN | + DP_UP_REQ_EN | + DP_UPSTREAM_IS_SRC); + if (ret < 0) { + drm_dbg_kms(mgr->dev, "mst write failed - undocked during suspend?\n"); + goto out_fail; + } + + /* Some hubs forget their guids after they resume */ + ret = drm_dp_dpcd_read(mgr->aux, DP_GUID, guid, 16); + if (ret != 16) { + drm_dbg_kms(mgr->dev, "dpcd read failed - undocked during suspend?\n"); + goto out_fail; + } + + if (memchr_inv(guid, 0, 16) == NULL) { + tmp64 = get_jiffies_64(); + memcpy(&guid[0], &tmp64, sizeof(u64)); + memcpy(&guid[8], &tmp64, sizeof(u64)); + + ret = drm_dp_dpcd_write(mgr->aux, DP_GUID, guid, 16); + + if (ret != 16) { + drm_dbg_kms(mgr->dev, "check mstb guid failed - undocked during suspend?\n"); + goto out_fail; + } + } + + memcpy(mgr->mst_primary->guid, guid, 16); + +out_fail: + mutex_unlock(&mgr->lock); +} + static void s3_handle_mst(struct drm_device *dev, bool suspend) { struct amdgpu_dm_connector *aconnector; struct drm_connector *connector; struct drm_connector_list_iter iter; struct drm_dp_mst_topology_mgr *mgr; - int ret; - bool need_hotplug = false; drm_connector_list_iter_begin(dev, &iter); drm_for_each_connector_iter(connector, &iter) { @@ -2374,18 +2427,15 @@ if (!dp_is_lttpr_present(aconnector->dc_link)) dc_link_aux_try_to_configure_timeout(aconnector->dc_link->ddc, LINK_AUX_DEFAULT_TIMEOUT_PERIOD); - ret = drm_dp_mst_topology_mgr_resume(mgr, true); - if (ret < 0) { - dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx, - aconnector->dc_link); - need_hotplug = true; - } + /* TODO: move resume_mst_branch_status() into drm mst resume again + * once topology probing work is pulled out from mst resume into mst + * resume 2nd step. mst resume 2nd step should be called after old + * state getting restored (i.e. drm_atomic_helper_resume()). + */ + resume_mst_branch_status(mgr); } } drm_connector_list_iter_end(&iter); - - if (need_hotplug) - drm_kms_helper_hotplug_event(dev); } static int amdgpu_dm_smu_write_watermarks_table(struct amdgpu_device *adev) @@ -2774,7 +2824,8 @@ struct dm_atomic_state *dm_state = to_dm_atomic_state(dm->atomic_obj.state); enum dc_connection_type new_connection_type = dc_connection_none; struct dc_state *dc_state; - int i, r, j; + int i, r, j, ret; + bool need_hotplug = false; if (amdgpu_in_reset(adev)) { dc_state = dm->cached_dc_state; @@ -2872,7 +2923,7 @@ continue; /* - * this is the case when traversing through already created + * this is the case when traversing through already created end sink * MST connectors, should be skipped */ if (aconnector && aconnector->mst_port) @@ -2932,6 +2983,27 @@ dm->cached_state = NULL; + /* Do mst topology probing after resuming cached state*/ + drm_connector_list_iter_begin(ddev, &iter); + drm_for_each_connector_iter(connector, &iter) { + aconnector = to_amdgpu_dm_connector(connector); + if (aconnector->dc_link->type != dc_connection_mst_branch || + aconnector->mst_port) + continue; + + ret = drm_dp_mst_topology_mgr_resume(&aconnector->mst_mgr, true); + + if (ret < 0) { + dm_helpers_dp_mst_stop_top_mgr(aconnector->dc_link->ctx, + aconnector->dc_link); + need_hotplug = true; + } + } + drm_connector_list_iter_end(&iter); + + if (need_hotplug) + drm_kms_helper_hotplug_event(ddev); + amdgpu_dm_irq_resume_late(adev); amdgpu_dm_smu_write_watermarks_table(adev); @@ -5036,6 +5108,9 @@ if (plane->type == DRM_PLANE_TYPE_CURSOR) return; + if (new_plane_state->rotation != DRM_MODE_ROTATE_0) + goto ffu; + num_clips = drm_plane_get_damage_clips_count(new_plane_state); clips = drm_plane_get_damage_clips(new_plane_state); @@ -5928,8 +6003,7 @@ */ DRM_DEBUG_DRIVER("No preferred mode found\n"); } else { - recalculate_timing = amdgpu_freesync_vid_mode && - is_freesync_video_mode(&mode, aconnector); + recalculate_timing = is_freesync_video_mode(&mode, aconnector); if (recalculate_timing) { freesync_mode = get_highest_refresh_rate_mode(aconnector, false); drm_mode_copy(&saved_mode, &mode); @@ -7089,7 +7163,7 @@ struct amdgpu_dm_connector *amdgpu_dm_connector = to_amdgpu_dm_connector(connector); - if (!(amdgpu_freesync_vid_mode && edid)) + if (!edid) return; if (amdgpu_dm_connector->max_vfreq - amdgpu_dm_connector->min_vfreq > 10) @@ -7932,10 +8006,12 @@ * fast updates. */ if (crtc->state->async_flip && - acrtc_state->update_type != UPDATE_TYPE_FAST) + (acrtc_state->update_type != UPDATE_TYPE_FAST || + get_mem_type(old_plane_state->fb) != get_mem_type(fb))) drm_warn_once(state->dev, "[PLANE:%d:%s] async flip with non-fast update\n", plane->base.id, plane->name); + bundle->flip_addrs[planes_count].flip_immediate = crtc->state->async_flip && acrtc_state->update_type == UPDATE_TYPE_FAST && @@ -9098,8 +9174,7 @@ * TODO: Refactor this function to allow this check to work * in all conditions. */ - if (amdgpu_freesync_vid_mode && - dm_new_crtc_state->stream && + if (dm_new_crtc_state->stream && is_timing_unchanged_for_freesync(new_crtc_state, old_crtc_state)) goto skip_modeset; @@ -9139,7 +9214,7 @@ } /* Now check if we should set freesync video mode */ - if (amdgpu_freesync_vid_mode && dm_new_crtc_state->stream && + if (dm_new_crtc_state->stream && dc_is_stream_unchanged(new_stream, dm_old_crtc_state->stream) && dc_is_stream_scaling_unchanged(new_stream, dm_old_crtc_state->stream) && is_timing_unchanged_for_freesync(new_crtc_state, @@ -9152,7 +9227,7 @@ set_freesync_fixed_config(dm_new_crtc_state); goto skip_modeset; - } else if (amdgpu_freesync_vid_mode && aconnector && + } else if (aconnector && is_freesync_video_mode(&new_crtc_state->mode, aconnector)) { struct drm_display_mode *high_mode; @@ -9891,6 +9966,11 @@ /* Remove exiting planes if they are modified */ for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) { + if (old_plane_state->fb && new_plane_state->fb && + get_mem_type(old_plane_state->fb) != + get_mem_type(new_plane_state->fb)) + lock_and_validation_needed = true; + ret = dm_update_plane_state(dc, state, plane, old_plane_state, new_plane_state, @@ -10142,9 +10222,20 @@ struct dm_crtc_state *dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); + /* + * Only allow async flips for fast updates that don't change + * the FB pitch, the DCC state, rotation, etc. + */ + if (new_crtc_state->async_flip && lock_and_validation_needed) { + drm_dbg_atomic(crtc->dev, + "[CRTC:%d:%s] async flips are only supported for fast updates\n", + crtc->base.id, crtc->name); + ret = -EINVAL; + goto fail; + } + dm_new_crtc_state->update_type = lock_and_validation_needed ? - UPDATE_TYPE_FULL : - UPDATE_TYPE_FAST; + UPDATE_TYPE_FULL : UPDATE_TYPE_FAST; } /* Must be success */ diff -u linux-6.2.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c linux-6.2.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c --- linux-6.2.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -409,18 +409,6 @@ return -EINVAL; } - /* - * Only allow async flips for fast updates that don't change the FB - * pitch, the DCC state, rotation, etc. - */ - if (crtc_state->async_flip && - dm_crtc_state->update_type != UPDATE_TYPE_FAST) { - drm_dbg_atomic(crtc->dev, - "[CRTC:%d:%s] async flips are only supported for fast updates\n", - crtc->base.id, crtc->name); - return -EINVAL; - } - /* In some use cases, like reset, no stream is attached */ if (!dm_crtc_state->stream) return 0; diff -u linux-6.2.0/drivers/gpu/drm/amd/display/dc/core/dc.c linux-6.2.0/drivers/gpu/drm/amd/display/dc/core/dc.c --- linux-6.2.0/drivers/gpu/drm/amd/display/dc/core/dc.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -1978,12 +1978,12 @@ } } - /* Check for case where we are going from odm 2:1 to max - * pipe scenario. For these cases, we will call - * commit_minimal_transition_state() to exit out of odm 2:1 - * first before processing new streams + /* ODM Combine 2:1 power optimization is only applied for single stream + * scenario, it uses extra pipes than needed to reduce power consumption + * We need to switch off this feature to make room for new streams. */ - if (stream_count == dc->res_pool->pipe_count) { + if (stream_count > dc->current_state->stream_count && + dc->current_state->stream_count == 1) { for (i = 0; i < dc->res_pool->pipe_count; i++) { pipe = &dc->current_state->res_ctx.pipe_ctx[i]; if (pipe->next_odm_pipe) @@ -3362,6 +3362,45 @@ } } +static void wait_for_outstanding_hw_updates(struct dc *dc, const struct dc_state *dc_context) +{ +/* + * This function calls HWSS to wait for any potentially double buffered + * operations to complete. It should be invoked as a pre-amble prior + * to full update programming before asserting any HW locks. + */ + int pipe_idx; + int opp_inst; + int opp_count = dc->res_pool->pipe_count; + struct hubp *hubp; + int mpcc_inst; + const struct pipe_ctx *pipe_ctx; + + for (pipe_idx = 0; pipe_idx < dc->res_pool->pipe_count; pipe_idx++) { + pipe_ctx = &dc_context->res_ctx.pipe_ctx[pipe_idx]; + + if (!pipe_ctx->stream) + continue; + + if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear) + pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg); + + hubp = pipe_ctx->plane_res.hubp; + if (!hubp) + continue; + + mpcc_inst = hubp->inst; + // MPCC inst is equal to pipe index in practice + for (opp_inst = 0; opp_inst < opp_count; opp_inst++) { + if (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst]) { + dc->res_pool->mpc->funcs->wait_for_idle(dc->res_pool->mpc, mpcc_inst); + dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst] = false; + break; + } + } + } +} + static void commit_planes_for_stream(struct dc *dc, struct dc_surface_update *srf_updates, int surface_count, @@ -3379,24 +3418,9 @@ // dc->current_state anymore, so we have to cache it before we apply // the new SubVP context subvp_prev_use = false; - - dc_z10_restore(dc); - - if (update_type == UPDATE_TYPE_FULL) { - /* wait for all double-buffer activity to clear on all pipes */ - int pipe_idx; - - for (pipe_idx = 0; pipe_idx < dc->res_pool->pipe_count; pipe_idx++) { - struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[pipe_idx]; - - if (!pipe_ctx->stream) - continue; - - if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear) - pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg); - } - } + if (update_type == UPDATE_TYPE_FULL) + wait_for_outstanding_hw_updates(dc, context); if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) { /* Optimize seamless boot flag keeps clocks and watermarks high until diff -u linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c --- linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c @@ -3435,7 +3435,8 @@ .h_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.horz, .v_scale_ratio = pipe_ctx->plane_res.scl_data.ratios.vert, .rotation = pipe_ctx->plane_state->rotation, - .mirror = pipe_ctx->plane_state->horizontal_mirror + .mirror = pipe_ctx->plane_state->horizontal_mirror, + .stream = pipe_ctx->stream, }; bool pipe_split_on = false; bool odm_combine_on = (pipe_ctx->next_odm_pipe != NULL) || diff -u linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c --- linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c @@ -1551,17 +1551,6 @@ || plane_state->update_flags.bits.global_alpha_change || plane_state->update_flags.bits.per_pixel_alpha_change) { // MPCC inst is equal to pipe index in practice - int mpcc_inst = hubp->inst; - int opp_inst; - int opp_count = dc->res_pool->pipe_count; - - for (opp_inst = 0; opp_inst < opp_count; opp_inst++) { - if (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst]) { - dc->res_pool->mpc->funcs->wait_for_idle(dc->res_pool->mpc, mpcc_inst); - dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst] = false; - break; - } - } hws->funcs.update_mpcc(dc, pipe_ctx); } diff -u linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c --- linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c @@ -84,7 +84,8 @@ struct dcn_dccg *dccg_dcn, enum phyd32clk_clock_source src) { - if (dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { + if (dccg_dcn->base.ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && + dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { if (src == PHYD32CLKC) src = PHYD32CLKF; if (src == PHYD32CLKD) diff -u linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c --- linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c @@ -290,7 +290,8 @@ struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); /* set the dtbclk_p source */ - dccg32_set_dtbclk_p_src(dccg, src, otg_inst); + /* always program refclk as DTBCLK. No use-case expected to require DPREFCLK as refclk */ + dccg32_set_dtbclk_p_src(dccg, DTBCLK0, otg_inst); /* enabled to select one of the DTBCLKs for pipe */ switch (dp_hpo_inst) { diff -u linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c --- linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn31/display_mode_vba_31.c @@ -4132,7 +4132,9 @@ } if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN31_MAX_FMT_420_BUFFER_WIDTH && v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) { - if (v->HActive[k] / 2 > DCN31_MAX_FMT_420_BUFFER_WIDTH) { + if (v->Output[k] == dm_hdmi) { + FMTBufferExceeded = true; + } else if (v->HActive[k] / 2 > DCN31_MAX_FMT_420_BUFFER_WIDTH) { v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1; v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1; diff -u linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c --- linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c @@ -33,7 +33,7 @@ #include "dml/display_mode_vba.h" struct _vcs_dpi_ip_params_st dcn3_14_ip = { - .VBlankNomDefaultUS = 800, + .VBlankNomDefaultUS = 668, .gpuvm_enable = 1, .gpuvm_max_page_table_levels = 1, .hostvm_enable = 1, diff -u linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c --- linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn314/display_mode_vba_314.c @@ -4224,7 +4224,9 @@ } if (v->OutputFormat[k] == dm_420 && v->HActive[k] > DCN314_MAX_FMT_420_BUFFER_WIDTH && v->ODMCombineEnablePerState[i][k] != dm_odm_combine_mode_4to1) { - if (v->HActive[k] / 2 > DCN314_MAX_FMT_420_BUFFER_WIDTH) { + if (v->Output[k] == dm_hdmi) { + FMTBufferExceeded = true; + } else if (v->HActive[k] / 2 > DCN314_MAX_FMT_420_BUFFER_WIDTH) { v->ODMCombineEnablePerState[i][k] = dm_odm_combine_mode_4to1; v->PlaneRequiredDISPCLK = v->PlaneRequiredDISPCLKWithODMCombine4To1; diff -u linux-6.2.0/drivers/gpu/drm/amd/pm/amdgpu_pm.c linux-6.2.0/drivers/gpu/drm/amd/pm/amdgpu_pm.c --- linux-6.2.0/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ linux-6.2.0/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -2072,15 +2072,19 @@ uint32_t mask, struct list_head *attr_list) { int ret = 0; - struct device_attribute *dev_attr = &attr->dev_attr; - const char *name = dev_attr->attr.name; enum amdgpu_device_attr_states attr_states = ATTR_STATE_SUPPORTED; struct amdgpu_device_attr_entry *attr_entry; + struct device_attribute *dev_attr; + const char *name; int (*attr_update)(struct amdgpu_device *adev, struct amdgpu_device_attr *attr, uint32_t mask, enum amdgpu_device_attr_states *states) = default_attr_update; - BUG_ON(!attr); + if (!attr) + return -EINVAL; + + dev_attr = &attr->dev_attr; + name = dev_attr->attr.name; attr_update = attr->attr_update ? attr->attr_update : default_attr_update; diff -u linux-6.2.0/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c linux-6.2.0/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c --- linux-6.2.0/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ linux-6.2.0/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -2081,36 +2081,41 @@ return ret; } +#define MAX(a, b) ((a) > (b) ? (a) : (b)) + static int sienna_cichlid_update_pcie_parameters(struct smu_context *smu, uint32_t pcie_gen_cap, uint32_t pcie_width_cap) { struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; struct smu_11_0_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table; - u32 smu_pcie_arg; + uint8_t *table_member1, *table_member2; + uint32_t min_gen_speed, max_gen_speed; + uint32_t min_lane_width, max_lane_width; + uint32_t smu_pcie_arg; int ret, i; - /* PCIE gen speed and lane width override */ - if (!amdgpu_device_pcie_dynamic_switching_supported()) { - if (pcie_table->pcie_gen[NUM_LINK_LEVELS - 1] < pcie_gen_cap) - pcie_gen_cap = pcie_table->pcie_gen[NUM_LINK_LEVELS - 1]; + GET_PPTABLE_MEMBER(PcieGenSpeed, &table_member1); + GET_PPTABLE_MEMBER(PcieLaneCount, &table_member2); - if (pcie_table->pcie_lane[NUM_LINK_LEVELS - 1] < pcie_width_cap) - pcie_width_cap = pcie_table->pcie_lane[NUM_LINK_LEVELS - 1]; + min_gen_speed = MAX(0, table_member1[0]); + max_gen_speed = MIN(pcie_gen_cap, table_member1[1]); + min_gen_speed = min_gen_speed > max_gen_speed ? + max_gen_speed : min_gen_speed; + min_lane_width = MAX(1, table_member2[0]); + max_lane_width = MIN(pcie_width_cap, table_member2[1]); + min_lane_width = min_lane_width > max_lane_width ? + max_lane_width : min_lane_width; - /* Force all levels to use the same settings */ - for (i = 0; i < NUM_LINK_LEVELS; i++) { - pcie_table->pcie_gen[i] = pcie_gen_cap; - pcie_table->pcie_lane[i] = pcie_width_cap; - } + if (!amdgpu_device_pcie_dynamic_switching_supported()) { + pcie_table->pcie_gen[0] = max_gen_speed; + pcie_table->pcie_lane[0] = max_lane_width; } else { - for (i = 0; i < NUM_LINK_LEVELS; i++) { - if (pcie_table->pcie_gen[i] > pcie_gen_cap) - pcie_table->pcie_gen[i] = pcie_gen_cap; - if (pcie_table->pcie_lane[i] > pcie_width_cap) - pcie_table->pcie_lane[i] = pcie_width_cap; - } + pcie_table->pcie_gen[0] = min_gen_speed; + pcie_table->pcie_lane[0] = min_lane_width; } + pcie_table->pcie_gen[1] = max_gen_speed; + pcie_table->pcie_lane[1] = max_lane_width; for (i = 0; i < NUM_LINK_LEVELS; i++) { smu_pcie_arg = (i << 16 | diff -u linux-6.2.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c linux-6.2.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c --- linux-6.2.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ linux-6.2.0/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -1305,7 +1305,7 @@ gpu_metrics->average_vclk1_frequency = metrics->AverageVclk1Frequency; gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency; - gpu_metrics->current_gfxclk = metrics->CurrClock[PPCLK_GFXCLK]; + gpu_metrics->current_gfxclk = gpu_metrics->average_gfxclk_frequency; gpu_metrics->current_socclk = metrics->CurrClock[PPCLK_SOCCLK]; gpu_metrics->current_uclk = metrics->CurrClock[PPCLK_UCLK]; gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0]; diff -u linux-6.2.0/drivers/gpu/drm/bridge/analogix/anx7625.c linux-6.2.0/drivers/gpu/drm/bridge/analogix/anx7625.c --- linux-6.2.0/drivers/gpu/drm/bridge/analogix/anx7625.c +++ linux-6.2.0/drivers/gpu/drm/bridge/analogix/anx7625.c @@ -874,11 +874,11 @@ } /* Read downstream capability */ - ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_READ, 0x68028, 1, &bcap); + ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_READ, DP_AUX_HDCP_BCAPS, 1, &bcap); if (ret < 0) return ret; - if (!(bcap & 0x01)) { + if (!(bcap & DP_BCAPS_HDCP_CAPABLE)) { pr_warn("downstream not support HDCP 1.4, cap(%x).\n", bcap); return 0; } @@ -933,8 +933,8 @@ dev_dbg(dev, "set downstream sink into normal\n"); /* Downstream sink enter into normal mode */ - data = 1; - ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, 0x000600, 1, &data); + data = DP_SET_POWER_D0; + ret = anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, DP_SET_POWER, 1, &data); if (ret < 0) dev_err(dev, "IO error : set sink into normal mode fail\n"); @@ -973,8 +973,8 @@ dev_dbg(dev, "notify downstream enter into standby\n"); /* Downstream monitor enter into standby mode */ - data = 2; - ret |= anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, 0x000600, 1, &data); + data = DP_SET_POWER_D3; + ret |= anx7625_aux_trans(ctx, DP_AUX_NATIVE_WRITE, DP_SET_POWER, 1, &data); if (ret < 0) DRM_DEV_ERROR(dev, "IO error : mute video fail\n"); diff -u linux-6.2.0/drivers/gpu/drm/bridge/ti-sn65dsi83.c linux-6.2.0/drivers/gpu/drm/bridge/ti-sn65dsi83.c --- linux-6.2.0/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ linux-6.2.0/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -655,7 +655,9 @@ dsi->lanes = dsi_lanes; dsi->format = MIPI_DSI_FMT_RGB888; - dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST; + dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_VIDEO_NO_HFP | MIPI_DSI_MODE_VIDEO_NO_HBP | + MIPI_DSI_MODE_VIDEO_NO_HSA | MIPI_DSI_MODE_NO_EOT_PACKET; ret = devm_mipi_dsi_attach(dev, dsi); if (ret < 0) { diff -u linux-6.2.0/drivers/gpu/drm/drm_edid.c linux-6.2.0/drivers/gpu/drm/drm_edid.c --- linux-6.2.0/drivers/gpu/drm/drm_edid.c +++ linux-6.2.0/drivers/gpu/drm/drm_edid.c @@ -231,6 +231,7 @@ /* OSVR HDK and HDK2 VR Headsets */ EDID_QUIRK('S', 'V', 'R', 0x1019, EDID_QUIRK_NON_DESKTOP), + EDID_QUIRK('A', 'U', 'O', 0x1111, EDID_QUIRK_NON_DESKTOP), }; /* diff -u linux-6.2.0/drivers/gpu/drm/hyperv/hyperv_drm_drv.c linux-6.2.0/drivers/gpu/drm/hyperv/hyperv_drm_drv.c --- linux-6.2.0/drivers/gpu/drm/hyperv/hyperv_drm_drv.c +++ linux-6.2.0/drivers/gpu/drm/hyperv/hyperv_drm_drv.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff -u linux-6.2.0/drivers/gpu/drm/i915/gt/intel_engine_cs.c linux-6.2.0/drivers/gpu/drm/i915/gt/intel_engine_cs.c --- linux-6.2.0/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ linux-6.2.0/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -557,7 +557,6 @@ DRIVER_CAPS(i915)->has_logical_contexts = true; ewma__engine_latency_init(&engine->latency); - seqcount_init(&engine->stats.execlists.lock); ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier); diff -u linux-6.2.0/drivers/gpu/drm/i915/gt/intel_execlists_submission.c linux-6.2.0/drivers/gpu/drm/i915/gt/intel_execlists_submission.c --- linux-6.2.0/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ linux-6.2.0/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -3549,6 +3549,8 @@ logical_ring_default_vfuncs(engine); logical_ring_default_irqs(engine); + seqcount_init(&engine->stats.execlists.lock); + if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE) rcs_submission_override(engine); diff -u linux-6.2.0/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c linux-6.2.0/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c --- linux-6.2.0/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ linux-6.2.0/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -1401,6 +1401,36 @@ int srcu, ret; /* + * Ideally the busyness worker should take a gt pm wakeref because the + * worker only needs to be active while gt is awake. However, the + * gt_park path cancels the worker synchronously and this complicates + * the flow if the worker is also running at the same time. The cancel + * waits for the worker and when the worker releases the wakeref, that + * would call gt_park and would lead to a deadlock. + * + * The resolution is to take the global pm wakeref if runtime pm is + * already active. If not, we don't need to update the busyness stats as + * the stats would already be updated when the gt was parked. + * + * Note: + * - We do not requeue the worker if we cannot take a reference to runtime + * pm since intel_guc_busyness_unpark would requeue the worker in the + * resume path. + * + * - If the gt was parked longer than time taken for GT timestamp to roll + * over, we ignore those rollovers since we don't care about tracking + * the exact GT time. We only care about roll overs when the gt is + * active and running workloads. + * + * - There is a window of time between gt_park and runtime suspend, + * where the worker may run. This is acceptable since the worker will + * not find any new data to update busyness. + */ + wakeref = intel_runtime_pm_get_if_active(>->i915->runtime_pm); + if (!wakeref) + return; + + /* * Synchronize with gt reset to make sure the worker does not * corrupt the engine/guc stats. NB: can't actually block waiting * for a reset to complete as the reset requires flushing out @@ -1408,15 +1438,17 @@ */ ret = intel_gt_reset_trylock(gt, &srcu); if (ret) - return; + goto err_trylock; - with_intel_runtime_pm(>->i915->runtime_pm, wakeref) - __update_guc_busyness_stats(guc); + __update_guc_busyness_stats(guc); intel_gt_reset_unlock(gt, srcu); mod_delayed_work(system_highpri_wq, &guc->timestamp.work, guc->timestamp.ping_delay); + +err_trylock: + intel_runtime_pm_put(>->i915->runtime_pm, wakeref); } static int guc_action_enable_usage_stats(struct intel_guc *guc) @@ -5343,6 +5375,9 @@ ve->base.flags = I915_ENGINE_IS_VIRTUAL; + BUILD_BUG_ON(ilog2(VIRTUAL_ENGINES) < I915_NUM_ENGINES); + ve->base.mask = VIRTUAL_ENGINES; + intel_context_init(&ve->context, &ve->base); for (n = 0; n < count; n++) { diff -u linux-6.2.0/drivers/gpu/drm/i915/i915_request.c linux-6.2.0/drivers/gpu/drm/i915/i915_request.c --- linux-6.2.0/drivers/gpu/drm/i915/i915_request.c +++ linux-6.2.0/drivers/gpu/drm/i915/i915_request.c @@ -134,9 +134,7 @@ i915_sw_fence_fini(&rq->semaphore); /* - * Keep one request on each engine for reserved use under mempressure - * do not use with virtual engines as this really is only needed for - * kernel contexts. + * Keep one request on each engine for reserved use under mempressure. * * We do not hold a reference to the engine here and so have to be * very careful in what rq->engine we poke. The virtual engine is @@ -166,8 +164,7 @@ * know that if the rq->execution_mask is a single bit, rq->engine * can be a physical engine with the exact corresponding mask. */ - if (!intel_engine_is_virtual(rq->engine) && - is_power_of_2(rq->execution_mask) && + if (is_power_of_2(rq->execution_mask) && !cmpxchg(&rq->engine->request_pool, NULL, rq)) return; diff -u linux-6.2.0/drivers/gpu/drm/mediatek/mtk_dp.c linux-6.2.0/drivers/gpu/drm/mediatek/mtk_dp.c --- linux-6.2.0/drivers/gpu/drm/mediatek/mtk_dp.c +++ linux-6.2.0/drivers/gpu/drm/mediatek/mtk_dp.c @@ -847,7 +847,7 @@ u32 phy_status = mtk_dp_read(mtk_dp, MTK_DP_AUX_P0_3628) & AUX_RX_PHY_STATE_AUX_TX_P0_MASK; if (phy_status != AUX_RX_PHY_STATE_AUX_TX_P0_RX_IDLE) { - drm_err(mtk_dp->drm_dev, + dev_err(mtk_dp->dev, "AUX Rx Aux hang, need SW reset\n"); return -EIO; } @@ -1588,7 +1588,9 @@ u8 val; ssize_t ret; - drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap); + ret = drm_dp_read_dpcd_caps(&mtk_dp->aux, mtk_dp->rx_cap); + if (ret < 0) + return ret; if (drm_dp_tps4_supported(mtk_dp->rx_cap)) mtk_dp->train_info.channel_eq_pattern = DP_TRAINING_PATTERN_4; @@ -1615,10 +1617,13 @@ return ret == 0 ? -EIO : ret; } - if (val) - drm_dp_dpcd_writeb(&mtk_dp->aux, - DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, - val); + if (val) { + ret = drm_dp_dpcd_writeb(&mtk_dp->aux, + DP_DEVICE_SERVICE_IRQ_VECTOR_ESI0, + val); + if (ret < 0) + return ret; + } } return 0; @@ -2057,7 +2062,7 @@ is_read = true; break; default: - drm_err(mtk_aux->drm_dev, "invalid aux cmd = %d\n", + dev_err(mtk_dp->dev, "invalid aux cmd = %d\n", msg->request); ret = -EINVAL; goto err; @@ -2073,7 +2078,7 @@ to_access, &msg->reply); if (ret) { - drm_info(mtk_dp->drm_dev, + dev_info(mtk_dp->dev, "Failed to do AUX transfer: %d\n", ret); goto err; } diff -u linux-6.2.0/drivers/gpu/drm/mediatek/mtk_drm_crtc.c linux-6.2.0/drivers/gpu/drm/mediatek/mtk_drm_crtc.c --- linux-6.2.0/drivers/gpu/drm/mediatek/mtk_drm_crtc.c +++ linux-6.2.0/drivers/gpu/drm/mediatek/mtk_drm_crtc.c @@ -115,10 +115,9 @@ dma_addr_t dma_addr; pkt->va_base = kzalloc(size, GFP_KERNEL); - if (!pkt->va_base) { - kfree(pkt); + if (!pkt->va_base) return -ENOMEM; - } + pkt->buf_size = size; pkt->cl = (void *)client; @@ -128,7 +127,6 @@ if (dma_mapping_error(dev, dma_addr)) { dev_err(dev, "dma map failed, size=%u\n", (u32)(u64)size); kfree(pkt->va_base); - kfree(pkt); return -ENOMEM; } @@ -144,7 +142,6 @@ dma_unmap_single(client->chan->mbox->dev, pkt->pa_base, pkt->buf_size, DMA_TO_DEVICE); kfree(pkt->va_base); - kfree(pkt); } #endif diff -u linux-6.2.0/drivers/gpu/drm/mediatek/mtk_drm_gem.c linux-6.2.0/drivers/gpu/drm/mediatek/mtk_drm_gem.c --- linux-6.2.0/drivers/gpu/drm/mediatek/mtk_drm_gem.c +++ linux-6.2.0/drivers/gpu/drm/mediatek/mtk_drm_gem.c @@ -242,7 +242,11 @@ mtk_gem->kvaddr = vmap(mtk_gem->pages, npages, VM_MAP, pgprot_writecombine(PAGE_KERNEL)); - + if (!mtk_gem->kvaddr) { + kfree(sgt); + kfree(mtk_gem->pages); + return -ENOMEM; + } out: kfree(sgt); iosys_map_set_vaddr(map, mtk_gem->kvaddr); diff -u linux-6.2.0/drivers/gpu/drm/panel/panel-simple.c linux-6.2.0/drivers/gpu/drm/panel/panel-simple.c --- linux-6.2.0/drivers/gpu/drm/panel/panel-simple.c +++ linux-6.2.0/drivers/gpu/drm/panel/panel-simple.c @@ -1159,7 +1159,9 @@ .delay = { .disable = 5, .unprepare = 1000, - } + }, + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, + .connector_type = DRM_MODE_CONNECTOR_LVDS, }; static const struct drm_display_mode avic_tm070ddh03_mode = { diff -u linux-6.2.0/drivers/hid/hid-input.c linux-6.2.0/drivers/hid/hid-input.c --- linux-6.2.0/drivers/hid/hid-input.c +++ linux-6.2.0/drivers/hid/hid-input.c @@ -961,6 +961,7 @@ return; case 0x3c: /* Invert */ + device->quirks &= ~HID_QUIRK_NOINVERT; map_key_clear(BTN_TOOL_RUBBER); break; @@ -986,9 +987,13 @@ case 0x45: /* ERASER */ /* * This event is reported when eraser tip touches the surface. - * Actual eraser (BTN_TOOL_RUBBER) is set by Invert usage when - * tool gets in proximity. + * Actual eraser (BTN_TOOL_RUBBER) is set and released either + * by Invert if tool reports proximity or by Eraser directly. */ + if (!test_bit(BTN_TOOL_RUBBER, input->keybit)) { + device->quirks |= HID_QUIRK_NOINVERT; + set_bit(BTN_TOOL_RUBBER, input->keybit); + } map_key_clear(BTN_TOUCH); break; @@ -1536,6 +1541,15 @@ else if (report->tool != BTN_TOOL_RUBBER) /* value is off, tool is not rubber, ignore */ return; + else if (*quirks & HID_QUIRK_NOINVERT && + !test_bit(BTN_TOUCH, input->key)) { + /* + * There is no invert to release the tool, let hid_input + * send BTN_TOUCH with scancode and release the tool after. + */ + hid_report_release_tool(report, input, BTN_TOOL_RUBBER); + return; + } /* let hid-input set BTN_TOUCH */ break; diff -u linux-6.2.0/drivers/hid/hid-multitouch.c linux-6.2.0/drivers/hid/hid-multitouch.c --- linux-6.2.0/drivers/hid/hid-multitouch.c +++ linux-6.2.0/drivers/hid/hid-multitouch.c @@ -1594,7 +1594,6 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) { struct mt_device *td = hid_get_drvdata(hdev); - char *name; const char *suffix = NULL; struct mt_report_data *rdata; struct mt_application *mt_application = NULL; @@ -1645,15 +1644,9 @@ break; } - if (suffix) { - name = devm_kzalloc(&hi->input->dev, - strlen(hdev->name) + strlen(suffix) + 2, - GFP_KERNEL); - if (name) { - sprintf(name, "%s %s", hdev->name, suffix); - hi->input->name = name; - } - } + if (suffix) + hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, + "%s %s", hdev->name, suffix); return 0; } diff -u linux-6.2.0/drivers/hid/hid-uclogic-core.c linux-6.2.0/drivers/hid/hid-uclogic-core.c --- linux-6.2.0/drivers/hid/hid-uclogic-core.c +++ linux-6.2.0/drivers/hid/hid-uclogic-core.c @@ -85,10 +85,8 @@ { struct uclogic_drvdata *drvdata = hid_get_drvdata(hdev); struct uclogic_params *params = &drvdata->params; - char *name; const char *suffix = NULL; struct hid_field *field; - size_t len; size_t i; const struct uclogic_params_frame *frame; @@ -146,14 +144,9 @@ } } - if (suffix) { - len = strlen(hdev->name) + 2 + strlen(suffix); - name = devm_kzalloc(&hi->input->dev, len, GFP_KERNEL); - if (name) { - snprintf(name, len, "%s %s", hdev->name, suffix); - hi->input->name = name; - } - } + if (suffix) + hi->input->name = devm_kasprintf(&hdev->dev, GFP_KERNEL, + "%s %s", hdev->name, suffix); return 0; } diff -u linux-6.2.0/drivers/hid/intel-ish-hid/ipc/pci-ish.c linux-6.2.0/drivers/hid/intel-ish-hid/ipc/pci-ish.c --- linux-6.2.0/drivers/hid/intel-ish-hid/ipc/pci-ish.c +++ linux-6.2.0/drivers/hid/intel-ish-hid/ipc/pci-ish.c @@ -133,6 +133,14 @@ } wakeup = &adev->wakeup; + /* + * Call acpi_disable_gpe(), so that reference count + * gpe_event_info->runtime_count doesn't overflow. + * When gpe_event_info->runtime_count = 0, the call + * to acpi_disable_gpe() simply return. + */ + acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number); + acpi_sts = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); if (ACPI_FAILURE(acpi_sts)) { dev_err(dev, "enable ose_gpe failed\n"); diff -u linux-6.2.0/drivers/hv/vmbus_drv.c linux-6.2.0/drivers/hv/vmbus_drv.c --- linux-6.2.0/drivers/hv/vmbus_drv.c +++ linux-6.2.0/drivers/hv/vmbus_drv.c @@ -2472,7 +2472,8 @@ * Some ancestor of the vmbus acpi device (Gen1 or Gen2 * firmware) is the VMOD that has the mmio ranges. Get that. */ - for (ancestor = acpi_dev_parent(device); ancestor; + for (ancestor = acpi_dev_parent(device); + ancestor && ancestor->handle != ACPI_ROOT_OBJECT; ancestor = acpi_dev_parent(ancestor)) { result = acpi_walk_resources(ancestor->handle, METHOD_NAME__CRS, vmbus_walk_resources, NULL); diff -u linux-6.2.0/drivers/hwmon/tmp513.c linux-6.2.0/drivers/hwmon/tmp513.c --- linux-6.2.0/drivers/hwmon/tmp513.c +++ linux-6.2.0/drivers/hwmon/tmp513.c @@ -434,7 +434,7 @@ switch (type) { case hwmon_temp: - if (data->id == tmp512 && channel == 4) + if (data->id == tmp512 && channel == 3) return 0; switch (attr) { case hwmon_temp_input: diff -u linux-6.2.0/drivers/hwtracing/coresight/coresight-tmc-etr.c linux-6.2.0/drivers/hwtracing/coresight/coresight-tmc-etr.c --- linux-6.2.0/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ linux-6.2.0/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -45,7 +45,8 @@ }; /* Convert the perf index to an offset within the ETR buffer */ -#define PERF_IDX2OFF(idx, buf) ((idx) % ((buf)->nr_pages << PAGE_SHIFT)) +#define PERF_IDX2OFF(idx, buf) \ + ((idx) % ((unsigned long)(buf)->nr_pages << PAGE_SHIFT)) /* Lower limit for ETR hardware buffer */ #define TMC_ETR_PERF_MIN_BUF_SIZE SZ_1M @@ -1249,7 +1250,7 @@ * than the size requested via sysfs. */ if ((nr_pages << PAGE_SHIFT) > drvdata->size) { - etr_buf = tmc_alloc_etr_buf(drvdata, (nr_pages << PAGE_SHIFT), + etr_buf = tmc_alloc_etr_buf(drvdata, ((ssize_t)nr_pages << PAGE_SHIFT), 0, node, NULL); if (!IS_ERR(etr_buf)) goto done; diff -u linux-6.2.0/drivers/i2c/busses/i2c-xiic.c linux-6.2.0/drivers/i2c/busses/i2c-xiic.c --- linux-6.2.0/drivers/i2c/busses/i2c-xiic.c +++ linux-6.2.0/drivers/i2c/busses/i2c-xiic.c @@ -420,7 +420,7 @@ * reset the IP instead of just flush fifos */ ret = xiic_reinit(i2c); - if (!ret) + if (ret < 0) dev_dbg(i2c->adap.dev.parent, "reinit failed\n"); if (i2c->rx_msg) { diff -u linux-6.2.0/drivers/i3c/master/svc-i3c-master.c linux-6.2.0/drivers/i3c/master/svc-i3c-master.c --- linux-6.2.0/drivers/i3c/master/svc-i3c-master.c +++ linux-6.2.0/drivers/i3c/master/svc-i3c-master.c @@ -782,6 +782,10 @@ */ break; } else if (SVC_I3C_MSTATUS_NACKED(reg)) { + /* No I3C devices attached */ + if (dev_nb == 0) + break; + /* * A slave device nacked the address, this is * allowed only once, DAA will be stopped and @@ -1251,11 +1255,17 @@ { struct svc_i3c_master *master = to_svc_i3c_master(m); bool broadcast = cmd->id < 0x80; + int ret; if (broadcast) - return svc_i3c_master_send_bdcast_ccc_cmd(master, cmd); + ret = svc_i3c_master_send_bdcast_ccc_cmd(master, cmd); else - return svc_i3c_master_send_direct_ccc_cmd(master, cmd); + ret = svc_i3c_master_send_direct_ccc_cmd(master, cmd); + + if (ret) + cmd->err = I3C_ERROR_M2; + + return ret; } static int svc_i3c_master_priv_xfers(struct i3c_dev_desc *dev, diff -u linux-6.2.0/drivers/infiniband/core/cma.c linux-6.2.0/drivers/infiniband/core/cma.c --- linux-6.2.0/drivers/infiniband/core/cma.c +++ linux-6.2.0/drivers/infiniband/core/cma.c @@ -4945,7 +4945,7 @@ int err = 0; struct sockaddr *addr = (struct sockaddr *)&mc->addr; struct net_device *ndev = NULL; - struct ib_sa_multicast ib; + struct ib_sa_multicast ib = {}; enum ib_gid_type gid_type; bool send_only; diff -u linux-6.2.0/drivers/infiniband/core/uverbs_main.c linux-6.2.0/drivers/infiniband/core/uverbs_main.c --- linux-6.2.0/drivers/infiniband/core/uverbs_main.c +++ linux-6.2.0/drivers/infiniband/core/uverbs_main.c @@ -535,7 +535,7 @@ if (hdr->in_words * 4 != count) return -EINVAL; - if (count < method_elm->req_size + sizeof(hdr)) { + if (count < method_elm->req_size + sizeof(*hdr)) { /* * rdma-core v18 and v19 have a bug where they send DESTROY_CQ * with a 16 byte write instead of 24. Old kernels didn't diff -u linux-6.2.0/drivers/infiniband/hw/efa/efa_verbs.c linux-6.2.0/drivers/infiniband/hw/efa/efa_verbs.c --- linux-6.2.0/drivers/infiniband/hw/efa/efa_verbs.c +++ linux-6.2.0/drivers/infiniband/hw/efa/efa_verbs.c @@ -443,12 +443,12 @@ ibdev_dbg(&dev->ibdev, "Destroy qp[%u]\n", ibqp->qp_num); - efa_qp_user_mmap_entries_remove(qp); - err = efa_destroy_qp_handle(dev, qp->qp_handle); if (err) return err; + efa_qp_user_mmap_entries_remove(qp); + if (qp->rq_cpu_addr) { ibdev_dbg(&dev->ibdev, "qp->cpu_addr[0x%p] freed: size[%lu], dma[%pad]\n", @@ -1007,8 +1007,8 @@ "Destroy cq[%d] virt[0x%p] freed: size[%lu], dma[%pad]\n", cq->cq_idx, cq->cpu_addr, cq->size, &cq->dma_addr); - efa_cq_user_mmap_entries_remove(cq); efa_destroy_cq_idx(dev, cq->cq_idx); + efa_cq_user_mmap_entries_remove(cq); if (cq->eq) { xa_erase(&dev->cqs_xa, cq->cq_idx); synchronize_irq(cq->eq->irq.irqn); diff -u linux-6.2.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.c linux-6.2.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.c --- linux-6.2.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ linux-6.2.0/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -757,7 +757,8 @@ qp->sq.head += nreq; qp->next_sge = sge_idx; - if (nreq == 1 && (qp->en_flags & HNS_ROCE_QP_CAP_DIRECT_WQE)) + if (nreq == 1 && !ret && + (qp->en_flags & HNS_ROCE_QP_CAP_DIRECT_WQE)) write_dwqe(hr_dev, qp, wqe); else update_sq_db(hr_dev, qp); @@ -6864,14 +6865,14 @@ ret = hns_roce_init(hr_dev); if (ret) { dev_err(hr_dev->dev, "RoCE Engine init failed!\n"); - goto error_failed_cfg; + goto error_failed_roce_init; } if (hr_dev->pci_dev->revision == PCI_REVISION_ID_HIP08) { ret = free_mr_init(hr_dev); if (ret) { dev_err(hr_dev->dev, "failed to init free mr!\n"); - goto error_failed_roce_init; + goto error_failed_free_mr_init; } } @@ -6879,10 +6880,10 @@ return 0; -error_failed_roce_init: +error_failed_free_mr_init: hns_roce_exit(hr_dev); -error_failed_cfg: +error_failed_roce_init: kfree(hr_dev->priv); error_failed_kzalloc: diff -u linux-6.2.0/drivers/infiniband/hw/hns/hns_roce_main.c linux-6.2.0/drivers/infiniband/hw/hns/hns_roce_main.c --- linux-6.2.0/drivers/infiniband/hw/hns/hns_roce_main.c +++ linux-6.2.0/drivers/infiniband/hw/hns/hns_roce_main.c @@ -219,6 +219,7 @@ unsigned long flags; enum ib_mtu mtu; u32 port; + int ret; port = port_num - 1; @@ -231,8 +232,10 @@ IB_PORT_BOOT_MGMT_SUP; props->max_msg_sz = HNS_ROCE_MAX_MSG_LEN; props->pkey_tbl_len = 1; - props->active_width = IB_WIDTH_4X; - props->active_speed = 1; + ret = ib_get_eth_speed(ib_dev, port_num, &props->active_speed, + &props->active_width); + if (ret) + ibdev_warn(ib_dev, "failed to get speed, ret = %d.\n", ret); spin_lock_irqsave(&hr_dev->iboe.lock, flags); diff -u linux-6.2.0/drivers/infiniband/hw/irdma/main.h linux-6.2.0/drivers/infiniband/hw/irdma/main.h --- linux-6.2.0/drivers/infiniband/hw/irdma/main.h +++ linux-6.2.0/drivers/infiniband/hw/irdma/main.h @@ -236,7 +236,7 @@ struct irdma_qvlist_info { u32 num_vectors; - struct irdma_qv_info qv_info[1]; + struct irdma_qv_info qv_info[]; }; struct irdma_gen_ops { diff -u linux-6.2.0/drivers/infiniband/hw/irdma/verbs.c linux-6.2.0/drivers/infiniband/hw/irdma/verbs.c --- linux-6.2.0/drivers/infiniband/hw/irdma/verbs.c +++ linux-6.2.0/drivers/infiniband/hw/irdma/verbs.c @@ -4360,7 +4360,6 @@ ah_attr->grh.traffic_class = ah->sc_ah.ah_info.tc_tos; ah_attr->grh.hop_limit = ah->sc_ah.ah_info.hop_ttl; ah_attr->grh.sgid_index = ah->sgid_index; - ah_attr->grh.sgid_index = ah->sgid_index; memcpy(&ah_attr->grh.dgid, &ah->dgid, sizeof(ah_attr->grh.dgid)); } diff -u linux-6.2.0/drivers/infiniband/hw/mlx5/fs.c linux-6.2.0/drivers/infiniband/hw/mlx5/fs.c --- linux-6.2.0/drivers/infiniband/hw/mlx5/fs.c +++ linux-6.2.0/drivers/infiniband/hw/mlx5/fs.c @@ -2470,8 +2470,8 @@ mlx5_steering_anchor_destroy_res(ft_prio); put_flow_table: put_flow_table(dev, ft_prio, true); - mutex_unlock(&dev->flow_db->lock); free_obj: + mutex_unlock(&dev->flow_db->lock); kfree(obj); return err; diff -u linux-6.2.0/drivers/infiniband/hw/mlx5/main.c linux-6.2.0/drivers/infiniband/hw/mlx5/main.c --- linux-6.2.0/drivers/infiniband/hw/mlx5/main.c +++ linux-6.2.0/drivers/infiniband/hw/mlx5/main.c @@ -2074,7 +2074,7 @@ case MLX5_IB_MMAP_DEVICE_MEM: return "Device Memory"; default: - return NULL; + return "Unknown"; } } diff -u linux-6.2.0/drivers/infiniband/sw/rxe/rxe_loc.h linux-6.2.0/drivers/infiniband/sw/rxe/rxe_loc.h --- linux-6.2.0/drivers/infiniband/sw/rxe/rxe_loc.h +++ linux-6.2.0/drivers/infiniband/sw/rxe/rxe_loc.h @@ -139,12 +139,6 @@ return IB_MTU_4096; } -static inline int rcv_wqe_size(int max_sge) -{ - return sizeof(struct rxe_recv_wqe) + - max_sge * sizeof(struct ib_sge); -} - void free_rd_atomic_resource(struct resp_res *res); static inline void rxe_advance_resp_resource(struct rxe_qp *qp) diff -u linux-6.2.0/drivers/infiniband/sw/rxe/rxe_qp.c linux-6.2.0/drivers/infiniband/sw/rxe/rxe_qp.c --- linux-6.2.0/drivers/infiniband/sw/rxe/rxe_qp.c +++ linux-6.2.0/drivers/infiniband/sw/rxe/rxe_qp.c @@ -183,13 +183,63 @@ atomic_set(&qp->skb_out, 0); } +static int rxe_init_sq(struct rxe_qp *qp, struct ib_qp_init_attr *init, + struct ib_udata *udata, + struct rxe_create_qp_resp __user *uresp) +{ + struct rxe_dev *rxe = to_rdev(qp->ibqp.device); + int wqe_size; + int err; + + qp->sq.max_wr = init->cap.max_send_wr; + wqe_size = max_t(int, init->cap.max_send_sge * sizeof(struct ib_sge), + init->cap.max_inline_data); + qp->sq.max_sge = wqe_size / sizeof(struct ib_sge); + qp->sq.max_inline = wqe_size; + wqe_size += sizeof(struct rxe_send_wqe); + + qp->sq.queue = rxe_queue_init(rxe, &qp->sq.max_wr, wqe_size, + QUEUE_TYPE_FROM_CLIENT); + if (!qp->sq.queue) { + rxe_err_qp(qp, "Unable to allocate send queue"); + err = -ENOMEM; + goto err_out; + } + + /* prepare info for caller to mmap send queue if user space qp */ + err = do_mmap_info(rxe, uresp ? &uresp->sq_mi : NULL, udata, + qp->sq.queue->buf, qp->sq.queue->buf_size, + &qp->sq.queue->ip); + if (err) { + rxe_err_qp(qp, "do_mmap_info failed, err = %d", err); + goto err_free; + } + + /* return actual capabilities to caller which may be larger + * than requested + */ + init->cap.max_send_wr = qp->sq.max_wr; + init->cap.max_send_sge = qp->sq.max_sge; + init->cap.max_inline_data = qp->sq.max_inline; + + return 0; + +err_free: + vfree(qp->sq.queue->buf); + kfree(qp->sq.queue); + qp->sq.queue = NULL; +err_out: + return err; +} + static int rxe_qp_init_req(struct rxe_dev *rxe, struct rxe_qp *qp, struct ib_qp_init_attr *init, struct ib_udata *udata, struct rxe_create_qp_resp __user *uresp) { int err; - int wqe_size; - enum queue_type type; + + /* if we don't finish qp create make sure queue is valid */ + skb_queue_head_init(&qp->req_pkts); err = sock_create_kern(&init_net, AF_INET, SOCK_DGRAM, 0, &qp->sk); if (err < 0) @@ -204,32 +254,10 @@ * (0xc000 - 0xffff). */ qp->src_port = RXE_ROCE_V2_SPORT + (hash_32(qp_num(qp), 14) & 0x3fff); - qp->sq.max_wr = init->cap.max_send_wr; - - /* These caps are limited by rxe_qp_chk_cap() done by the caller */ - wqe_size = max_t(int, init->cap.max_send_sge * sizeof(struct ib_sge), - init->cap.max_inline_data); - qp->sq.max_sge = init->cap.max_send_sge = - wqe_size / sizeof(struct ib_sge); - qp->sq.max_inline = init->cap.max_inline_data = wqe_size; - wqe_size += sizeof(struct rxe_send_wqe); - - type = QUEUE_TYPE_FROM_CLIENT; - qp->sq.queue = rxe_queue_init(rxe, &qp->sq.max_wr, - wqe_size, type); - if (!qp->sq.queue) - return -ENOMEM; - err = do_mmap_info(rxe, uresp ? &uresp->sq_mi : NULL, udata, - qp->sq.queue->buf, qp->sq.queue->buf_size, - &qp->sq.queue->ip); - - if (err) { - vfree(qp->sq.queue->buf); - kfree(qp->sq.queue); - qp->sq.queue = NULL; + err = rxe_init_sq(qp, init, udata, uresp); + if (err) return err; - } qp->req.wqe_index = queue_get_producer(qp->sq.queue, QUEUE_TYPE_FROM_CLIENT); @@ -250,36 +278,65 @@ return 0; } +static int rxe_init_rq(struct rxe_qp *qp, struct ib_qp_init_attr *init, + struct ib_udata *udata, + struct rxe_create_qp_resp __user *uresp) +{ + struct rxe_dev *rxe = to_rdev(qp->ibqp.device); + int wqe_size; + int err; + + qp->rq.max_wr = init->cap.max_recv_wr; + qp->rq.max_sge = init->cap.max_recv_sge; + wqe_size = sizeof(struct rxe_recv_wqe) + + qp->rq.max_sge*sizeof(struct ib_sge); + + qp->rq.queue = rxe_queue_init(rxe, &qp->rq.max_wr, wqe_size, + QUEUE_TYPE_FROM_CLIENT); + if (!qp->rq.queue) { + rxe_err_qp(qp, "Unable to allocate recv queue"); + err = -ENOMEM; + goto err_out; + } + + /* prepare info for caller to mmap recv queue if user space qp */ + err = do_mmap_info(rxe, uresp ? &uresp->rq_mi : NULL, udata, + qp->rq.queue->buf, qp->rq.queue->buf_size, + &qp->rq.queue->ip); + if (err) { + rxe_err_qp(qp, "do_mmap_info failed, err = %d", err); + goto err_free; + } + + /* return actual capabilities to caller which may be larger + * than requested + */ + init->cap.max_recv_wr = qp->rq.max_wr; + + return 0; + +err_free: + vfree(qp->rq.queue->buf); + kfree(qp->rq.queue); + qp->rq.queue = NULL; +err_out: + return err; +} + static int rxe_qp_init_resp(struct rxe_dev *rxe, struct rxe_qp *qp, struct ib_qp_init_attr *init, struct ib_udata *udata, struct rxe_create_qp_resp __user *uresp) { int err; - int wqe_size; - enum queue_type type; - if (!qp->srq) { - qp->rq.max_wr = init->cap.max_recv_wr; - qp->rq.max_sge = init->cap.max_recv_sge; - - wqe_size = rcv_wqe_size(qp->rq.max_sge); + /* if we don't finish qp create make sure queue is valid */ + skb_queue_head_init(&qp->resp_pkts); - type = QUEUE_TYPE_FROM_CLIENT; - qp->rq.queue = rxe_queue_init(rxe, &qp->rq.max_wr, - wqe_size, type); - if (!qp->rq.queue) - return -ENOMEM; - - err = do_mmap_info(rxe, uresp ? &uresp->rq_mi : NULL, udata, - qp->rq.queue->buf, qp->rq.queue->buf_size, - &qp->rq.queue->ip); - if (err) { - vfree(qp->rq.queue->buf); - kfree(qp->rq.queue); - qp->rq.queue = NULL; + if (!qp->srq) { + err = rxe_init_rq(qp, init, udata, uresp); + if (err) return err; - } } rxe_init_task(&qp->resp.task, qp, rxe_responder); @@ -309,10 +366,10 @@ if (srq) rxe_get(srq); - qp->pd = pd; - qp->rcq = rcq; - qp->scq = scq; - qp->srq = srq; + qp->pd = pd; + qp->rcq = rcq; + qp->scq = scq; + qp->srq = srq; atomic_inc(&rcq->num_wq); atomic_inc(&scq->num_wq); diff -u linux-6.2.0/drivers/infiniband/sw/rxe/rxe_req.c linux-6.2.0/drivers/infiniband/sw/rxe/rxe_req.c --- linux-6.2.0/drivers/infiniband/sw/rxe/rxe_req.c +++ linux-6.2.0/drivers/infiniband/sw/rxe/rxe_req.c @@ -551,10 +551,11 @@ struct rxe_send_wqe *rollback_wqe, u32 *rollback_psn) { - rollback_wqe->state = wqe->state; + rollback_wqe->state = wqe->state; rollback_wqe->first_psn = wqe->first_psn; - rollback_wqe->last_psn = wqe->last_psn; - *rollback_psn = qp->req.psn; + rollback_wqe->last_psn = wqe->last_psn; + rollback_wqe->dma = wqe->dma; + *rollback_psn = qp->req.psn; } static void rollback_state(struct rxe_send_wqe *wqe, @@ -562,10 +563,11 @@ struct rxe_send_wqe *rollback_wqe, u32 rollback_psn) { - wqe->state = rollback_wqe->state; + wqe->state = rollback_wqe->state; wqe->first_psn = rollback_wqe->first_psn; - wqe->last_psn = rollback_wqe->last_psn; - qp->req.psn = rollback_psn; + wqe->last_psn = rollback_wqe->last_psn; + wqe->dma = rollback_wqe->dma; + qp->req.psn = rollback_psn; } static void update_state(struct rxe_qp *qp, struct rxe_pkt_info *pkt) @@ -769,6 +771,9 @@ pkt.mask = rxe_opcode[opcode].mask; pkt.wqe = wqe; + /* save wqe state before we build and send packet */ + save_state(wqe, qp, &rollback_wqe, &rollback_psn); + av = rxe_get_av(&pkt, &ah); if (unlikely(!av)) { rxe_dbg_qp(qp, "Failed no address vector\n"); @@ -801,29 +806,29 @@ if (ah) rxe_put(ah); - /* - * To prevent a race on wqe access between requester and completer, - * wqe members state and psn need to be set before calling - * rxe_xmit_packet(). - * Otherwise, completer might initiate an unjustified retry flow. - */ - save_state(wqe, qp, &rollback_wqe, &rollback_psn); + /* update wqe state as though we had sent it */ update_wqe_state(qp, wqe, &pkt); update_wqe_psn(qp, wqe, &pkt, payload); err = rxe_xmit_packet(qp, &pkt, skb); if (err) { - qp->need_req_skb = 1; + if (err != -EAGAIN) { + wqe->status = IB_WC_LOC_QP_OP_ERR; + goto err; + } + /* the packet was dropped so reset wqe to the state + * before we sent it so we can try to resend + */ rollback_state(wqe, qp, &rollback_wqe, rollback_psn); - if (err == -EAGAIN) { - rxe_sched_task(&qp->req.task); - goto exit; - } + /* force a delay until the dropped packet is freed and + * the send queue is drained below the low water mark + */ + qp->need_req_skb = 1; - wqe->status = IB_WC_LOC_QP_OP_ERR; - goto err; + rxe_sched_task(&qp->req.task); + goto exit; } update_state(qp, &pkt); diff -u linux-6.2.0/drivers/infiniband/sw/rxe/rxe_srq.c linux-6.2.0/drivers/infiniband/sw/rxe/rxe_srq.c --- linux-6.2.0/drivers/infiniband/sw/rxe/rxe_srq.c +++ linux-6.2.0/drivers/infiniband/sw/rxe/rxe_srq.c @@ -45,40 +45,41 @@ struct ib_srq_init_attr *init, struct ib_udata *udata, struct rxe_create_srq_resp __user *uresp) { - int err; - int srq_wqe_size; struct rxe_queue *q; - enum queue_type type; + int wqe_size; + int err; - srq->ibsrq.event_handler = init->event_handler; - srq->ibsrq.srq_context = init->srq_context; - srq->limit = init->attr.srq_limit; - srq->srq_num = srq->elem.index; - srq->rq.max_wr = init->attr.max_wr; - srq->rq.max_sge = init->attr.max_sge; + srq->ibsrq.event_handler = init->event_handler; + srq->ibsrq.srq_context = init->srq_context; + srq->limit = init->attr.srq_limit; + srq->srq_num = srq->elem.index; + srq->rq.max_wr = init->attr.max_wr; + srq->rq.max_sge = init->attr.max_sge; - srq_wqe_size = rcv_wqe_size(srq->rq.max_sge); + wqe_size = sizeof(struct rxe_recv_wqe) + + srq->rq.max_sge*sizeof(struct ib_sge); spin_lock_init(&srq->rq.producer_lock); spin_lock_init(&srq->rq.consumer_lock); - type = QUEUE_TYPE_FROM_CLIENT; - q = rxe_queue_init(rxe, &srq->rq.max_wr, srq_wqe_size, type); + q = rxe_queue_init(rxe, &srq->rq.max_wr, wqe_size, + QUEUE_TYPE_FROM_CLIENT); if (!q) { rxe_dbg_srq(srq, "Unable to allocate queue\n"); - return -ENOMEM; + err = -ENOMEM; + goto err_out; } - srq->rq.queue = q; - err = do_mmap_info(rxe, uresp ? &uresp->mi : NULL, udata, q->buf, q->buf_size, &q->ip); if (err) { - vfree(q->buf); - kfree(q); - return err; + rxe_dbg_srq(srq, "Unable to init mmap info for caller\n"); + goto err_free; } + srq->rq.queue = q; + init->attr.max_wr = srq->rq.max_wr; + if (uresp) { if (copy_to_user(&uresp->srq_num, &srq->srq_num, sizeof(uresp->srq_num))) { @@ -88,6 +89,12 @@ } return 0; + +err_free: + vfree(q->buf); + kfree(q); +err_out: + return err; } int rxe_srq_chk_attr(struct rxe_dev *rxe, struct rxe_srq *srq, @@ -145,9 +152,10 @@ struct ib_srq_attr *attr, enum ib_srq_attr_mask mask, struct rxe_modify_srq_cmd *ucmd, struct ib_udata *udata) { - int err; struct rxe_queue *q = srq->rq.queue; struct mminfo __user *mi = NULL; + int wqe_size; + int err; if (mask & IB_SRQ_MAX_WR) { /* @@ -156,12 +164,16 @@ */ mi = u64_to_user_ptr(ucmd->mmap_info_addr); - err = rxe_queue_resize(q, &attr->max_wr, - rcv_wqe_size(srq->rq.max_sge), udata, mi, - &srq->rq.producer_lock, + wqe_size = sizeof(struct rxe_recv_wqe) + + srq->rq.max_sge*sizeof(struct ib_sge); + + err = rxe_queue_resize(q, &attr->max_wr, wqe_size, + udata, mi, &srq->rq.producer_lock, &srq->rq.consumer_lock); if (err) - goto err2; + goto err_free; + + srq->rq.max_wr = attr->max_wr; } if (mask & IB_SRQ_LIMIT) @@ -169,7 +181,7 @@ return 0; -err2: +err_free: rxe_queue_cleanup(q); srq->rq.queue = NULL; return err; diff -u linux-6.2.0/drivers/infiniband/sw/siw/siw_main.c linux-6.2.0/drivers/infiniband/sw/siw/siw_main.c --- linux-6.2.0/drivers/infiniband/sw/siw/siw_main.c +++ linux-6.2.0/drivers/infiniband/sw/siw/siw_main.c @@ -75,8 +75,7 @@ return rv; } - siw_dbg(base_dev, "HWaddr=%pM\n", sdev->netdev->dev_addr); - + siw_dbg(base_dev, "HWaddr=%pM\n", sdev->raw_gid); return 0; } @@ -313,24 +312,19 @@ return NULL; base_dev = &sdev->base_dev; - sdev->netdev = netdev; - if (netdev->type != ARPHRD_LOOPBACK && netdev->type != ARPHRD_NONE) { - addrconf_addr_eui48((unsigned char *)&base_dev->node_guid, - netdev->dev_addr); + if (netdev->addr_len) { + memcpy(sdev->raw_gid, netdev->dev_addr, + min_t(unsigned int, netdev->addr_len, ETH_ALEN)); } else { /* - * This device does not have a HW address, - * but connection mangagement lib expects gid != 0 + * This device does not have a HW address, but + * connection mangagement requires a unique gid. */ - size_t len = min_t(size_t, strlen(base_dev->name), 6); - char addr[6] = { }; - - memcpy(addr, base_dev->name, len); - addrconf_addr_eui48((unsigned char *)&base_dev->node_guid, - addr); + eth_random_addr(sdev->raw_gid); } + addrconf_addr_eui48((u8 *)&base_dev->node_guid, sdev->raw_gid); base_dev->uverbs_cmd_mask |= BIT_ULL(IB_USER_VERBS_CMD_POST_SEND); diff -u linux-6.2.0/drivers/infiniband/ulp/isert/ib_isert.c linux-6.2.0/drivers/infiniband/ulp/isert/ib_isert.c --- linux-6.2.0/drivers/infiniband/ulp/isert/ib_isert.c +++ linux-6.2.0/drivers/infiniband/ulp/isert/ib_isert.c @@ -2570,6 +2570,8 @@ isert_put_unsol_pending_cmds(conn); isert_wait4cmds(conn); isert_wait4logout(isert_conn); + + queue_work(isert_release_wq, &isert_conn->release_work); } static void isert_free_conn(struct iscsit_conn *conn) diff -u linux-6.2.0/drivers/input/serio/i8042-acpipnpio.h linux-6.2.0/drivers/input/serio/i8042-acpipnpio.h --- linux-6.2.0/drivers/input/serio/i8042-acpipnpio.h +++ linux-6.2.0/drivers/input/serio/i8042-acpipnpio.h @@ -1281,6 +1281,13 @@ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS | SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP) }, + /* See comment on TUXEDO InfinityBook S17 Gen6 / Clevo NS70MU above */ + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "PD5x_7xPNP_PNR_PNN_PNT"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOAUX) + }, { .matches = { DMI_MATCH(DMI_BOARD_NAME, "X170SM"), diff -u linux-6.2.0/drivers/interconnect/core.c linux-6.2.0/drivers/interconnect/core.c --- linux-6.2.0/drivers/interconnect/core.c +++ linux-6.2.0/drivers/interconnect/core.c @@ -29,6 +29,7 @@ static int providers_count; static bool synced_state; static DEFINE_MUTEX(icc_lock); +static DEFINE_MUTEX(icc_bw_lock); static struct dentry *icc_debugfs_dir; static void icc_summary_show_one(struct seq_file *s, struct icc_node *n) @@ -632,7 +633,7 @@ if (WARN_ON(IS_ERR(path) || !path->num_nodes)) return -EINVAL; - mutex_lock(&icc_lock); + mutex_lock(&icc_bw_lock); old_avg = path->reqs[0].avg_bw; old_peak = path->reqs[0].peak_bw; @@ -664,7 +665,7 @@ apply_constraints(path); } - mutex_unlock(&icc_lock); + mutex_unlock(&icc_bw_lock); trace_icc_set_bw_end(path, ret); @@ -967,6 +968,7 @@ return; mutex_lock(&icc_lock); + mutex_lock(&icc_bw_lock); node->provider = provider; list_add_tail(&node->node_list, &provider->nodes); @@ -992,6 +994,7 @@ node->avg_bw = 0; node->peak_bw = 0; + mutex_unlock(&icc_bw_lock); mutex_unlock(&icc_lock); } EXPORT_SYMBOL_GPL(icc_node_add); @@ -1129,6 +1132,7 @@ return; mutex_lock(&icc_lock); + mutex_lock(&icc_bw_lock); synced_state = true; list_for_each_entry(p, &icc_providers, provider_list) { dev_dbg(p->dev, "interconnect provider is in synced state\n"); @@ -1141,13 +1145,21 @@ } } } + mutex_unlock(&icc_bw_lock); mutex_unlock(&icc_lock); } EXPORT_SYMBOL_GPL(icc_sync_state); static int __init icc_init(void) { - struct device_node *root = of_find_node_by_path("/"); + struct device_node *root; + + /* Teach lockdep about lock ordering wrt. shrinker: */ + fs_reclaim_acquire(GFP_KERNEL); + might_lock(&icc_bw_lock); + fs_reclaim_release(GFP_KERNEL); + + root = of_find_node_by_path("/"); providers_count = of_count_icc_providers(root); of_node_put(root); diff -u linux-6.2.0/drivers/interconnect/qcom/bcm-voter.c linux-6.2.0/drivers/interconnect/qcom/bcm-voter.c --- linux-6.2.0/drivers/interconnect/qcom/bcm-voter.c +++ linux-6.2.0/drivers/interconnect/qcom/bcm-voter.c @@ -58,6 +58,36 @@ return num; } +/* BCMs with enable_mask use one-hot-encoding for on/off signaling */ +static void bcm_aggregate_mask(struct qcom_icc_bcm *bcm) +{ + struct qcom_icc_node *node; + int bucket, i; + + for (bucket = 0; bucket < QCOM_ICC_NUM_BUCKETS; bucket++) { + bcm->vote_x[bucket] = 0; + bcm->vote_y[bucket] = 0; + + for (i = 0; i < bcm->num_nodes; i++) { + node = bcm->nodes[i]; + + /* If any vote in this bucket exists, keep the BCM enabled */ + if (node->sum_avg[bucket] || node->max_peak[bucket]) { + bcm->vote_x[bucket] = 0; + bcm->vote_y[bucket] = bcm->enable_mask; + break; + } + } + } + + if (bcm->keepalive) { + bcm->vote_x[QCOM_ICC_BUCKET_AMC] = bcm->enable_mask; + bcm->vote_x[QCOM_ICC_BUCKET_WAKE] = bcm->enable_mask; + bcm->vote_y[QCOM_ICC_BUCKET_AMC] = bcm->enable_mask; + bcm->vote_y[QCOM_ICC_BUCKET_WAKE] = bcm->enable_mask; + } +} + static void bcm_aggregate(struct qcom_icc_bcm *bcm) { struct qcom_icc_node *node; @@ -83,11 +113,6 @@ temp = agg_peak[bucket] * bcm->vote_scale; bcm->vote_y[bucket] = bcm_div(temp, bcm->aux_data.unit); - - if (bcm->enable_mask && (bcm->vote_x[bucket] || bcm->vote_y[bucket])) { - bcm->vote_x[bucket] = 0; - bcm->vote_y[bucket] = bcm->enable_mask; - } } if (bcm->keepalive && bcm->vote_x[QCOM_ICC_BUCKET_AMC] == 0 && @@ -260,8 +285,12 @@ return 0; mutex_lock(&voter->lock); - list_for_each_entry(bcm, &voter->commit_list, list) - bcm_aggregate(bcm); + list_for_each_entry(bcm, &voter->commit_list, list) { + if (bcm->enable_mask) + bcm_aggregate_mask(bcm); + else + bcm_aggregate(bcm); + } /* * Pre sort the BCMs based on VCD for ease of generating a command list diff -u linux-6.2.0/drivers/interconnect/qcom/qcm2290.c linux-6.2.0/drivers/interconnect/qcom/qcm2290.c --- linux-6.2.0/drivers/interconnect/qcom/qcm2290.c +++ linux-6.2.0/drivers/interconnect/qcom/qcm2290.c @@ -1355,6 +1355,7 @@ .driver = { .name = "qnoc-qcm2290", .of_match_table = qcm2290_noc_of_match, + .sync_state = icc_sync_state, }, }; module_platform_driver(qcm2290_noc_driver); diff -u linux-6.2.0/drivers/interconnect/qcom/sm8450.c linux-6.2.0/drivers/interconnect/qcom/sm8450.c --- linux-6.2.0/drivers/interconnect/qcom/sm8450.c +++ linux-6.2.0/drivers/interconnect/qcom/sm8450.c @@ -1886,6 +1886,7 @@ .driver = { .name = "qnoc-sm8450", .of_match_table = qnoc_of_match, + .sync_state = icc_sync_state, }, }; diff -u linux-6.2.0/drivers/iommu/amd/iommu_v2.c linux-6.2.0/drivers/iommu/amd/iommu_v2.c --- linux-6.2.0/drivers/iommu/amd/iommu_v2.c +++ linux-6.2.0/drivers/iommu/amd/iommu_v2.c @@ -262,8 +262,8 @@ static void put_pasid_state_wait(struct pasid_state *pasid_state) { - refcount_dec(&pasid_state->count); - wait_event(pasid_state->wq, !refcount_read(&pasid_state->count)); + if (!refcount_dec_and_test(&pasid_state->count)) + wait_event(pasid_state->wq, !refcount_read(&pasid_state->count)); free_pasid_state(pasid_state); } diff -u linux-6.2.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c linux-6.2.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c --- linux-6.2.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ linux-6.2.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -1886,13 +1886,23 @@ /* Get the leaf page size */ tg = __ffs(smmu_domain->domain.pgsize_bitmap); + num_pages = size >> tg; + /* Convert page size of 12,14,16 (log2) to 1,2,3 */ cmd->tlbi.tg = (tg - 10) / 2; - /* Determine what level the granule is at */ - cmd->tlbi.ttl = 4 - ((ilog2(granule) - 3) / (tg - 3)); - - num_pages = size >> tg; + /* + * Determine what level the granule is at. For non-leaf, both + * io-pgtable and SVA pass a nominal last-level granule because + * they don't know what level(s) actually apply, so ignore that + * and leave TTL=0. However for various errata reasons we still + * want to use a range command, so avoid the SVA corner case + * where both scale and num could be 0 as well. + */ + if (cmd->tlbi.leaf) + cmd->tlbi.ttl = 4 - ((ilog2(granule) - 3) / (tg - 3)); + else if ((num_pages & CMDQ_TLBI_RANGE_NUM_MAX) == 1) + num_pages++; } cmds.num = 0; diff -u linux-6.2.0/drivers/iommu/intel/iommu.c linux-6.2.0/drivers/iommu/intel/iommu.c --- linux-6.2.0/drivers/iommu/intel/iommu.c +++ linux-6.2.0/drivers/iommu/intel/iommu.c @@ -3132,13 +3132,6 @@ struct intel_iommu *iommu = NULL; unsigned long flag; - for_each_active_iommu(iommu, drhd) { - iommu->iommu_state = kcalloc(MAX_SR_DMAR_REGS, sizeof(u32), - GFP_KERNEL); - if (!iommu->iommu_state) - goto nomem; - } - iommu_flush_all(); for_each_active_iommu(iommu, drhd) { @@ -3158,12 +3151,6 @@ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); } return 0; - -nomem: - for_each_active_iommu(iommu, drhd) - kfree(iommu->iommu_state); - - return -ENOMEM; } static void iommu_resume(void) @@ -3195,9 +3182,6 @@ raw_spin_unlock_irqrestore(&iommu->register_lock, flag); } - - for_each_active_iommu(iommu, drhd) - kfree(iommu->iommu_state); } static struct syscore_ops iommu_syscore_ops = { diff -u linux-6.2.0/drivers/iommu/intel/pasid.c linux-6.2.0/drivers/iommu/intel/pasid.c --- linux-6.2.0/drivers/iommu/intel/pasid.c +++ linux-6.2.0/drivers/iommu/intel/pasid.c @@ -129,7 +129,7 @@ info->pasid_table = pasid_table; if (!ecap_coherent(info->iommu->ecap)) - clflush_cache_range(pasid_table->table, size); + clflush_cache_range(pasid_table->table, (1 << order) * PAGE_SIZE); return 0; } diff -u linux-6.2.0/drivers/iommu/iommu.c linux-6.2.0/drivers/iommu/iommu.c --- linux-6.2.0/drivers/iommu/iommu.c +++ linux-6.2.0/drivers/iommu/iommu.c @@ -3255,7 +3255,7 @@ /** * iommu_group_release_dma_owner() - Release DMA ownership of a group - * @dev: The device + * @group: The group * * Release the DMA ownership claimed by iommu_group_claim_dma_owner(). */ @@ -3269,7 +3269,7 @@ /** * iommu_device_release_dma_owner() - Release DMA ownership of a device - * @group: The device. + * @dev: The device. * * Release the DMA ownership claimed by iommu_device_claim_dma_owner(). */ diff -u linux-6.2.0/drivers/iommu/iommufd/device.c linux-6.2.0/drivers/iommu/iommufd/device.c --- linux-6.2.0/drivers/iommu/iommufd/device.c +++ linux-6.2.0/drivers/iommu/iommufd/device.c @@ -303,8 +303,8 @@ goto out_abort; list_add_tail(&hwpt->hwpt_item, &ioas->hwpt_list); - mutex_unlock(&ioas->mutex); iommufd_object_finalize(idev->ictx, &hwpt->obj); + mutex_unlock(&ioas->mutex); return 0; out_abort: diff -u linux-6.2.0/drivers/iommu/mtk_iommu.c linux-6.2.0/drivers/iommu/mtk_iommu.c --- linux-6.2.0/drivers/iommu/mtk_iommu.c +++ linux-6.2.0/drivers/iommu/mtk_iommu.c @@ -229,6 +229,8 @@ struct device *smicomm_dev; struct mtk_iommu_bank_data *bank; + struct mtk_iommu_domain *share_dom; + struct regmap *pericfg; struct mutex mutex; /* Protect m4u_group/m4u_dom above */ @@ -585,15 +587,14 @@ struct mtk_iommu_data *data, unsigned int region_id) { + struct mtk_iommu_domain *share_dom = data->share_dom; const struct mtk_iommu_iova_region *region; - struct mtk_iommu_domain *m4u_dom; - /* Always use bank0 in sharing pgtable case */ - m4u_dom = data->bank[0].m4u_dom; - if (m4u_dom) { - dom->iop = m4u_dom->iop; - dom->cfg = m4u_dom->cfg; - dom->domain.pgsize_bitmap = m4u_dom->cfg.pgsize_bitmap; + /* Share pgtable when 2 MM IOMMU share the pgtable or one IOMMU use multiple iova ranges */ + if (share_dom) { + dom->iop = share_dom->iop; + dom->cfg = share_dom->cfg; + dom->domain.pgsize_bitmap = share_dom->cfg.pgsize_bitmap; goto update_iova_region; } @@ -623,6 +624,8 @@ /* Update our support page sizes bitmap */ dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap; + data->share_dom = dom; + update_iova_region: /* Update the iova region for this domain */ region = data->plat_data->iova_region + region_id; @@ -673,7 +676,9 @@ /* Data is in the frstdata in sharing pgtable case. */ frstdata = mtk_iommu_get_frst_data(hw_list); + mutex_lock(&frstdata->mutex); ret = mtk_iommu_domain_finalise(dom, frstdata, region_id); + mutex_unlock(&frstdata->mutex); if (ret) { mutex_unlock(&dom->mutex); return ret; diff -u linux-6.2.0/drivers/iommu/rockchip-iommu.c linux-6.2.0/drivers/iommu/rockchip-iommu.c --- linux-6.2.0/drivers/iommu/rockchip-iommu.c +++ linux-6.2.0/drivers/iommu/rockchip-iommu.c @@ -98,8 +98,6 @@ phys_addr_t (*pt_address)(u32 dte); u32 (*mk_dtentries)(dma_addr_t pt_dma); u32 (*mk_ptentries)(phys_addr_t page, int prot); - phys_addr_t (*dte_addr_phys)(u32 addr); - u32 (*dma_addr_dte)(dma_addr_t dt_dma); u64 dma_bit_mask; }; @@ -277,8 +275,8 @@ /* * In v2: * 31:12 - Page address bit 31:0 - * 11:9 - Page address bit 34:32 - * 8:4 - Page address bit 39:35 + * 11: 8 - Page address bit 35:32 + * 7: 4 - Page address bit 39:36 * 3 - Security * 2 - Writable * 1 - Readable @@ -505,7 +503,7 @@ /* * Check if register DTE_ADDR is working by writing DTE_ADDR_DUMMY - * and verifying that upper 5 nybbles are read back. + * and verifying that upper 5 (v1) or 7 (v2) nybbles are read back. */ for (i = 0; i < iommu->num_mmu; i++) { dte_addr = rk_ops->pt_address(DTE_ADDR_DUMMY); @@ -530,33 +528,6 @@ return 0; } -static inline phys_addr_t rk_dte_addr_phys(u32 addr) -{ - return (phys_addr_t)addr; -} - -static inline u32 rk_dma_addr_dte(dma_addr_t dt_dma) -{ - return dt_dma; -} - -#define DT_HI_MASK GENMASK_ULL(39, 32) -#define DTE_BASE_HI_MASK GENMASK(11, 4) -#define DT_SHIFT 28 - -static inline phys_addr_t rk_dte_addr_phys_v2(u32 addr) -{ - u64 addr64 = addr; - return (phys_addr_t)(addr64 & RK_DTE_PT_ADDRESS_MASK) | - ((addr64 & DTE_BASE_HI_MASK) << DT_SHIFT); -} - -static inline u32 rk_dma_addr_dte_v2(dma_addr_t dt_dma) -{ - return (dt_dma & RK_DTE_PT_ADDRESS_MASK) | - ((dt_dma & DT_HI_MASK) >> DT_SHIFT); -} - static void log_iova(struct rk_iommu *iommu, int index, dma_addr_t iova) { void __iomem *base = iommu->bases[index]; @@ -576,7 +547,7 @@ page_offset = rk_iova_page_offset(iova); mmu_dte_addr = rk_iommu_read(base, RK_MMU_DTE_ADDR); - mmu_dte_addr_phys = rk_ops->dte_addr_phys(mmu_dte_addr); + mmu_dte_addr_phys = rk_ops->pt_address(mmu_dte_addr); dte_addr_phys = mmu_dte_addr_phys + (4 * dte_index); dte_addr = phys_to_virt(dte_addr_phys); @@ -966,7 +937,7 @@ for (i = 0; i < iommu->num_mmu; i++) { rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, - rk_ops->dma_addr_dte(rk_domain->dt_dma)); + rk_ops->mk_dtentries(rk_domain->dt_dma)); rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE); rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK); } @@ -1373,8 +1344,6 @@ .pt_address = &rk_dte_pt_address, .mk_dtentries = &rk_mk_dte, .mk_ptentries = &rk_mk_pte, - .dte_addr_phys = &rk_dte_addr_phys, - .dma_addr_dte = &rk_dma_addr_dte, .dma_bit_mask = DMA_BIT_MASK(32), }; @@ -1382,8 +1351,6 @@ .pt_address = &rk_dte_pt_address_v2, .mk_dtentries = &rk_mk_dte_v2, .mk_ptentries = &rk_mk_pte_v2, - .dte_addr_phys = &rk_dte_addr_phys_v2, - .dma_addr_dte = &rk_dma_addr_dte_v2, .dma_bit_mask = DMA_BIT_MASK(40), }; diff -u linux-6.2.0/drivers/irqchip/irq-loongson-eiointc.c linux-6.2.0/drivers/irqchip/irq-loongson-eiointc.c --- linux-6.2.0/drivers/irqchip/irq-loongson-eiointc.c +++ linux-6.2.0/drivers/irqchip/irq-loongson-eiointc.c @@ -146,7 +146,7 @@ int i, bit; uint32_t data; uint32_t node = cpu_to_eio_node(cpu); - uint32_t index = eiointc_index(node); + int index = eiointc_index(node); if (index < 0) { pr_err("Error: invalid nodemap!\n"); diff -u linux-6.2.0/drivers/md/dm-core.h linux-6.2.0/drivers/md/dm-core.h --- linux-6.2.0/drivers/md/dm-core.h +++ linux-6.2.0/drivers/md/dm-core.h @@ -214,6 +214,7 @@ /* a list of devices used by this table */ struct list_head devices; + struct rw_semaphore devices_lock; /* events get handed up using this callback */ void (*event_fn)(void *); diff -u linux-6.2.0/drivers/md/dm-ioctl.c linux-6.2.0/drivers/md/dm-ioctl.c --- linux-6.2.0/drivers/md/dm-ioctl.c +++ linux-6.2.0/drivers/md/dm-ioctl.c @@ -1566,6 +1566,8 @@ struct dm_dev_internal *dd; struct dm_target_deps *deps; + down_read(&table->devices_lock); + deps = get_result_buffer(param, param_size, &len); /* @@ -1580,7 +1582,7 @@ needed = struct_size(deps, dev, count); if (len < needed) { param->flags |= DM_BUFFER_FULL_FLAG; - return; + goto out; } /* @@ -1592,6 +1594,9 @@ deps->dev[count++] = huge_encode_dev(dd->dm_dev->bdev->bd_dev); param->data_size = param->data_start + needed; + +out: + up_read(&table->devices_lock); } static int table_deps(struct file *filp, struct dm_ioctl *param, size_t param_size) diff -u linux-6.2.0/drivers/md/dm-table.c linux-6.2.0/drivers/md/dm-table.c --- linux-6.2.0/drivers/md/dm-table.c +++ linux-6.2.0/drivers/md/dm-table.c @@ -134,6 +134,7 @@ return -ENOMEM; INIT_LIST_HEAD(&t->devices); + init_rwsem(&t->devices_lock); if (!num_targets) num_targets = KEYS_PER_NODE; @@ -362,15 +363,19 @@ return -ENODEV; } + down_write(&t->devices_lock); + dd = find_device(&t->devices, dev); if (!dd) { dd = kmalloc(sizeof(*dd), GFP_KERNEL); - if (!dd) - return -ENOMEM; + if (!dd) { + r = -ENOMEM; + goto unlock_ret_r; + } if ((r = dm_get_table_device(t->md, dev, mode, &dd->dm_dev))) { kfree(dd); - return r; + goto unlock_ret_r; } refcount_set(&dd->count, 1); @@ -380,12 +385,17 @@ } else if (dd->dm_dev->mode != (mode | dd->dm_dev->mode)) { r = upgrade_mode(dd, mode, t->md); if (r) - return r; + goto unlock_ret_r; } refcount_inc(&dd->count); out: + up_write(&t->devices_lock); *result = dd->dm_dev; return 0; + +unlock_ret_r: + up_write(&t->devices_lock); + return r; } EXPORT_SYMBOL(dm_get_device); @@ -421,9 +431,12 @@ void dm_put_device(struct dm_target *ti, struct dm_dev *d) { int found = 0; - struct list_head *devices = &ti->table->devices; + struct dm_table *t = ti->table; + struct list_head *devices = &t->devices; struct dm_dev_internal *dd; + down_write(&t->devices_lock); + list_for_each_entry(dd, devices, list) { if (dd->dm_dev == d) { found = 1; @@ -432,14 +445,17 @@ } if (!found) { DMERR("%s: device %s not in table devices list", - dm_device_name(ti->table->md), d->name); - return; + dm_device_name(t->md), d->name); + goto unlock_ret; } if (refcount_dec_and_test(&dd->count)) { - dm_put_table_device(ti->table->md, d); + dm_put_table_device(t->md, d); list_del(&dd->list); kfree(dd); } + +unlock_ret: + up_write(&t->devices_lock); } EXPORT_SYMBOL(dm_put_device); diff -u linux-6.2.0/drivers/md/dm.c linux-6.2.0/drivers/md/dm.c --- linux-6.2.0/drivers/md/dm.c +++ linux-6.2.0/drivers/md/dm.c @@ -707,24 +707,6 @@ rcu_read_unlock(); } -static inline struct dm_table *dm_get_live_table_bio(struct mapped_device *md, - int *srcu_idx, blk_opf_t bio_opf) -{ - if (bio_opf & REQ_NOWAIT) - return dm_get_live_table_fast(md); - else - return dm_get_live_table(md, srcu_idx); -} - -static inline void dm_put_live_table_bio(struct mapped_device *md, int srcu_idx, - blk_opf_t bio_opf) -{ - if (bio_opf & REQ_NOWAIT) - dm_put_live_table_fast(md); - else - dm_put_live_table(md, srcu_idx); -} - static char *_dm_claim_ptr = "I belong to device-mapper"; /* @@ -1792,9 +1774,8 @@ struct mapped_device *md = bio->bi_bdev->bd_disk->private_data; int srcu_idx; struct dm_table *map; - blk_opf_t bio_opf = bio->bi_opf; - map = dm_get_live_table_bio(md, &srcu_idx, bio_opf); + map = dm_get_live_table(md, &srcu_idx); /* If suspended, or map not yet available, queue this IO for later */ if (unlikely(test_bit(DMF_BLOCK_IO_FOR_SUSPEND, &md->flags)) || @@ -1810,7 +1791,7 @@ dm_split_and_process_bio(md, map, bio); out: - dm_put_live_table_bio(md, srcu_idx, bio_opf); + dm_put_live_table(md, srcu_idx); } static bool dm_poll_dm_io(struct dm_io *io, struct io_comp_batch *iob, diff -u linux-6.2.0/drivers/md/md-bitmap.c linux-6.2.0/drivers/md/md-bitmap.c --- linux-6.2.0/drivers/md/md-bitmap.c +++ linux-6.2.0/drivers/md/md-bitmap.c @@ -2481,6 +2481,10 @@ if (backlog > COUNTER_MAX) return -EINVAL; + rv = mddev_lock(mddev); + if (rv) + return rv; + /* * Without write mostly device, it doesn't make sense to set * backlog for max_write_behind. @@ -2494,6 +2498,7 @@ if (!has_write_mostly) { pr_warn_ratelimited("%s: can't set backlog, no write mostly device available\n", mdname(mddev)); + mddev_unlock(mddev); return -EINVAL; } @@ -2504,13 +2509,13 @@ mddev_destroy_serial_pool(mddev, NULL, false); } else if (backlog && !mddev->serial_info_pool) { /* serial_info_pool is needed since backlog is not zero */ - struct md_rdev *rdev; - rdev_for_each(rdev, mddev) mddev_create_serial_pool(mddev, rdev, false); } if (old_mwb != backlog) md_bitmap_update_sb(mddev->bitmap); + + mddev_unlock(mddev); return len; } diff -u linux-6.2.0/drivers/md/md.c linux-6.2.0/drivers/md/md.c --- linux-6.2.0/drivers/md/md.c +++ linux-6.2.0/drivers/md/md.c @@ -380,6 +380,10 @@ static LIST_HEAD(all_mddevs); static DEFINE_SPINLOCK(all_mddevs_lock); +static bool is_md_suspended(struct mddev *mddev) +{ + return percpu_ref_is_dying(&mddev->active_io); +} /* Rather than calling directly into the personality make_request function, * IO requests come here first so that we can check if the device is * being suspended pending a reconfiguration. @@ -389,7 +393,7 @@ */ static bool is_suspended(struct mddev *mddev, struct bio *bio) { - if (mddev->suspended) + if (is_md_suspended(mddev)) return true; if (bio_data_dir(bio) != WRITE) return false; @@ -405,12 +409,10 @@ void md_handle_request(struct mddev *mddev, struct bio *bio) { check_suspended: - rcu_read_lock(); if (is_suspended(mddev, bio)) { DEFINE_WAIT(__wait); /* Bail out if REQ_NOWAIT is set for the bio */ if (bio->bi_opf & REQ_NOWAIT) { - rcu_read_unlock(); bio_wouldblock_error(bio); return; } @@ -419,23 +421,19 @@ TASK_UNINTERRUPTIBLE); if (!is_suspended(mddev, bio)) break; - rcu_read_unlock(); schedule(); - rcu_read_lock(); } finish_wait(&mddev->sb_wait, &__wait); } - atomic_inc(&mddev->active_io); - rcu_read_unlock(); + if (!percpu_ref_tryget_live(&mddev->active_io)) + goto check_suspended; if (!mddev->pers->make_request(mddev, bio)) { - atomic_dec(&mddev->active_io); - wake_up(&mddev->sb_wait); + percpu_ref_put(&mddev->active_io); goto check_suspended; } - if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended) - wake_up(&mddev->sb_wait); + percpu_ref_put(&mddev->active_io); } EXPORT_SYMBOL(md_handle_request); @@ -483,11 +481,10 @@ lockdep_assert_held(&mddev->reconfig_mutex); if (mddev->suspended++) return; - synchronize_rcu(); wake_up(&mddev->sb_wait); set_bit(MD_ALLOW_SB_UPDATE, &mddev->flags); - smp_mb__after_atomic(); - wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); + percpu_ref_kill(&mddev->active_io); + wait_event(mddev->sb_wait, percpu_ref_is_zero(&mddev->active_io)); mddev->pers->quiesce(mddev, 1); clear_bit_unlock(MD_ALLOW_SB_UPDATE, &mddev->flags); wait_event(mddev->sb_wait, !test_bit(MD_UPDATING_SB, &mddev->flags)); @@ -500,11 +497,14 @@ void mddev_resume(struct mddev *mddev) { - /* entred the memalloc scope from mddev_suspend() */ - memalloc_noio_restore(mddev->noio_flag); lockdep_assert_held(&mddev->reconfig_mutex); if (--mddev->suspended) return; + + /* entred the memalloc scope from mddev_suspend() */ + memalloc_noio_restore(mddev->noio_flag); + + percpu_ref_resurrect(&mddev->active_io); wake_up(&mddev->sb_wait); mddev->pers->quiesce(mddev, 0); @@ -683,7 +683,6 @@ timer_setup(&mddev->safemode_timer, md_safemode_timeout, 0); atomic_set(&mddev->active, 1); atomic_set(&mddev->openers, 0); - atomic_set(&mddev->active_io, 0); spin_lock_init(&mddev->lock); atomic_set(&mddev->flush_pending, 0); init_waitqueue_head(&mddev->sb_wait); @@ -5766,6 +5765,12 @@ } static int start_dirty_degraded; +static void active_io_release(struct percpu_ref *ref) +{ + struct mddev *mddev = container_of(ref, struct mddev, active_io); + + wake_up(&mddev->sb_wait); +} int md_run(struct mddev *mddev) { @@ -5846,10 +5851,15 @@ nowait = nowait && bdev_nowait(rdev->bdev); } + err = percpu_ref_init(&mddev->active_io, active_io_release, + PERCPU_REF_ALLOW_REINIT, GFP_KERNEL); + if (err) + return err; + if (!bioset_initialized(&mddev->bio_set)) { err = bioset_init(&mddev->bio_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); if (err) - return err; + goto exit_active_io; } if (!bioset_initialized(&mddev->sync_set)) { err = bioset_init(&mddev->sync_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); @@ -6037,6 +6047,8 @@ bioset_exit(&mddev->sync_set); exit_bio_set: bioset_exit(&mddev->bio_set); +exit_active_io: + percpu_ref_exit(&mddev->active_io); return err; } EXPORT_SYMBOL_GPL(md_run); @@ -6225,7 +6237,7 @@ static void mddev_detach(struct mddev *mddev) { md_bitmap_wait_behind_writes(mddev); - if (mddev->pers && mddev->pers->quiesce && !mddev->suspended) { + if (mddev->pers && mddev->pers->quiesce && !is_md_suspended(mddev)) { mddev->pers->quiesce(mddev, 1); mddev->pers->quiesce(mddev, 0); } @@ -6252,6 +6264,10 @@ mddev->to_remove = &md_redundancy_group; module_put(pers->owner); clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); + + percpu_ref_exit(&mddev->active_io); + bioset_exit(&mddev->bio_set); + bioset_exit(&mddev->sync_set); } void md_stop(struct mddev *mddev) @@ -6263,8 +6279,7 @@ */ __md_stop_writes(mddev); __md_stop(mddev); - bioset_exit(&mddev->bio_set); - bioset_exit(&mddev->sync_set); + percpu_ref_exit(&mddev->writes_pending); } EXPORT_SYMBOL_GPL(md_stop); @@ -7836,9 +7851,6 @@ struct mddev *mddev = disk->private_data; percpu_ref_exit(&mddev->writes_pending); - bioset_exit(&mddev->bio_set); - bioset_exit(&mddev->sync_set); - mddev_free(mddev); } @@ -7969,6 +7981,9 @@ return; mddev->pers->error_handler(mddev, rdev); + if (mddev->pers->level == 0 || mddev->pers->level == LEVEL_LINEAR) + return; + if (mddev->degraded && !test_bit(MD_BROKEN, &mddev->flags)) set_bit(MD_RECOVERY_RECOVER, &mddev->recovery); sysfs_notify_dirent_safe(rdev->sysfs_state); @@ -8204,7 +8219,7 @@ spin_unlock(&all_mddevs_lock); if (to_put) - mddev_put(mddev); + mddev_put(to_put); return next_mddev; } @@ -8539,7 +8554,7 @@ return true; wait_event(mddev->sb_wait, !test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags) || - mddev->suspended); + is_md_suspended(mddev)); if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) { percpu_ref_put(&mddev->writes_pending); return false; @@ -9267,7 +9282,7 @@ wake_up(&mddev->sb_wait); } - if (mddev->suspended) + if (is_md_suspended(mddev)) return; if (mddev->bitmap) diff -u linux-6.2.0/drivers/md/raid0.c linux-6.2.0/drivers/md/raid0.c --- linux-6.2.0/drivers/md/raid0.c +++ linux-6.2.0/drivers/md/raid0.c @@ -558,14 +558,50 @@ bio_endio(bio); } -static bool raid0_make_request(struct mddev *mddev, struct bio *bio) +static void raid0_map_submit_bio(struct mddev *mddev, struct bio *bio) { struct r0conf *conf = mddev->private; struct strip_zone *zone; struct md_rdev *tmp_dev; - sector_t bio_sector; + sector_t bio_sector = bio->bi_iter.bi_sector; + sector_t sector = bio_sector; + + md_account_bio(mddev, &bio); + + zone = find_zone(mddev->private, §or); + switch (conf->layout) { + case RAID0_ORIG_LAYOUT: + tmp_dev = map_sector(mddev, zone, bio_sector, §or); + break; + case RAID0_ALT_MULTIZONE_LAYOUT: + tmp_dev = map_sector(mddev, zone, sector, §or); + break; + default: + WARN(1, "md/raid0:%s: Invalid layout\n", mdname(mddev)); + bio_io_error(bio); + return; + } + + if (unlikely(is_rdev_broken(tmp_dev))) { + bio_io_error(bio); + md_error(mddev, tmp_dev); + return; + } + + bio_set_dev(bio, tmp_dev->bdev); + bio->bi_iter.bi_sector = sector + zone->dev_start + + tmp_dev->data_offset; + + if (mddev->gendisk) + trace_block_bio_remap(bio, disk_devt(mddev->gendisk), + bio_sector); + mddev_check_write_zeroes(mddev, bio); + submit_bio_noacct(bio); +} + +static bool raid0_make_request(struct mddev *mddev, struct bio *bio) +{ sector_t sector; - sector_t orig_sector; unsigned chunk_sects; unsigned sectors; @@ -578,8 +614,7 @@ return true; } - bio_sector = bio->bi_iter.bi_sector; - sector = bio_sector; + sector = bio->bi_iter.bi_sector; chunk_sects = mddev->chunk_sectors; sectors = chunk_sects - @@ -587,49 +622,15 @@ ? (sector & (chunk_sects-1)) : sector_div(sector, chunk_sects)); - /* Restore due to sector_div */ - sector = bio_sector; - if (sectors < bio_sectors(bio)) { struct bio *split = bio_split(bio, sectors, GFP_NOIO, &mddev->bio_set); bio_chain(split, bio); - submit_bio_noacct(bio); + raid0_map_submit_bio(mddev, bio); bio = split; } - if (bio->bi_pool != &mddev->bio_set) - md_account_bio(mddev, &bio); - - orig_sector = sector; - zone = find_zone(mddev->private, §or); - switch (conf->layout) { - case RAID0_ORIG_LAYOUT: - tmp_dev = map_sector(mddev, zone, orig_sector, §or); - break; - case RAID0_ALT_MULTIZONE_LAYOUT: - tmp_dev = map_sector(mddev, zone, sector, §or); - break; - default: - WARN(1, "md/raid0:%s: Invalid layout\n", mdname(mddev)); - bio_io_error(bio); - return true; - } - - if (unlikely(is_mddev_broken(tmp_dev, "raid0"))) { - bio_io_error(bio); - return true; - } - - bio_set_dev(bio, tmp_dev->bdev); - bio->bi_iter.bi_sector = sector + zone->dev_start + - tmp_dev->data_offset; - - if (mddev->gendisk) - trace_block_bio_remap(bio, disk_devt(mddev->gendisk), - bio_sector); - mddev_check_write_zeroes(mddev, bio); - submit_bio_noacct(bio); + raid0_map_submit_bio(mddev, bio); return true; } @@ -639,6 +640,16 @@ return; } +static void raid0_error(struct mddev *mddev, struct md_rdev *rdev) +{ + if (!test_and_set_bit(MD_BROKEN, &mddev->flags)) { + char *md_name = mdname(mddev); + + pr_crit("md/raid0%s: Disk failure on %pg detected, failing array.\n", + md_name, rdev->bdev); + } +} + static void *raid0_takeover_raid45(struct mddev *mddev) { struct md_rdev *rdev; @@ -814,6 +825,7 @@ .size = raid0_size, .takeover = raid0_takeover, .quiesce = raid0_quiesce, + .error_handler = raid0_error, }; static int __init raid0_init (void) diff -u linux-6.2.0/drivers/md/raid1.c linux-6.2.0/drivers/md/raid1.c --- linux-6.2.0/drivers/md/raid1.c +++ linux-6.2.0/drivers/md/raid1.c @@ -1828,6 +1828,9 @@ int number = rdev->raid_disk; struct raid1_info *p = conf->mirrors + number; + if (unlikely(number >= conf->raid_disks)) + goto abort; + if (rdev != p->rdev) p = conf->mirrors + conf->raid_disks + number; diff -u linux-6.2.0/drivers/md/raid10.c linux-6.2.0/drivers/md/raid10.c --- linux-6.2.0/drivers/md/raid10.c +++ linux-6.2.0/drivers/md/raid10.c @@ -1317,6 +1317,25 @@ } } +static struct md_rdev *dereference_rdev_and_rrdev(struct raid10_info *mirror, + struct md_rdev **prrdev) +{ + struct md_rdev *rdev, *rrdev; + + rrdev = rcu_dereference(mirror->replacement); + /* + * Read replacement first to prevent reading both rdev and + * replacement as NULL during replacement replace rdev. + */ + smp_mb(); + rdev = rcu_dereference(mirror->rdev); + if (rdev == rrdev) + rrdev = NULL; + + *prrdev = rrdev; + return rdev; +} + static void wait_blocked_dev(struct mddev *mddev, struct r10bio *r10_bio) { int i; @@ -1327,11 +1346,9 @@ blocked_rdev = NULL; rcu_read_lock(); for (i = 0; i < conf->copies; i++) { - struct md_rdev *rdev = rcu_dereference(conf->mirrors[i].rdev); - struct md_rdev *rrdev = rcu_dereference( - conf->mirrors[i].replacement); - if (rdev == rrdev) - rrdev = NULL; + struct md_rdev *rdev, *rrdev; + + rdev = dereference_rdev_and_rrdev(&conf->mirrors[i], &rrdev); if (rdev && unlikely(test_bit(Blocked, &rdev->flags))) { atomic_inc(&rdev->nr_pending); blocked_rdev = rdev; @@ -1460,15 +1477,7 @@ int d = r10_bio->devs[i].devnum; struct md_rdev *rdev, *rrdev; - rrdev = rcu_dereference(conf->mirrors[d].replacement); - /* - * Read replacement first to prevent reading both rdev and - * replacement as NULL during replacement replace rdev. - */ - smp_mb(); - rdev = rcu_dereference(conf->mirrors[d].rdev); - if (rdev == rrdev) - rrdev = NULL; + rdev = dereference_rdev_and_rrdev(&conf->mirrors[d], &rrdev); if (rdev && (test_bit(Faulty, &rdev->flags))) rdev = NULL; if (rrdev && (test_bit(Faulty, &rrdev->flags))) @@ -1775,10 +1784,9 @@ */ rcu_read_lock(); for (disk = 0; disk < geo->raid_disks; disk++) { - struct md_rdev *rdev = rcu_dereference(conf->mirrors[disk].rdev); - struct md_rdev *rrdev = rcu_dereference( - conf->mirrors[disk].replacement); + struct md_rdev *rdev, *rrdev; + rdev = dereference_rdev_and_rrdev(&conf->mirrors[disk], &rrdev); r10_bio->devs[disk].bio = NULL; r10_bio->devs[disk].repl_bio = NULL; diff -u linux-6.2.0/drivers/md/raid5.c linux-6.2.0/drivers/md/raid5.c --- linux-6.2.0/drivers/md/raid5.c +++ linux-6.2.0/drivers/md/raid5.c @@ -854,6 +854,13 @@ set_bit(R5_INACTIVE_BLOCKED, &conf->cache_state); r5l_wake_reclaim(conf->log, 0); + + /* release batch_last before wait to avoid risk of deadlock */ + if (ctx && ctx->batch_last) { + raid5_release_stripe(ctx->batch_last); + ctx->batch_last = NULL; + } + wait_event_lock_irq(conf->wait_for_stripe, is_inactive_blocked(conf, hash), *(conf->hash_locks + hash)); diff -u linux-6.2.0/drivers/media/cec/core/cec-adap.c linux-6.2.0/drivers/media/cec/core/cec-adap.c --- linux-6.2.0/drivers/media/cec/core/cec-adap.c +++ linux-6.2.0/drivers/media/cec/core/cec-adap.c @@ -385,8 +385,8 @@ cec_queue_msg_monitor(adap, &data->msg, 1); if (!data->blocking && data->msg.sequence) - /* Allow drivers to process the message first */ - call_op(adap, received, &data->msg); + /* Allow drivers to react to a canceled transmit */ + call_void_op(adap, adap_nb_transmit_canceled, &data->msg); cec_data_completed(data); } @@ -1345,7 +1345,7 @@ cec_flush(adap); wake_up_interruptible(&adap->kthread_waitq); cec_post_state_event(adap); - call_void_op(adap, adap_configured, false); + call_void_op(adap, adap_unconfigured); } /* @@ -1536,7 +1536,7 @@ adap->kthread_config = NULL; complete(&adap->config_completion); mutex_unlock(&adap->lock); - call_void_op(adap, adap_configured, true); + call_void_op(adap, configured); return 0; unconfigure: diff -u linux-6.2.0/drivers/media/i2c/Kconfig linux-6.2.0/drivers/media/i2c/Kconfig --- linux-6.2.0/drivers/media/i2c/Kconfig +++ linux-6.2.0/drivers/media/i2c/Kconfig @@ -25,8 +25,15 @@ # V4L2 I2C drivers that are related with Camera support # -menu "Camera sensor devices" - visible if MEDIA_CAMERA_SUPPORT +menuconfig VIDEO_CAMERA_SENSOR + bool "Camera sensor devices" + depends on MEDIA_CAMERA_SUPPORT && I2C + select MEDIA_CONTROLLER + select V4L2_FWNODE + select VIDEO_V4L2_SUBDEV_API + default y + +if VIDEO_CAMERA_SENSOR config VIDEO_APTINA_PLL tristate @@ -809,7 +816,7 @@ source "drivers/media/i2c/et8ek8/Kconfig" source "drivers/media/i2c/m5mols/Kconfig" -endmenu +endif menu "Lens drivers" visible if MEDIA_CAMERA_SUPPORT diff -u linux-6.2.0/drivers/media/i2c/ov5640.c linux-6.2.0/drivers/media/i2c/ov5640.c --- linux-6.2.0/drivers/media/i2c/ov5640.c +++ linux-6.2.0/drivers/media/i2c/ov5640.c @@ -557,9 +557,7 @@ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0}, - {0x501f, 0x00, 0, 0}, {0x4407, 0x04, 0, 0}, - {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, - {0x4837, 0x0a, 0, 0}, {0x3824, 0x02, 0, 0}, + {0x501f, 0x00, 0, 0}, {0x440e, 0x00, 0, 0}, {0x4837, 0x0a, 0, 0}, {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0}, @@ -623,7 +621,8 @@ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0}, {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0}, {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, - {0x4407, 0x04, 0, 0}, {0x5001, 0xa3, 0, 0}, + {0x4407, 0x04, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0}, + {0x3824, 0x02, 0, 0}, {0x5001, 0xa3, 0, 0}, }; static const struct reg_value ov5640_setting_720P_1280_720[] = { @@ -2442,16 +2441,13 @@ static void ov5640_powerup_sequence(struct ov5640_dev *sensor) { if (sensor->pwdn_gpio) { - gpiod_set_value_cansleep(sensor->reset_gpio, 0); + gpiod_set_value_cansleep(sensor->reset_gpio, 1); /* camera power cycle */ ov5640_power(sensor, false); - usleep_range(5000, 10000); + usleep_range(5000, 10000); /* t2 */ ov5640_power(sensor, true); - usleep_range(5000, 10000); - - gpiod_set_value_cansleep(sensor->reset_gpio, 1); - usleep_range(1000, 2000); + usleep_range(1000, 2000); /* t3 */ gpiod_set_value_cansleep(sensor->reset_gpio, 0); } else { @@ -2459,7 +2455,7 @@ ov5640_write_reg(sensor, OV5640_REG_SYS_CTRL0, OV5640_REG_SYS_CTRL0_SW_RST); } - usleep_range(20000, 25000); + usleep_range(20000, 25000); /* t4 */ /* * software standby: allows registers programming; @@ -2532,9 +2528,9 @@ * "ov5640_set_stream_mipi()") * [4] = 0 : Power up MIPI HS Tx * [3] = 0 : Power up MIPI LS Rx - * [2] = 0 : MIPI interface disabled + * [2] = 1 : MIPI interface enabled */ - ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x40); + ret = ov5640_write_reg(sensor, OV5640_REG_IO_MIPI_CTRL00, 0x44); if (ret) return ret; diff -u linux-6.2.0/drivers/media/pci/cx23885/cx23885-video.c linux-6.2.0/drivers/media/pci/cx23885/cx23885-video.c --- linux-6.2.0/drivers/media/pci/cx23885/cx23885-video.c +++ linux-6.2.0/drivers/media/pci/cx23885/cx23885-video.c @@ -413,7 +413,7 @@ dev->height >> 1); break; default: - BUG(); + return -EINVAL; /* should not happen */ } dprintk(2, "[%p/%d] buffer_init - %dx%d %dbpp 0x%08x - dma=0x%08lx\n", buf, buf->vb.vb2_buf.index, diff -u linux-6.2.0/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c linux-6.2.0/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c --- linux-6.2.0/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c +++ linux-6.2.0/drivers/media/pci/intel/ipu3/ipu3-cio2-main.c @@ -354,7 +354,7 @@ void __iomem *const base = cio2->base; u8 lanes, csi2bus = q->csi2.port; u8 sensor_vc = SENSOR_VIR_CH_DFLT; - struct cio2_csi2_timing timing; + struct cio2_csi2_timing timing = { 0 }; int i, r; fmt = cio2_find_format(NULL, &q->subdev_fmt.code); diff -u linux-6.2.0/drivers/media/platform/amphion/vdec.c linux-6.2.0/drivers/media/platform/amphion/vdec.c --- linux-6.2.0/drivers/media/platform/amphion/vdec.c +++ linux-6.2.0/drivers/media/platform/amphion/vdec.c @@ -278,7 +278,8 @@ vdec->state = VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE; if (inst->state != pre_state) - vpu_trace(inst->dev, "[%d] %d -> %d\n", inst->id, pre_state, inst->state); + vpu_trace(inst->dev, "[%d] %s -> %s\n", inst->id, + vpu_codec_state_name(pre_state), vpu_codec_state_name(inst->state)); if (inst->state == VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE) vdec_handle_resolution_change(inst); @@ -720,6 +721,21 @@ dev_info(inst->dev, "[%d] buf[%d] has been decoded\n", inst->id, info->id); vpu_set_buffer_state(vbuf, VPU_BUF_STATE_DECODED); vdec->decoded_frame_count++; + if (vdec->params.display_delay_enable) { + struct vpu_format *cur_fmt; + + cur_fmt = vpu_get_format(inst, inst->cap_format.type); + vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY); + for (int i = 0; i < vbuf->vb2_buf.num_planes; i++) + vb2_set_plane_payload(&vbuf->vb2_buf, + i, vpu_get_fmt_plane_size(cur_fmt, i)); + vbuf->field = cur_fmt->field; + vbuf->sequence = vdec->sequence++; + dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp); + + v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); + vdec->display_frame_count++; + } exit: vpu_inst_unlock(inst); @@ -747,14 +763,14 @@ struct vpu_format *cur_fmt; struct vpu_vb2_buffer *vpu_buf; struct vb2_v4l2_buffer *vbuf; - u32 sequence; int i; if (!frame) return; vpu_inst_lock(inst); - sequence = vdec->sequence++; + if (!vdec->params.display_delay_enable) + vdec->sequence++; vpu_buf = vdec_find_buffer(inst, frame->luma); vpu_inst_unlock(inst); if (!vpu_buf) { @@ -773,13 +789,17 @@ dev_err(inst->dev, "[%d] buffer id(%d, %d) dismatch\n", inst->id, vbuf->vb2_buf.index, frame->id); + if (vpu_get_buffer_state(vbuf) == VPU_BUF_STATE_READY && vdec->params.display_delay_enable) + return; + if (vpu_get_buffer_state(vbuf) != VPU_BUF_STATE_DECODED) dev_err(inst->dev, "[%d] buffer(%d) ready without decoded\n", inst->id, frame->id); + vpu_set_buffer_state(vbuf, VPU_BUF_STATE_READY); for (i = 0; i < vbuf->vb2_buf.num_planes; i++) vb2_set_plane_payload(&vbuf->vb2_buf, i, vpu_get_fmt_plane_size(cur_fmt, i)); vbuf->field = cur_fmt->field; - vbuf->sequence = sequence; + vbuf->sequence = vdec->sequence; dev_dbg(inst->dev, "[%d][OUTPUT TS]%32lld\n", inst->id, vbuf->vb2_buf.timestamp); v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_DONE); @@ -978,6 +998,7 @@ { struct vdec_t *vdec = inst->priv; struct vpu_fs_info info; + int ret; if (!vdec->req_frame_count) return 0; @@ -985,7 +1006,9 @@ memset(&info, 0, sizeof(info)); info.type = MEM_RES_FRAME; info.tag = vdec->seq_tag + 0xf0; - vpu_session_alloc_fs(inst, &info); + ret = vpu_session_alloc_fs(inst, &info); + if (ret) + return ret; vdec->req_frame_count--; return 0; @@ -1016,8 +1039,8 @@ return -EINVAL; } - dev_dbg(inst->dev, "[%d] state = %d, alloc fs %d, tag = 0x%x\n", - inst->id, inst->state, vbuf->vb2_buf.index, vdec->seq_tag); + dev_dbg(inst->dev, "[%d] state = %s, alloc fs %d, tag = 0x%x\n", + inst->id, vpu_codec_state_name(inst->state), vbuf->vb2_buf.index, vdec->seq_tag); vpu_buf = to_vpu_vb2_buffer(vbuf); memset(&info, 0, sizeof(info)); @@ -1379,7 +1402,7 @@ struct vpu_rpc_buffer_desc desc; int ret; - vpu_trace(inst->dev, "[%d] state = %d\n", inst->id, inst->state); + vpu_trace(inst->dev, "[%d] state = %s\n", inst->id, vpu_codec_state_name(inst->state)); vdec->aborting = true; vpu_iface_add_scode(inst, SCODE_PADDING_ABORT); @@ -1432,9 +1455,7 @@ { if (inst->id != VPU_INST_NULL_ID) vpu_trace(inst->dev, "[%d]\n", inst->id); - vpu_inst_lock(inst); vdec_stop(inst, true); - vpu_inst_unlock(inst); } static void vdec_cleanup(struct vpu_inst *inst) diff -u linux-6.2.0/drivers/media/platform/amphion/venc.c linux-6.2.0/drivers/media/platform/amphion/venc.c --- linux-6.2.0/drivers/media/platform/amphion/venc.c +++ linux-6.2.0/drivers/media/platform/amphion/venc.c @@ -277,7 +277,7 @@ { struct vpu_inst *inst = to_inst(file); struct venc_t *venc = inst->priv; - struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe; + struct v4l2_fract *timeperframe; if (!parm) return -EINVAL; @@ -288,6 +288,7 @@ if (!vpu_helper_check_type(inst, parm->type)) return -EINVAL; + timeperframe = &parm->parm.capture.timeperframe; parm->parm.capture.capability = V4L2_CAP_TIMEPERFRAME; parm->parm.capture.readbuffers = 0; timeperframe->numerator = venc->params.frame_rate.numerator; @@ -300,7 +301,7 @@ { struct vpu_inst *inst = to_inst(file); struct venc_t *venc = inst->priv; - struct v4l2_fract *timeperframe = &parm->parm.capture.timeperframe; + struct v4l2_fract *timeperframe; unsigned long n, d; if (!parm) @@ -312,6 +313,7 @@ if (!vpu_helper_check_type(inst, parm->type)) return -EINVAL; + timeperframe = &parm->parm.capture.timeperframe; if (!timeperframe->numerator) timeperframe->numerator = venc->params.frame_rate.numerator; if (!timeperframe->denominator) diff -u linux-6.2.0/drivers/media/platform/amphion/vpu_core.c linux-6.2.0/drivers/media/platform/amphion/vpu_core.c --- linux-6.2.0/drivers/media/platform/amphion/vpu_core.c +++ linux-6.2.0/drivers/media/platform/amphion/vpu_core.c @@ -88,6 +88,8 @@ core->supported_instance_count = min(core->supported_instance_count, count); } + if (core->supported_instance_count >= BITS_PER_TYPE(core->instance_mask)) + core->supported_instance_count = BITS_PER_TYPE(core->instance_mask); core->fw_version = fw_version; vpu_core_set_state(core, VPU_CORE_ACTIVE); diff -u linux-6.2.0/drivers/media/platform/amphion/vpu_v4l2.c linux-6.2.0/drivers/media/platform/amphion/vpu_v4l2.c --- linux-6.2.0/drivers/media/platform/amphion/vpu_v4l2.c +++ linux-6.2.0/drivers/media/platform/amphion/vpu_v4l2.c @@ -489,6 +489,11 @@ for (i = 0; i < cur_fmt->mem_planes; i++) psize[i] = vpu_get_fmt_plane_size(cur_fmt, i); + if (V4L2_TYPE_IS_OUTPUT(vq->type) && inst->state == VPU_CODEC_STATE_SEEK) { + vpu_trace(inst->dev, "reinit when VIDIOC_REQBUFS(OUTPUT, 0)\n"); + call_void_vop(inst, release); + } + return 0; } @@ -773,9 +778,9 @@ v4l2_m2m_ctx_release(inst->fh.m2m_ctx); inst->fh.m2m_ctx = NULL; } + call_void_vop(inst, release); vpu_inst_unlock(inst); - call_void_vop(inst, release); vpu_inst_unregister(inst); vpu_inst_put(inst); diff -u linux-6.2.0/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c linux-6.2.0/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c --- linux-6.2.0/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ linux-6.2.0/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -1794,6 +1794,7 @@ { 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); diff -u linux-6.2.0/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c linux-6.2.0/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c --- linux-6.2.0/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c +++ linux-6.2.0/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c @@ -246,6 +246,7 @@ mtk_vcodec_mem_free(ctx, mem); kfree(lat_buf->private_data); + lat_buf->private_data = NULL; } } @@ -312,6 +313,7 @@ err = mtk_vcodec_mem_alloc(ctx, &msg_queue->wdma_addr); if (err) { mtk_v4l2_err("failed to allocate wdma_addr buf"); + msg_queue->wdma_addr.size = 0; return -ENOMEM; } msg_queue->wdma_rptr_addr = msg_queue->wdma_addr.dma_addr; diff -u linux-6.2.0/drivers/media/usb/dvb-usb-v2/az6007.c linux-6.2.0/drivers/media/usb/dvb-usb-v2/az6007.c --- linux-6.2.0/drivers/media/usb/dvb-usb-v2/az6007.c +++ linux-6.2.0/drivers/media/usb/dvb-usb-v2/az6007.c @@ -788,6 +788,10 @@ if (az6007_xfer_debug) printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n", addr, msgs[i].len); + if (msgs[i].len < 1) { + ret = -EIO; + goto err; + } req = AZ6007_I2C_WR; index = msgs[i].buf[0]; value = addr | (1 << 8); @@ -802,6 +806,10 @@ if (az6007_xfer_debug) printk(KERN_DEBUG "az6007: I2C R addr=0x%x len=%d\n", addr, msgs[i].len); + if (msgs[i].len < 1) { + ret = -EIO; + goto err; + } req = AZ6007_I2C_RD; index = msgs[i].buf[0]; value = addr; diff -u linux-6.2.0/drivers/media/usb/dvb-usb/dw2102.c linux-6.2.0/drivers/media/usb/dvb-usb/dw2102.c --- linux-6.2.0/drivers/media/usb/dvb-usb/dw2102.c +++ linux-6.2.0/drivers/media/usb/dvb-usb/dw2102.c @@ -128,6 +128,10 @@ switch (num) { case 2: + if (msg[0].len < 1) { + num = -EOPNOTSUPP; + break; + } /* read stv0299 register */ value = msg[0].buf[0];/* register */ for (i = 0; i < msg[1].len; i++) { @@ -139,6 +143,10 @@ case 1: switch (msg[0].addr) { case 0x68: + if (msg[0].len < 2) { + num = -EOPNOTSUPP; + break; + } /* write to stv0299 register */ buf6[0] = 0x2a; buf6[1] = msg[0].buf[0]; @@ -148,6 +156,10 @@ break; case 0x60: if (msg[0].flags == 0) { + if (msg[0].len < 4) { + num = -EOPNOTSUPP; + break; + } /* write to tuner pll */ buf6[0] = 0x2c; buf6[1] = 5; @@ -159,6 +171,10 @@ dw210x_op_rw(d->udev, 0xb2, 0, 0, buf6, 7, DW210X_WRITE_MSG); } else { + if (msg[0].len < 1) { + num = -EOPNOTSUPP; + break; + } /* read from tuner */ dw210x_op_rw(d->udev, 0xb5, 0, 0, buf6, 1, DW210X_READ_MSG); @@ -166,12 +182,20 @@ } break; case (DW2102_RC_QUERY): + if (msg[0].len < 2) { + num = -EOPNOTSUPP; + break; + } dw210x_op_rw(d->udev, 0xb8, 0, 0, buf6, 2, DW210X_READ_MSG); msg[0].buf[0] = buf6[0]; msg[0].buf[1] = buf6[1]; break; case (DW2102_VOLTAGE_CTRL): + if (msg[0].len < 1) { + num = -EOPNOTSUPP; + break; + } buf6[0] = 0x30; buf6[1] = msg[0].buf[0]; dw210x_op_rw(d->udev, 0xb2, 0, 0, diff -u linux-6.2.0/drivers/media/usb/siano/smsusb.c linux-6.2.0/drivers/media/usb/siano/smsusb.c --- linux-6.2.0/drivers/media/usb/siano/smsusb.c +++ linux-6.2.0/drivers/media/usb/siano/smsusb.c @@ -455,12 +455,7 @@ rc = smscore_register_device(¶ms, &dev->coredev, 0, mdev); if (rc < 0) { pr_err("smscore_register_device(...) failed, rc %d\n", rc); - smsusb_term_device(intf); -#ifdef CONFIG_MEDIA_CONTROLLER_DVB - media_device_unregister(mdev); -#endif - kfree(mdev); - return rc; + goto err_unregister_device; } smscore_set_board_id(dev->coredev, board_id); @@ -477,8 +472,7 @@ rc = smsusb_start_streaming(dev); if (rc < 0) { pr_err("smsusb_start_streaming(...) failed\n"); - smsusb_term_device(intf); - return rc; + goto err_unregister_device; } dev->state = SMSUSB_ACTIVE; @@ -486,13 +480,20 @@ rc = smscore_start_device(dev->coredev); if (rc < 0) { pr_err("smscore_start_device(...) failed\n"); - smsusb_term_device(intf); - return rc; + goto err_unregister_device; } pr_debug("device 0x%p created\n", dev); return rc; + +err_unregister_device: + smsusb_term_device(intf); +#ifdef CONFIG_MEDIA_CONTROLLER_DVB + media_device_unregister(mdev); +#endif + kfree(mdev); + return rc; } static int smsusb_probe(struct usb_interface *intf, diff -u linux-6.2.0/drivers/media/usb/uvc/uvc_ctrl.c linux-6.2.0/drivers/media/usb/uvc/uvc_ctrl.c --- linux-6.2.0/drivers/media/usb/uvc/uvc_ctrl.c +++ linux-6.2.0/drivers/media/usb/uvc/uvc_ctrl.c @@ -1347,6 +1347,9 @@ query_menu->id = id; query_menu->index = index; + if (index >= BITS_PER_TYPE(mapping->menu_mask)) + return -EINVAL; + ret = mutex_lock_interruptible(&chain->ctrl_mutex); if (ret < 0) return -ERESTARTSYS; diff -u linux-6.2.0/drivers/misc/fastrpc.c linux-6.2.0/drivers/misc/fastrpc.c --- linux-6.2.0/drivers/misc/fastrpc.c +++ linux-6.2.0/drivers/misc/fastrpc.c @@ -754,6 +754,7 @@ { struct fastrpc_session_ctx *sess = fl->sctx; struct fastrpc_map *map = NULL; + struct sg_table *table; int err = 0; if (!fastrpc_map_lookup(fl, fd, ppmap, true)) @@ -781,11 +782,12 @@ goto attach_err; } - map->table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL); - if (IS_ERR(map->table)) { - err = PTR_ERR(map->table); + table = dma_buf_map_attachment_unlocked(map->attach, DMA_BIDIRECTIONAL); + if (IS_ERR(table)) { + err = PTR_ERR(table); goto map_err; } + map->table = table; map->phys = sg_dma_address(map->table->sgl); map->phys += ((u64)fl->sctx->sid << 32); @@ -1854,7 +1856,11 @@ return -EINVAL; } - err = fastrpc_buf_alloc(fl, fl->sctx->dev, req.size, &buf); + if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR) + err = fastrpc_remote_heap_alloc(fl, dev, req.size, &buf); + else + err = fastrpc_buf_alloc(fl, dev, req.size, &buf); + if (err) { dev_err(dev, "failed to allocate buffer\n"); return err; @@ -1893,12 +1899,8 @@ /* Add memory to static PD pool, protection thru hypervisor */ if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) { - struct qcom_scm_vmperm perm; - - perm.vmid = QCOM_SCM_VMID_HLOS; - perm.perm = QCOM_SCM_PERM_RWX; - err = qcom_scm_assign_mem(buf->phys, buf->size, - &fl->cctx->perms, &perm, 1); + err = qcom_scm_assign_mem(buf->phys, (u64)buf->size, + &fl->cctx->perms, fl->cctx->vmperms, fl->cctx->vmcount); if (err) { dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", buf->phys, buf->size, err); diff -u linux-6.2.0/drivers/mmc/host/sdhci-esdhc-imx.c linux-6.2.0/drivers/mmc/host/sdhci-esdhc-imx.c --- linux-6.2.0/drivers/mmc/host/sdhci-esdhc-imx.c +++ linux-6.2.0/drivers/mmc/host/sdhci-esdhc-imx.c @@ -171,8 +171,8 @@ #define ESDHC_FLAG_HS400 BIT(9) /* * The IP has errata ERR010450 - * uSDHC: Due to the I/O timing limit, for SDR mode, SD card clock can't - * exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz. + * uSDHC: At 1.8V due to the I/O timing limit, for SDR mode, SD card + * clock can't exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz. */ #define ESDHC_FLAG_ERR010450 BIT(10) /* The IP supports HS400ES mode */ @@ -933,7 +933,8 @@ | ESDHC_CLOCK_MASK); sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); - if (imx_data->socdata->flags & ESDHC_FLAG_ERR010450) { + if ((imx_data->socdata->flags & ESDHC_FLAG_ERR010450) && + (!(host->quirks2 & SDHCI_QUIRK2_NO_1_8_V))) { unsigned int max_clock; max_clock = imx_data->is_ddr ? 45000000 : 150000000; diff -u linux-6.2.0/drivers/mtd/spi-nor/core.c linux-6.2.0/drivers/mtd/spi-nor/core.c --- linux-6.2.0/drivers/mtd/spi-nor/core.c +++ linux-6.2.0/drivers/mtd/spi-nor/core.c @@ -770,21 +770,22 @@ ret = spi_nor_read_cr(nor, &sr_cr[1]); if (ret) return ret; - } else if (nor->params->quad_enable) { + } else if (spi_nor_get_protocol_width(nor->read_proto) == 4 && + spi_nor_get_protocol_width(nor->write_proto) == 4 && + nor->params->quad_enable) { /* * If the Status Register 2 Read command (35h) is not * supported, we should at least be sure we don't * change the value of the SR2 Quad Enable bit. * - * We can safely assume that when the Quad Enable method is - * set, the value of the QE bit is one, as a consequence of the - * nor->params->quad_enable() call. + * When the Quad Enable method is set and the buswidth is 4, we + * can safely assume that the value of the QE bit is one, as a + * consequence of the nor->params->quad_enable() call. * - * We can safely assume that the Quad Enable bit is present in - * the Status Register 2 at BIT(1). According to the JESD216 - * revB standard, BFPT DWORDS[15], bits 22:20, the 16-bit - * Write Status (01h) command is available just for the cases - * in which the QE bit is described in SR2 at BIT(1). + * According to the JESD216 revB standard, BFPT DWORDS[15], + * bits 22:20, the 16-bit Write Status (01h) command is + * available just for the cases in which the QE bit is + * described in SR2 at BIT(1). */ sr_cr[1] = SR2_QUAD_EN_BIT1; } else { diff -u linux-6.2.0/drivers/mtd/ubi/build.c linux-6.2.0/drivers/mtd/ubi/build.c --- linux-6.2.0/drivers/mtd/ubi/build.c +++ linux-6.2.0/drivers/mtd/ubi/build.c @@ -901,4 +901,11 @@ } + /* UBI cannot work on flashes with zero erasesize. */ + if (!mtd->erasesize) { + pr_err("ubi: refuse attaching mtd%d - zero erasesize flash is not supported\n", + mtd->index); + return -EINVAL; + } + if (ubi_num == UBI_DEV_NUM_AUTO) { /* Search for an empty slot in the @ubi_devices array */ diff -u linux-6.2.0/drivers/net/can/usb/gs_usb.c linux-6.2.0/drivers/net/can/usb/gs_usb.c --- linux-6.2.0/drivers/net/can/usb/gs_usb.c +++ linux-6.2.0/drivers/net/can/usb/gs_usb.c @@ -633,6 +633,9 @@ } if (hf->flags & GS_CAN_FLAG_OVERFLOW) { + stats->rx_over_errors++; + stats->rx_errors++; + skb = alloc_can_err_skb(netdev, &cf); if (!skb) goto resubmit_urb; @@ -640,8 +643,6 @@ cf->can_id |= CAN_ERR_CRTL; cf->len = CAN_ERR_DLC; cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; - stats->rx_over_errors++; - stats->rx_errors++; netif_rx(skb); } diff -u linux-6.2.0/drivers/net/dsa/microchip/ksz_common.c linux-6.2.0/drivers/net/dsa/microchip/ksz_common.c --- linux-6.2.0/drivers/net/dsa/microchip/ksz_common.c +++ linux-6.2.0/drivers/net/dsa/microchip/ksz_common.c @@ -628,10 +628,9 @@ regmap_reg_range(0x1030, 0x1030), regmap_reg_range(0x1100, 0x1115), regmap_reg_range(0x111a, 0x111f), - regmap_reg_range(0x1122, 0x1127), - regmap_reg_range(0x112a, 0x112b), - regmap_reg_range(0x1136, 0x1139), - regmap_reg_range(0x113e, 0x113f), + regmap_reg_range(0x1120, 0x112b), + regmap_reg_range(0x1134, 0x113b), + regmap_reg_range(0x113c, 0x113f), regmap_reg_range(0x1400, 0x1401), regmap_reg_range(0x1403, 0x1403), regmap_reg_range(0x1410, 0x1417), @@ -662,10 +661,9 @@ regmap_reg_range(0x2030, 0x2030), regmap_reg_range(0x2100, 0x2115), regmap_reg_range(0x211a, 0x211f), - regmap_reg_range(0x2122, 0x2127), - regmap_reg_range(0x212a, 0x212b), - regmap_reg_range(0x2136, 0x2139), - regmap_reg_range(0x213e, 0x213f), + regmap_reg_range(0x2120, 0x212b), + regmap_reg_range(0x2134, 0x213b), + regmap_reg_range(0x213c, 0x213f), regmap_reg_range(0x2400, 0x2401), regmap_reg_range(0x2403, 0x2403), regmap_reg_range(0x2410, 0x2417), @@ -696,10 +694,9 @@ regmap_reg_range(0x3030, 0x3030), regmap_reg_range(0x3100, 0x3115), regmap_reg_range(0x311a, 0x311f), - regmap_reg_range(0x3122, 0x3127), - regmap_reg_range(0x312a, 0x312b), - regmap_reg_range(0x3136, 0x3139), - regmap_reg_range(0x313e, 0x313f), + regmap_reg_range(0x3120, 0x312b), + regmap_reg_range(0x3134, 0x313b), + regmap_reg_range(0x313c, 0x313f), regmap_reg_range(0x3400, 0x3401), regmap_reg_range(0x3403, 0x3403), regmap_reg_range(0x3410, 0x3417), @@ -730,10 +727,9 @@ regmap_reg_range(0x4030, 0x4030), regmap_reg_range(0x4100, 0x4115), regmap_reg_range(0x411a, 0x411f), - regmap_reg_range(0x4122, 0x4127), - regmap_reg_range(0x412a, 0x412b), - regmap_reg_range(0x4136, 0x4139), - regmap_reg_range(0x413e, 0x413f), + regmap_reg_range(0x4120, 0x412b), + regmap_reg_range(0x4134, 0x413b), + regmap_reg_range(0x413c, 0x413f), regmap_reg_range(0x4400, 0x4401), regmap_reg_range(0x4403, 0x4403), regmap_reg_range(0x4410, 0x4417), @@ -764,10 +760,9 @@ regmap_reg_range(0x5030, 0x5030), regmap_reg_range(0x5100, 0x5115), regmap_reg_range(0x511a, 0x511f), - regmap_reg_range(0x5122, 0x5127), - regmap_reg_range(0x512a, 0x512b), - regmap_reg_range(0x5136, 0x5139), - regmap_reg_range(0x513e, 0x513f), + regmap_reg_range(0x5120, 0x512b), + regmap_reg_range(0x5134, 0x513b), + regmap_reg_range(0x513c, 0x513f), regmap_reg_range(0x5400, 0x5401), regmap_reg_range(0x5403, 0x5403), regmap_reg_range(0x5410, 0x5417), diff -u linux-6.2.0/drivers/net/dsa/mv88e6xxx/chip.c linux-6.2.0/drivers/net/dsa/mv88e6xxx/chip.c --- linux-6.2.0/drivers/net/dsa/mv88e6xxx/chip.c +++ linux-6.2.0/drivers/net/dsa/mv88e6xxx/chip.c @@ -3012,14 +3012,16 @@ * from the wrong location resulting in the switch booting * to wrong mode and inoperable. */ - mv88e6xxx_g1_wait_eeprom_done(chip); + if (chip->info->ops->get_eeprom) + mv88e6xxx_g2_eeprom_wait(chip); gpiod_set_value_cansleep(gpiod, 1); usleep_range(10000, 20000); gpiod_set_value_cansleep(gpiod, 0); usleep_range(10000, 20000); - mv88e6xxx_g1_wait_eeprom_done(chip); + if (chip->info->ops->get_eeprom) + mv88e6xxx_g2_eeprom_wait(chip); } } diff -u linux-6.2.0/drivers/net/dsa/mv88e6xxx/global2.c linux-6.2.0/drivers/net/dsa/mv88e6xxx/global2.c --- linux-6.2.0/drivers/net/dsa/mv88e6xxx/global2.c +++ linux-6.2.0/drivers/net/dsa/mv88e6xxx/global2.c @@ -340,7 +340,7 @@ * Offset 0x15: EEPROM Addr (for 8-bit data access) */ -static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) +int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) { int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY); int err; diff -u linux-6.2.0/drivers/net/dsa/mv88e6xxx/global2.h linux-6.2.0/drivers/net/dsa/mv88e6xxx/global2.h --- linux-6.2.0/drivers/net/dsa/mv88e6xxx/global2.h +++ linux-6.2.0/drivers/net/dsa/mv88e6xxx/global2.h @@ -359,6 +359,7 @@ int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target, int port); +int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip); extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops; extern const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops; diff -u linux-6.2.0/drivers/net/dsa/sja1105/sja1105.h linux-6.2.0/drivers/net/dsa/sja1105/sja1105.h --- linux-6.2.0/drivers/net/dsa/sja1105/sja1105.h +++ linux-6.2.0/drivers/net/dsa/sja1105/sja1105.h @@ -132,6 +132,8 @@ int max_frame_mem; int num_ports; bool multiple_cascade_ports; + /* Every {port, TXQ} has its own CBS shaper */ + bool fixed_cbs_mapping; enum dsa_tag_protocol tag_proto; const struct sja1105_dynamic_table_ops *dyn_ops; const struct sja1105_table_ops *static_ops; @@ -262,6 +264,8 @@ * the switch doesn't confuse them with one another. */ struct mutex mgmt_lock; + /* Serializes accesses to the FDB */ + struct mutex fdb_lock; /* PTP two-step TX timestamp ID, and its serialization lock */ spinlock_t ts_id_lock; u8 ts_id; diff -u linux-6.2.0/drivers/net/dsa/sja1105/sja1105_main.c linux-6.2.0/drivers/net/dsa/sja1105/sja1105_main.c --- linux-6.2.0/drivers/net/dsa/sja1105/sja1105_main.c +++ linux-6.2.0/drivers/net/dsa/sja1105/sja1105_main.c @@ -1805,6 +1805,7 @@ struct dsa_db db) { struct sja1105_private *priv = ds->priv; + int rc; if (!vid) { switch (db.type) { @@ -1819,12 +1820,16 @@ } } - return priv->info->fdb_add_cmd(ds, port, addr, vid); + mutex_lock(&priv->fdb_lock); + rc = priv->info->fdb_add_cmd(ds, port, addr, vid); + mutex_unlock(&priv->fdb_lock); + + return rc; } -static int sja1105_fdb_del(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid, - struct dsa_db db) +static int __sja1105_fdb_del(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid, + struct dsa_db db) { struct sja1105_private *priv = ds->priv; @@ -1844,6 +1849,20 @@ return priv->info->fdb_del_cmd(ds, port, addr, vid); } +static int sja1105_fdb_del(struct dsa_switch *ds, int port, + const unsigned char *addr, u16 vid, + struct dsa_db db) +{ + struct sja1105_private *priv = ds->priv; + int rc; + + mutex_lock(&priv->fdb_lock); + rc = __sja1105_fdb_del(ds, port, addr, vid, db); + mutex_unlock(&priv->fdb_lock); + + return rc; +} + static int sja1105_fdb_dump(struct dsa_switch *ds, int port, dsa_fdb_dump_cb_t *cb, void *data) { @@ -1875,13 +1894,14 @@ if (!(l2_lookup.destports & BIT(port))) continue; - /* We need to hide the FDB entry for unknown multicast */ - if (l2_lookup.macaddr == SJA1105_UNKNOWN_MULTICAST && - l2_lookup.mask_macaddr == SJA1105_UNKNOWN_MULTICAST) - continue; - u64_to_ether_addr(l2_lookup.macaddr, macaddr); + /* Hardware FDB is shared for fdb and mdb, "bridge fdb show" + * only wants to see unicast + */ + if (is_multicast_ether_addr(macaddr)) + continue; + /* We need to hide the dsa_8021q VLANs from the user. */ if (vid_is_dsa_8021q(l2_lookup.vlanid)) l2_lookup.vlanid = 0; @@ -1905,6 +1925,8 @@ }; int i; + mutex_lock(&priv->fdb_lock); + for (i = 0; i < SJA1105_MAX_L2_LOOKUP_COUNT; i++) { struct sja1105_l2_lookup_entry l2_lookup = {0}; u8 macaddr[ETH_ALEN]; @@ -1918,7 +1940,7 @@ if (rc) { dev_err(ds->dev, "Failed to read FDB: %pe\n", ERR_PTR(rc)); - return; + break; } if (!(l2_lookup.destports & BIT(port))) @@ -1930,14 +1952,16 @@ u64_to_ether_addr(l2_lookup.macaddr, macaddr); - rc = sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db); + rc = __sja1105_fdb_del(ds, port, macaddr, l2_lookup.vlanid, db); if (rc) { dev_err(ds->dev, "Failed to delete FDB entry %pM vid %lld: %pe\n", macaddr, l2_lookup.vlanid, ERR_PTR(rc)); - return; + break; } } + + mutex_unlock(&priv->fdb_lock); } static int sja1105_mdb_add(struct dsa_switch *ds, int port, @@ -2122,11 +2146,36 @@ } #define BYTES_PER_KBIT (1000LL / 8) +/* Port 0 (the uC port) does not have CBS shapers */ +#define SJA1110_FIXED_CBS(port, prio) ((((port) - 1) * SJA1105_NUM_TC) + (prio)) + +static int sja1105_find_cbs_shaper(struct sja1105_private *priv, + int port, int prio) +{ + int i; + + if (priv->info->fixed_cbs_mapping) { + i = SJA1110_FIXED_CBS(port, prio); + if (i >= 0 && i < priv->info->num_cbs_shapers) + return i; + + return -1; + } + + for (i = 0; i < priv->info->num_cbs_shapers; i++) + if (priv->cbs[i].port == port && priv->cbs[i].prio == prio) + return i; + + return -1; +} static int sja1105_find_unused_cbs_shaper(struct sja1105_private *priv) { int i; + if (priv->info->fixed_cbs_mapping) + return -1; + for (i = 0; i < priv->info->num_cbs_shapers; i++) if (!priv->cbs[i].idle_slope && !priv->cbs[i].send_slope) return i; @@ -2157,14 +2206,20 @@ { struct sja1105_private *priv = ds->priv; struct sja1105_cbs_entry *cbs; + s64 port_transmit_rate_kbps; int index; if (!offload->enable) return sja1105_delete_cbs_shaper(priv, port, offload->queue); - index = sja1105_find_unused_cbs_shaper(priv); - if (index < 0) - return -ENOSPC; + /* The user may be replacing an existing shaper */ + index = sja1105_find_cbs_shaper(priv, port, offload->queue); + if (index < 0) { + /* That isn't the case - see if we can allocate a new one */ + index = sja1105_find_unused_cbs_shaper(priv); + if (index < 0) + return -ENOSPC; + } cbs = &priv->cbs[index]; cbs->port = port; @@ -2174,9 +2229,17 @@ */ cbs->credit_hi = offload->hicredit; cbs->credit_lo = abs(offload->locredit); - /* User space is in kbits/sec, hardware in bytes/sec */ - cbs->idle_slope = offload->idleslope * BYTES_PER_KBIT; - cbs->send_slope = abs(offload->sendslope * BYTES_PER_KBIT); + /* User space is in kbits/sec, while the hardware in bytes/sec times + * link speed. Since the given offload->sendslope is good only for the + * current link speed anyway, and user space is likely to reprogram it + * when that changes, don't even bother to track the port's link speed, + * but deduce the port transmit rate from idleslope - sendslope. + */ + port_transmit_rate_kbps = offload->idleslope - offload->sendslope; + cbs->idle_slope = div_s64(offload->idleslope * BYTES_PER_KBIT, + port_transmit_rate_kbps); + cbs->send_slope = div_s64(abs(offload->sendslope * BYTES_PER_KBIT), + port_transmit_rate_kbps); /* Convert the negative values from 64-bit 2's complement * to 32-bit 2's complement (for the case of 0x80000000 whose * negative is still negative). @@ -2241,6 +2304,7 @@ int rc, i; s64 now; + mutex_lock(&priv->fdb_lock); mutex_lock(&priv->mgmt_lock); mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; @@ -2355,6 +2419,7 @@ goto out; out: mutex_unlock(&priv->mgmt_lock); + mutex_unlock(&priv->fdb_lock); return rc; } @@ -2924,7 +2989,9 @@ { struct sja1105_l2_lookup_entry *l2_lookup; struct sja1105_table *table; - int match; + int match, rc; + + mutex_lock(&priv->fdb_lock); table = &priv->static_config.tables[BLK_IDX_L2_LOOKUP]; l2_lookup = table->entries; @@ -2937,7 +3004,8 @@ if (match == table->entry_count) { NL_SET_ERR_MSG_MOD(extack, "Could not find FDB entry for unknown multicast"); - return -ENOSPC; + rc = -ENOSPC; + goto out; } if (flags.val & BR_MCAST_FLOOD) @@ -2945,10 +3013,13 @@ else l2_lookup[match].destports &= ~BIT(to); - return sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, - l2_lookup[match].index, - &l2_lookup[match], - true); + rc = sja1105_dynamic_config_write(priv, BLK_IDX_L2_LOOKUP, + l2_lookup[match].index, + &l2_lookup[match], true); +out: + mutex_unlock(&priv->fdb_lock); + + return rc; } static int sja1105_port_pre_bridge_flags(struct dsa_switch *ds, int port, @@ -3318,6 +3389,7 @@ mutex_init(&priv->ptp_data.lock); mutex_init(&priv->dynamic_config_lock); mutex_init(&priv->mgmt_lock); + mutex_init(&priv->fdb_lock); spin_lock_init(&priv->ts_id_lock); rc = sja1105_parse_dt(priv); diff -u linux-6.2.0/drivers/net/ethernet/broadcom/bnxt/bnxt.c linux-6.2.0/drivers/net/ethernet/broadcom/bnxt/bnxt.c --- linux-6.2.0/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ linux-6.2.0/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -2658,6 +2658,7 @@ struct rx_cmp_ext *rxcmp1; u32 cp_cons, tmp_raw_cons; u32 raw_cons = cpr->cp_raw_cons; + bool flush_xdp = false; u32 rx_pkts = 0; u8 event = 0; @@ -2692,6 +2693,8 @@ rx_pkts++; else if (rc == -EBUSY) /* partial completion */ break; + if (event & BNXT_REDIRECT_EVENT) + flush_xdp = true; } else if (unlikely(TX_CMP_TYPE(txcmp) == CMPL_BASE_TYPE_HWRM_DONE)) { bnxt_hwrm_handler(bp, txcmp); @@ -2711,6 +2714,8 @@ if (event & BNXT_AGG_EVENT) bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod); + if (flush_xdp) + xdp_do_flush(); if (!bnxt_has_work(bp, cpr) && rx_pkts < budget) { napi_complete_done(napi, rx_pkts); diff -u linux-6.2.0/drivers/net/ethernet/cadence/macb_main.c linux-6.2.0/drivers/net/ethernet/cadence/macb_main.c --- linux-6.2.0/drivers/net/ethernet/cadence/macb_main.c +++ linux-6.2.0/drivers/net/ethernet/cadence/macb_main.c @@ -288,6 +288,11 @@ top = cpu_to_le16(*((u16 *)(bp->dev->dev_addr + 4))); macb_or_gem_writel(bp, SA1T, top); + if (gem_has_ptp(bp)) { + gem_writel(bp, RXPTPUNI, bottom); + gem_writel(bp, TXPTPUNI, bottom); + } + /* Clear unused address register sets */ macb_or_gem_writel(bp, SA2B, 0); macb_or_gem_writel(bp, SA2T, 0); @@ -700,8 +705,6 @@ if (rx_pause) ctrl |= MACB_BIT(PAE); - macb_set_tx_clk(bp, speed); - /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down * cleared the pipeline and control registers. */ @@ -721,8 +724,15 @@ spin_unlock_irqrestore(&bp->lock, flags); - /* Enable Rx and Tx */ - macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(RE) | MACB_BIT(TE)); + if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) + macb_set_tx_clk(bp, speed); + + /* Enable Rx and Tx; Enable PTP unicast */ + ctrl = macb_readl(bp, NCR); + if (gem_has_ptp(bp)) + ctrl |= MACB_BIT(PTPUNI); + + macb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE)); netif_tx_wake_all_queues(ndev); } diff -u linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hnae3.h linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hnae3.h --- linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -797,6 +797,7 @@ u8 max_tc; /* Total number of TCs */ u8 num_tc; /* Total number of enabled TCs */ bool mqprio_active; + bool dcb_ets_active; }; #define HNAE3_MAX_DSCP 64 diff -u linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c --- linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -1406,9 +1406,9 @@ return 0; out: - mutex_destroy(&handle->dbgfs_lock); debugfs_remove_recursive(handle->hnae3_dbgfs); handle->hnae3_dbgfs = NULL; + mutex_destroy(&handle->dbgfs_lock); return ret; } @@ -1416,6 +1416,9 @@ { u32 i; + debugfs_remove_recursive(handle->hnae3_dbgfs); + handle->hnae3_dbgfs = NULL; + for (i = 0; i < ARRAY_SIZE(hns3_dbg_cmd); i++) if (handle->dbgfs_buf[i]) { kvfree(handle->dbgfs_buf[i]); @@ -1423,8 +1426,6 @@ } mutex_destroy(&handle->dbgfs_lock); - debugfs_remove_recursive(handle->hnae3_dbgfs); - handle->hnae3_dbgfs = NULL; } void hns3_dbg_register_debugfs(const char *debugfs_dir_name) diff -u linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c --- linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +++ linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c @@ -2102,8 +2102,12 @@ */ if (test_bit(HNS3_NIC_STATE_TX_PUSH_ENABLE, &priv->state) && num && !ring->pending_buf && num <= HNS3_MAX_PUSH_BD_NUM && doorbell) { + /* This smp_store_release() pairs with smp_load_aquire() in + * hns3_nic_reclaim_desc(). Ensure that the BD valid bit + * is updated. + */ + smp_store_release(&ring->last_to_use, ring->next_to_use); hns3_tx_push_bd(ring, num); - WRITE_ONCE(ring->last_to_use, ring->next_to_use); return; } @@ -2114,6 +2118,11 @@ return; } + /* This smp_store_release() pairs with smp_load_aquire() in + * hns3_nic_reclaim_desc(). Ensure that the BD valid bit is updated. + */ + smp_store_release(&ring->last_to_use, ring->next_to_use); + if (ring->tqp->mem_base) hns3_tx_mem_doorbell(ring); else @@ -2121,7 +2130,6 @@ ring->tqp->io_base + HNS3_RING_TX_RING_TAIL_REG); ring->pending_buf = 0; - WRITE_ONCE(ring->last_to_use, ring->next_to_use); } static void hns3_tsyn(struct net_device *netdev, struct sk_buff *skb, @@ -3307,8 +3315,6 @@ netdev->priv_flags |= IFF_UNICAST_FLT; - netdev->gso_partial_features |= NETIF_F_GSO_GRE_CSUM; - netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO | @@ -3346,6 +3352,15 @@ NETIF_F_HW_TC); netdev->hw_enc_features |= netdev->vlan_features | NETIF_F_TSO_MANGLEID; + + /* The device_version V3 hardware can't offload the checksum for IP in + * GRE packets, but can do it for NvGRE. So default to disable the + * checksum and GSO offload for GRE. + */ + if (ae_dev->dev_version > HNAE3_DEVICE_VERSION_V2) { + netdev->features &= ~NETIF_F_GSO_GRE; + netdev->features &= ~NETIF_F_GSO_GRE_CSUM; + } } static int hns3_alloc_buffer(struct hns3_enet_ring *ring, @@ -3562,9 +3577,8 @@ static bool hns3_nic_reclaim_desc(struct hns3_enet_ring *ring, int *bytes, int *pkts, int budget) { - /* pair with ring->last_to_use update in hns3_tx_doorbell(), - * smp_store_release() is not used in hns3_tx_doorbell() because - * the doorbell operation already have the needed barrier operation. + /* This smp_load_acquire() pairs with smp_store_release() in + * hns3_tx_doorbell(). */ int ltu = smp_load_acquire(&ring->last_to_use); int ntc = ring->next_to_clean; diff -u linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c --- linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c +++ linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c @@ -251,7 +251,7 @@ int ret; if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) || - hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE) + h->kinfo.tc_info.mqprio_active) return -EINVAL; ret = hclge_ets_validate(hdev, ets, &num_tc, &map_changed); @@ -267,10 +267,7 @@ } hclge_tm_schd_info_update(hdev, num_tc); - if (num_tc > 1) - hdev->flag |= HCLGE_FLAG_DCB_ENABLE; - else - hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE; + h->kinfo.tc_info.dcb_ets_active = num_tc > 1; ret = hclge_ieee_ets_to_tm_info(hdev, ets); if (ret) @@ -463,7 +460,7 @@ struct hclge_vport *vport = hclge_get_vport(h); struct hclge_dev *hdev = vport->back; - if (hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE) + if (h->kinfo.tc_info.mqprio_active) return 0; return hdev->dcbx_cap; @@ -587,7 +584,8 @@ if (!test_bit(HCLGE_STATE_NIC_REGISTERED, &hdev->state)) return -EBUSY; - if (hdev->flag & HCLGE_FLAG_DCB_ENABLE) + kinfo = &vport->nic.kinfo; + if (kinfo->tc_info.dcb_ets_active) return -EINVAL; ret = hclge_mqprio_qopt_check(hdev, mqprio_qopt); @@ -601,7 +599,6 @@ if (ret) return ret; - kinfo = &vport->nic.kinfo; memcpy(&old_tc_info, &kinfo->tc_info, sizeof(old_tc_info)); hclge_sync_mqprio_qopt(&kinfo->tc_info, mqprio_qopt); kinfo->tc_info.mqprio_active = tc > 0; @@ -610,13 +607,6 @@ if (ret) goto err_out; - hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE; - - if (tc > 1) - hdev->flag |= HCLGE_FLAG_MQPRIO_ENABLE; - else - hdev->flag &= ~HCLGE_FLAG_MQPRIO_ENABLE; - return hclge_notify_init_up(hdev); err_out: diff -u linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c --- linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -1517,7 +1517,7 @@ struct hclge_desc desc[3]; int pos = 0; int ret, i; - u32 *req; + __le32 *req; hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_FD_TCAM_OP, true); desc[0].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT); @@ -1542,22 +1542,22 @@ tcam_msg.loc); /* tcam_data0 ~ tcam_data1 */ - req = (u32 *)req1->tcam_data; + req = (__le32 *)req1->tcam_data; for (i = 0; i < 2; i++) pos += scnprintf(tcam_buf + pos, HCLGE_DBG_TCAM_BUF_SIZE - pos, - "%08x\n", *req++); + "%08x\n", le32_to_cpu(*req++)); /* tcam_data2 ~ tcam_data7 */ - req = (u32 *)req2->tcam_data; + req = (__le32 *)req2->tcam_data; for (i = 0; i < 6; i++) pos += scnprintf(tcam_buf + pos, HCLGE_DBG_TCAM_BUF_SIZE - pos, - "%08x\n", *req++); + "%08x\n", le32_to_cpu(*req++)); /* tcam_data8 ~ tcam_data12 */ - req = (u32 *)req3->tcam_data; + req = (__le32 *)req3->tcam_data; for (i = 0; i < 5; i++) pos += scnprintf(tcam_buf + pos, HCLGE_DBG_TCAM_BUF_SIZE - pos, - "%08x\n", *req++); + "%08x\n", le32_to_cpu(*req++)); return ret; } diff -u linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c --- linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -3662,9 +3662,14 @@ static void hclge_clear_event_cause(struct hclge_dev *hdev, u32 event_type, u32 regclr) { +#define HCLGE_IMP_RESET_DELAY 5 + switch (event_type) { case HCLGE_VECTOR0_EVENT_PTP: case HCLGE_VECTOR0_EVENT_RST: + if (regclr == BIT(HCLGE_VECTOR0_IMPRESET_INT_B)) + mdelay(HCLGE_IMP_RESET_DELAY); + hclge_write_dev(&hdev->hw, HCLGE_MISC_RESET_STS_REG, regclr); break; case HCLGE_VECTOR0_EVENT_MBX: @@ -7454,6 +7459,12 @@ ret = hclge_fd_tcam_config(hdev, HCLGE_FD_STAGE_1, true, rule->location, NULL, false); if (ret) { + /* if tcam config fail, set rule state to TO_DEL, + * so the rule will be deleted when periodic + * task being scheduled. + */ + hclge_update_fd_list(hdev, HCLGE_FD_TO_DEL, rule->location, NULL); + set_bit(HCLGE_STATE_FD_TBL_CHANGED, &hdev->state); spin_unlock_bh(&hdev->fd_rule_lock); return ret; } @@ -8930,7 +8941,7 @@ if (mac_type == HCLGE_MAC_ADDR_UC) { if (is_all_added) vport->overflow_promisc_flags &= ~HNAE3_OVERFLOW_UPE; - else + else if (hclge_is_umv_space_full(vport, true)) vport->overflow_promisc_flags |= HNAE3_OVERFLOW_UPE; } else { if (is_all_added) @@ -10936,9 +10947,12 @@ u32 rx_pause, tx_pause; u8 flowctl; - if (!phydev->link || !phydev->autoneg) + if (!phydev->link) return 0; + if (!phydev->autoneg) + return hclge_mac_pause_setup_hw(hdev); + local_advertising = linkmode_adv_to_lcl_adv_t(phydev->advertising); if (phydev->pause) @@ -11129,6 +11143,7 @@ static void hclge_info_show(struct hclge_dev *hdev) { + struct hnae3_handle *handle = &hdev->vport->nic; struct device *dev = &hdev->pdev->dev; dev_info(dev, "PF info begin:\n"); @@ -11145,9 +11160,9 @@ dev_info(dev, "This is %s PF\n", hdev->flag & HCLGE_FLAG_MAIN ? "main" : "not main"); dev_info(dev, "DCB %s\n", - hdev->flag & HCLGE_FLAG_DCB_ENABLE ? "enable" : "disable"); + handle->kinfo.tc_info.dcb_ets_active ? "enable" : "disable"); dev_info(dev, "MQPRIO %s\n", - hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE ? "enable" : "disable"); + handle->kinfo.tc_info.mqprio_active ? "enable" : "disable"); dev_info(dev, "Default tx spare buffer size: %u\n", hdev->tx_spare_buf_size); diff -u linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c --- linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -1549,7 +1549,7 @@ return 0; } -static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev) +int hclge_mac_pause_setup_hw(struct hclge_dev *hdev) { bool tx_en, rx_en; diff -u linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h --- linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h +++ linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h @@ -242,6 +242,7 @@ u8 pfc_bitmap); int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx); int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr); +int hclge_mac_pause_setup_hw(struct hclge_dev *hdev); void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats); void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats); int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate); diff -u linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c --- linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -1909,7 +1909,8 @@ unsigned long delta = round_jiffies_relative(HZ); struct hnae3_handle *handle = &hdev->nic; - if (test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state)) + if (test_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state) || + test_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state)) return; if (time_is_after_jiffies(hdev->last_serv_processed + HZ)) { diff -u linux-6.2.0/drivers/net/ethernet/ibm/ibmveth.c linux-6.2.0/drivers/net/ethernet/ibm/ibmveth.c --- linux-6.2.0/drivers/net/ethernet/ibm/ibmveth.c +++ linux-6.2.0/drivers/net/ethernet/ibm/ibmveth.c @@ -1303,24 +1303,23 @@ * the user space for finding a flow. During this process, OVS computes * checksum on the first packet when CHECKSUM_PARTIAL flag is set. * - * So, re-compute TCP pseudo header checksum when configured for - * trunk mode. + * So, re-compute TCP pseudo header checksum. */ + if (iph_proto == IPPROTO_TCP) { struct tcphdr *tcph = (struct tcphdr *)(skb->data + iphlen); + if (tcph->check == 0x0000) { /* Recompute TCP pseudo header checksum */ - if (adapter->is_active_trunk) { - tcphdrlen = skb->len - iphlen; - if (skb_proto == ETH_P_IP) - tcph->check = - ~csum_tcpudp_magic(iph->saddr, - iph->daddr, tcphdrlen, iph_proto, 0); - else if (skb_proto == ETH_P_IPV6) - tcph->check = - ~csum_ipv6_magic(&iph6->saddr, - &iph6->daddr, tcphdrlen, iph_proto, 0); - } + tcphdrlen = skb->len - iphlen; + if (skb_proto == ETH_P_IP) + tcph->check = + ~csum_tcpudp_magic(iph->saddr, + iph->daddr, tcphdrlen, iph_proto, 0); + else if (skb_proto == ETH_P_IPV6) + tcph->check = + ~csum_ipv6_magic(&iph6->saddr, + &iph6->daddr, tcphdrlen, iph_proto, 0); /* Setup SKB fields for checksum offload */ skb_partial_csum_set(skb, iphlen, offsetof(struct tcphdr, check)); diff -u linux-6.2.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c linux-6.2.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c --- linux-6.2.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ linux-6.2.0/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -4397,9 +4397,7 @@ goto error_pvid; i40e_vlan_stripping_enable(vsi); - i40e_vc_reset_vf(vf, true); - /* During reset the VF got a new VSI, so refresh a pointer. */ - vsi = pf->vsi[vf->lan_vsi_idx]; + /* Locked once because multiple functions below iterate list */ spin_lock_bh(&vsi->mac_filter_hash_lock); @@ -4485,6 +4483,10 @@ */ vf->port_vlan_id = le16_to_cpu(vsi->info.pvid); + i40e_vc_reset_vf(vf, true); + /* During reset the VF got a new VSI, so refresh a pointer. */ + vsi = pf->vsi[vf->lan_vsi_idx]; + ret = i40e_config_vf_promiscuous_mode(vf, vsi->id, allmulti, alluni); if (ret) { dev_err(&pf->pdev->dev, "Unable to config vf promiscuous mode\n"); diff -u linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf.h linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf.h --- linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf.h +++ linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf.h @@ -521,7 +521,7 @@ int iavf_process_config(struct iavf_adapter *adapter); int iavf_parse_vf_resource_msg(struct iavf_adapter *adapter); void iavf_schedule_reset(struct iavf_adapter *adapter, u64 flags); -void iavf_schedule_request_stats(struct iavf_adapter *adapter); +void iavf_schedule_aq_request(struct iavf_adapter *adapter, u64 flags); void iavf_schedule_finish_config(struct iavf_adapter *adapter); void iavf_reset(struct iavf_adapter *adapter); void iavf_set_ethtool_ops(struct net_device *netdev); diff -u linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf_ethtool.c linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf_ethtool.c --- linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +++ linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf_ethtool.c @@ -362,7 +362,7 @@ unsigned int i; /* Explicitly request stats refresh */ - iavf_schedule_request_stats(adapter); + iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_REQUEST_STATS); iavf_add_ethtool_stats(&data, adapter, iavf_gstrings_stats); diff -u linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf_main.c linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf_main.c --- linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf_main.c +++ linux-6.2.0/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -322,15 +322,13 @@ } /** - * iavf_schedule_request_stats - Set the flags and schedule statistics request + * iavf_schedule_aq_request - Set the flags and schedule aq request * @adapter: board private structure - * - * Sets IAVF_FLAG_AQ_REQUEST_STATS flag so iavf_watchdog_task() will explicitly - * request and refresh ethtool stats + * @flags: requested aq flags **/ -void iavf_schedule_request_stats(struct iavf_adapter *adapter) +void iavf_schedule_aq_request(struct iavf_adapter *adapter, u64 flags) { - adapter->aq_required |= IAVF_FLAG_AQ_REQUEST_STATS; + adapter->aq_required |= flags; mod_delayed_work(adapter->wq, &adapter->watchdog_task, 0); } @@ -831,7 +829,7 @@ list_add_tail(&f->list, &adapter->vlan_filter_list); f->state = IAVF_VLAN_ADD; adapter->num_vlan_filters++; - adapter->aq_required |= IAVF_FLAG_AQ_ADD_VLAN_FILTER; + iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_ADD_VLAN_FILTER); } clearout: @@ -853,7 +851,7 @@ f = iavf_find_vlan(adapter, vlan); if (f) { f->state = IAVF_VLAN_REMOVE; - adapter->aq_required |= IAVF_FLAG_AQ_DEL_VLAN_FILTER; + iavf_schedule_aq_request(adapter, IAVF_FLAG_AQ_DEL_VLAN_FILTER); } spin_unlock_bh(&adapter->mac_vlan_list_lock); @@ -1433,7 +1431,8 @@ iavf_clear_fdir_filters(adapter); iavf_clear_adv_rss_conf(adapter); - if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)) { + if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) && + !(test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section))) { /* cancel any current operation */ adapter->current_op = VIRTCHNL_OP_UNKNOWN; /* Schedule operations to close down the HW. Don't wait diff -u linux-6.2.0/drivers/net/ethernet/intel/ice/ice_eswitch.c linux-6.2.0/drivers/net/ethernet/intel/ice/ice_eswitch.c --- linux-6.2.0/drivers/net/ethernet/intel/ice/ice_eswitch.c +++ linux-6.2.0/drivers/net/ethernet/intel/ice/ice_eswitch.c @@ -361,6 +361,9 @@ np = netdev_priv(netdev); vsi = np->vsi; + if (!vsi || !ice_is_switchdev_running(vsi->back)) + return NETDEV_TX_BUSY; + if (ice_is_reset_in_progress(vsi->back->state) || test_bit(ICE_VF_DIS, vsi->back->state)) return NETDEV_TX_BUSY; diff -u linux-6.2.0/drivers/net/ethernet/intel/ice/ice_main.c linux-6.2.0/drivers/net/ethernet/intel/ice/ice_main.c --- linux-6.2.0/drivers/net/ethernet/intel/ice/ice_main.c +++ linux-6.2.0/drivers/net/ethernet/intel/ice/ice_main.c @@ -1346,6 +1346,7 @@ static void ice_aq_check_events(struct ice_pf *pf, u16 opcode, struct ice_rq_event_info *event) { + struct ice_rq_event_info *task_ev; struct ice_aq_task *task; bool found = false; @@ -1354,15 +1355,15 @@ if (task->state || task->opcode != opcode) continue; - memcpy(&task->event->desc, &event->desc, sizeof(event->desc)); - task->event->msg_len = event->msg_len; + task_ev = task->event; + memcpy(&task_ev->desc, &event->desc, sizeof(event->desc)); + task_ev->msg_len = event->msg_len; /* Only copy the data buffer if a destination was set */ - if (task->event->msg_buf && - task->event->buf_len > event->buf_len) { - memcpy(task->event->msg_buf, event->msg_buf, + if (task_ev->msg_buf && task_ev->buf_len >= event->buf_len) { + memcpy(task_ev->msg_buf, event->msg_buf, event->buf_len); - task->event->buf_len = event->buf_len; + task_ev->buf_len = event->buf_len; } task->state = ICE_AQ_TASK_COMPLETE; diff -u linux-6.2.0/drivers/net/ethernet/intel/igb/igb_main.c linux-6.2.0/drivers/net/ethernet/intel/igb/igb_main.c --- linux-6.2.0/drivers/net/ethernet/intel/igb/igb_main.c +++ linux-6.2.0/drivers/net/ethernet/intel/igb/igb_main.c @@ -3877,8 +3877,9 @@ struct pci_dev *pdev = adapter->pdev; struct e1000_hw *hw = &adapter->hw; - /* Virtualization features not supported on i210 family. */ - if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) + /* Virtualization features not supported on i210 and 82580 family. */ + if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211) || + (hw->mac.type == e1000_82580)) return; /* Of the below we really only want the effect of getting diff -u linux-6.2.0/drivers/net/ethernet/intel/igc/igc.h linux-6.2.0/drivers/net/ethernet/intel/igc/igc.h --- linux-6.2.0/drivers/net/ethernet/intel/igc/igc.h +++ linux-6.2.0/drivers/net/ethernet/intel/igc/igc.h @@ -358,11 +358,11 @@ /* TX/RX descriptor defines */ #define IGC_DEFAULT_TXD 256 #define IGC_DEFAULT_TX_WORK 128 -#define IGC_MIN_TXD 80 +#define IGC_MIN_TXD 64 #define IGC_MAX_TXD 4096 #define IGC_DEFAULT_RXD 256 -#define IGC_MIN_RXD 80 +#define IGC_MIN_RXD 64 #define IGC_MAX_RXD 4096 /* Supported Rx Buffer Sizes */ diff -u linux-6.2.0/drivers/net/ethernet/intel/igc/igc_ethtool.c linux-6.2.0/drivers/net/ethernet/intel/igc/igc_ethtool.c --- linux-6.2.0/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ linux-6.2.0/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -867,6 +867,18 @@ spin_unlock(&adapter->stats64_lock); } +static int igc_ethtool_get_previous_rx_coalesce(struct igc_adapter *adapter) +{ + return (adapter->rx_itr_setting <= 3) ? + adapter->rx_itr_setting : adapter->rx_itr_setting >> 2; +} + +static int igc_ethtool_get_previous_tx_coalesce(struct igc_adapter *adapter) +{ + return (adapter->tx_itr_setting <= 3) ? + adapter->tx_itr_setting : adapter->tx_itr_setting >> 2; +} + static int igc_ethtool_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec, struct kernel_ethtool_coalesce *kernel_coal, @@ -874,17 +886,8 @@ { struct igc_adapter *adapter = netdev_priv(netdev); - if (adapter->rx_itr_setting <= 3) - ec->rx_coalesce_usecs = adapter->rx_itr_setting; - else - ec->rx_coalesce_usecs = adapter->rx_itr_setting >> 2; - - if (!(adapter->flags & IGC_FLAG_QUEUE_PAIRS)) { - if (adapter->tx_itr_setting <= 3) - ec->tx_coalesce_usecs = adapter->tx_itr_setting; - else - ec->tx_coalesce_usecs = adapter->tx_itr_setting >> 2; - } + ec->rx_coalesce_usecs = igc_ethtool_get_previous_rx_coalesce(adapter); + ec->tx_coalesce_usecs = igc_ethtool_get_previous_tx_coalesce(adapter); return 0; } @@ -909,8 +912,12 @@ ec->tx_coalesce_usecs == 2) return -EINVAL; - if ((adapter->flags & IGC_FLAG_QUEUE_PAIRS) && ec->tx_coalesce_usecs) + if ((adapter->flags & IGC_FLAG_QUEUE_PAIRS) && + ec->tx_coalesce_usecs != igc_ethtool_get_previous_tx_coalesce(adapter)) { + NL_SET_ERR_MSG_MOD(extack, + "Queue Pair mode enabled, both Rx and Tx coalescing controlled by rx-usecs"); return -EINVAL; + } /* If ITR is disabled, disable DMAC */ if (ec->rx_coalesce_usecs == 0) { diff -u linux-6.2.0/drivers/net/ethernet/intel/igc/igc_main.c linux-6.2.0/drivers/net/ethernet/intel/igc/igc_main.c --- linux-6.2.0/drivers/net/ethernet/intel/igc/igc_main.c +++ linux-6.2.0/drivers/net/ethernet/intel/igc/igc_main.c @@ -6333,7 +6333,7 @@ struct igc_ring *ring; int i, drops; - if (unlikely(test_bit(__IGC_DOWN, &adapter->state))) + if (unlikely(!netif_carrier_ok(dev))) return -ENETDOWN; if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK)) diff -u linux-6.2.0/drivers/net/ethernet/marvell/octeon_ep/octep_main.c linux-6.2.0/drivers/net/ethernet/marvell/octeon_ep/octep_main.c --- linux-6.2.0/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +++ linux-6.2.0/drivers/net/ethernet/marvell/octeon_ep/octep_main.c @@ -727,13 +727,13 @@ dma_map_sg_err: if (si > 0) { dma_unmap_single(iq->dev, sglist[0].dma_ptr[0], - sglist[0].len[0], DMA_TO_DEVICE); - sglist[0].len[0] = 0; + sglist[0].len[3], DMA_TO_DEVICE); + sglist[0].len[3] = 0; } while (si > 1) { dma_unmap_page(iq->dev, sglist[si >> 2].dma_ptr[si & 3], - sglist[si >> 2].len[si & 3], DMA_TO_DEVICE); - sglist[si >> 2].len[si & 3] = 0; + sglist[si >> 2].len[3 - (si & 3)], DMA_TO_DEVICE); + sglist[si >> 2].len[3 - (si & 3)] = 0; si--; } tx_buffer->gather = 0; diff -u linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/af/rpm.c linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/af/rpm.c --- linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/af/rpm.c +++ linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/af/rpm.c @@ -355,8 +355,8 @@ void rpm_lmac_pause_frm_config(void *rpmd, int lmac_id, bool enable) { + u64 cfg, pfc_class_mask_cfg; rpm_t *rpm = rpmd; - u64 cfg; /* ALL pause frames received are completely ignored */ cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); @@ -380,9 +380,11 @@ rpm_write(rpm, 0, RPMX_CMR_CHAN_MSK_OR, ~0ULL); /* Disable all PFC classes */ - cfg = rpm_read(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL); + pfc_class_mask_cfg = is_dev_rpm2(rpm) ? RPM2_CMRX_PRT_CBFC_CTL : + RPMX_CMRX_PRT_CBFC_CTL; + cfg = rpm_read(rpm, lmac_id, pfc_class_mask_cfg); cfg = FIELD_SET(RPM_PFC_CLASS_MASK, 0, cfg); - rpm_write(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL, cfg); + rpm_write(rpm, lmac_id, pfc_class_mask_cfg, cfg); } int rpm_get_rx_stats(void *rpmd, int lmac_id, int idx, u64 *rx_stat) @@ -605,8 +607,11 @@ if (!is_lmac_valid(rpm, lmac_id)) return -ENODEV; + pfc_class_mask_cfg = is_dev_rpm2(rpm) ? RPM2_CMRX_PRT_CBFC_CTL : + RPMX_CMRX_PRT_CBFC_CTL; + cfg = rpm_read(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG); - class_en = rpm_read(rpm, lmac_id, RPMX_CMRX_PRT_CBFC_CTL); + class_en = rpm_read(rpm, lmac_id, pfc_class_mask_cfg); pfc_en |= FIELD_GET(RPM_PFC_CLASS_MASK, class_en); if (rx_pause) { @@ -635,10 +640,6 @@ cfg |= RPMX_MTI_MAC100X_COMMAND_CONFIG_PFC_MODE; rpm_write(rpm, lmac_id, RPMX_MTI_MAC100X_COMMAND_CONFIG, cfg); - - pfc_class_mask_cfg = is_dev_rpm2(rpm) ? RPM2_CMRX_PRT_CBFC_CTL : - RPMX_CMRX_PRT_CBFC_CTL; - rpm_write(rpm, lmac_id, pfc_class_mask_cfg, class_en); return 0; diff -u linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c --- linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +++ linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c @@ -834,6 +834,21 @@ return 0; } +static void nix_get_aq_req_smq(struct rvu *rvu, struct nix_aq_enq_req *req, + u16 *smq, u16 *smq_mask) +{ + struct nix_cn10k_aq_enq_req *aq_req; + + if (!is_rvu_otx2(rvu)) { + aq_req = (struct nix_cn10k_aq_enq_req *)req; + *smq = aq_req->sq.smq; + *smq_mask = aq_req->sq_mask.smq; + } else { + *smq = req->sq.smq; + *smq_mask = req->sq_mask.smq; + } +} + static int rvu_nix_blk_aq_enq_inst(struct rvu *rvu, struct nix_hw *nix_hw, struct nix_aq_enq_req *req, struct nix_aq_enq_rsp *rsp) @@ -845,6 +860,7 @@ struct rvu_block *block; struct admin_queue *aq; struct rvu_pfvf *pfvf; + u16 smq, smq_mask; void *ctx, *mask; bool ena; u64 cfg; @@ -916,13 +932,14 @@ if (rc) return rc; + nix_get_aq_req_smq(rvu, req, &smq, &smq_mask); /* Check if SQ pointed SMQ belongs to this PF/VF or not */ if (req->ctype == NIX_AQ_CTYPE_SQ && ((req->op == NIX_AQ_INSTOP_INIT && req->sq.ena) || (req->op == NIX_AQ_INSTOP_WRITE && - req->sq_mask.ena && req->sq_mask.smq && req->sq.ena))) { + req->sq_mask.ena && req->sq.ena && smq_mask))) { if (!is_valid_txschq(rvu, blkaddr, NIX_TXSCH_LVL_SMQ, - pcifunc, req->sq.smq)) + pcifunc, smq)) return NIX_AF_ERR_AQ_ENQUEUE; } @@ -1691,6 +1708,42 @@ return true; } +static void nix_reset_tx_schedule(struct rvu *rvu, int blkaddr, + int lvl, int schq) +{ + u64 tlx_parent = 0, tlx_schedule = 0; + + switch (lvl) { + case NIX_TXSCH_LVL_TL2: + tlx_parent = NIX_AF_TL2X_PARENT(schq); + tlx_schedule = NIX_AF_TL2X_SCHEDULE(schq); + break; + case NIX_TXSCH_LVL_TL3: + tlx_parent = NIX_AF_TL3X_PARENT(schq); + tlx_schedule = NIX_AF_TL3X_SCHEDULE(schq); + break; + case NIX_TXSCH_LVL_TL4: + tlx_parent = NIX_AF_TL4X_PARENT(schq); + tlx_schedule = NIX_AF_TL4X_SCHEDULE(schq); + break; + case NIX_TXSCH_LVL_MDQ: + /* no need to reset SMQ_CFG as HW clears this CSR + * on SMQ flush + */ + tlx_parent = NIX_AF_MDQX_PARENT(schq); + tlx_schedule = NIX_AF_MDQX_SCHEDULE(schq); + break; + default: + return; + } + + if (tlx_parent) + rvu_write64(rvu, blkaddr, tlx_parent, 0x0); + + if (tlx_schedule) + rvu_write64(rvu, blkaddr, tlx_schedule, 0x0); +} + /* Disable shaping of pkts by a scheduler queue * at a given scheduler level. */ @@ -2040,6 +2093,7 @@ pfvf_map[schq] = TXSCH_MAP(pcifunc, 0); nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq); nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq); + nix_reset_tx_schedule(rvu, blkaddr, lvl, schq); } for (idx = 0; idx < req->schq[lvl]; idx++) { @@ -2049,6 +2103,7 @@ pfvf_map[schq] = TXSCH_MAP(pcifunc, 0); nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq); nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq); + nix_reset_tx_schedule(rvu, blkaddr, lvl, schq); } } @@ -2137,6 +2192,7 @@ continue; nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq); nix_clear_tx_xoff(rvu, blkaddr, lvl, schq); + nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq); } } nix_clear_tx_xoff(rvu, blkaddr, NIX_TXSCH_LVL_TL1, @@ -2175,6 +2231,7 @@ for (schq = 0; schq < txsch->schq.max; schq++) { if (TXSCH_MAP_FUNC(txsch->pfvf_map[schq]) != pcifunc) continue; + nix_reset_tx_schedule(rvu, blkaddr, lvl, schq); rvu_free_rsrc(&txsch->schq, schq); txsch->pfvf_map[schq] = TXSCH_MAP(0, NIX_TXSCHQ_FREE); } @@ -2234,6 +2291,9 @@ */ nix_clear_tx_xoff(rvu, blkaddr, lvl, schq); + nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq); + nix_reset_tx_shaping(rvu, blkaddr, nixlf, lvl, schq); + /* Flush if it is a SMQ. Onus of disabling * TL2/3 queue links before SMQ flush is on user */ @@ -2243,6 +2303,8 @@ goto err; } + nix_reset_tx_schedule(rvu, blkaddr, lvl, schq); + /* Free the resource */ rvu_free_rsrc(&txsch->schq, schq); txsch->pfvf_map[schq] = TXSCH_MAP(0, NIX_TXSCHQ_FREE); diff -u linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h --- linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +++ linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h @@ -920,7 +920,8 @@ int otx2_config_nix_queues(struct otx2_nic *pfvf); int otx2_txschq_config(struct otx2_nic *pfvf, int lvl, int prio, bool pfc_en); int otx2_txsch_alloc(struct otx2_nic *pfvf); -int otx2_txschq_stop(struct otx2_nic *pfvf); +void otx2_txschq_stop(struct otx2_nic *pfvf); +void otx2_txschq_free_one(struct otx2_nic *pfvf, u16 lvl, u16 schq); void otx2_sqb_flush(struct otx2_nic *pfvf); int __otx2_alloc_rbuf(struct otx2_nic *pfvf, struct otx2_pool *pool, dma_addr_t *dma); diff -u linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c --- linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -791,10 +791,6 @@ case MBOX_MSG_NIX_LF_ALLOC: mbox_handler_nix_lf_alloc(pf, (struct nix_lf_alloc_rsp *)msg); break; - case MBOX_MSG_NIX_TXSCH_ALLOC: - mbox_handler_nix_txsch_alloc(pf, - (struct nix_txsch_alloc_rsp *)msg); - break; case MBOX_MSG_NIX_BP_ENABLE: mbox_handler_nix_bp_enable(pf, (struct nix_bp_cfg_rsp *)msg); break; @@ -1517,8 +1513,7 @@ otx2_free_cq_res(pf); otx2_ctx_disable(mbox, NIX_AQ_CTYPE_RQ, false); err_free_txsch: - if (otx2_txschq_stop(pf)) - dev_err(pf->dev, "%s failed to stop TX schedulers\n", __func__); + otx2_txschq_stop(pf); err_free_sq_ptrs: otx2_sq_free_sqbs(pf); err_free_rq_ptrs: @@ -1553,15 +1548,13 @@ struct mbox *mbox = &pf->mbox; struct otx2_cq_queue *cq; struct msg_req *req; - int qidx, err; + int qidx; /* Ensure all SQE are processed */ otx2_sqb_flush(pf); /* Stop transmission */ - err = otx2_txschq_stop(pf); - if (err) - dev_err(pf->dev, "RVUPF: Failed to stop/free TX schedulers\n"); + otx2_txschq_stop(pf); #ifdef CONFIG_DCB if (pf->pfc_en) diff -u linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c --- linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c +++ linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c @@ -29,7 +29,8 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, struct bpf_prog *prog, struct nix_cqe_rx_s *cqe, - struct otx2_cq_queue *cq); + struct otx2_cq_queue *cq, + bool *need_xdp_flush); static int otx2_nix_cq_op_status(struct otx2_nic *pfvf, struct otx2_cq_queue *cq) @@ -340,7 +341,7 @@ static void otx2_rcv_pkt_handler(struct otx2_nic *pfvf, struct napi_struct *napi, struct otx2_cq_queue *cq, - struct nix_cqe_rx_s *cqe) + struct nix_cqe_rx_s *cqe, bool *need_xdp_flush) { struct nix_rx_parse_s *parse = &cqe->parse; struct nix_rx_sg_s *sg = &cqe->sg; @@ -356,7 +357,7 @@ } if (pfvf->xdp_prog) - if (otx2_xdp_rcv_pkt_handler(pfvf, pfvf->xdp_prog, cqe, cq)) + if (otx2_xdp_rcv_pkt_handler(pfvf, pfvf->xdp_prog, cqe, cq, need_xdp_flush)) return; skb = napi_get_frags(napi); @@ -389,6 +390,7 @@ struct napi_struct *napi, struct otx2_cq_queue *cq, int budget) { + bool need_xdp_flush = false; struct nix_cqe_rx_s *cqe; int processed_cqe = 0; @@ -410,13 +412,15 @@ cq->cq_head++; cq->cq_head &= (cq->cqe_cnt - 1); - otx2_rcv_pkt_handler(pfvf, napi, cq, cqe); + otx2_rcv_pkt_handler(pfvf, napi, cq, cqe, &need_xdp_flush); cqe->hdr.cqe_type = NIX_XQE_TYPE_INVALID; cqe->sg.seg_addr = 0x00; processed_cqe++; cq->pend_cqe--; } + if (need_xdp_flush) + xdp_do_flush(); /* Free CQEs to HW */ otx2_write64(pfvf, NIX_LF_CQ_OP_DOOR, @@ -1323,7 +1327,8 @@ static bool otx2_xdp_rcv_pkt_handler(struct otx2_nic *pfvf, struct bpf_prog *prog, struct nix_cqe_rx_s *cqe, - struct otx2_cq_queue *cq) + struct otx2_cq_queue *cq, + bool *need_xdp_flush) { unsigned char *hard_start, *data; int qidx = cq->cq_idx; @@ -1360,8 +1365,10 @@ otx2_dma_unmap_page(pfvf, iova, pfvf->rbsize, DMA_FROM_DEVICE); - if (!err) + if (!err) { + *need_xdp_flush = true; return true; + } put_page(page); break; default: diff -u linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c --- linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c +++ linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c @@ -70,10 +70,6 @@ case MBOX_MSG_NIX_LF_ALLOC: mbox_handler_nix_lf_alloc(vf, (struct nix_lf_alloc_rsp *)msg); break; - case MBOX_MSG_NIX_TXSCH_ALLOC: - mbox_handler_nix_txsch_alloc(vf, - (struct nix_txsch_alloc_rsp *)msg); - break; case MBOX_MSG_NIX_BP_ENABLE: mbox_handler_nix_bp_enable(vf, (struct nix_bp_cfg_rsp *)msg); break; diff -u linux-6.2.0/drivers/net/ethernet/mediatek/mtk_eth_soc.c linux-6.2.0/drivers/net/ethernet/mediatek/mtk_eth_soc.c --- linux-6.2.0/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ linux-6.2.0/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -2812,6 +2812,9 @@ int i; for (i = 0; i < MTK_MAX_LRO_IP_CNT; i++) { + if (cnt == cmd->rule_cnt) + return -EMSGSIZE; + if (mac->hwlro_ip[i]) { rule_locs[cnt] = i; cnt++; @@ -2970,8 +2973,8 @@ eth->rx_events++; if (likely(napi_schedule_prep(ð->rx_napi))) { - __napi_schedule(ð->rx_napi); mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); + __napi_schedule(ð->rx_napi); } return IRQ_HANDLED; @@ -2983,8 +2986,8 @@ eth->tx_events++; if (likely(napi_schedule_prep(ð->tx_napi))) { - __napi_schedule(ð->tx_napi); mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); + __napi_schedule(ð->tx_napi); } return IRQ_HANDLED; diff -u linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c --- linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +++ linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c @@ -97,7 +97,6 @@ #if IS_ENABLED(CONFIG_INET) && IS_ENABLED(CONFIG_IPV6) else if (ip_version == 6) { int ipv6_size = MLX5_FLD_SZ_BYTES(ipv6_layout, ipv6); - struct in6_addr zerov6 = {}; daddr = MLX5_ADDR_OF(fte_match_param, spec->match_value, outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6); @@ -105,8 +104,8 @@ outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6); memcpy(&tun_attr->dst_ip.v6, daddr, ipv6_size); memcpy(&tun_attr->src_ip.v6, saddr, ipv6_size); - if (!memcmp(&tun_attr->dst_ip.v6, &zerov6, sizeof(zerov6)) || - !memcmp(&tun_attr->src_ip.v6, &zerov6, sizeof(zerov6))) + if (ipv6_addr_any(&tun_attr->dst_ip.v6) || + ipv6_addr_any(&tun_attr->src_ip.v6)) return 0; } #endif diff -u linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c --- linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +++ linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c @@ -319,16 +319,11 @@ pci_cfg_access_lock(sdev); } /* PCI link toggle */ - err = pci_read_config_word(bridge, cap + PCI_EXP_LNKCTL, ®16); - if (err) - return err; - reg16 |= PCI_EXP_LNKCTL_LD; - err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16); + err = pcie_capability_set_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD); if (err) return err; msleep(500); - reg16 &= ~PCI_EXP_LNKCTL_LD; - err = pci_write_config_word(bridge, cap + PCI_EXP_LNKCTL, reg16); + err = pcie_capability_clear_word(bridge, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_LD); if (err) return err; diff -u linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c --- linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +++ linux-6.2.0/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c @@ -124,18 +124,32 @@ return ret; } -static void irq_release(struct mlx5_irq *irq) +/* mlx5_system_free_irq - Free an IRQ + * @irq: IRQ to free + * + * Free the IRQ and other resources such as rmap from the system. + * BUT doesn't free or remove reference from mlx5. + * This function is very important for the shutdown flow, where we need to + * cleanup system resoruces but keep mlx5 objects alive, + * see mlx5_irq_table_free_irqs(). + */ +static void mlx5_system_free_irq(struct mlx5_irq *irq) { - struct mlx5_irq_pool *pool = irq->pool; - - xa_erase(&pool->irqs, irq->index); /* free_irq requires that affinity_hint and rmap will be cleared * before calling it. This is why there is asymmetry with set_rmap * which should be called after alloc_irq but before request_irq. */ irq_update_affinity_hint(irq->irqn, NULL); - free_cpumask_var(irq->mask); free_irq(irq->irqn, &irq->nh); +} + +static void irq_release(struct mlx5_irq *irq) +{ + struct mlx5_irq_pool *pool = irq->pool; + + xa_erase(&pool->irqs, irq->index); + mlx5_system_free_irq(irq); + free_cpumask_var(irq->mask); kfree(irq); } @@ -598,7 +612,7 @@ unsigned long index; xa_for_each(&pool->irqs, index, irq) - free_irq(irq->irqn, &irq->nh); + mlx5_system_free_irq(irq); } static void mlx5_irq_pools_free_irqs(struct mlx5_irq_table *table) diff -u linux-6.2.0/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c linux-6.2.0/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c --- linux-6.2.0/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c +++ linux-6.2.0/drivers/net/ethernet/microchip/lan966x/lan966x_ptp.c @@ -59,7 +59,7 @@ int err; vrule = vcap_get_rule(lan966x->vcap_ctrl, rule_id); - if (vrule) { + if (!IS_ERR(vrule)) { u32 value, mask; /* Just modify the ingress port mask and exit */ @@ -107,7 +107,7 @@ int err; vrule = vcap_get_rule(lan966x->vcap_ctrl, rule_id); - if (!vrule) + if (IS_ERR(vrule)) return -EEXIST; vcap_rule_get_key_u32(vrule, VCAP_KF_IF_IGR_PORT_MASK, &value, &mask); diff -u linux-6.2.0/drivers/net/ethernet/microsoft/mana/mana_en.c linux-6.2.0/drivers/net/ethernet/microsoft/mana/mana_en.c --- linux-6.2.0/drivers/net/ethernet/microsoft/mana/mana_en.c +++ linux-6.2.0/drivers/net/ethernet/microsoft/mana/mana_en.c @@ -1063,17 +1063,21 @@ case CQE_TX_VPORT_IDX_OUT_OF_RANGE: case CQE_TX_VPORT_DISABLED: case CQE_TX_VLAN_TAGGING_VIOLATION: - WARN_ONCE(1, "TX: CQE error %d: ignored.\n", - cqe_oob->cqe_hdr.cqe_type); + if (net_ratelimit()) + netdev_err(ndev, "TX: CQE error %d\n", + cqe_oob->cqe_hdr.cqe_type); + break; default: - /* If the CQE type is unexpected, log an error, assert, - * and go through the error path. + /* If the CQE type is unknown, log an error, + * and still free the SKB, update tail, etc. */ - WARN_ONCE(1, "TX: Unexpected CQE type %d: HW BUG?\n", - cqe_oob->cqe_hdr.cqe_type); - return; + if (net_ratelimit()) + netdev_err(ndev, "TX: unknown CQE type %d\n", + cqe_oob->cqe_hdr.cqe_type); + + break; } if (WARN_ON_ONCE(txq->gdma_txq_id != completions[i].wq_num)) diff -u linux-6.2.0/drivers/net/ethernet/realtek/r8169_main.c linux-6.2.0/drivers/net/ethernet/realtek/r8169_main.c --- linux-6.2.0/drivers/net/ethernet/realtek/r8169_main.c +++ linux-6.2.0/drivers/net/ethernet/realtek/r8169_main.c @@ -620,6 +620,7 @@ unsigned supports_gmii:1; unsigned aspm_manageable:1; + unsigned dash_enabled:1; dma_addr_t counters_phys_addr; struct rtl8169_counters *counters; struct rtl8169_tc_offsets tc_offset; @@ -1249,14 +1250,26 @@ return r8168ep_ocp_read(tp, 0x128) & BIT(0); } -static enum rtl_dash_type rtl_check_dash(struct rtl8169_private *tp) +static bool rtl_dash_is_enabled(struct rtl8169_private *tp) +{ + switch (tp->dash_type) { + case RTL_DASH_DP: + return r8168dp_check_dash(tp); + case RTL_DASH_EP: + return r8168ep_check_dash(tp); + default: + return false; + } +} + +static enum rtl_dash_type rtl_get_dash_type(struct rtl8169_private *tp) { switch (tp->mac_version) { case RTL_GIGA_MAC_VER_28: case RTL_GIGA_MAC_VER_31: - return r8168dp_check_dash(tp) ? RTL_DASH_DP : RTL_DASH_NONE; + return RTL_DASH_DP; case RTL_GIGA_MAC_VER_51 ... RTL_GIGA_MAC_VER_53: - return r8168ep_check_dash(tp) ? RTL_DASH_EP : RTL_DASH_NONE; + return RTL_DASH_EP; default: return RTL_DASH_NONE; } @@ -1449,7 +1462,7 @@ device_set_wakeup_enable(tp_to_dev(tp), wolopts); - if (tp->dash_type == RTL_DASH_NONE) { + if (!tp->dash_enabled) { rtl_set_d3_pll_down(tp, !wolopts); tp->dev->wol_enabled = wolopts ? 1 : 0; } @@ -2508,7 +2521,7 @@ static void rtl_prepare_power_down(struct rtl8169_private *tp) { - if (tp->dash_type != RTL_DASH_NONE) + if (tp->dash_enabled) return; if (tp->mac_version == RTL_GIGA_MAC_VER_32 || @@ -4680,10 +4693,16 @@ rtl8169_cleanup(tp); rtl_disable_exit_l1(tp); rtl_prepare_power_down(tp); + + if (tp->dash_type != RTL_DASH_NONE) + rtl8168_driver_stop(tp); } static void rtl8169_up(struct rtl8169_private *tp) { + if (tp->dash_type != RTL_DASH_NONE) + rtl8168_driver_start(tp); + pci_set_master(tp->pci_dev); phy_init_hw(tp->phydev); phy_resume(tp->phydev); @@ -4901,7 +4920,7 @@ { struct rtl8169_private *tp = dev_get_drvdata(device); - if (tp->dash_type != RTL_DASH_NONE) + if (tp->dash_enabled) return -EBUSY; if (!netif_running(tp->dev) || !netif_carrier_ok(tp->dev)) @@ -4927,8 +4946,7 @@ /* Restore original MAC address */ rtl_rar_set(tp, tp->dev->perm_addr); - if (system_state == SYSTEM_POWER_OFF && - tp->dash_type == RTL_DASH_NONE) { + if (system_state == SYSTEM_POWER_OFF && !tp->dash_enabled) { pci_wake_from_d3(pdev, tp->saved_wolopts); pci_set_power_state(pdev, PCI_D3hot); } @@ -5288,7 +5306,8 @@ rc = pci_disable_link_state(pdev, PCIE_LINK_STATE_L1); tp->aspm_manageable = !rc; - tp->dash_type = rtl_check_dash(tp); + tp->dash_type = rtl_get_dash_type(tp); + tp->dash_enabled = rtl_dash_is_enabled(tp); tp->cp_cmd = RTL_R16(tp, CPlusCmd) & CPCMD_MASK; @@ -5360,7 +5379,7 @@ /* configure chip for default features */ rtl8169_set_features(dev, dev->features); - if (tp->dash_type == RTL_DASH_NONE) { + if (!tp->dash_enabled) { rtl_set_d3_pll_down(tp, true); } else { rtl_set_d3_pll_down(tp, false); @@ -5400,7 +5419,8 @@ "ok" : "ko"); if (tp->dash_type != RTL_DASH_NONE) { - netdev_info(dev, "DASH enabled\n"); + netdev_info(dev, "DASH %s\n", + tp->dash_enabled ? "enabled" : "disabled"); rtl8168_driver_start(tp); } diff -u linux-6.2.0/drivers/net/ethernet/renesas/rswitch.c linux-6.2.0/drivers/net/ethernet/renesas/rswitch.c --- linux-6.2.0/drivers/net/ethernet/renesas/rswitch.c +++ linux-6.2.0/drivers/net/ethernet/renesas/rswitch.c @@ -796,10 +796,10 @@ netif_wake_subqueue(ndev, 0); - napi_complete(napi); - - rswitch_enadis_data_irq(priv, rdev->tx_queue->index, true); - rswitch_enadis_data_irq(priv, rdev->rx_queue->index, true); + if (napi_complete_done(napi, budget - quota)) { + rswitch_enadis_data_irq(priv, rdev->tx_queue->index, true); + rswitch_enadis_data_irq(priv, rdev->rx_queue->index, true); + } out: return budget - quota; diff -u linux-6.2.0/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c linux-6.2.0/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c --- linux-6.2.0/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ linux-6.2.0/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -2694,9 +2694,7 @@ /* We still have pending packets, let's call for a new scheduling */ if (tx_q->dirty_tx != tx_q->cur_tx) - hrtimer_start(&tx_q->txtimer, - STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), - HRTIMER_MODE_REL); + stmmac_tx_timer_arm(priv, queue); __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue)); @@ -2977,9 +2975,13 @@ static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue) { struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue]; + u32 tx_coal_timer = priv->tx_coal_timer[queue]; + + if (!tx_coal_timer) + return; hrtimer_start(&tx_q->txtimer, - STMMAC_COAL_TIMER(priv->tx_coal_timer[queue]), + STMMAC_COAL_TIMER(tx_coal_timer), HRTIMER_MODE_REL); } diff -u linux-6.2.0/drivers/net/ethernet/ti/am65-cpsw-nuss.c linux-6.2.0/drivers/net/ethernet/ti/am65-cpsw-nuss.c --- linux-6.2.0/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ linux-6.2.0/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -1648,6 +1648,7 @@ if (tx_chn->irq <= 0) { dev_err(dev, "Failed to get tx dma irq %d\n", tx_chn->irq); + ret = tx_chn->irq ?: -ENXIO; goto err; } diff -u linux-6.2.0/drivers/net/macsec.c linux-6.2.0/drivers/net/macsec.c --- linux-6.2.0/drivers/net/macsec.c +++ linux-6.2.0/drivers/net/macsec.c @@ -1331,8 +1331,7 @@ struct crypto_aead *tfm; int ret; - /* Pick a sync gcm(aes) cipher to ensure order is preserved. */ - tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC); + tfm = crypto_alloc_aead("gcm(aes)", 0, 0); if (IS_ERR(tfm)) return tfm; diff -u linux-6.2.0/drivers/net/team/team.c linux-6.2.0/drivers/net/team/team.c --- linux-6.2.0/drivers/net/team/team.c +++ linux-6.2.0/drivers/net/team/team.c @@ -2127,7 +2127,12 @@ static void team_setup_by_port(struct net_device *dev, struct net_device *port_dev) { - dev->header_ops = port_dev->header_ops; + struct team *team = netdev_priv(dev); + + if (port_dev->type == ARPHRD_ETHER) + dev->header_ops = team->header_ops_cache; + else + dev->header_ops = port_dev->header_ops; dev->type = port_dev->type; dev->hard_header_len = port_dev->hard_header_len; dev->needed_headroom = port_dev->needed_headroom; @@ -2174,8 +2179,11 @@ static void team_setup(struct net_device *dev) { + struct team *team = netdev_priv(dev); + ether_setup(dev); dev->max_mtu = ETH_MAX_MTU; + team->header_ops_cache = dev->header_ops; dev->netdev_ops = &team_netdev_ops; dev->ethtool_ops = &team_ethtool_ops; diff -u linux-6.2.0/drivers/net/usb/qmi_wwan.c linux-6.2.0/drivers/net/usb/qmi_wwan.c --- linux-6.2.0/drivers/net/usb/qmi_wwan.c +++ linux-6.2.0/drivers/net/usb/qmi_wwan.c @@ -1423,6 +1423,7 @@ {QMI_QUIRK_SET_DTR(0x2c7c, 0x0191, 4)}, /* Quectel EG91 */ {QMI_QUIRK_SET_DTR(0x2c7c, 0x0195, 4)}, /* Quectel EG95 */ {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */ + {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */ {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */ {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ diff -u linux-6.2.0/drivers/net/usb/r8152.c linux-6.2.0/drivers/net/usb/r8152.c --- linux-6.2.0/drivers/net/usb/r8152.c +++ linux-6.2.0/drivers/net/usb/r8152.c @@ -2628,6 +2628,9 @@ struct r8152 *tp = container_of(napi, struct r8152, napi); int work_done; + if (!budget) + return 0; + work_done = rx_bottom(tp, budget); if (work_done < budget) { diff -u linux-6.2.0/drivers/net/usb/smsc75xx.c linux-6.2.0/drivers/net/usb/smsc75xx.c --- linux-6.2.0/drivers/net/usb/smsc75xx.c +++ linux-6.2.0/drivers/net/usb/smsc75xx.c @@ -90,7 +90,9 @@ ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0, index, &buf, 4); - if (unlikely(ret < 0)) { + if (unlikely(ret < 4)) { + ret = ret < 0 ? ret : -ENODATA; + netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n", index, ret); return ret; diff -u linux-6.2.0/drivers/net/veth.c linux-6.2.0/drivers/net/veth.c --- linux-6.2.0/drivers/net/veth.c +++ linux-6.2.0/drivers/net/veth.c @@ -313,6 +313,7 @@ { struct veth_priv *rcv_priv, *priv = netdev_priv(dev); struct veth_rq *rq = NULL; + int ret = NETDEV_TX_OK; struct net_device *rcv; int length = skb->len; bool use_napi = false; @@ -345,6 +346,7 @@ } else { drop: atomic64_inc(&priv->dropped); + ret = NET_XMIT_DROP; } if (use_napi) @@ -352,7 +354,7 @@ rcu_read_unlock(); - return NETDEV_TX_OK; + return ret; } static u64 veth_stats_tx(struct net_device *dev, u64 *packets, u64 *bytes) diff -u linux-6.2.0/drivers/net/vxlan/vxlan_core.c linux-6.2.0/drivers/net/vxlan/vxlan_core.c --- linux-6.2.0/drivers/net/vxlan/vxlan_core.c +++ linux-6.2.0/drivers/net/vxlan/vxlan_core.c @@ -2072,7 +2072,7 @@ struct vxlan_fdb *f; struct sk_buff *reply; - if (!(n->nud_state & NUD_CONNECTED)) { + if (!(READ_ONCE(n->nud_state) & NUD_CONNECTED)) { neigh_release(n); goto out; } @@ -2236,7 +2236,7 @@ struct vxlan_fdb *f; struct sk_buff *reply; - if (!(n->nud_state & NUD_CONNECTED)) { + if (!(READ_ONCE(n->nud_state) & NUD_CONNECTED)) { neigh_release(n); goto out; } @@ -4516,6 +4516,10 @@ nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_UDP_ZERO_CSUM6_RX */ nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM_TX */ nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_REMCSUM_RX */ + nla_total_size(0) + /* IFLA_VXLAN_GBP */ + nla_total_size(0) + /* IFLA_VXLAN_GPE */ + nla_total_size(0) + /* IFLA_VXLAN_REMCSUM_NOPARTIAL */ + nla_total_size(sizeof(__u8)) + /* IFLA_VXLAN_VNIFILTER */ nla_total_size(sizeof(struct ip_fan_map) * 256) + 0; } diff -u linux-6.2.0/drivers/net/wireless/ath/ath11k/pci.c linux-6.2.0/drivers/net/wireless/ath/ath11k/pci.c --- linux-6.2.0/drivers/net/wireless/ath/ath11k/pci.c +++ linux-6.2.0/drivers/net/wireless/ath/ath11k/pci.c @@ -582,8 +582,8 @@ u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1)); /* disable L0s and L1 */ - pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL, - ab_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC); + pcie_capability_clear_word(ab_pci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_ASPMC); set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags); } @@ -591,8 +591,10 @@ static void ath11k_pci_aspm_restore(struct ath11k_pci *ab_pci) { if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags)) - pcie_capability_write_word(ab_pci->pdev, PCI_EXP_LNKCTL, - ab_pci->link_ctl); + pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_ASPMC, + ab_pci->link_ctl & + PCI_EXP_LNKCTL_ASPMC); } static int ath11k_pci_power_up(struct ath11k_base *ab) diff -u linux-6.2.0/drivers/net/wireless/ath/ath9k/wmi.c linux-6.2.0/drivers/net/wireless/ath/ath9k/wmi.c --- linux-6.2.0/drivers/net/wireless/ath/ath9k/wmi.c +++ linux-6.2.0/drivers/net/wireless/ath/ath9k/wmi.c @@ -242,10 +242,10 @@ spin_unlock_irqrestore(&wmi->wmi_lock, flags); goto free_skb; } - spin_unlock_irqrestore(&wmi->wmi_lock, flags); /* WMI command response */ ath9k_wmi_rsp_callback(wmi, skb); + spin_unlock_irqrestore(&wmi->wmi_lock, flags); free_skb: kfree_skb(skb); @@ -283,7 +283,8 @@ static int ath9k_wmi_cmd_issue(struct wmi *wmi, struct sk_buff *skb, - enum wmi_cmd_id cmd, u16 len) + enum wmi_cmd_id cmd, u16 len, + u8 *rsp_buf, u32 rsp_len) { struct wmi_cmd_hdr *hdr; unsigned long flags; @@ -293,6 +294,11 @@ hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); spin_lock_irqsave(&wmi->wmi_lock, flags); + + /* record the rsp buffer and length */ + wmi->cmd_rsp_buf = rsp_buf; + wmi->cmd_rsp_len = rsp_len; + wmi->last_seq_id = wmi->tx_seq_id; spin_unlock_irqrestore(&wmi->wmi_lock, flags); @@ -308,8 +314,8 @@ struct ath_common *common = ath9k_hw_common(ah); u16 headroom = sizeof(struct htc_frame_hdr) + sizeof(struct wmi_cmd_hdr); + unsigned long time_left, flags; struct sk_buff *skb; - unsigned long time_left; int ret = 0; if (ah->ah_flags & AH_UNPLUGGED) @@ -333,11 +339,7 @@ goto out; } - /* record the rsp buffer and length */ - wmi->cmd_rsp_buf = rsp_buf; - wmi->cmd_rsp_len = rsp_len; - - ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len); + ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len, rsp_buf, rsp_len); if (ret) goto out; @@ -345,7 +347,9 @@ if (!time_left) { ath_dbg(common, WMI, "Timeout waiting for WMI command: %s\n", wmi_cmd_to_name(cmd_id)); + spin_lock_irqsave(&wmi->wmi_lock, flags); wmi->last_seq_id = 0; + spin_unlock_irqrestore(&wmi->wmi_lock, flags); mutex_unlock(&wmi->op_mutex); return -ETIMEDOUT; } diff -u linux-6.2.0/drivers/net/wireless/intel/iwlwifi/mvm/fw.c linux-6.2.0/drivers/net/wireless/intel/iwlwifi/mvm/fw.c --- linux-6.2.0/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ linux-6.2.0/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -817,7 +817,7 @@ mvm->nvm_data->bands[0].n_channels = 1; mvm->nvm_data->bands[0].n_bitrates = 1; mvm->nvm_data->bands[0].bitrates = - (void *)((u8 *)mvm->nvm_data->channels + 1); + (void *)(mvm->nvm_data->channels + 1); mvm->nvm_data->bands[0].bitrates->hw_value = 10; } diff -u linux-6.2.0/drivers/net/wireless/mac80211_hwsim.c linux-6.2.0/drivers/net/wireless/mac80211_hwsim.c --- linux-6.2.0/drivers/net/wireless/mac80211_hwsim.c +++ linux-6.2.0/drivers/net/wireless/mac80211_hwsim.c @@ -4907,14 +4907,15 @@ frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]); frame_data = (void *)nla_data(info->attrs[HWSIM_ATTR_FRAME]); + if (frame_data_len < sizeof(struct ieee80211_hdr_3addr) || + frame_data_len > IEEE80211_MAX_DATA_LEN) + goto err; + /* Allocate new skb here */ skb = alloc_skb(frame_data_len, GFP_KERNEL); if (skb == NULL) goto err; - if (frame_data_len > IEEE80211_MAX_DATA_LEN) - goto err; - /* Copy the data */ skb_put_data(skb, frame_data, frame_data_len); diff -u linux-6.2.0/drivers/net/wireless/marvell/mwifiex/pcie.c linux-6.2.0/drivers/net/wireless/marvell/mwifiex/pcie.c --- linux-6.2.0/drivers/net/wireless/marvell/mwifiex/pcie.c +++ linux-6.2.0/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -189,6 +189,8 @@ } static void mwifiex_pcie_work(struct work_struct *work); +static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter); +static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter); static int mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, @@ -802,14 +804,15 @@ if (!skb) { mwifiex_dbg(adapter, ERROR, "Unable to allocate skb for RX ring.\n"); - kfree(card->rxbd_ring_vbase); return -ENOMEM; } if (mwifiex_map_pci_memory(adapter, skb, MWIFIEX_RX_DATA_BUF_SIZE, - DMA_FROM_DEVICE)) - return -1; + DMA_FROM_DEVICE)) { + kfree_skb(skb); + return -ENOMEM; + } buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); @@ -859,7 +862,6 @@ if (!skb) { mwifiex_dbg(adapter, ERROR, "Unable to allocate skb for EVENT buf.\n"); - kfree(card->evtbd_ring_vbase); return -ENOMEM; } skb_put(skb, MAX_EVENT_SIZE); @@ -867,8 +869,7 @@ if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE, DMA_FROM_DEVICE)) { kfree_skb(skb); - kfree(card->evtbd_ring_vbase); - return -1; + return -ENOMEM; } buf_pa = MWIFIEX_SKB_DMA_ADDR(skb); @@ -1068,6 +1069,7 @@ */ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) { + int ret; struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; @@ -1106,7 +1108,10 @@ (u32)((u64)card->rxbd_ring_pbase >> 32), card->rxbd_ring_size); - return mwifiex_init_rxq_ring(adapter); + ret = mwifiex_init_rxq_ring(adapter); + if (ret) + mwifiex_pcie_delete_rxbd_ring(adapter); + return ret; } /* @@ -1137,6 +1142,7 @@ */ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) { + int ret; struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; @@ -1171,7 +1177,10 @@ (u32)((u64)card->evtbd_ring_pbase >> 32), card->evtbd_ring_size); - return mwifiex_pcie_init_evt_ring(adapter); + ret = mwifiex_pcie_init_evt_ring(adapter); + if (ret) + mwifiex_pcie_delete_evtbd_ring(adapter); + return ret; } /* diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/dma.c linux-6.2.0/drivers/net/wireless/mediatek/mt76/dma.c --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/dma.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/dma.c @@ -93,13 +93,13 @@ { struct mt76_txwi_cache *t = NULL; - spin_lock(&dev->wed_lock); + spin_lock_bh(&dev->wed_lock); if (!list_empty(&dev->rxwi_cache)) { t = list_first_entry(&dev->rxwi_cache, struct mt76_txwi_cache, list); list_del(&t->list); } - spin_unlock(&dev->wed_lock); + spin_unlock_bh(&dev->wed_lock); return t; } @@ -145,9 +145,9 @@ if (!t) return; - spin_lock(&dev->wed_lock); + spin_lock_bh(&dev->wed_lock); list_add(&t->list, &dev->rxwi_cache); - spin_unlock(&dev->wed_lock); + spin_unlock_bh(&dev->wed_lock); } EXPORT_SYMBOL_GPL(mt76_put_rxwi); diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76.h linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76.h --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76.h +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76.h @@ -274,7 +274,7 @@ u64 tx_mcs[16]; /* mcs idx */ u64 tx_bytes; /* WED TX */ - u32 tx_packets; + u32 tx_packets; /* unit: MSDU */ u32 tx_retries; u32 tx_failed; /* WED RX */ diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c @@ -490,9 +490,9 @@ q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS + mt76_connac_lmac_mapping(skb_get_queue_mapping(skb)); - /* counting non-offloading skbs */ - wcid->stats.tx_bytes += skb->len; - wcid->stats.tx_packets++; + /* mt7915 WA only counts WED path */ + if (is_mt7915(dev) && mtk_wed_device_active(&dev->mmio.wed)) + wcid->stats.tx_packets++; } val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) | @@ -577,12 +577,11 @@ txs = le32_to_cpu(txs_data[0]); /* PPDU based reporting */ - if (FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) { + if (mtk_wed_device_active(&dev->mmio.wed) && + FIELD_GET(MT_TXS0_TXS_FORMAT, txs) > 1) { stats->tx_bytes += le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_BYTE) - le32_get_bits(txs_data[7], MT_TXS7_MPDU_RETRY_BYTE); - stats->tx_packets += - le32_get_bits(txs_data[5], MT_TXS5_MPDU_TX_CNT); stats->tx_failed += le32_get_bits(txs_data[6], MT_TXS6_MPDU_FAIL_CNT); stats->tx_retries += diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h @@ -993,6 +993,7 @@ MCU_EXT_EVENT_ASSERT_DUMP = 0x23, MCU_EXT_EVENT_RDD_REPORT = 0x3a, MCU_EXT_EVENT_CSA_NOTIFY = 0x4f, + MCU_EXT_EVENT_WA_TX_STAT = 0x74, MCU_EXT_EVENT_BCC_NOTIFY = 0x75, MCU_EXT_EVENT_MURU_CTRL = 0x9f, }; diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/init.c linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/init.c --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/init.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/init.c @@ -485,6 +485,12 @@ set = FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_MODE, 0) | FIELD_PREP(MT_WTBLOFF_TOP_RSCR_RCPI_PARAM, 0x3); mt76_rmw(dev, MT_WTBLOFF_TOP_RSCR(band), mask, set); + + /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than + * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set. + */ + if (mtk_wed_device_active(&dev->mt76.mmio.wed)) + mt76_set(dev, MT_AGG_ACR4(band), MT_AGG_ACR_PPDU_TXS2H); } void mt7915_mac_init(struct mt7915_dev *dev) diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/main.c linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/main.c --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/main.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/main.c @@ -471,7 +471,8 @@ ieee80211_wake_queues(hw); } - if (changed & IEEE80211_CONF_CHANGE_POWER) { + if (changed & (IEEE80211_CONF_CHANGE_POWER | + IEEE80211_CONF_CHANGE_CHANNEL)) { ret = mt7915_mcu_set_txpower_sku(phy); if (ret) return ret; @@ -1043,8 +1044,10 @@ sinfo->tx_bytes = msta->wcid.stats.tx_bytes; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES64); - sinfo->tx_packets = msta->wcid.stats.tx_packets; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); + if (!mt7915_mcu_wed_wa_tx_stats(phy->dev, msta->wcid.idx)) { + sinfo->tx_packets = msta->wcid.stats.tx_packets; + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS); + } sinfo->tx_failed = msta->wcid.stats.tx_failed; sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -164,7 +164,9 @@ } rxd = (struct mt76_connac2_mcu_rxd *)skb->data; - if (seq != rxd->seq) + if (seq != rxd->seq && + !(rxd->eid == MCU_CMD_EXT_CID && + rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT)) return -EAGAIN; if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) { @@ -382,12 +384,14 @@ struct mt76_connac2_mcu_rxd *rxd; rxd = (struct mt76_connac2_mcu_rxd *)skb->data; - if (rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT || - rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST || - rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP || - rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC || - rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY || - !rxd->seq) + if ((rxd->ext_eid == MCU_EXT_EVENT_THERMAL_PROTECT || + rxd->ext_eid == MCU_EXT_EVENT_FW_LOG_2_HOST || + rxd->ext_eid == MCU_EXT_EVENT_ASSERT_DUMP || + rxd->ext_eid == MCU_EXT_EVENT_PS_SYNC || + rxd->ext_eid == MCU_EXT_EVENT_BCC_NOTIFY || + !rxd->seq) && + !(rxd->eid == MCU_CMD_EXT_CID && + rxd->ext_eid == MCU_EXT_EVENT_WA_TX_STAT)) mt7915_mcu_rx_unsolicited_event(dev, skb); else mt76_mcu_rx_event(&dev->mt76, skb); @@ -3752,6 +3756,62 @@ &req, sizeof(req), true); } +int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wlan_idx) +{ + struct { + __le32 cmd; + __le32 num; + __le32 __rsv; + __le16 wlan_idx; + } req = { + .cmd = cpu_to_le32(0x15), + .num = cpu_to_le32(1), + .wlan_idx = cpu_to_le16(wlan_idx), + }; + struct mt7915_mcu_wa_tx_stat { + __le16 wlan_idx; + u8 __rsv[2]; + + /* tx_bytes is deprecated since WA byte counter uses u32, + * which easily leads to overflow. + */ + __le32 tx_bytes; + __le32 tx_packets; + } *res; + struct mt76_wcid *wcid; + struct sk_buff *skb; + int ret; + + ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_WA_PARAM_CMD(QUERY), + &req, sizeof(req), true, &skb); + if (ret) + return ret; + + if (!is_mt7915(&dev->mt76)) + skb_pull(skb, 4); + + res = (struct mt7915_mcu_wa_tx_stat *)skb->data; + + if (le16_to_cpu(res->wlan_idx) != wlan_idx) { + ret = -EINVAL; + goto out; + } + + rcu_read_lock(); + + wcid = rcu_dereference(dev->mt76.wcid[wlan_idx]); + if (wcid) + wcid->stats.tx_packets += le32_to_cpu(res->tx_packets); + else + ret = -EINVAL; + + rcu_read_unlock(); +out: + dev_kfree_skb(skb); + + return ret; +} + int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set) { struct { diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c @@ -543,8 +543,6 @@ static int mt7915_mmio_wed_offload_enable(struct mtk_wed_device *wed) { struct mt7915_dev *dev; - struct mt7915_phy *phy; - int ret; dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed); @@ -552,43 +550,19 @@ dev->mt76.token_size = wed->wlan.token_start; spin_unlock_bh(&dev->mt76.token_lock); - ret = wait_event_timeout(dev->mt76.tx_wait, - !dev->mt76.wed_token_count, HZ); - if (!ret) - return -EAGAIN; - - phy = &dev->phy; - mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H); - - phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL; - if (phy) - mt76_set(dev, MT_AGG_ACR4(phy->mt76->band_idx), - MT_AGG_ACR_PPDU_TXS2H); - - return 0; + return !wait_event_timeout(dev->mt76.tx_wait, + !dev->mt76.wed_token_count, HZ); } static void mt7915_mmio_wed_offload_disable(struct mtk_wed_device *wed) { struct mt7915_dev *dev; - struct mt7915_phy *phy; dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed); spin_lock_bh(&dev->mt76.token_lock); dev->mt76.token_size = MT7915_TOKEN_SIZE; spin_unlock_bh(&dev->mt76.token_lock); - - /* MT_TXD5_TX_STATUS_HOST (MPDU format) has higher priority than - * MT_AGG_ACR_PPDU_TXS2H (PPDU format) even though ACR bit is set. - */ - phy = &dev->phy; - mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx), MT_AGG_ACR_PPDU_TXS2H); - - phy = dev->mt76.phys[MT_BAND1] ? dev->mt76.phys[MT_BAND1]->priv : NULL; - if (phy) - mt76_clear(dev, MT_AGG_ACR4(phy->mt76->band_idx), - MT_AGG_ACR_PPDU_TXS2H); } static void mt7915_mmio_wed_release_rx_buf(struct mtk_wed_device *wed) diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -553,6 +553,7 @@ struct ieee80211_sta *sta, struct rate_info *rate); int mt7915_mcu_rdd_background_enable(struct mt7915_phy *phy, struct cfg80211_chan_def *chandef); +int mt7915_mcu_wed_wa_tx_stats(struct mt7915_dev *dev, u16 wcid); int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set); int mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3); int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 type, u8 ctrl); diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7921/init.c linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7921/init.c --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7921/init.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7921/init.c @@ -110,7 +110,8 @@ wiphy->max_sched_scan_ssids = MT76_CONNAC_MAX_SCHED_SCAN_SSID; wiphy->max_match_sets = MT76_CONNAC_MAX_SCAN_MATCH; wiphy->max_sched_scan_reqs = 1; - wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; + wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH | + WIPHY_FLAG_SPLIT_SCAN_6GHZ; wiphy->reg_notifier = mt7921_regd_notifier; wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR | diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -338,7 +338,11 @@ if (r->band_idx >= ARRAY_SIZE(dev->mt76.phys)) return; - mphy = dev->mt76.phys[r->band_idx]; + if (dev->rdd2_phy && r->band_idx == MT_RX_SEL2) + mphy = dev->rdd2_phy->mt76; + else + mphy = dev->mt76.phys[r->band_idx]; + if (!mphy) return; @@ -712,6 +716,7 @@ struct cfg80211_chan_def *chandef = &phy->chandef; struct mt76_connac_bss_basic_tlv *bss; u32 type = CONNECTION_INFRA_AP; + u16 sta_wlan_idx = wlan_idx; struct tlv *tlv; int idx; @@ -731,7 +736,7 @@ struct mt76_wcid *wcid; wcid = (struct mt76_wcid *)sta->drv_priv; - wlan_idx = wcid->idx; + sta_wlan_idx = wcid->idx; } rcu_read_unlock(); } @@ -751,7 +756,7 @@ bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int); bss->dtim_period = vif->bss_conf.dtim_period; bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx); - bss->sta_idx = cpu_to_le16(wlan_idx); + bss->sta_idx = cpu_to_le16(sta_wlan_idx); bss->conn_type = cpu_to_le32(type); bss->omac_idx = mvif->omac_idx; bss->band_idx = mvif->band_idx; diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -27,6 +27,7 @@ #define MT7996_RX_RING_SIZE 1536 #define MT7996_RX_MCU_RING_SIZE 512 +#define MT7996_RX_MCU_RING_SIZE_WA 1024 #define MT7996_FIRMWARE_WA "mediatek/mt7996/mt7996_wa.bin" #define MT7996_FIRMWARE_WM "mediatek/mt7996/mt7996_wm.bin" diff -u linux-6.2.0/drivers/net/wireless/mediatek/mt76/tx.c linux-6.2.0/drivers/net/wireless/mediatek/mt76/tx.c --- linux-6.2.0/drivers/net/wireless/mediatek/mt76/tx.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/tx.c @@ -121,6 +121,7 @@ mt76_tx_status_skb_add(struct mt76_dev *dev, struct mt76_wcid *wcid, struct sk_buff *skb) { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct mt76_tx_cb *cb = mt76_tx_skb_cb(skb); int pid; @@ -134,8 +135,14 @@ return MT_PACKET_ID_NO_ACK; if (!(info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS | - IEEE80211_TX_CTL_RATE_CTRL_PROBE))) + IEEE80211_TX_CTL_RATE_CTRL_PROBE))) { + if (mtk_wed_device_active(&dev->mmio.wed) && + ((info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) || + ieee80211_is_data(hdr->frame_control))) + return MT_PACKET_ID_WED; + return MT_PACKET_ID_NO_SKB; + } spin_lock_bh(&dev->status_lock); diff -u linux-6.2.0/drivers/net/wireless/realtek/rtw89/debug.c linux-6.2.0/drivers/net/wireless/realtek/rtw89/debug.c --- linux-6.2.0/drivers/net/wireless/realtek/rtw89/debug.c +++ linux-6.2.0/drivers/net/wireless/realtek/rtw89/debug.c @@ -3170,12 +3170,14 @@ struct rtw89_dev *rtwdev = debugfs_priv->rtwdev; struct rtw89_btc *btc = &rtwdev->btc; bool btc_manual; + int ret; - if (kstrtobool_from_user(user_buf, count, &btc_manual)) - goto out; + ret = kstrtobool_from_user(user_buf, count, &btc_manual); + if (ret) + return ret; btc->ctrl.manual = btc_manual; -out: + return count; } diff -u linux-6.2.0/drivers/ntb/ntb_transport.c linux-6.2.0/drivers/ntb/ntb_transport.c --- linux-6.2.0/drivers/ntb/ntb_transport.c +++ linux-6.2.0/drivers/ntb/ntb_transport.c @@ -909,7 +909,7 @@ return 0; } -static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp) +static void ntb_qp_link_context_reset(struct ntb_transport_qp *qp) { qp->link_is_up = false; qp->active = false; @@ -932,6 +932,13 @@ qp->tx_async = 0; } +static void ntb_qp_link_down_reset(struct ntb_transport_qp *qp) +{ + ntb_qp_link_context_reset(qp); + if (qp->remote_rx_info) + qp->remote_rx_info->entry = qp->rx_max_entry - 1; +} + static void ntb_qp_link_cleanup(struct ntb_transport_qp *qp) { struct ntb_transport_ctx *nt = qp->transport; @@ -1174,7 +1181,7 @@ qp->ndev = nt->ndev; qp->client_ready = false; qp->event_handler = NULL; - ntb_qp_link_down_reset(qp); + ntb_qp_link_context_reset(qp); if (mw_num < qp_count % mw_count) num_qps_mw = qp_count / mw_count + 1; @@ -2276,9 +2283,13 @@ struct ntb_queue_entry *entry; int rc; - if (!qp || !qp->link_is_up || !len) + if (!qp || !len) return -EINVAL; + /* If the qp link is down already, just ignore. */ + if (!qp->link_is_up) + return 0; + entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q); if (!entry) { qp->tx_err_no_buf++; @@ -2418,7 +2429,7 @@ unsigned int head = qp->tx_index; unsigned int tail = qp->remote_rx_info->entry; - return tail > head ? tail - head : qp->tx_max_entry + tail - head; + return tail >= head ? tail - head : qp->tx_max_entry + tail - head; } EXPORT_SYMBOL_GPL(ntb_transport_tx_free_entry); diff -u linux-6.2.0/drivers/nvme/host/core.c linux-6.2.0/drivers/nvme/host/core.c --- linux-6.2.0/drivers/nvme/host/core.c +++ linux-6.2.0/drivers/nvme/host/core.c @@ -2430,25 +2430,8 @@ else ctrl->ctrl_config = NVME_CC_CSS_NVM; - if (ctrl->cap & NVME_CAP_CRMS_CRWMS) { - u32 crto; - - ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CRTO, &crto); - if (ret) { - dev_err(ctrl->device, "Reading CRTO failed (%d)\n", - ret); - return ret; - } - - if (ctrl->cap & NVME_CAP_CRMS_CRIMS) { - ctrl->ctrl_config |= NVME_CC_CRIME; - timeout = NVME_CRTO_CRIMT(crto); - } else { - timeout = NVME_CRTO_CRWMT(crto); - } - } else { - timeout = NVME_CAP_TIMEOUT(ctrl->cap); - } + if (ctrl->cap & NVME_CAP_CRMS_CRWMS && ctrl->cap & NVME_CAP_CRMS_CRIMS) + ctrl->ctrl_config |= NVME_CC_CRIME; ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE; @@ -2462,6 +2445,39 @@ if (ret) return ret; + /* CAP value may change after initial CC write */ + ret = ctrl->ops->reg_read64(ctrl, NVME_REG_CAP, &ctrl->cap); + if (ret) + return ret; + + timeout = NVME_CAP_TIMEOUT(ctrl->cap); + if (ctrl->cap & NVME_CAP_CRMS_CRWMS) { + u32 crto, ready_timeout; + + ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CRTO, &crto); + if (ret) { + dev_err(ctrl->device, "Reading CRTO failed (%d)\n", + ret); + return ret; + } + + /* + * CRTO should always be greater or equal to CAP.TO, but some + * devices are known to get this wrong. Use the larger of the + * two values. + */ + if (ctrl->ctrl_config & NVME_CC_CRIME) + ready_timeout = NVME_CRTO_CRIMT(crto); + else + ready_timeout = NVME_CRTO_CRWMT(crto); + + if (ready_timeout < timeout) + dev_warn_once(ctrl->device, "bad crto:%x cap:%llx\n", + crto, ctrl->cap); + else + timeout = ready_timeout; + } + ctrl->ctrl_config |= NVME_CC_ENABLE; ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config); if (ret) diff -u linux-6.2.0/drivers/nvme/host/pci.c linux-6.2.0/drivers/nvme/host/pci.c --- linux-6.2.0/drivers/nvme/host/pci.c +++ linux-6.2.0/drivers/nvme/host/pci.c @@ -2967,9 +2967,6 @@ struct nvme_dev *dev; int ret = -ENOMEM; - if (node == NUMA_NO_NODE) - set_dev_node(&pdev->dev, first_memory_node); - dev = kzalloc_node(sizeof(*dev), GFP_KERNEL, node); if (!dev) return ERR_PTR(-ENOMEM); diff -u linux-6.2.0/drivers/nvme/target/tcp.c linux-6.2.0/drivers/nvme/target/tcp.c --- linux-6.2.0/drivers/nvme/target/tcp.c +++ linux-6.2.0/drivers/nvme/target/tcp.c @@ -321,9 +321,8 @@ while (length) { u32 iov_len = min_t(u32, length, sg->length - sg_offset); - iov->bv_page = sg_page(sg); - iov->bv_len = sg->length; - iov->bv_offset = sg->offset + sg_offset; + bvec_set_page(iov, sg_page(sg), iov_len, + sg->offset + sg_offset); length -= iov_len; sg = sg_next(sg); diff -u linux-6.2.0/drivers/of/dynamic.c linux-6.2.0/drivers/of/dynamic.c --- linux-6.2.0/drivers/of/dynamic.c +++ linux-6.2.0/drivers/of/dynamic.c @@ -225,6 +225,7 @@ np->sibling = np->parent->child; np->parent->child = np; of_node_clear_flag(np, OF_DETACHED); + np->fwnode.flags |= FWNODE_FLAG_NOT_DEVICE; } /** @@ -901,13 +902,13 @@ { struct of_changeset_entry *ce; + if (WARN_ON(action >= ARRAY_SIZE(action_names))) + return -EINVAL; + ce = kzalloc(sizeof(*ce), GFP_KERNEL); if (!ce) return -ENOMEM; - if (WARN_ON(action >= ARRAY_SIZE(action_names))) - return -EINVAL; - /* get a reference to the node */ ce->action = action; ce->np = of_node_get(np); diff -u linux-6.2.0/drivers/of/overlay.c linux-6.2.0/drivers/of/overlay.c --- linux-6.2.0/drivers/of/overlay.c +++ linux-6.2.0/drivers/of/overlay.c @@ -752,8 +752,6 @@ if (!of_node_is_root(ovcs->overlay_root)) pr_debug("%s() ovcs->overlay_root is not root\n", __func__); - of_changeset_init(&ovcs->cset); - cnt = 0; /* fragment nodes */ @@ -1013,6 +1011,7 @@ INIT_LIST_HEAD(&ovcs->ovcs_list); list_add_tail(&ovcs->ovcs_list, &ovcs_list); + of_changeset_init(&ovcs->cset); /* * Must create permanent copy of FDT because of_fdt_unflatten_tree() diff -u linux-6.2.0/drivers/of/platform.c linux-6.2.0/drivers/of/platform.c --- linux-6.2.0/drivers/of/platform.c +++ linux-6.2.0/drivers/of/platform.c @@ -740,6 +740,11 @@ if (of_node_check_flag(rd->dn, OF_POPULATED)) return NOTIFY_OK; + /* + * Clear the flag before adding the device so that fw_devlink + * doesn't skip adding consumers to this device. + */ + rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE; /* pdev_parent may be NULL when no bus platform device */ pdev_parent = of_find_device_by_node(rd->dn->parent); pdev = of_platform_device_create(rd->dn, NULL, diff -u linux-6.2.0/drivers/of/unittest.c linux-6.2.0/drivers/of/unittest.c --- linux-6.2.0/drivers/of/unittest.c +++ linux-6.2.0/drivers/of/unittest.c @@ -70,7 +70,7 @@ np = of_find_node_by_path("/testcase-data"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data", name), + unittest(np && name && !strcmp("/testcase-data", name), "find /testcase-data failed\n"); of_node_put(np); kfree(name); @@ -81,14 +81,14 @@ np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name), + unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name), "find /testcase-data/phandle-tests/consumer-a failed\n"); of_node_put(np); kfree(name); np = of_find_node_by_path("testcase-alias"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data", name), + unittest(np && name && !strcmp("/testcase-data", name), "find testcase-alias failed\n"); of_node_put(np); kfree(name); @@ -99,7 +99,7 @@ np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name), + unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name), "find testcase-alias/phandle-tests/consumer-a failed\n"); of_node_put(np); kfree(name); @@ -1379,6 +1379,8 @@ const char *full_name; full_name = kasprintf(GFP_KERNEL, "%pOF", np); + if (!full_name) + return; if (!strcmp(full_name, "/__local_fixups__") || !strcmp(full_name, "/__fixups__")) { @@ -2060,7 +2062,7 @@ of_unittest_untrack_overlay(save_ovcs_id); /* unittest device must be again in before state */ - if (of_unittest_device_exists(unittest_nr, PDEV_OVERLAY) != before) { + if (of_unittest_device_exists(unittest_nr, ovtype) != before) { unittest(0, "%s with device @\"%s\" %s\n", overlay_name_from_nr(overlay_nr), unittest_path(unittest_nr, ovtype), diff -u linux-6.2.0/drivers/opp/core.c linux-6.2.0/drivers/opp/core.c --- linux-6.2.0/drivers/opp/core.c +++ linux-6.2.0/drivers/opp/core.c @@ -2372,7 +2372,7 @@ virt_dev = dev_pm_domain_attach_by_name(dev, *name); if (IS_ERR_OR_NULL(virt_dev)) { - ret = PTR_ERR(virt_dev) ? : -ENODEV; + ret = virt_dev ? PTR_ERR(virt_dev) : -ENODEV; dev_err(dev, "Couldn't attach to pm_domain: %d\n", ret); goto err; } diff -u linux-6.2.0/drivers/pci/controller/dwc/pci-imx6.c linux-6.2.0/drivers/pci/controller/dwc/pci-imx6.c --- linux-6.2.0/drivers/pci/controller/dwc/pci-imx6.c +++ linux-6.2.0/drivers/pci/controller/dwc/pci-imx6.c @@ -999,6 +999,7 @@ static const struct dw_pcie_host_ops imx6_pcie_host_ops = { .host_init = imx6_pcie_host_init, + .host_deinit = imx6_pcie_host_exit, }; static const struct dw_pcie_ops dw_pcie_ops = { diff -u linux-6.2.0/drivers/pci/controller/dwc/pcie-qcom.c linux-6.2.0/drivers/pci/controller/dwc/pcie-qcom.c --- linux-6.2.0/drivers/pci/controller/dwc/pcie-qcom.c +++ linux-6.2.0/drivers/pci/controller/dwc/pcie-qcom.c @@ -42,7 +42,6 @@ #define PARF_PHY_REFCLK 0x4c #define PARF_CONFIG_BITS 0x50 #define PARF_DBI_BASE_ADDR 0x168 -#define PARF_SLV_ADDR_SPACE_SIZE_2_3_3 0x16c /* Register offset specific to IP ver 2.3.3 */ #define PARF_MHI_CLOCK_RESET_CTRL 0x174 #define PARF_AXI_MSTR_WR_ADDR_HALT 0x178 #define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1a8 @@ -1151,8 +1150,7 @@ u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); u32 val; - writel(SLV_ADDR_SPACE_SZ, - pcie->parf + PARF_SLV_ADDR_SPACE_SIZE_2_3_3); + writel(SLV_ADDR_SPACE_SZ, pcie->parf + PARF_SLV_ADDR_SPACE_SIZE); val = readl(pcie->parf + PARF_PHY_CTRL); val &= ~BIT(0); diff -u linux-6.2.0/drivers/pci/controller/dwc/pcie-tegra194.c linux-6.2.0/drivers/pci/controller/dwc/pcie-tegra194.c --- linux-6.2.0/drivers/pci/controller/dwc/pcie-tegra194.c +++ linux-6.2.0/drivers/pci/controller/dwc/pcie-tegra194.c @@ -878,11 +878,6 @@ pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci, PCI_CAP_ID_EXP); - val_16 = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL); - val_16 &= ~PCI_EXP_DEVCTL_PAYLOAD; - val_16 |= PCI_EXP_DEVCTL_PAYLOAD_256B; - dw_pcie_writew_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL, val_16); - val = dw_pcie_readl_dbi(pci, PCI_IO_BASE); val &= ~(IO_BASE_IO_DECODE | IO_BASE_IO_DECODE_BIT8); dw_pcie_writel_dbi(pci, PCI_IO_BASE, val); @@ -1871,11 +1866,6 @@ pcie->pcie_cap_base = dw_pcie_find_capability(&pcie->pci, PCI_CAP_ID_EXP); - val_16 = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL); - val_16 &= ~PCI_EXP_DEVCTL_PAYLOAD; - val_16 |= PCI_EXP_DEVCTL_PAYLOAD_256B; - dw_pcie_writew_dbi(pci, pcie->pcie_cap_base + PCI_EXP_DEVCTL, val_16); - /* Clear Slot Clock Configuration bit if SRNS configuration */ if (pcie->enable_srns) { val_16 = dw_pcie_readw_dbi(pci, pcie->pcie_cap_base + diff -u linux-6.2.0/drivers/pci/controller/pci-hyperv.c linux-6.2.0/drivers/pci/controller/pci-hyperv.c --- linux-6.2.0/drivers/pci/controller/pci-hyperv.c +++ linux-6.2.0/drivers/pci/controller/pci-hyperv.c @@ -3917,6 +3917,9 @@ struct msi_desc *entry; int ret = 0; + if (!pdev->msi_enabled && !pdev->msix_enabled) + return 0; + msi_lock_descs(&pdev->dev); msi_for_each_desc(entry, &pdev->dev, MSI_DESC_ASSOCIATED) { irq_data = irq_get_irq_data(entry->irq); diff -u linux-6.2.0/drivers/pci/controller/pcie-rockchip.h linux-6.2.0/drivers/pci/controller/pcie-rockchip.h --- linux-6.2.0/drivers/pci/controller/pcie-rockchip.h +++ linux-6.2.0/drivers/pci/controller/pcie-rockchip.h @@ -158,7 +158,9 @@ #define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274) #define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK GENMASK(31, 20) -#define PCIE_ADDR_MASK 0xffffff00 +#define MAX_AXI_IB_ROOTPORT_REGION_NUM 3 +#define MIN_AXI_ADDR_BITS_PASSED 8 +#define PCIE_ADDR_MASK GENMASK_ULL(63, MIN_AXI_ADDR_BITS_PASSED) #define PCIE_CORE_AXI_CONF_BASE 0xc00000 #define PCIE_CORE_OB_REGION_ADDR0 (PCIE_CORE_AXI_CONF_BASE + 0x0) #define PCIE_CORE_OB_REGION_ADDR0_NUM_BITS 0x3f @@ -185,8 +187,6 @@ #define AXI_WRAPPER_TYPE1_CFG 0xb #define AXI_WRAPPER_NOR_MSG 0xc -#define MAX_AXI_IB_ROOTPORT_REGION_NUM 3 -#define MIN_AXI_ADDR_BITS_PASSED 8 #define PCIE_RC_SEND_PME_OFF 0x11960 #define ROCKCHIP_VENDOR_ID 0x1d87 #define PCIE_LINK_IS_L2(x) \ diff -u linux-6.2.0/drivers/pci/controller/vmd.c linux-6.2.0/drivers/pci/controller/vmd.c --- linux-6.2.0/drivers/pci/controller/vmd.c +++ linux-6.2.0/drivers/pci/controller/vmd.c @@ -541,8 +541,23 @@ PCI_CLASS_BRIDGE_PCI)) continue; - memset_io(base + PCI_IO_BASE, 0, - PCI_ROM_ADDRESS1 - PCI_IO_BASE); + /* + * Temporarily disable the I/O range before updating + * PCI_IO_BASE. + */ + writel(0x0000ffff, base + PCI_IO_BASE_UPPER16); + /* Update lower 16 bits of I/O base/limit */ + writew(0x00f0, base + PCI_IO_BASE); + /* Update upper 16 bits of I/O base/limit */ + writel(0, base + PCI_IO_BASE_UPPER16); + + /* MMIO Base/Limit */ + writel(0x0000fff0, base + PCI_MEMORY_BASE); + + /* Prefetchable MMIO Base/Limit */ + writel(0, base + PCI_PREF_LIMIT_UPPER32); + writel(0x0000fff0, base + PCI_PREF_MEMORY_BASE); + writel(0xffffffff, base + PCI_PREF_BASE_UPPER32); } } } diff -u linux-6.2.0/drivers/pci/doe.c linux-6.2.0/drivers/pci/doe.c --- linux-6.2.0/drivers/pci/doe.c +++ linux-6.2.0/drivers/pci/doe.c @@ -223,8 +223,8 @@ static void signal_task_complete(struct pci_doe_task *task, int rv) { task->rv = rv; - task->complete(task); destroy_work_on_stack(&task->work); + task->complete(task); } static void signal_task_abort(struct pci_doe_task *task, int rv) reverted: --- linux-6.2.0/drivers/pci/hotplug/acpiphp_glue.c +++ linux-6.2.0.orig/drivers/pci/hotplug/acpiphp_glue.c @@ -512,15 +512,12 @@ if (pass && dev->subordinate) { check_hotplug_bridge(slot, dev); pcibios_resource_survey_bus(dev->subordinate); + __pci_bus_size_bridges(dev->subordinate, + &add_list); - if (pci_is_root_bus(bus)) - __pci_bus_size_bridges(dev->subordinate, &add_list); } } } + __pci_bus_assign_resources(bus, &add_list, NULL); - if (pci_is_root_bus(bus)) - __pci_bus_assign_resources(bus, &add_list, NULL); - else - pci_assign_unassigned_bridge_resources(bus->self); } acpiphp_sanitize_bus(bus); diff -u linux-6.2.0/drivers/pci/hotplug/pciehp_hpc.c linux-6.2.0/drivers/pci/hotplug/pciehp_hpc.c --- linux-6.2.0/drivers/pci/hotplug/pciehp_hpc.c +++ linux-6.2.0/drivers/pci/hotplug/pciehp_hpc.c @@ -332,17 +332,11 @@ static int __pciehp_link_set(struct controller *ctrl, bool enable) { struct pci_dev *pdev = ctrl_dev(ctrl); - u16 lnk_ctrl; - pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &lnk_ctrl); + pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_LD, + enable ? 0 : PCI_EXP_LNKCTL_LD); - if (enable) - lnk_ctrl &= ~PCI_EXP_LNKCTL_LD; - else - lnk_ctrl |= PCI_EXP_LNKCTL_LD; - - pcie_capability_write_word(pdev, PCI_EXP_LNKCTL, lnk_ctrl); - ctrl_dbg(ctrl, "%s: lnk_ctrl = %x\n", __func__, lnk_ctrl); return 0; } diff -u linux-6.2.0/drivers/pci/pci.c linux-6.2.0/drivers/pci/pci.c --- linux-6.2.0/drivers/pci/pci.c +++ linux-6.2.0/drivers/pci/pci.c @@ -1193,6 +1193,10 @@ * * On success, return 0 or 1, depending on whether or not it is necessary to * restore the device's BARs subsequently (1 is returned in that case). + * + * On failure, return a negative error code. Always return failure if @dev + * lacks a Power Management Capability, even if the platform was able to + * put the device in D0 via non-PCI means. */ int pci_power_up(struct pci_dev *dev) { @@ -1209,9 +1213,6 @@ else dev->current_state = state; - if (state == PCI_D0) - return 0; - return -EIO; } @@ -1269,8 +1270,12 @@ int ret; ret = pci_power_up(dev); - if (ret < 0) + if (ret < 0) { + if (dev->current_state == PCI_D0) + return 0; + return ret; + } pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); dev->current_state = pmcsr & PCI_PM_CTRL_STATE_MASK; diff -u linux-6.2.0/drivers/pci/pcie/aspm.c linux-6.2.0/drivers/pci/pcie/aspm.c --- linux-6.2.0/drivers/pci/pcie/aspm.c +++ linux-6.2.0/drivers/pci/pcie/aspm.c @@ -250,7 +250,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) { int same_clock = 1; - u16 reg16, parent_reg, child_reg[8]; + u16 reg16, ccc, parent_old_ccc, child_old_ccc[8]; struct pci_dev *child, *parent = link->pdev; struct pci_bus *linkbus = parent->subordinate; /* @@ -272,6 +272,7 @@ /* Port might be already in common clock mode */ pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); + parent_old_ccc = reg16 & PCI_EXP_LNKCTL_CCC; if (same_clock && (reg16 & PCI_EXP_LNKCTL_CCC)) { bool consistent = true; @@ -288,34 +289,29 @@ pci_info(parent, "ASPM: current common clock configuration is inconsistent, reconfiguring\n"); } + ccc = same_clock ? PCI_EXP_LNKCTL_CCC : 0; /* Configure downstream component, all functions */ list_for_each_entry(child, &linkbus->devices, bus_list) { pcie_capability_read_word(child, PCI_EXP_LNKCTL, ®16); - child_reg[PCI_FUNC(child->devfn)] = reg16; - if (same_clock) - reg16 |= PCI_EXP_LNKCTL_CCC; - else - reg16 &= ~PCI_EXP_LNKCTL_CCC; - pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16); + child_old_ccc[PCI_FUNC(child->devfn)] = reg16 & PCI_EXP_LNKCTL_CCC; + pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, ccc); } /* Configure upstream component */ - pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); - parent_reg = reg16; - if (same_clock) - reg16 |= PCI_EXP_LNKCTL_CCC; - else - reg16 &= ~PCI_EXP_LNKCTL_CCC; - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); + pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, ccc); if (pcie_retrain_link(link)) { /* Training failed. Restore common clock configurations */ pci_err(parent, "ASPM: Could not configure common clock\n"); list_for_each_entry(child, &linkbus->devices, bus_list) - pcie_capability_write_word(child, PCI_EXP_LNKCTL, - child_reg[PCI_FUNC(child->devfn)]); - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg); + pcie_capability_clear_and_set_word(child, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, + child_old_ccc[PCI_FUNC(child->devfn)]); + pcie_capability_clear_and_set_word(parent, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_CCC, parent_old_ccc); } } diff -u linux-6.2.0/drivers/pci/probe.c linux-6.2.0/drivers/pci/probe.c --- linux-6.2.0/drivers/pci/probe.c +++ linux-6.2.0/drivers/pci/probe.c @@ -998,6 +998,7 @@ res = window->res; if (!res->flags && !res->start && !res->end) { release_resource(res); + resource_list_destroy_entry(window); continue; } @@ -2317,6 +2318,7 @@ .end = -1, }; + spin_lock_init(&dev->pcie_cap_lock); #ifdef CONFIG_PCI_MSI raw_spin_lock_init(&dev->msi_lock); #endif diff -u linux-6.2.0/drivers/pci/quirks.c linux-6.2.0/drivers/pci/quirks.c --- linux-6.2.0/drivers/pci/quirks.c +++ linux-6.2.0/drivers/pci/quirks.c @@ -3646,7 +3646,7 @@ */ static void quirk_nvidia_no_bus_reset(struct pci_dev *dev) { - if ((dev->device & 0xffc0) == 0x2340) + if ((dev->device & 0xffc0) == 0x2340 || dev->device == 0x1eb8) quirk_no_bus_reset(dev); } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, diff -u linux-6.2.0/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c linux-6.2.0/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c --- linux-6.2.0/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +++ linux-6.2.0/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c @@ -214,8 +214,7 @@ if (!hsphy->phy_initialized) return 0; - qcom_snps_hsphy_suspend(hsphy); - return 0; + return qcom_snps_hsphy_suspend(hsphy); } static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) @@ -225,8 +224,7 @@ if (!hsphy->phy_initialized) return 0; - qcom_snps_hsphy_resume(hsphy); - return 0; + return qcom_snps_hsphy_resume(hsphy); } static int qcom_snps_hsphy_set_mode(struct phy *phy, enum phy_mode mode, diff -u linux-6.2.0/drivers/pinctrl/intel/pinctrl-cherryview.c linux-6.2.0/drivers/pinctrl/intel/pinctrl-cherryview.c --- linux-6.2.0/drivers/pinctrl/intel/pinctrl-cherryview.c +++ linux-6.2.0/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1700,7 +1700,6 @@ struct intel_community_context *cctx; struct intel_community *community; struct device *dev = &pdev->dev; - struct acpi_device *adev = ACPI_COMPANION(dev); struct intel_pinctrl *pctrl; acpi_status status; unsigned int i; @@ -1768,7 +1767,7 @@ if (ret) return ret; - status = acpi_install_address_space_handler(adev->handle, + status = acpi_install_address_space_handler(ACPI_HANDLE(dev), community->acpi_space_id, chv_pinctrl_mmio_access_handler, NULL, pctrl); @@ -1785,7 +1784,7 @@ struct intel_pinctrl *pctrl = platform_get_drvdata(pdev); const struct intel_community *community = &pctrl->communities[0]; - acpi_remove_address_space_handler(ACPI_COMPANION(&pdev->dev), + acpi_remove_address_space_handler(ACPI_HANDLE(&pdev->dev), community->acpi_space_id, chv_pinctrl_mmio_access_handler); diff -u linux-6.2.0/drivers/platform/mellanox/Kconfig linux-6.2.0/drivers/platform/mellanox/Kconfig --- linux-6.2.0/drivers/platform/mellanox/Kconfig +++ linux-6.2.0/drivers/platform/mellanox/Kconfig @@ -60,6 +60,7 @@ tristate "Mellanox BlueField Firmware Boot Control driver" depends on ARM64 depends on ACPI + depends on NET help The Mellanox BlueField firmware implements functionality to request swapping the primary and alternate eMMC boot partition, @@ -80,8 +81,8 @@ config NVSW_SN2201 tristate "Nvidia SN2201 platform driver support" - depends on HWMON - depends on I2C + depends on HWMON && I2C + depends on ACPI || COMPILE_TEST select REGMAP_I2C help This driver provides support for the Nvidia SN2201 platform. diff -u linux-6.2.0/drivers/platform/mellanox/mlxbf-pmc.c linux-6.2.0/drivers/platform/mellanox/mlxbf-pmc.c --- linux-6.2.0/drivers/platform/mellanox/mlxbf-pmc.c +++ linux-6.2.0/drivers/platform/mellanox/mlxbf-pmc.c @@ -191,6 +191,7 @@ }; static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_1[] = { + { 0x0, "DISABLE" }, { 0xa0, "TPIO_DATA_BEAT" }, { 0xa1, "TDMA_DATA_BEAT" }, { 0xa2, "MAP_DATA_BEAT" }, @@ -214,6 +215,7 @@ }; static const struct mlxbf_pmc_events mlxbf_pmc_trio_events_2[] = { + { 0x0, "DISABLE" }, { 0xa0, "TPIO_DATA_BEAT" }, { 0xa1, "TDMA_DATA_BEAT" }, { 0xa2, "MAP_DATA_BEAT" }, @@ -246,6 +248,7 @@ }; static const struct mlxbf_pmc_events mlxbf_pmc_ecc_events[] = { + { 0x0, "DISABLE" }, { 0x100, "ECC_SINGLE_ERROR_CNT" }, { 0x104, "ECC_DOUBLE_ERROR_CNT" }, { 0x114, "SERR_INJ" }, @@ -258,6 +261,7 @@ }; static const struct mlxbf_pmc_events mlxbf_pmc_mss_events[] = { + { 0x0, "DISABLE" }, { 0xc0, "RXREQ_MSS" }, { 0xc1, "RXDAT_MSS" }, { 0xc2, "TXRSP_MSS" }, @@ -265,6 +269,7 @@ }; static const struct mlxbf_pmc_events mlxbf_pmc_hnf_events[] = { + { 0x0, "DISABLE" }, { 0x45, "HNF_REQUESTS" }, { 0x46, "HNF_REJECTS" }, { 0x47, "ALL_BUSY" }, @@ -323,6 +328,7 @@ }; static const struct mlxbf_pmc_events mlxbf_pmc_hnfnet_events[] = { + { 0x0, "DISABLE" }, { 0x12, "CDN_REQ" }, { 0x13, "DDN_REQ" }, { 0x14, "NDN_REQ" }, @@ -892,7 +898,7 @@ uint64_t *result) { uint32_t perfcfg_offset, perfval_offset; - uint64_t perfmon_cfg, perfevt, perfctl; + uint64_t perfmon_cfg, perfevt; if (cnt_num >= pmc->block[blk_num].counters) return -EINVAL; @@ -906,25 +912,6 @@ /* Set counter in "read" mode */ perfmon_cfg = FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_ADDR, - MLXBF_PMC_PERFCTL); - perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_STROBE, 1); - perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_WR_R_B, 0); - - if (mlxbf_pmc_write(pmc->block[blk_num].mmio_base + perfcfg_offset, - MLXBF_PMC_WRITE_REG_64, perfmon_cfg)) - return -EFAULT; - - /* Check if the counter is enabled */ - - if (mlxbf_pmc_read(pmc->block[blk_num].mmio_base + perfval_offset, - MLXBF_PMC_READ_REG_64, &perfctl)) - return -EFAULT; - - if (!FIELD_GET(MLXBF_PMC_PERFCTL_EN0, perfctl)) - return -EINVAL; - - /* Set counter in "read" mode */ - perfmon_cfg = FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_ADDR, MLXBF_PMC_PERFEVT); perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_STROBE, 1); perfmon_cfg |= FIELD_PREP(MLXBF_PMC_PERFMON_CONFIG_WR_R_B, 0); @@ -1008,7 +995,7 @@ } else return -EINVAL; - return sprintf(buf, "0x%llx\n", value); + return sysfs_emit(buf, "0x%llx\n", value); } /* Store function for "counter" sysfs files */ @@ -1078,13 +1065,13 @@ err = mlxbf_pmc_read_event(blk_num, cnt_num, is_l3, &evt_num); if (err) - return sprintf(buf, "No event being monitored\n"); + return sysfs_emit(buf, "No event being monitored\n"); evt_name = mlxbf_pmc_get_event_name(pmc->block_name[blk_num], evt_num); if (!evt_name) return -EINVAL; - return sprintf(buf, "0x%llx: %s\n", evt_num, evt_name); + return sysfs_emit(buf, "0x%llx: %s\n", evt_num, evt_name); } /* Store function for "event" sysfs files */ @@ -1139,9 +1126,9 @@ return -EINVAL; for (i = 0, buf[0] = '\0'; i < size; ++i) { - len += sprintf(e_info, "0x%x: %s\n", events[i].evt_num, - events[i].evt_name); - if (len > PAGE_SIZE) + len += snprintf(e_info, sizeof(e_info), "0x%x: %s\n", + events[i].evt_num, events[i].evt_name); + if (len >= PAGE_SIZE) break; strcat(buf, e_info); ret = len; @@ -1168,7 +1155,7 @@ value = FIELD_GET(MLXBF_PMC_L3C_PERF_CNT_CFG_EN, perfcnt_cfg); - return sprintf(buf, "%d\n", value); + return sysfs_emit(buf, "%d\n", value); } /* Store function for "enable" sysfs files - only for l3cache */ diff -u linux-6.2.0/drivers/platform/mellanox/mlxbf-tmfifo.c linux-6.2.0/drivers/platform/mellanox/mlxbf-tmfifo.c --- linux-6.2.0/drivers/platform/mellanox/mlxbf-tmfifo.c +++ linux-6.2.0/drivers/platform/mellanox/mlxbf-tmfifo.c @@ -59,6 +59,7 @@ * @vq: pointer to the virtio virtqueue * @desc: current descriptor of the pending packet * @desc_head: head descriptor of the pending packet + * @drop_desc: dummy desc for packet dropping * @cur_len: processed length of the current descriptor * @rem_len: remaining length of the pending packet * @pkt_len: total length of the pending packet @@ -75,6 +76,7 @@ struct virtqueue *vq; struct vring_desc *desc; struct vring_desc *desc_head; + struct vring_desc drop_desc; int cur_len; int rem_len; u32 pkt_len; @@ -86,6 +88,14 @@ struct mlxbf_tmfifo *fifo; }; +/* Check whether vring is in drop mode. */ +#define IS_VRING_DROP(_r) ({ \ + typeof(_r) (r) = (_r); \ + (r->desc_head == &r->drop_desc ? true : false); }) + +/* A stub length to drop maximum length packet. */ +#define VRING_DROP_DESC_MAX_LEN GENMASK(15, 0) + /* Interrupt types. */ enum { MLXBF_TM_RX_LWM_IRQ, @@ -214,7 +224,7 @@ static efi_char16_t mlxbf_tmfifo_efi_name[] = L"RshimMacAddr"; /* Maximum L2 header length. */ -#define MLXBF_TMFIFO_NET_L2_OVERHEAD 36 +#define MLXBF_TMFIFO_NET_L2_OVERHEAD (ETH_HLEN + VLAN_HLEN) /* Supported virtio-net features. */ #define MLXBF_TMFIFO_NET_FEATURES \ @@ -262,6 +272,7 @@ vring->align = SMP_CACHE_BYTES; vring->index = i; vring->vdev_id = tm_vdev->vdev.id.device; + vring->drop_desc.len = VRING_DROP_DESC_MAX_LEN; dev = &tm_vdev->vdev.dev; size = vring_size(vring->num, vring->align); @@ -367,7 +378,7 @@ return len; } -static void mlxbf_tmfifo_release_pending_pkt(struct mlxbf_tmfifo_vring *vring) +static void mlxbf_tmfifo_release_pkt(struct mlxbf_tmfifo_vring *vring) { struct vring_desc *desc_head; u32 len = 0; @@ -596,19 +607,25 @@ if (vring->cur_len + sizeof(u64) <= len) { /* The whole word. */ - if (is_rx) - memcpy(addr + vring->cur_len, &data, sizeof(u64)); - else - memcpy(&data, addr + vring->cur_len, sizeof(u64)); + if (!IS_VRING_DROP(vring)) { + if (is_rx) + memcpy(addr + vring->cur_len, &data, + sizeof(u64)); + else + memcpy(&data, addr + vring->cur_len, + sizeof(u64)); + } vring->cur_len += sizeof(u64); } else { /* Leftover bytes. */ - if (is_rx) - memcpy(addr + vring->cur_len, &data, - len - vring->cur_len); - else - memcpy(&data, addr + vring->cur_len, - len - vring->cur_len); + if (!IS_VRING_DROP(vring)) { + if (is_rx) + memcpy(addr + vring->cur_len, &data, + len - vring->cur_len); + else + memcpy(&data, addr + vring->cur_len, + len - vring->cur_len); + } vring->cur_len = len; } @@ -625,13 +642,14 @@ * flag is set. */ static void mlxbf_tmfifo_rxtx_header(struct mlxbf_tmfifo_vring *vring, - struct vring_desc *desc, + struct vring_desc **desc, bool is_rx, bool *vring_change) { struct mlxbf_tmfifo *fifo = vring->fifo; struct virtio_net_config *config; struct mlxbf_tmfifo_msg_hdr hdr; int vdev_id, hdr_len; + bool drop_rx = false; /* Read/Write packet header. */ if (is_rx) { @@ -651,8 +669,8 @@ if (ntohs(hdr.len) > __virtio16_to_cpu(virtio_legacy_is_little_endian(), config->mtu) + - MLXBF_TMFIFO_NET_L2_OVERHEAD) - return; + MLXBF_TMFIFO_NET_L2_OVERHEAD) + drop_rx = true; } else { vdev_id = VIRTIO_ID_CONSOLE; hdr_len = 0; @@ -667,16 +685,25 @@ if (!tm_dev2) return; - vring->desc = desc; + vring->desc = *desc; vring = &tm_dev2->vrings[MLXBF_TMFIFO_VRING_RX]; *vring_change = true; } + + if (drop_rx && !IS_VRING_DROP(vring)) { + if (vring->desc_head) + mlxbf_tmfifo_release_pkt(vring); + *desc = &vring->drop_desc; + vring->desc_head = *desc; + vring->desc = *desc; + } + vring->pkt_len = ntohs(hdr.len) + hdr_len; } else { /* Network virtio has an extra header. */ hdr_len = (vring->vdev_id == VIRTIO_ID_NET) ? sizeof(struct virtio_net_hdr) : 0; - vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, desc); + vring->pkt_len = mlxbf_tmfifo_get_pkt_len(vring, *desc); hdr.type = (vring->vdev_id == VIRTIO_ID_NET) ? VIRTIO_ID_NET : VIRTIO_ID_CONSOLE; hdr.len = htons(vring->pkt_len - hdr_len); @@ -709,15 +736,23 @@ /* Get the descriptor of the next packet. */ if (!vring->desc) { desc = mlxbf_tmfifo_get_next_pkt(vring, is_rx); - if (!desc) - return false; + if (!desc) { + /* Drop next Rx packet to avoid stuck. */ + if (is_rx) { + desc = &vring->drop_desc; + vring->desc_head = desc; + vring->desc = desc; + } else { + return false; + } + } } else { desc = vring->desc; } /* Beginning of a packet. Start to Rx/Tx packet header. */ if (vring->pkt_len == 0) { - mlxbf_tmfifo_rxtx_header(vring, desc, is_rx, &vring_change); + mlxbf_tmfifo_rxtx_header(vring, &desc, is_rx, &vring_change); (*avail)--; /* Return if new packet is for another ring. */ @@ -743,17 +778,24 @@ vring->rem_len -= len; /* Get the next desc on the chain. */ - if (vring->rem_len > 0 && + if (!IS_VRING_DROP(vring) && vring->rem_len > 0 && (virtio16_to_cpu(vdev, desc->flags) & VRING_DESC_F_NEXT)) { idx = virtio16_to_cpu(vdev, desc->next); desc = &vr->desc[idx]; goto mlxbf_tmfifo_desc_done; } - /* Done and release the pending packet. */ - mlxbf_tmfifo_release_pending_pkt(vring); + /* Done and release the packet. */ desc = NULL; fifo->vring[is_rx] = NULL; + if (!IS_VRING_DROP(vring)) { + mlxbf_tmfifo_release_pkt(vring); + } else { + vring->pkt_len = 0; + vring->desc_head = NULL; + vring->desc = NULL; + return false; + } /* * Make sure the load/store are in order before @@ -887,6 +929,7 @@ tm_vdev = fifo->vdev[VIRTIO_ID_CONSOLE]; mlxbf_tmfifo_console_output(tm_vdev, vring); spin_unlock_irqrestore(&fifo->spin_lock[0], flags); + set_bit(MLXBF_TM_TX_LWM_IRQ, &fifo->pend_events); } else if (test_and_set_bit(MLXBF_TM_TX_LWM_IRQ, &fifo->pend_events)) { return true; @@ -932,7 +975,7 @@ /* Release the pending packet. */ if (vring->desc) - mlxbf_tmfifo_release_pending_pkt(vring); + mlxbf_tmfifo_release_pkt(vring); vq = vring->vq; if (vq) { vring->vq = NULL; diff -u linux-6.2.0/drivers/platform/x86/amd/pmf/core.c linux-6.2.0/drivers/platform/x86/amd/pmf/core.c --- linux-6.2.0/drivers/platform/x86/amd/pmf/core.c +++ linux-6.2.0/drivers/platform/x86/amd/pmf/core.c @@ -322,7 +322,8 @@ static void amd_pmf_deinit_features(struct amd_pmf_dev *dev) { - if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { + if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR) || + is_apmf_func_supported(dev, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) { power_supply_unreg_notifier(&dev->pwr_src_notifier); amd_pmf_deinit_sps(dev); } diff -u linux-6.2.0/drivers/platform/x86/amd/pmf/sps.c linux-6.2.0/drivers/platform/x86/amd/pmf/sps.c --- linux-6.2.0/drivers/platform/x86/amd/pmf/sps.c +++ linux-6.2.0/drivers/platform/x86/amd/pmf/sps.c @@ -121,7 +121,8 @@ int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev) { - u8 mode, flag = 0; + u8 flag = 0; + int mode; int src; mode = amd_pmf_get_pprof_modes(dev); diff -u linux-6.2.0/drivers/platform/x86/asus-nb-wmi.c linux-6.2.0/drivers/platform/x86/asus-nb-wmi.c --- linux-6.2.0/drivers/platform/x86/asus-nb-wmi.c +++ linux-6.2.0/drivers/platform/x86/asus-nb-wmi.c @@ -480,6 +480,15 @@ }, { .callback = dmi_matched, + .ident = "ASUS ROG FLOW X16", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "GV601V"), + }, + .driver_data = &quirk_asus_tablet_mode, + }, + { + .callback = dmi_matched, .ident = "ASUS VivoBook E410MA", .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), diff -u linux-6.2.0/drivers/platform/x86/asus-wmi.c linux-6.2.0/drivers/platform/x86/asus-wmi.c --- linux-6.2.0/drivers/platform/x86/asus-wmi.c +++ linux-6.2.0/drivers/platform/x86/asus-wmi.c @@ -738,13 +738,23 @@ struct device_attribute *attr, const char *buf, size_t count) { - u32 cmd, mode, r, g, b, speed; + u32 cmd, mode, r, g, b, speed; int err; if (sscanf(buf, "%d %d %d %d %d %d", &cmd, &mode, &r, &g, &b, &speed) != 6) return -EINVAL; - cmd = !!cmd; + /* B3 is set and B4 is save to BIOS */ + switch (cmd) { + case 0: + cmd = 0xb3; + break; + case 1: + cmd = 0xb4; + break; + default: + return -EINVAL; + } /* These are the known usable modes across all TUF/ROG */ if (mode >= 12 || mode == 9) diff -u linux-6.2.0/drivers/platform/x86/intel/hid.c linux-6.2.0/drivers/platform/x86/intel/hid.c --- linux-6.2.0/drivers/platform/x86/intel/hid.c +++ linux-6.2.0/drivers/platform/x86/intel/hid.c @@ -157,6 +157,12 @@ DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite Dragonfly G2 Notebook PC"), + }, + }, { } }; @@ -627,7 +633,7 @@ static int intel_hid_probe(struct platform_device *device) { acpi_handle handle = ACPI_HANDLE(&device->dev); - unsigned long long mode; + unsigned long long mode, dummy; struct intel_hid_priv *priv; acpi_status status; int err; @@ -699,18 +705,15 @@ if (err) goto err_remove_notify; - if (priv->array) { - unsigned long long dummy; + intel_button_array_enable(&device->dev, true); - intel_button_array_enable(&device->dev, true); - - /* Call button load method to enable HID power button */ - if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, - &dummy)) { - dev_warn(&device->dev, - "failed to enable HID power button\n"); - } - } + /* + * Call button load method to enable HID power button + * Always do this since it activates events on some devices without + * a button array too. + */ + if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, &dummy)) + dev_warn(&device->dev, "failed to enable HID power button\n"); device_init_wakeup(&device->dev, true); /* diff -u linux-6.2.0/drivers/platform/x86/think-lmi.c linux-6.2.0/drivers/platform/x86/think-lmi.c --- linux-6.2.0/drivers/platform/x86/think-lmi.c +++ linux-6.2.0/drivers/platform/x86/think-lmi.c @@ -719,12 +719,12 @@ /* Format: 'Password,Signature' */ auth_str = kasprintf(GFP_KERNEL, "%s,%s", passwd, setting->signature); if (!auth_str) { - kfree(passwd); + kfree_sensitive(passwd); return -ENOMEM; } ret = tlmi_simple_call(LENOVO_CERT_TO_PASSWORD_GUID, auth_str); kfree(auth_str); - kfree(passwd); + kfree_sensitive(passwd); return ret ?: count; } diff -u linux-6.2.0/drivers/power/supply/ab8500_btemp.c linux-6.2.0/drivers/power/supply/ab8500_btemp.c --- linux-6.2.0/drivers/power/supply/ab8500_btemp.c +++ linux-6.2.0/drivers/power/supply/ab8500_btemp.c @@ -115,7 +115,6 @@ static enum power_supply_property ab8500_btemp_props[] = { POWER_SUPPLY_PROP_PRESENT, POWER_SUPPLY_PROP_ONLINE, - POWER_SUPPLY_PROP_TECHNOLOGY, POWER_SUPPLY_PROP_TEMP, }; @@ -532,12 +531,6 @@ else val->intval = 1; break; - case POWER_SUPPLY_PROP_TECHNOLOGY: - if (di->bm->bi) - val->intval = di->bm->bi->technology; - else - val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; - break; case POWER_SUPPLY_PROP_TEMP: val->intval = ab8500_btemp_get_temp(di); break; @@ -662,7 +655,7 @@ static const struct power_supply_desc ab8500_btemp_desc = { .name = "ab8500_btemp", - .type = POWER_SUPPLY_TYPE_BATTERY, + .type = POWER_SUPPLY_TYPE_UNKNOWN, .properties = ab8500_btemp_props, .num_properties = ARRAY_SIZE(ab8500_btemp_props), .get_property = ab8500_btemp_get_property, diff -u linux-6.2.0/drivers/power/supply/rk817_charger.c linux-6.2.0/drivers/power/supply/rk817_charger.c --- linux-6.2.0/drivers/power/supply/rk817_charger.c +++ linux-6.2.0/drivers/power/supply/rk817_charger.c @@ -1058,6 +1058,13 @@ queue_delayed_work(system_wq, &charger->work, msecs_to_jiffies(8000)); } +static void rk817_cleanup_node(void *data) +{ + struct device_node *node = data; + + of_node_put(node); +} + static int rk817_charger_probe(struct platform_device *pdev) { struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent); @@ -1074,11 +1081,13 @@ if (!node) return -ENODEV; + ret = devm_add_action_or_reset(&pdev->dev, rk817_cleanup_node, node); + if (ret) + return ret; + charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); - if (!charger) { - of_node_put(node); + if (!charger) return -ENOMEM; - } charger->rk808 = rk808; @@ -1226,0 +1236 @@ +MODULE_ALIAS("platform:rk817-charger"); diff -u linux-6.2.0/drivers/regulator/core.c linux-6.2.0/drivers/regulator/core.c --- linux-6.2.0/drivers/regulator/core.c +++ linux-6.2.0/drivers/regulator/core.c @@ -5549,6 +5549,8 @@ goto rinse; } device_initialize(&rdev->dev); + dev_set_drvdata(&rdev->dev, rdev); + rdev->dev.class = ®ulator_class; spin_lock_init(&rdev->err_lock); /* @@ -5610,11 +5612,9 @@ rdev->supply_name = regulator_desc->supply_name; /* register with sysfs */ - rdev->dev.class = ®ulator_class; rdev->dev.parent = config->dev; dev_set_name(&rdev->dev, "regulator.%lu", (unsigned long) atomic_inc_return(®ulator_no)); - dev_set_drvdata(&rdev->dev, rdev); /* set regulator constraints */ if (init_data) diff -u linux-6.2.0/drivers/rpmsg/qcom_glink_native.c linux-6.2.0/drivers/rpmsg/qcom_glink_native.c --- linux-6.2.0/drivers/rpmsg/qcom_glink_native.c +++ linux-6.2.0/drivers/rpmsg/qcom_glink_native.c @@ -224,6 +224,10 @@ channel->glink = glink; channel->name = kstrdup(name, GFP_KERNEL); + if (!channel->name) { + kfree(channel); + return ERR_PTR(-ENOMEM); + } init_completion(&channel->open_req); init_completion(&channel->open_ack); diff -u linux-6.2.0/drivers/s390/block/dasd.c linux-6.2.0/drivers/s390/block/dasd.c --- linux-6.2.0/drivers/s390/block/dasd.c +++ linux-6.2.0/drivers/s390/block/dasd.c @@ -2926,41 +2926,32 @@ * Requeue a request back to the block request queue * only works for block requests */ -static int _dasd_requeue_request(struct dasd_ccw_req *cqr) +static void _dasd_requeue_request(struct dasd_ccw_req *cqr) { - struct dasd_block *block = cqr->block; struct request *req; - if (!block) - return -EINVAL; /* * If the request is an ERP request there is nothing to requeue. * This will be done with the remaining original request. */ if (cqr->refers) - return 0; + return; spin_lock_irq(&cqr->dq->lock); req = (struct request *) cqr->callback_data; blk_mq_requeue_request(req, true); spin_unlock_irq(&cqr->dq->lock); - return 0; + return; } -/* - * Go through all request on the dasd_block request queue, cancel them - * on the respective dasd_device, and return them to the generic - * block layer. - */ -static int dasd_flush_block_queue(struct dasd_block *block) +static int _dasd_requests_to_flushqueue(struct dasd_block *block, + struct list_head *flush_queue) { struct dasd_ccw_req *cqr, *n; - int rc, i; - struct list_head flush_queue; unsigned long flags; + int rc, i; - INIT_LIST_HEAD(&flush_queue); - spin_lock_bh(&block->queue_lock); + spin_lock_irqsave(&block->queue_lock, flags); rc = 0; restart: list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) { @@ -2975,13 +2966,32 @@ * is returned from the dasd_device layer. */ cqr->callback = _dasd_wake_block_flush_cb; - for (i = 0; cqr != NULL; cqr = cqr->refers, i++) - list_move_tail(&cqr->blocklist, &flush_queue); + for (i = 0; cqr; cqr = cqr->refers, i++) + list_move_tail(&cqr->blocklist, flush_queue); if (i > 1) /* moved more than one request - need to restart */ goto restart; } - spin_unlock_bh(&block->queue_lock); + spin_unlock_irqrestore(&block->queue_lock, flags); + + return rc; +} + +/* + * Go through all request on the dasd_block request queue, cancel them + * on the respective dasd_device, and return them to the generic + * block layer. + */ +static int dasd_flush_block_queue(struct dasd_block *block) +{ + struct dasd_ccw_req *cqr, *n; + struct list_head flush_queue; + unsigned long flags; + int rc; + + INIT_LIST_HEAD(&flush_queue); + rc = _dasd_requests_to_flushqueue(block, &flush_queue); + /* Now call the callback function of flushed requests */ restart_cb: list_for_each_entry_safe(cqr, n, &flush_queue, blocklist) { @@ -3864,75 +3874,36 @@ */ int dasd_generic_requeue_all_requests(struct dasd_device *device) { + struct dasd_block *block = device->block; struct list_head requeue_queue; struct dasd_ccw_req *cqr, *n; - struct dasd_ccw_req *refers; int rc; - INIT_LIST_HEAD(&requeue_queue); - spin_lock_irq(get_ccwdev_lock(device->cdev)); - rc = 0; - list_for_each_entry_safe(cqr, n, &device->ccw_queue, devlist) { - /* Check status and move request to flush_queue */ - if (cqr->status == DASD_CQR_IN_IO) { - rc = device->discipline->term_IO(cqr); - if (rc) { - /* unable to terminate requeust */ - dev_err(&device->cdev->dev, - "Unable to terminate request %p " - "on suspend\n", cqr); - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - dasd_put_device(device); - return rc; - } - } - list_move_tail(&cqr->devlist, &requeue_queue); - } - spin_unlock_irq(get_ccwdev_lock(device->cdev)); + if (!block) + return 0; - list_for_each_entry_safe(cqr, n, &requeue_queue, devlist) { - wait_event(dasd_flush_wq, - (cqr->status != DASD_CQR_CLEAR_PENDING)); - - /* - * requeue requests to blocklayer will only work - * for block device requests - */ - if (_dasd_requeue_request(cqr)) - continue; + INIT_LIST_HEAD(&requeue_queue); + rc = _dasd_requests_to_flushqueue(block, &requeue_queue); - /* remove requests from device and block queue */ - list_del_init(&cqr->devlist); - while (cqr->refers != NULL) { - refers = cqr->refers; - /* remove the request from the block queue */ - list_del(&cqr->blocklist); - /* free the finished erp request */ - dasd_free_erp_request(cqr, cqr->memdev); - cqr = refers; + /* Now call the callback function of flushed requests */ +restart_cb: + list_for_each_entry_safe(cqr, n, &requeue_queue, blocklist) { + wait_event(dasd_flush_wq, (cqr->status < DASD_CQR_QUEUED)); + /* Process finished ERP request. */ + if (cqr->refers) { + spin_lock_bh(&block->queue_lock); + __dasd_process_erp(block->base, cqr); + spin_unlock_bh(&block->queue_lock); + /* restart list_for_xx loop since dasd_process_erp + * might remove multiple elements + */ + goto restart_cb; } - - /* - * _dasd_requeue_request already checked for a valid - * blockdevice, no need to check again - * all erp requests (cqr->refers) have a cqr->block - * pointer copy from the original cqr - */ + _dasd_requeue_request(cqr); list_del_init(&cqr->blocklist); cqr->block->base->discipline->free_cp( cqr, (struct request *) cqr->callback_data); } - - /* - * if requests remain then they are internal request - * and go back to the device queue - */ - if (!list_empty(&requeue_queue)) { - /* move freeze_queue to start of the ccw_queue */ - spin_lock_irq(get_ccwdev_lock(device->cdev)); - list_splice_tail(&requeue_queue, &device->ccw_queue); - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - } dasd_schedule_device_bh(device); return rc; } diff -u linux-6.2.0/drivers/s390/block/dasd_3990_erp.c linux-6.2.0/drivers/s390/block/dasd_3990_erp.c --- linux-6.2.0/drivers/s390/block/dasd_3990_erp.c +++ linux-6.2.0/drivers/s390/block/dasd_3990_erp.c @@ -2441,7 +2441,7 @@ erp->block = cqr->block; erp->magic = cqr->magic; erp->expires = cqr->expires; - erp->retries = 256; + erp->retries = device->default_retries; erp->buildclk = get_tod_clock(); erp->status = DASD_CQR_FILLED; diff -u linux-6.2.0/drivers/s390/block/dasd_eckd.c linux-6.2.0/drivers/s390/block/dasd_eckd.c --- linux-6.2.0/drivers/s390/block/dasd_eckd.c +++ linux-6.2.0/drivers/s390/block/dasd_eckd.c @@ -1079,12 +1079,12 @@ create_uid(conf, &uid); if (strlen(uid.vduit) > 0) - snprintf(print_uid, sizeof(*print_uid), + snprintf(print_uid, DASD_UID_STRLEN, "%s.%s.%04x.%02x.%s", uid.vendor, uid.serial, uid.ssid, uid.real_unit_addr, uid.vduit); else - snprintf(print_uid, sizeof(*print_uid), + snprintf(print_uid, DASD_UID_STRLEN, "%s.%s.%04x.%02x", uid.vendor, uid.serial, uid.ssid, uid.real_unit_addr); @@ -1093,8 +1093,8 @@ static int dasd_eckd_check_cabling(struct dasd_device *device, void *conf_data, __u8 lpm) { + char print_path_uid[DASD_UID_STRLEN], print_device_uid[DASD_UID_STRLEN]; struct dasd_eckd_private *private = device->private; - char print_path_uid[60], print_device_uid[60]; struct dasd_conf path_conf; path_conf.data = conf_data; @@ -1293,9 +1293,9 @@ __u8 path_rcd_buf[DASD_ECKD_RCD_DATA_SIZE]; __u8 lpm, opm, npm, ppm, epm, hpfpm, cablepm; struct dasd_conf_data *conf_data; + char print_uid[DASD_UID_STRLEN]; struct dasd_conf path_conf; unsigned long flags; - char print_uid[60]; int rc, pos; opm = 0; @@ -5856,8 +5856,8 @@ static int dasd_eckd_reload_device(struct dasd_device *device) { struct dasd_eckd_private *private = device->private; + char print_uid[DASD_UID_STRLEN]; int rc, old_base; - char print_uid[60]; struct dasd_uid uid; unsigned long flags; diff -u linux-6.2.0/drivers/s390/crypto/pkey_api.c linux-6.2.0/drivers/s390/crypto/pkey_api.c --- linux-6.2.0/drivers/s390/crypto/pkey_api.c +++ linux-6.2.0/drivers/s390/crypto/pkey_api.c @@ -212,7 +212,8 @@ card = apqns[i] >> 16; dom = apqns[i] & 0xFFFF; rc = ep11_clr2keyblob(card, dom, clrkeylen * 8, - 0, clrkey, keybuf, keybuflen); + 0, clrkey, keybuf, keybuflen, + PKEY_TYPE_EP11); if (rc == 0) break; } @@ -565,6 +566,11 @@ if (*keybufsize < MINEP11AESKEYBLOBSIZE) return -EINVAL; break; + case PKEY_TYPE_EP11_AES: + if (*keybufsize < (sizeof(struct ep11kblob_header) + + MINEP11AESKEYBLOBSIZE)) + return -EINVAL; + break; default: return -EINVAL; } @@ -581,9 +587,10 @@ for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { card = apqns[i].card; dom = apqns[i].domain; - if (ktype == PKEY_TYPE_EP11) { + if (ktype == PKEY_TYPE_EP11 || + ktype == PKEY_TYPE_EP11_AES) { rc = ep11_genaeskey(card, dom, ksize, kflags, - keybuf, keybufsize); + keybuf, keybufsize, ktype); } else if (ktype == PKEY_TYPE_CCA_DATA) { rc = cca_genseckey(card, dom, ksize, keybuf); *keybufsize = (rc ? 0 : SECKEYBLOBSIZE); @@ -621,6 +628,11 @@ if (*keybufsize < MINEP11AESKEYBLOBSIZE) return -EINVAL; break; + case PKEY_TYPE_EP11_AES: + if (*keybufsize < (sizeof(struct ep11kblob_header) + + MINEP11AESKEYBLOBSIZE)) + return -EINVAL; + break; default: return -EINVAL; } @@ -639,9 +651,11 @@ for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { card = apqns[i].card; dom = apqns[i].domain; - if (ktype == PKEY_TYPE_EP11) { + if (ktype == PKEY_TYPE_EP11 || + ktype == PKEY_TYPE_EP11_AES) { rc = ep11_clr2keyblob(card, dom, ksize, kflags, - clrkey, keybuf, keybufsize); + clrkey, keybuf, keybufsize, + ktype); } else if (ktype == PKEY_TYPE_CCA_DATA) { rc = cca_clr2seckey(card, dom, ksize, clrkey, keybuf); @@ -747,7 +761,7 @@ if (ktype) *ktype = PKEY_TYPE_EP11; if (ksize) - *ksize = kb->head.keybitlen; + *ksize = kb->head.bitlen; rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain, ZCRYPT_CEX7, EP11_API_V, kb->wkvp); @@ -1313,7 +1327,7 @@ apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries); if (IS_ERR(apqns)) return PTR_ERR(apqns); - kkey = kmalloc(klen, GFP_KERNEL); + kkey = kzalloc(klen, GFP_KERNEL); if (!kkey) { kfree(apqns); return -ENOMEM; @@ -1355,7 +1369,7 @@ apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries); if (IS_ERR(apqns)) return PTR_ERR(apqns); - kkey = kmalloc(klen, GFP_KERNEL); + kkey = kzalloc(klen, GFP_KERNEL); if (!kkey) { kfree(apqns); return -ENOMEM; @@ -1941,7 +1955,7 @@ * (i.e. off != 0 or count < key blob size) -EINVAL is returned. * This function and the sysfs attributes using it provide EP11 key blobs * padded to the upper limit of MAXEP11AESKEYBLOBSIZE which is currently - * 320 bytes. + * 336 bytes. */ static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits, bool is_xts, char *buf, loff_t off, @@ -1969,7 +1983,8 @@ for (i = 0, rc = -ENODEV; i < nr_apqns; i++) { card = apqns[i] >> 16; dom = apqns[i] & 0xFFFF; - rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize); + rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize, + PKEY_TYPE_EP11_AES); if (rc == 0) break; } @@ -1979,7 +1994,8 @@ if (is_xts) { keysize = MAXEP11AESKEYBLOBSIZE; buf += MAXEP11AESKEYBLOBSIZE; - rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize); + rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize, + PKEY_TYPE_EP11_AES); if (rc == 0) return 2 * MAXEP11AESKEYBLOBSIZE; } diff -u linux-6.2.0/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c linux-6.2.0/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c --- linux-6.2.0/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ linux-6.2.0/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2026,6 +2026,11 @@ u16 dma_tx_err_type = le16_to_cpu(err_record->dma_tx_err_type); u16 sipc_rx_err_type = le16_to_cpu(err_record->sipc_rx_err_type); u32 dma_rx_err_type = le32_to_cpu(err_record->dma_rx_err_type); + struct hisi_sas_complete_v2_hdr *complete_queue = + hisi_hba->complete_hdr[slot->cmplt_queue]; + struct hisi_sas_complete_v2_hdr *complete_hdr = + &complete_queue[slot->cmplt_queue_slot]; + u32 dw0 = le32_to_cpu(complete_hdr->dw0); int error = -1; if (err_phase == 1) { @@ -2310,7 +2315,8 @@ break; } } - hisi_sas_sata_done(task, slot); + if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) + hisi_sas_sata_done(task, slot); } break; default: @@ -2443,7 +2449,8 @@ case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: { ts->stat = SAS_SAM_STAT_GOOD; - hisi_sas_sata_done(task, slot); + if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) + hisi_sas_sata_done(task, slot); break; } default: diff -u linux-6.2.0/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c linux-6.2.0/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c --- linux-6.2.0/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ linux-6.2.0/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2189,6 +2189,7 @@ u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type); u16 sipc_rx_err_type = le16_to_cpu(record->sipc_rx_err_type); u32 dw3 = le32_to_cpu(complete_hdr->dw3); + u32 dw0 = le32_to_cpu(complete_hdr->dw0); switch (task->task_proto) { case SAS_PROTOCOL_SSP: @@ -2198,8 +2199,8 @@ * but I/O information has been written to the host memory, we examine * response IU. */ - if (!(complete_hdr->dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) && - (complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)) + if (!(dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) && + (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)) return false; ts->residual = trans_tx_fail_type; @@ -2215,7 +2216,7 @@ case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_STP: case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: - if ((complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) && + if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) && (sipc_rx_err_type & RX_FIS_STATUS_ERR_MSK)) { ts->stat = SAS_PROTO_RESPONSE; } else if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { @@ -2229,7 +2230,8 @@ ts->stat = SAS_OPEN_REJECT; ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; } - hisi_sas_sata_done(task, slot); + if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) + hisi_sas_sata_done(task, slot); break; case SAS_PROTOCOL_SMP: ts->stat = SAS_SAM_STAT_CHECK_CONDITION; @@ -2356,7 +2358,8 @@ case SAS_PROTOCOL_STP: case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: ts->stat = SAS_SAM_STAT_GOOD; - hisi_sas_sata_done(task, slot); + if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) + hisi_sas_sata_done(task, slot); break; default: ts->stat = SAS_SAM_STAT_CHECK_CONDITION; diff -u linux-6.2.0/drivers/scsi/hosts.c linux-6.2.0/drivers/scsi/hosts.c --- linux-6.2.0/drivers/scsi/hosts.c +++ linux-6.2.0/drivers/scsi/hosts.c @@ -536,7 +536,7 @@ static int __scsi_host_match(struct device *dev, const void *data) { struct Scsi_Host *p; - const unsigned short *hostnum = data; + const unsigned int *hostnum = data; p = class_to_shost(dev); return p->host_no == *hostnum; @@ -553,7 +553,7 @@ * that scsi_host_get() took. The put_device() below dropped * the reference from class_find_device(). **/ -struct Scsi_Host *scsi_host_lookup(unsigned short hostnum) +struct Scsi_Host *scsi_host_lookup(unsigned int hostnum) { struct device *cdev; struct Scsi_Host *shost = NULL; diff -u linux-6.2.0/drivers/scsi/iscsi_tcp.c linux-6.2.0/drivers/scsi/iscsi_tcp.c --- linux-6.2.0/drivers/scsi/iscsi_tcp.c +++ linux-6.2.0/drivers/scsi/iscsi_tcp.c @@ -724,6 +724,10 @@ return -EEXIST; } + err = -EINVAL; + if (!sk_is_tcp(sock->sk)) + goto free_socket; + err = iscsi_conn_bind(cls_session, cls_conn, is_leading); if (err) goto free_socket; diff -u linux-6.2.0/drivers/scsi/lpfc/lpfc_debugfs.c linux-6.2.0/drivers/scsi/lpfc/lpfc_debugfs.c --- linux-6.2.0/drivers/scsi/lpfc/lpfc_debugfs.c +++ linux-6.2.0/drivers/scsi/lpfc/lpfc_debugfs.c @@ -6069,7 +6069,7 @@ phba->hba_debugfs_root, phba, &lpfc_debugfs_op_multixripools); - if (!phba->debug_multixri_pools) { + if (IS_ERR(phba->debug_multixri_pools)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0527 Cannot create debugfs multixripools\n"); goto debug_failed; @@ -6081,7 +6081,7 @@ debugfs_create_file(name, S_IFREG | 0644, phba->hba_debugfs_root, phba, &lpfc_cgn_buffer_op); - if (!phba->debug_cgn_buffer) { + if (IS_ERR(phba->debug_cgn_buffer)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "6527 Cannot create debugfs " "cgn_buffer\n"); @@ -6094,7 +6094,7 @@ debugfs_create_file(name, S_IFREG | 0644, phba->hba_debugfs_root, phba, &lpfc_rx_monitor_op); - if (!phba->debug_rx_monitor) { + if (IS_ERR(phba->debug_rx_monitor)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "6528 Cannot create debugfs " "rx_monitor\n"); @@ -6107,7 +6107,7 @@ debugfs_create_file(name, 0644, phba->hba_debugfs_root, phba, &lpfc_debugfs_ras_log); - if (!phba->debug_ras_log) { + if (IS_ERR(phba->debug_ras_log)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "6148 Cannot create debugfs" " ras_log\n"); @@ -6128,7 +6128,7 @@ debugfs_create_file(name, S_IFREG | 0644, phba->hba_debugfs_root, phba, &lpfc_debugfs_op_lockstat); - if (!phba->debug_lockstat) { + if (IS_ERR(phba->debug_lockstat)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "4610 Can't create debugfs lockstat\n"); goto debug_failed; @@ -6354,7 +6354,7 @@ debugfs_create_file(name, 0644, vport->vport_debugfs_root, vport, &lpfc_debugfs_op_scsistat); - if (!vport->debug_scsistat) { + if (IS_ERR(vport->debug_scsistat)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "4611 Cannot create debugfs scsistat\n"); goto debug_failed; @@ -6365,7 +6365,7 @@ debugfs_create_file(name, 0644, vport->vport_debugfs_root, vport, &lpfc_debugfs_op_ioktime); - if (!vport->debug_ioktime) { + if (IS_ERR(vport->debug_ioktime)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0815 Cannot create debugfs ioktime\n"); goto debug_failed; diff -u linux-6.2.0/drivers/scsi/lpfc/lpfc_els.c linux-6.2.0/drivers/scsi/lpfc/lpfc_els.c --- linux-6.2.0/drivers/scsi/lpfc/lpfc_els.c +++ linux-6.2.0/drivers/scsi/lpfc/lpfc_els.c @@ -9559,11 +9559,13 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport) { LIST_HEAD(abort_list); + LIST_HEAD(cancel_list); struct lpfc_hba *phba = vport->phba; struct lpfc_sli_ring *pring; struct lpfc_iocbq *tmp_iocb, *piocb; u32 ulp_command; unsigned long iflags = 0; + bool mbx_tmo_err; lpfc_fabric_abort_vport(vport); @@ -9585,15 +9587,16 @@ if (phba->sli_rev == LPFC_SLI_REV4) spin_lock(&pring->ring_lock); + mbx_tmo_err = test_bit(MBX_TMO_ERR, &phba->bit_flags); /* First we need to issue aborts to outstanding cmds on txcmpl */ list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) { - if (piocb->cmd_flag & LPFC_IO_LIBDFC) + if (piocb->cmd_flag & LPFC_IO_LIBDFC && !mbx_tmo_err) continue; if (piocb->vport != vport) continue; - if (piocb->cmd_flag & LPFC_DRIVER_ABORTED) + if (piocb->cmd_flag & LPFC_DRIVER_ABORTED && !mbx_tmo_err) continue; /* On the ELS ring we can have ELS_REQUESTs or @@ -9612,8 +9615,8 @@ */ if (phba->link_state == LPFC_LINK_DOWN) piocb->cmd_cmpl = lpfc_cmpl_els_link_down; - } - if (ulp_command == CMD_GEN_REQUEST64_CR) + } else if (ulp_command == CMD_GEN_REQUEST64_CR || + mbx_tmo_err) list_add_tail(&piocb->dlist, &abort_list); } @@ -9625,11 +9628,19 @@ list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) { spin_lock_irqsave(&phba->hbalock, iflags); list_del_init(&piocb->dlist); - lpfc_sli_issue_abort_iotag(phba, pring, piocb, NULL); + if (mbx_tmo_err) + list_move_tail(&piocb->list, &cancel_list); + else + lpfc_sli_issue_abort_iotag(phba, pring, piocb, NULL); + spin_unlock_irqrestore(&phba->hbalock, iflags); } - /* Make sure HBA is alive */ - lpfc_issue_hb_tmo(phba); + if (!list_empty(&cancel_list)) + lpfc_sli_cancel_iocbs(phba, &cancel_list, IOSTAT_LOCAL_REJECT, + IOERR_SLI_ABORTED); + else + /* Make sure HBA is alive */ + lpfc_issue_hb_tmo(phba); if (!list_empty(&abort_list)) lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, diff -u linux-6.2.0/drivers/scsi/lpfc/lpfc_init.c linux-6.2.0/drivers/scsi/lpfc/lpfc_init.c --- linux-6.2.0/drivers/scsi/lpfc/lpfc_init.c +++ linux-6.2.0/drivers/scsi/lpfc/lpfc_init.c @@ -7564,6 +7564,8 @@ void lpfc_reset_hba(struct lpfc_hba *phba) { + int rc = 0; + /* If resets are disabled then set error state and return. */ if (!phba->cfg_enable_hba_reset) { phba->link_state = LPFC_HBA_ERROR; @@ -7574,13 +7576,25 @@ if (phba->sli.sli_flag & LPFC_SLI_ACTIVE) { lpfc_offline_prep(phba, LPFC_MBX_WAIT); } else { + if (test_bit(MBX_TMO_ERR, &phba->bit_flags)) { + /* Perform a PCI function reset to start from clean */ + rc = lpfc_pci_function_reset(phba); + lpfc_els_flush_all_cmd(phba); + } lpfc_offline_prep(phba, LPFC_MBX_NO_WAIT); lpfc_sli_flush_io_rings(phba); } lpfc_offline(phba); - lpfc_sli_brdrestart(phba); - lpfc_online(phba); - lpfc_unblock_mgmt_io(phba); + clear_bit(MBX_TMO_ERR, &phba->bit_flags); + if (unlikely(rc)) { + lpfc_printf_log(phba, KERN_ERR, LOG_SLI, + "8888 PCI function reset failed rc %x\n", + rc); + } else { + lpfc_sli_brdrestart(phba); + lpfc_online(phba); + lpfc_unblock_mgmt_io(phba); + } } /** diff -u linux-6.2.0/drivers/scsi/lpfc/lpfc_sli.c linux-6.2.0/drivers/scsi/lpfc/lpfc_sli.c --- linux-6.2.0/drivers/scsi/lpfc/lpfc_sli.c +++ linux-6.2.0/drivers/scsi/lpfc/lpfc_sli.c @@ -3935,6 +3935,8 @@ uint64_t sli_intr, cnt; phba = from_timer(phba, t, eratt_poll); + if (!(phba->hba_flag & HBA_SETUP)) + return; /* Here we will also keep track of interrupts per sec of the hba */ sli_intr = phba->sli.slistat.sli_intr; @@ -7728,7 +7730,9 @@ spin_unlock_irq(&phba->hbalock); } else { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, - "3161 Failure to post sgl to port.\n"); + "3161 Failure to post sgl to port,status %x " + "blkcnt %d totalcnt %d postcnt %d\n", + status, block_cnt, total_cnt, post_cnt); return -EIO; } @@ -8512,6 +8516,7 @@ spin_unlock_irq(&phba->hbalock); } } + phba->hba_flag &= ~HBA_SETUP; lpfc_sli4_dip(phba); @@ -9334,6 +9339,7 @@ * would get IOCB_ERROR from lpfc_sli_issue_iocb, allowing * it to fail all outstanding SCSI IO. */ + set_bit(MBX_TMO_ERR, &phba->bit_flags); spin_lock_irq(&phba->pport->work_port_lock); phba->pport->work_port_events &= ~WORKER_MBOX_TMO; spin_unlock_irq(&phba->pport->work_port_lock); diff -u linux-6.2.0/drivers/scsi/megaraid/megaraid_sas.h linux-6.2.0/drivers/scsi/megaraid/megaraid_sas.h --- linux-6.2.0/drivers/scsi/megaraid/megaraid_sas.h +++ linux-6.2.0/drivers/scsi/megaraid/megaraid_sas.h @@ -2332,7 +2332,7 @@ u32 support_morethan256jbod; /* FW support for more than 256 PD/JBOD */ bool use_seqnum_jbod_fp; /* Added for PD sequence */ bool smp_affinity_enable; - spinlock_t crashdump_lock; + struct mutex crashdump_lock; struct megasas_register_set __iomem *reg_set; u32 __iomem *reply_post_host_index_addr[MR_MAX_MSIX_REG_ARRAY]; diff -u linux-6.2.0/drivers/scsi/megaraid/megaraid_sas_base.c linux-6.2.0/drivers/scsi/megaraid/megaraid_sas_base.c --- linux-6.2.0/drivers/scsi/megaraid/megaraid_sas_base.c +++ linux-6.2.0/drivers/scsi/megaraid/megaraid_sas_base.c @@ -3271,14 +3271,13 @@ struct megasas_instance *instance = (struct megasas_instance *) shost->hostdata; int val = 0; - unsigned long flags; if (kstrtoint(buf, 0, &val) != 0) return -EINVAL; - spin_lock_irqsave(&instance->crashdump_lock, flags); + mutex_lock(&instance->crashdump_lock); instance->fw_crash_buffer_offset = val; - spin_unlock_irqrestore(&instance->crashdump_lock, flags); + mutex_unlock(&instance->crashdump_lock); return strlen(buf); } @@ -3293,24 +3292,23 @@ unsigned long dmachunk = CRASH_DMA_BUF_SIZE; unsigned long chunk_left_bytes; unsigned long src_addr; - unsigned long flags; u32 buff_offset; - spin_lock_irqsave(&instance->crashdump_lock, flags); + mutex_lock(&instance->crashdump_lock); buff_offset = instance->fw_crash_buffer_offset; if (!instance->crash_dump_buf || !((instance->fw_crash_state == AVAILABLE) || (instance->fw_crash_state == COPYING))) { dev_err(&instance->pdev->dev, "Firmware crash dump is not available\n"); - spin_unlock_irqrestore(&instance->crashdump_lock, flags); + mutex_unlock(&instance->crashdump_lock); return -EINVAL; } if (buff_offset > (instance->fw_crash_buffer_size * dmachunk)) { dev_err(&instance->pdev->dev, "Firmware crash dump offset is out of range\n"); - spin_unlock_irqrestore(&instance->crashdump_lock, flags); + mutex_unlock(&instance->crashdump_lock); return 0; } @@ -3322,7 +3320,7 @@ src_addr = (unsigned long)instance->crash_buf[buff_offset / dmachunk] + (buff_offset % dmachunk); memcpy(buf, (void *)src_addr, size); - spin_unlock_irqrestore(&instance->crashdump_lock, flags); + mutex_unlock(&instance->crashdump_lock); return size; } @@ -3347,7 +3345,6 @@ struct megasas_instance *instance = (struct megasas_instance *) shost->hostdata; int val = 0; - unsigned long flags; if (kstrtoint(buf, 0, &val) != 0) return -EINVAL; @@ -3361,9 +3358,9 @@ instance->fw_crash_state = val; if ((val == COPIED) || (val == COPY_ERROR)) { - spin_lock_irqsave(&instance->crashdump_lock, flags); + mutex_lock(&instance->crashdump_lock); megasas_free_host_crash_buffer(instance); - spin_unlock_irqrestore(&instance->crashdump_lock, flags); + mutex_unlock(&instance->crashdump_lock); if (val == COPY_ERROR) dev_info(&instance->pdev->dev, "application failed to " "copy Firmware crash dump\n"); @@ -7422,7 +7419,7 @@ init_waitqueue_head(&instance->int_cmd_wait_q); init_waitqueue_head(&instance->abort_cmd_wait_q); - spin_lock_init(&instance->crashdump_lock); + mutex_init(&instance->crashdump_lock); spin_lock_init(&instance->mfi_pool_lock); spin_lock_init(&instance->hba_lock); spin_lock_init(&instance->stream_lock); diff -u linux-6.2.0/drivers/scsi/mpt3sas/mpt3sas_base.c linux-6.2.0/drivers/scsi/mpt3sas/mpt3sas_base.c --- linux-6.2.0/drivers/scsi/mpt3sas/mpt3sas_base.c +++ linux-6.2.0/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -139,6 +139,9 @@ static void _base_clear_outstanding_commands(struct MPT3SAS_ADAPTER *ioc); +static u32 +_base_readl_ext_retry(const volatile void __iomem *addr); + /** * mpt3sas_base_check_cmd_timeout - Function * to check timeout and command termination due @@ -214,6 +217,20 @@ return ret_val; } +static u32 +_base_readl_ext_retry(const volatile void __iomem *addr) +{ + u32 i, ret_val; + + for (i = 0 ; i < 30 ; i++) { + ret_val = readl(addr); + if (ret_val == 0) + continue; + } + + return ret_val; +} + static inline u32 _base_readl(const volatile void __iomem *addr) { @@ -941,7 +958,7 @@ dump_stack(); - doorbell = ioc->base_readl(&ioc->chip->Doorbell); + doorbell = ioc->base_readl_ext_retry(&ioc->chip->Doorbell); if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { mpt3sas_print_fault_code(ioc, doorbell & MPI2_DOORBELL_DATA_MASK); @@ -6697,7 +6714,7 @@ { u32 s, sc; - s = ioc->base_readl(&ioc->chip->Doorbell); + s = ioc->base_readl_ext_retry(&ioc->chip->Doorbell); sc = s & MPI2_IOC_STATE_MASK; return cooked ? sc : s; } @@ -6842,7 +6859,7 @@ __func__, count, timeout)); return 0; } else if (int_status & MPI2_HIS_IOC2SYS_DB_STATUS) { - doorbell = ioc->base_readl(&ioc->chip->Doorbell); + doorbell = ioc->base_readl_ext_retry(&ioc->chip->Doorbell); if ((doorbell & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { mpt3sas_print_fault_code(ioc, doorbell); @@ -6882,7 +6899,7 @@ count = 0; cntdn = 1000 * timeout; do { - doorbell_reg = ioc->base_readl(&ioc->chip->Doorbell); + doorbell_reg = ioc->base_readl_ext_retry(&ioc->chip->Doorbell); if (!(doorbell_reg & MPI2_DOORBELL_USED)) { dhsprintk(ioc, ioc_info(ioc, "%s: successful count(%d), timeout(%d)\n", @@ -7030,7 +7047,7 @@ __le32 *mfp; /* make sure doorbell is not in use */ - if ((ioc->base_readl(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { + if ((ioc->base_readl_ext_retry(&ioc->chip->Doorbell) & MPI2_DOORBELL_USED)) { ioc_err(ioc, "doorbell is in use (line=%d)\n", __LINE__); return -EFAULT; } @@ -7079,7 +7096,7 @@ } /* read the first two 16-bits, it gives the total length of the reply */ - reply[0] = le16_to_cpu(ioc->base_readl(&ioc->chip->Doorbell) + reply[0] = le16_to_cpu(ioc->base_readl_ext_retry(&ioc->chip->Doorbell) & MPI2_DOORBELL_DATA_MASK); writel(0, &ioc->chip->HostInterruptStatus); if ((_base_wait_for_doorbell_int(ioc, 5))) { @@ -7087,7 +7104,7 @@ __LINE__); return -EFAULT; } - reply[1] = le16_to_cpu(ioc->base_readl(&ioc->chip->Doorbell) + reply[1] = le16_to_cpu(ioc->base_readl_ext_retry(&ioc->chip->Doorbell) & MPI2_DOORBELL_DATA_MASK); writel(0, &ioc->chip->HostInterruptStatus); @@ -7098,10 +7115,10 @@ return -EFAULT; } if (i >= reply_bytes/2) /* overflow case */ - ioc->base_readl(&ioc->chip->Doorbell); + ioc->base_readl_ext_retry(&ioc->chip->Doorbell); else reply[i] = le16_to_cpu( - ioc->base_readl(&ioc->chip->Doorbell) + ioc->base_readl_ext_retry(&ioc->chip->Doorbell) & MPI2_DOORBELL_DATA_MASK); writel(0, &ioc->chip->HostInterruptStatus); } @@ -7960,7 +7977,7 @@ goto out; } - host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic); + host_diagnostic = ioc->base_readl_ext_retry(&ioc->chip->HostDiagnostic); drsprintk(ioc, ioc_info(ioc, "wrote magic sequence: count(%d), host_diagnostic(0x%08x)\n", count, host_diagnostic)); @@ -7980,7 +7997,7 @@ for (count = 0; count < (300000000 / MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC); count++) { - host_diagnostic = ioc->base_readl(&ioc->chip->HostDiagnostic); + host_diagnostic = ioc->base_readl_ext_retry(&ioc->chip->HostDiagnostic); if (host_diagnostic == 0xFFFFFFFF) { ioc_info(ioc, @@ -8370,10 +8387,13 @@ ioc->rdpq_array_enable_assigned = 0; ioc->use_32bit_dma = false; ioc->dma_mask = 64; - if (ioc->is_aero_ioc) + if (ioc->is_aero_ioc) { ioc->base_readl = &_base_readl_aero; - else + ioc->base_readl_ext_retry = &_base_readl_ext_retry; + } else { ioc->base_readl = &_base_readl; + ioc->base_readl_ext_retry = &_base_readl; + } r = mpt3sas_base_map_resources(ioc); if (r) goto out_free_resources; diff -u linux-6.2.0/drivers/scsi/qedf/qedf_main.c linux-6.2.0/drivers/scsi/qedf/qedf_main.c --- linux-6.2.0/drivers/scsi/qedf/qedf_main.c +++ linux-6.2.0/drivers/scsi/qedf/qedf_main.c @@ -2807,6 +2807,8 @@ struct qedf_ioreq *io_req; struct qedf_rport *fcport; u32 comp_type; + u8 io_comp_type; + unsigned long flags; comp_type = (cqe->cqe_data >> FCOE_CQE_CQE_TYPE_SHIFT) & FCOE_CQE_CQE_TYPE_MASK; @@ -2840,11 +2842,14 @@ return; } + spin_lock_irqsave(&fcport->rport_lock, flags); + io_comp_type = io_req->cmd_type; + spin_unlock_irqrestore(&fcport->rport_lock, flags); switch (comp_type) { case FCOE_GOOD_COMPLETION_CQE_TYPE: atomic_inc(&fcport->free_sqes); - switch (io_req->cmd_type) { + switch (io_comp_type) { case QEDF_SCSI_CMD: qedf_scsi_completion(qedf, cqe, io_req); break; diff -u linux-6.2.0/drivers/scsi/qedi/qedi_main.c linux-6.2.0/drivers/scsi/qedi/qedi_main.c --- linux-6.2.0/drivers/scsi/qedi/qedi_main.c +++ linux-6.2.0/drivers/scsi/qedi/qedi_main.c @@ -1977,8 +1977,9 @@ struct qedi_percpu_s *p = this_cpu_ptr(&qedi_percpu); struct qedi_work *work, *tmp; struct task_struct *thread; + unsigned long flags; - spin_lock_bh(&p->p_work_lock); + spin_lock_irqsave(&p->p_work_lock, flags); thread = p->iothread; p->iothread = NULL; @@ -1989,7 +1990,7 @@ kfree(work); } - spin_unlock_bh(&p->p_work_lock); + spin_unlock_irqrestore(&p->p_work_lock, flags); if (thread) kthread_stop(thread); return 0; diff -u linux-6.2.0/drivers/scsi/qla2xxx/qla_attr.c linux-6.2.0/drivers/scsi/qla2xxx/qla_attr.c --- linux-6.2.0/drivers/scsi/qla2xxx/qla_attr.c +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_attr.c @@ -3093,8 +3093,6 @@ vha->flags.difdix_supported = 1; ql_dbg(ql_dbg_user, vha, 0x7082, "Registered for DIF/DIX type 1 and 3 protection.\n"); - if (ql2xenabledif == 1) - prot = SHOST_DIX_TYPE0_PROTECTION; scsi_host_set_prot(vha->host, prot | SHOST_DIF_TYPE1_PROTECTION | SHOST_DIF_TYPE2_PROTECTION diff -u linux-6.2.0/drivers/scsi/qla2xxx/qla_def.h linux-6.2.0/drivers/scsi/qla2xxx/qla_def.h --- linux-6.2.0/drivers/scsi/qla2xxx/qla_def.h +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_def.h @@ -458,6 +458,7 @@ } struct tmf_arg { + struct list_head tmf_elem; struct qla_qpair *qpair; struct fc_port *fcport; struct scsi_qla_host *vha; @@ -2534,7 +2535,6 @@ typedef struct fc_port { struct list_head list; struct scsi_qla_host *vha; - struct list_head tmf_pending; unsigned int conf_compl_supported:1; unsigned int deleted:2; @@ -2555,9 +2555,6 @@ unsigned int do_prli_nvme:1; uint8_t nvme_flag; - uint8_t active_tmf; -#define MAX_ACTIVE_TMF 8 - uint8_t node_name[WWN_SIZE]; uint8_t port_name[WWN_SIZE]; port_id_t d_id; @@ -3478,6 +3475,7 @@ int have_irq; int in_use; uint32_t vector; + uint32_t vector_base0; uint16_t entry; char name[30]; void *handle; @@ -3745,2 +3743,12 @@ +struct qla_fw_res { + u16 iocb_total; + u16 iocb_limit; + atomic_t iocb_used; + + u16 exch_total; + u16 exch_limit; + atomic_t exch_used; +}; + #define QLA_IOCB_PCT_LIMIT 95 @@ -3797,6 +3805,7 @@ uint64_t retry_term_jiff; struct qla_tgt_counters tgt_counters; uint16_t cpuid; + bool cpu_mapped; struct qla_fw_resources fwres ____cacheline_aligned; u32 cmd_cnt; u32 cmd_completion_cnt; @@ -4126,6 +4135,7 @@ struct req_que **req_q_map; struct rsp_que **rsp_q_map; struct qla_qpair **queue_pair_map; + struct qla_qpair **qp_cpu_map; unsigned long req_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)]; unsigned long rsp_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)]; unsigned long qpair_qid_map[(QLA_MAX_QUEUES / 8) @@ -4370,7 +4380,6 @@ uint8_t aen_mbx_count; atomic_t num_pend_mbx_stage1; atomic_t num_pend_mbx_stage2; - atomic_t num_pend_mbx_stage3; uint16_t frame_payload_size; uint32_t login_retry_count; @@ -4640,6 +4649,8 @@ uint32_t flt_region_aux_img_status_sec; }; uint8_t active_image; + uint8_t active_tmf; +#define MAX_ACTIVE_TMF 8 /* Needed for BEACON */ uint16_t beacon_blink_led; @@ -4654,6 +4665,8 @@ struct qla_msix_entry *msix_entries; + struct list_head tmf_pending; + struct list_head tmf_active; struct list_head vp_list; /* list of VP */ unsigned long vp_idx_map[(MAX_MULTI_ID_FABRIC / 8) / sizeof(unsigned long)]; @@ -4782,6 +4795,7 @@ spinlock_t sadb_lock; /* protects list */ struct els_reject elsrej; u8 edif_post_stop_cnt_down; + struct qla_fw_res fwres ____cacheline_aligned; }; #define RX_ELS_SIZE (roundup(sizeof(struct enode) + ELS_MAX_PAYLOAD, SMP_CACHE_BYTES)) diff -u linux-6.2.0/drivers/scsi/qla2xxx/qla_dfs.c linux-6.2.0/drivers/scsi/qla2xxx/qla_dfs.c --- linux-6.2.0/drivers/scsi/qla2xxx/qla_dfs.c +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_dfs.c @@ -116,7 +116,7 @@ sprintf(wwn, "pn-%016llx", wwn_to_u64(fp->port_name)); fp->dfs_rport_dir = debugfs_create_dir(wwn, vha->dfs_rport_root); - if (!fp->dfs_rport_dir) + if (IS_ERR(fp->dfs_rport_dir)) return; if (NVME_TARGET(vha->hw, fp)) debugfs_create_file("dev_loss_tmo", 0600, fp->dfs_rport_dir, @@ -276,6 +276,16 @@ seq_printf(s, "estimate exchange used[%d] high water limit [%d] n", exch_used, ha->base_qpair->fwres.exch_limit); + + if (ql2xenforce_iocb_limit == 2) { + iocbs_used = atomic_read(&ha->fwres.iocb_used); + exch_used = atomic_read(&ha->fwres.exch_used); + seq_printf(s, " estimate iocb2 used [%d] high water limit [%d]\n", + iocbs_used, ha->fwres.iocb_limit); + + seq_printf(s, " estimate exchange2 used[%d] high water limit [%d] \n", + exch_used, ha->fwres.exch_limit); + } } return 0; @@ -698,14 +708,14 @@ if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) { ha->tgt.dfs_naqp = debugfs_create_file("naqp", 0400, ha->dfs_dir, vha, &dfs_naqp_ops); - if (!ha->tgt.dfs_naqp) { + if (IS_ERR(ha->tgt.dfs_naqp)) { ql_log(ql_log_warn, vha, 0xd011, "Unable to create debugFS naqp node.\n"); goto out; } } vha->dfs_rport_root = debugfs_create_dir("rports", ha->dfs_dir); - if (!vha->dfs_rport_root) { + if (IS_ERR(vha->dfs_rport_root)) { ql_log(ql_log_warn, vha, 0xd012, "Unable to create debugFS rports node.\n"); goto out; diff -u linux-6.2.0/drivers/scsi/qla2xxx/qla_gbl.h linux-6.2.0/drivers/scsi/qla2xxx/qla_gbl.h --- linux-6.2.0/drivers/scsi/qla2xxx/qla_gbl.h +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_gbl.h @@ -143,6 +143,7 @@ void qla_edif_clear_appdata(struct scsi_qla_host *vha, struct fc_port *fcport); const char *sc_to_str(uint16_t cmd); +void qla_adjust_iocb_limit(scsi_qla_host_t *vha); /* * Global Data in qla_os.c source file. diff -u linux-6.2.0/drivers/scsi/qla2xxx/qla_init.c linux-6.2.0/drivers/scsi/qla2xxx/qla_init.c --- linux-6.2.0/drivers/scsi/qla2xxx/qla_init.c +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_init.c @@ -502,6 +502,7 @@ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea) { struct fc_port *fcport = ea->fcport; + unsigned long flags; ql_dbg(ql_dbg_disc, vha, 0x20d2, "%s %8phC DS %d LS %d rc %d login %d|%d rscn %d|%d lid %d\n", @@ -516,9 +517,15 @@ ql_dbg(ql_dbg_disc, vha, 0x2066, "%s %8phC: adisc fail: post delete\n", __func__, ea->fcport->port_name); + + spin_lock_irqsave(&vha->work_lock, flags); /* deleted = 0 & logout_on_delete = force fw cleanup */ - fcport->deleted = 0; + if (fcport->deleted == QLA_SESS_DELETED) + fcport->deleted = 0; + fcport->logout_on_delete = 1; + spin_unlock_irqrestore(&vha->work_lock, flags); + qlt_schedule_sess_for_deletion(ea->fcport); return; } @@ -1128,7 +1135,7 @@ u16 *mb; if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) - return rval; + goto done; ql_dbg(ql_dbg_disc, vha, 0x20d9, "Async-gnlist WWPN %8phC \n", fcport->port_name); @@ -1182,8 +1189,9 @@ done_free_sp: /* ref: INIT */ kref_put(&sp->cmd_kref, qla2x00_sp_release); + fcport->flags &= ~(FCF_ASYNC_SENT); done: - fcport->flags &= ~(FCF_ASYNC_ACTIVE | FCF_ASYNC_SENT); + fcport->flags &= ~(FCF_ASYNC_ACTIVE); return rval; } @@ -1440,7 +1448,6 @@ spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); ea->fcport->login_gen++; - ea->fcport->deleted = 0; ea->fcport->logout_on_delete = 1; if (!ea->fcport->login_succ && !IS_SW_RESV_ADDR(ea->fcport->d_id)) { @@ -1997,12 +2004,11 @@ int rc, h; unsigned long flags; - if (sp->type == SRB_MARKER) { - complete(&tmf->u.tmf.comp); - return; - } + if (sp->type == SRB_MARKER) + rc = QLA_FUNCTION_FAILED; + else + rc = qla24xx_async_abort_cmd(sp, false); - rc = qla24xx_async_abort_cmd(sp, false); if (rc) { spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { @@ -2033,10 +2039,14 @@ complete(&tmf->u.tmf.comp); } -#define START_SP_W_RETRIES(_sp, _rval) \ +#define START_SP_W_RETRIES(_sp, _rval, _chip_gen, _login_gen) \ {\ int cnt = 5; \ do { \ + if (_chip_gen != sp->vha->hw->chip_reset || _login_gen != sp->fcport->login_gen) {\ + _rval = EINVAL; \ + break; \ + } \ _rval = qla2x00_start_sp(_sp); \ if (_rval == EAGAIN) \ msleep(1); \ @@ -2059,6 +2069,7 @@ srb_t *sp; int rval = QLA_FUNCTION_FAILED; fc_port_t *fcport = arg->fcport; + u32 chip_gen, login_gen; if (TMF_NOT_READY(arg->fcport)) { ql_dbg(ql_dbg_taskm, vha, 0x8039, @@ -2068,6 +2079,9 @@ return QLA_SUSPENDED; } + chip_gen = vha->hw->chip_reset; + login_gen = fcport->login_gen; + /* ref: INIT */ sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL); if (!sp) @@ -2085,7 +2099,7 @@ tm_iocb->u.tmf.loop_id = fcport->loop_id; tm_iocb->u.tmf.vp_index = vha->vp_idx; - START_SP_W_RETRIES(sp, rval); + START_SP_W_RETRIES(sp, rval, chip_gen, login_gen); ql_dbg(ql_dbg_taskm, vha, 0x8006, "Async-marker hdl=%x loop-id=%x portid=%06x modifier=%x lun=%lld qp=%d rval %d.\n", @@ -2124,6 +2138,17 @@ complete(&tmf->u.tmf.comp); } +static int qla_tmf_wait(struct tmf_arg *arg) +{ + /* there are only 2 types of error handling that reaches here, lun or target reset */ + if (arg->flags & (TCF_LUN_RESET | TCF_ABORT_TASK_SET | TCF_CLEAR_TASK_SET)) + return qla2x00_eh_wait_for_pending_commands(arg->vha, + arg->fcport->d_id.b24, arg->lun, WAIT_LUN); + else + return qla2x00_eh_wait_for_pending_commands(arg->vha, + arg->fcport->d_id.b24, arg->lun, WAIT_TARGET); +} + static int __qla2x00_async_tm_cmd(struct tmf_arg *arg) { @@ -2131,8 +2156,9 @@ struct srb_iocb *tm_iocb; srb_t *sp; int rval = QLA_FUNCTION_FAILED; - fc_port_t *fcport = arg->fcport; + u32 chip_gen, login_gen; + u64 jif; if (TMF_NOT_READY(arg->fcport)) { ql_dbg(ql_dbg_taskm, vha, 0x8032, @@ -2142,6 +2168,9 @@ return QLA_SUSPENDED; } + chip_gen = vha->hw->chip_reset; + login_gen = fcport->login_gen; + /* ref: INIT */ sp = qla2xxx_get_qpair_sp(vha, arg->qpair, fcport, GFP_KERNEL); if (!sp) @@ -2159,7 +2188,7 @@ tm_iocb->u.tmf.flags = arg->flags; tm_iocb->u.tmf.lun = arg->lun; - START_SP_W_RETRIES(sp, rval); + START_SP_W_RETRIES(sp, rval, chip_gen, login_gen); ql_dbg(ql_dbg_taskm, vha, 0x802f, "Async-tmf hdl=%x loop-id=%x portid=%06x ctrl=%x lun=%lld qp=%d rval=%x.\n", @@ -2177,8 +2206,26 @@ "TM IOCB failed (%x).\n", rval); } - if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) - rval = qla26xx_marker(arg); + if (!test_bit(UNLOADING, &vha->dpc_flags) && !IS_QLAFX00(vha->hw)) { + jif = jiffies; + if (qla_tmf_wait(arg)) { + ql_log(ql_log_info, vha, 0x803e, + "Waited %u ms Nexus=%ld:%06x:%llu.\n", + jiffies_to_msecs(jiffies - jif), vha->host_no, + fcport->d_id.b24, arg->lun); + } + + if (chip_gen == vha->hw->chip_reset && login_gen == fcport->login_gen) { + rval = qla26xx_marker(arg); + } else { + ql_log(ql_log_info, vha, 0x803e, + "Skip Marker due to disruption. Nexus=%ld:%06x:%llu.\n", + vha->host_no, fcport->d_id.b24, arg->lun); + rval = QLA_FUNCTION_FAILED; + } + } + if (tm_iocb->u.tmf.data) + rval = tm_iocb->u.tmf.data; done_free_sp: /* ref: INIT */ @@ -2187,30 +2234,42 @@ return rval; } -static void qla_put_tmf(fc_port_t *fcport) +static void qla_put_tmf(struct tmf_arg *arg) { - struct scsi_qla_host *vha = fcport->vha; + struct scsi_qla_host *vha = arg->vha; struct qla_hw_data *ha = vha->hw; unsigned long flags; spin_lock_irqsave(&ha->tgt.sess_lock, flags); - fcport->active_tmf--; + ha->active_tmf--; + list_del(&arg->tmf_elem); spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); } static -int qla_get_tmf(fc_port_t *fcport) +int qla_get_tmf(struct tmf_arg *arg) { - struct scsi_qla_host *vha = fcport->vha; + struct scsi_qla_host *vha = arg->vha; struct qla_hw_data *ha = vha->hw; unsigned long flags; + fc_port_t *fcport = arg->fcport; int rc = 0; - LIST_HEAD(tmf_elem); + struct tmf_arg *t; spin_lock_irqsave(&ha->tgt.sess_lock, flags); - list_add_tail(&tmf_elem, &fcport->tmf_pending); + list_for_each_entry(t, &ha->tmf_active, tmf_elem) { + if (t->fcport == arg->fcport && t->lun == arg->lun) { + /* reject duplicate TMF */ + ql_log(ql_log_warn, vha, 0x802c, + "found duplicate TMF. Nexus=%ld:%06x:%llu.\n", + vha->host_no, fcport->d_id.b24, arg->lun); + spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); + return -EINVAL; + } + } - while (fcport->active_tmf >= MAX_ACTIVE_TMF) { + list_add_tail(&arg->tmf_elem, &ha->tmf_pending); + while (ha->active_tmf >= MAX_ACTIVE_TMF) { spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); msleep(1); @@ -2222,15 +2281,17 @@ rc = EIO; break; } - if (fcport->active_tmf < MAX_ACTIVE_TMF && - list_is_first(&tmf_elem, &fcport->tmf_pending)) + if (ha->active_tmf < MAX_ACTIVE_TMF && + list_is_first(&arg->tmf_elem, &ha->tmf_pending)) break; } - list_del(&tmf_elem); + list_del(&arg->tmf_elem); - if (!rc) - fcport->active_tmf++; + if (!rc) { + ha->active_tmf++; + list_add_tail(&arg->tmf_elem, &ha->tmf_active); + } spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); @@ -2242,9 +2303,8 @@ uint32_t tag) { struct scsi_qla_host *vha = fcport->vha; - struct qla_qpair *qpair; struct tmf_arg a; - int i, rval = QLA_SUCCESS; + int rval = QLA_SUCCESS; if (TMF_NOT_READY(fcport)) return QLA_SUSPENDED; @@ -2252,47 +2312,22 @@ a.vha = fcport->vha; a.fcport = fcport; a.lun = lun; + a.flags = flags; + INIT_LIST_HEAD(&a.tmf_elem); + if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) { a.modifier = MK_SYNC_ID_LUN; - - if (qla_get_tmf(fcport)) - return QLA_FUNCTION_FAILED; } else { a.modifier = MK_SYNC_ID; } - if (vha->hw->mqenable) { - for (i = 0; i < vha->hw->num_qpairs; i++) { - qpair = vha->hw->queue_pair_map[i]; - if (!qpair) - continue; - - if (TMF_NOT_READY(fcport)) { - ql_log(ql_log_warn, vha, 0x8026, - "Unable to send TM due to disruption.\n"); - rval = QLA_SUSPENDED; - break; - } - - a.qpair = qpair; - a.flags = flags|TCF_NOTMCMD_TO_TARGET; - rval = __qla2x00_async_tm_cmd(&a); - if (rval) - break; - } - } - - if (rval) - goto bailout; + if (qla_get_tmf(&a)) + return QLA_FUNCTION_FAILED; a.qpair = vha->hw->base_qpair; - a.flags = flags; rval = __qla2x00_async_tm_cmd(&a); -bailout: - if (a.modifier == MK_SYNC_ID_LUN) - qla_put_tmf(fcport); - + qla_put_tmf(&a); return rval; } @@ -4148,39 +4183,61 @@ return ha->flags.lr_detected; } -void qla_init_iocb_limit(scsi_qla_host_t *vha) +static void __qla_adjust_iocb_limit(struct qla_qpair *qpair) { - u16 i, num_qps; - u32 limit; - struct qla_hw_data *ha = vha->hw; + u8 num_qps; + u16 limit; + struct qla_hw_data *ha = qpair->vha->hw; num_qps = ha->num_qpairs + 1; limit = (ha->orig_fw_iocb_count * QLA_IOCB_PCT_LIMIT) / 100; - ha->base_qpair->fwres.iocbs_total = ha->orig_fw_iocb_count; - ha->base_qpair->fwres.iocbs_limit = limit; - ha->base_qpair->fwres.iocbs_qp_limit = limit / num_qps; - ha->base_qpair->fwres.iocbs_used = 0; + qpair->fwres.iocbs_total = ha->orig_fw_iocb_count; + qpair->fwres.iocbs_limit = limit; + qpair->fwres.iocbs_qp_limit = limit / num_qps; + + qpair->fwres.exch_total = ha->orig_fw_xcb_count; + qpair->fwres.exch_limit = (ha->orig_fw_xcb_count * + QLA_IOCB_PCT_LIMIT) / 100; +} + +void qla_init_iocb_limit(scsi_qla_host_t *vha) +{ + u8 i; + struct qla_hw_data *ha = vha->hw; - ha->base_qpair->fwres.exch_total = ha->orig_fw_xcb_count; - ha->base_qpair->fwres.exch_limit = (ha->orig_fw_xcb_count * - QLA_IOCB_PCT_LIMIT) / 100; + __qla_adjust_iocb_limit(ha->base_qpair); + ha->base_qpair->fwres.iocbs_used = 0; ha->base_qpair->fwres.exch_used = 0; for (i = 0; i < ha->max_qpairs; i++) { if (ha->queue_pair_map[i]) { - ha->queue_pair_map[i]->fwres.iocbs_total = - ha->orig_fw_iocb_count; - ha->queue_pair_map[i]->fwres.iocbs_limit = limit; - ha->queue_pair_map[i]->fwres.iocbs_qp_limit = - limit / num_qps; + __qla_adjust_iocb_limit(ha->queue_pair_map[i]); ha->queue_pair_map[i]->fwres.iocbs_used = 0; - ha->queue_pair_map[i]->fwres.exch_total = ha->orig_fw_xcb_count; - ha->queue_pair_map[i]->fwres.exch_limit = - (ha->orig_fw_xcb_count * QLA_IOCB_PCT_LIMIT) / 100; ha->queue_pair_map[i]->fwres.exch_used = 0; } } + + ha->fwres.iocb_total = ha->orig_fw_iocb_count; + ha->fwres.iocb_limit = (ha->orig_fw_iocb_count * QLA_IOCB_PCT_LIMIT) / 100; + ha->fwres.exch_total = ha->orig_fw_xcb_count; + ha->fwres.exch_limit = (ha->orig_fw_xcb_count * QLA_IOCB_PCT_LIMIT) / 100; + + atomic_set(&ha->fwres.iocb_used, 0); + atomic_set(&ha->fwres.exch_used, 0); +} + +void qla_adjust_iocb_limit(scsi_qla_host_t *vha) +{ + u8 i; + struct qla_hw_data *ha = vha->hw; + + __qla_adjust_iocb_limit(ha->base_qpair); + + for (i = 0; i < ha->max_qpairs; i++) { + if (ha->queue_pair_map[i]) + __qla_adjust_iocb_limit(ha->queue_pair_map[i]); + } } /** @@ -4778,15 +4835,16 @@ if (ha->flags.edif_enabled) mid_init_cb->init_cb.frame_payload_size = cpu_to_le16(ELS_MAX_PAYLOAD); + QLA_FW_STARTED(ha); rval = qla2x00_init_firmware(vha, ha->init_cb_size); next_check: if (rval) { + QLA_FW_STOPPED(ha); ql_log(ql_log_fatal, vha, 0x00d2, "Init Firmware **** FAILED ****.\n"); } else { ql_dbg(ql_dbg_init, vha, 0x00d3, "Init Firmware -- success.\n"); - QLA_FW_STARTED(ha); vha->u_ql2xexchoffld = vha->u_ql2xiniexchg = 0; } @@ -5528,7 +5586,6 @@ INIT_WORK(&fcport->reg_work, qla_register_fcport_fn); INIT_LIST_HEAD(&fcport->gnl_entry); INIT_LIST_HEAD(&fcport->list); - INIT_LIST_HEAD(&fcport->tmf_pending); INIT_LIST_HEAD(&fcport->sess_cmd_list); spin_lock_init(&fcport->sess_cmd_lock); @@ -6112,6 +6169,8 @@ void qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) { + unsigned long flags; + if (IS_SW_RESV_ADDR(fcport->d_id)) return; @@ -6121,7 +6180,11 @@ qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT); fcport->login_retry = vha->hw->login_retry_count; fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); + + spin_lock_irqsave(&vha->work_lock, flags); fcport->deleted = 0; + spin_unlock_irqrestore(&vha->work_lock, flags); + if (vha->hw->current_topology == ISP_CFG_NL) fcport->logout_on_delete = 0; else @@ -7387,14 +7450,15 @@ } /* purge MBox commands */ - if (atomic_read(&ha->num_pend_mbx_stage3)) { + spin_lock_irqsave(&ha->hardware_lock, flags); + if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags)) { clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); complete(&ha->mbx_intr_comp); } + spin_unlock_irqrestore(&ha->hardware_lock, flags); i = 0; - while (atomic_read(&ha->num_pend_mbx_stage3) || - atomic_read(&ha->num_pend_mbx_stage2) || + while (atomic_read(&ha->num_pend_mbx_stage2) || atomic_read(&ha->num_pend_mbx_stage1)) { msleep(20); i++; @@ -9690,8 +9754,9 @@ qpair->req = ha->req_q_map[req_id]; qpair->rsp->req = qpair->req; qpair->rsp->qpair = qpair; - /* init qpair to this cpu. Will adjust at run time. */ - qla_cpu_update(qpair, raw_smp_processor_id()); + + if (!qpair->cpu_mapped) + qla_cpu_update(qpair, raw_smp_processor_id()); if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) { if (ha->fw_attributes & BIT_4) diff -u linux-6.2.0/drivers/scsi/qla2xxx/qla_inline.h linux-6.2.0/drivers/scsi/qla2xxx/qla_inline.h --- linux-6.2.0/drivers/scsi/qla2xxx/qla_inline.h +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_inline.h @@ -386,6 +386,7 @@ RESOURCE_IOCB = BIT_0, RESOURCE_EXCH = BIT_1, /* exchange */ RESOURCE_FORCE = BIT_2, + RESOURCE_HA = BIT_3, }; static inline int @@ -393,7 +394,7 @@ { u16 iocbs_used, i; u16 exch_used; - struct qla_hw_data *ha = qp->vha->hw; + struct qla_hw_data *ha = qp->hw; if (!ql2xenforce_iocb_limit) { iores->res_type = RESOURCE_NONE; @@ -428,15 +429,69 @@ return -ENOSPC; } } + + if (ql2xenforce_iocb_limit == 2) { + if ((iores->iocb_cnt + atomic_read(&ha->fwres.iocb_used)) >= + ha->fwres.iocb_limit) { + iores->res_type = RESOURCE_NONE; + return -ENOSPC; + } + + if (iores->res_type & RESOURCE_EXCH) { + if ((iores->exch_cnt + atomic_read(&ha->fwres.exch_used)) >= + ha->fwres.exch_limit) { + iores->res_type = RESOURCE_NONE; + return -ENOSPC; + } + } + } + force: qp->fwres.iocbs_used += iores->iocb_cnt; qp->fwres.exch_used += iores->exch_cnt; + if (ql2xenforce_iocb_limit == 2) { + atomic_add(iores->iocb_cnt, &ha->fwres.iocb_used); + atomic_add(iores->exch_cnt, &ha->fwres.exch_used); + iores->res_type |= RESOURCE_HA; + } return 0; } +/* + * decrement to zero. This routine will not decrement below zero + * @v: pointer of type atomic_t + * @amount: amount to decrement from v + */ +static void qla_atomic_dtz(atomic_t *v, int amount) +{ + int c, old, dec; + + c = atomic_read(v); + for (;;) { + dec = c - amount; + if (unlikely(dec < 0)) + dec = 0; + + old = atomic_cmpxchg((v), c, dec); + if (likely(old == c)) + break; + c = old; + } +} + static inline void qla_put_fw_resources(struct qla_qpair *qp, struct iocb_resource *iores) { + struct qla_hw_data *ha = qp->hw; + + if (iores->res_type & RESOURCE_HA) { + if (iores->res_type & RESOURCE_IOCB) + qla_atomic_dtz(&ha->fwres.iocb_used, iores->iocb_cnt); + + if (iores->res_type & RESOURCE_EXCH) + qla_atomic_dtz(&ha->fwres.exch_used, iores->exch_cnt); + } + if (iores->res_type & RESOURCE_IOCB) { if (qp->fwres.iocbs_used >= iores->iocb_cnt) { qp->fwres.iocbs_used -= iores->iocb_cnt; @@ -520,0 +576,58 @@ + +static inline struct qla_qpair * +qla_mapq_nvme_select_qpair(struct qla_hw_data *ha, struct qla_qpair *qpair) +{ + int cpuid = raw_smp_processor_id(); + + if (qpair->cpuid != cpuid && + ha->qp_cpu_map[cpuid]) { + qpair = ha->qp_cpu_map[cpuid]; + } + return qpair; +} + +static inline void +qla_mapq_init_qp_cpu_map(struct qla_hw_data *ha, + struct qla_msix_entry *msix, + struct qla_qpair *qpair) +{ + const struct cpumask *mask; + unsigned int cpu; + + if (!ha->qp_cpu_map) + return; + mask = pci_irq_get_affinity(ha->pdev, msix->vector_base0); + if (!mask) + return; + qpair->cpuid = cpumask_first(mask); + for_each_cpu(cpu, mask) { + ha->qp_cpu_map[cpu] = qpair; + } + msix->cpuid = qpair->cpuid; + qpair->cpu_mapped = true; +} + +static inline void +qla_mapq_free_qp_cpu_map(struct qla_hw_data *ha) +{ + if (ha->qp_cpu_map) { + kfree(ha->qp_cpu_map); + ha->qp_cpu_map = NULL; + } +} + +static inline int qla_mapq_alloc_qp_cpu_map(struct qla_hw_data *ha) +{ + scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); + + if (!ha->qp_cpu_map) { + ha->qp_cpu_map = kcalloc(NR_CPUS, sizeof(struct qla_qpair *), + GFP_KERNEL); + if (!ha->qp_cpu_map) { + ql_log(ql_log_fatal, vha, 0x0180, + "Unable to allocate memory for qp_cpu_map ptrs.\n"); + return -1; + } + } + return 0; +} diff -u linux-6.2.0/drivers/scsi/qla2xxx/qla_iocb.c linux-6.2.0/drivers/scsi/qla2xxx/qla_iocb.c --- linux-6.2.0/drivers/scsi/qla2xxx/qla_iocb.c +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_iocb.c @@ -3887,6 +3887,7 @@ { mrk->entry_type = MARKER_TYPE; mrk->modifier = sp->u.iocb_cmd.u.tmf.modifier; + mrk->handle = make_handle(sp->qpair->req->id, sp->handle); if (sp->u.iocb_cmd.u.tmf.modifier != MK_SYNC_ALL) { mrk->nport_handle = cpu_to_le16(sp->u.iocb_cmd.u.tmf.loop_id); int_to_scsilun(sp->u.iocb_cmd.u.tmf.lun, (struct scsi_lun *)&mrk->lun); diff -u linux-6.2.0/drivers/scsi/qla2xxx/qla_isr.c linux-6.2.0/drivers/scsi/qla2xxx/qla_isr.c --- linux-6.2.0/drivers/scsi/qla2xxx/qla_isr.c +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_isr.c @@ -1121,8 +1121,12 @@ unsigned long flags; fc_port_t *fcport = NULL; - if (!vha->hw->flags.fw_started) + if (!vha->hw->flags.fw_started) { + ql_log(ql_log_warn, vha, 0x50ff, + "Dropping AEN - %04x %04x %04x %04x.\n", + mb[0], mb[1], mb[2], mb[3]); return; + } /* Setup to process RIO completion. */ handle_cnt = 0; @@ -2539,7 +2543,6 @@ case CS_PORT_BUSY: case CS_INCOMPLETE: case CS_PORT_UNAVAILABLE: - case CS_TIMEOUT: case CS_RESET: if (atomic_read(&fcport->state) == FCS_ONLINE) { ql_dbg(ql_dbg_disc, fcport->vha, 0x3021, @@ -3814,9 +3817,11 @@ if (!ha->flags.fw_started) return; - if (rsp->qpair->cpuid != smp_processor_id() || !rsp->qpair->rcv_intr) { + if (rsp->qpair->cpuid != raw_smp_processor_id() || !rsp->qpair->rcv_intr) { rsp->qpair->rcv_intr = 1; - qla_cpu_update(rsp->qpair, smp_processor_id()); + + if (!rsp->qpair->cpu_mapped) + qla_cpu_update(rsp->qpair, raw_smp_processor_id()); } #define __update_rsp_in(_is_shadow_hba, _rsp, _rsp_in) \ @@ -4303,7 +4308,7 @@ } ha = qpair->hw; - queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); + queue_work(ha->wq, &qpair->q_work); return IRQ_HANDLED; } @@ -4329,7 +4334,7 @@ wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); spin_unlock_irqrestore(&ha->hardware_lock, flags); - queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); + queue_work(ha->wq, &qpair->q_work); return IRQ_HANDLED; } @@ -4422,6 +4427,7 @@ for (i = 0; i < ha->msix_count; i++) { qentry = &ha->msix_entries[i]; qentry->vector = pci_irq_vector(ha->pdev, i); + qentry->vector_base0 = i; qentry->entry = i; qentry->have_irq = 0; qentry->in_use = 0; @@ -4650,4 +4656,5 @@ msix->have_irq = 1; msix->handle = qpair; + qla_mapq_init_qp_cpu_map(ha, msix, qpair); return ret; } diff -u linux-6.2.0/drivers/scsi/qla2xxx/qla_nvme.c linux-6.2.0/drivers/scsi/qla2xxx/qla_nvme.c --- linux-6.2.0/drivers/scsi/qla2xxx/qla_nvme.c +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_nvme.c @@ -132,6 +132,7 @@ "Failed to allocate qpair\n"); return -EINVAL; } + qla_adjust_iocb_limit(vha); } *handle = qpair; @@ -608,6 +609,7 @@ fc_port_t *fcport; struct srb_iocb *nvme; struct scsi_qla_host *vha; + struct qla_hw_data *ha; int rval; srb_t *sp; struct qla_qpair *qpair = hw_queue_handle; @@ -628,6 +630,7 @@ return -ENODEV; vha = fcport->vha; + ha = vha->hw; if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) return -EBUSY; @@ -642,6 +645,8 @@ if (fcport->nvme_flag & NVME_FLAG_RESETTING) return -EBUSY; + qpair = qla_mapq_nvme_select_qpair(ha, qpair); + /* Alloc SRB structure */ sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC); if (!sp) @@ -663,7 +668,7 @@ rval = qla2x00_start_nvme_mq(sp); if (rval != QLA_SUCCESS) { - ql_log(ql_log_warn, vha, 0x212d, + ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x212d, "qla2x00_start_nvme_mq failed = %d\n", rval); sp->priv = NULL; priv->sp = NULL; diff -u linux-6.2.0/drivers/scsi/qla2xxx/qla_os.c linux-6.2.0/drivers/scsi/qla2xxx/qla_os.c --- linux-6.2.0/drivers/scsi/qla2xxx/qla_os.c +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_os.c @@ -44,10 +44,11 @@ MODULE_PARM_DESC(ql2xfulldump_on_mpifail, "Set this to take full dump on MPI hang."); -int ql2xenforce_iocb_limit = 1; +int ql2xenforce_iocb_limit = 2; module_param(ql2xenforce_iocb_limit, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(ql2xenforce_iocb_limit, - "Enforce IOCB throttling, to avoid FW congestion. (default: 1)"); + "Enforce IOCB throttling, to avoid FW congestion. (default: 2) " + "1: track usage per queue, 2: track usage per adapter"); /* * CT6 CTX allocation cache @@ -479,6 +480,11 @@ "Unable to allocate memory for queue pair ptrs.\n"); goto fail_qpair_map; } + if (qla_mapq_alloc_qp_cpu_map(ha) != 0) { + kfree(ha->queue_pair_map); + ha->queue_pair_map = NULL; + goto fail_qpair_map; + } } /* @@ -553,6 +559,7 @@ ha->base_qpair = NULL; } + qla_mapq_free_qp_cpu_map(ha); spin_lock_irqsave(&ha->hardware_lock, flags); for (cnt = 0; cnt < ha->max_req_queues; cnt++) { if (!test_bit(cnt, ha->req_qid_map)) @@ -1478,8 +1485,9 @@ goto eh_reset_failed; } err = 3; - if (qla2x00_eh_wait_for_pending_commands(vha, sdev->id, - sdev->lun, WAIT_LUN) != QLA_SUCCESS) { + if (qla2x00_eh_wait_for_pending_commands(vha, fcport->d_id.b24, + cmd->device->lun, + WAIT_LUN) != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x800d, "wait for pending cmds failed for cmd=%p.\n", cmd); goto eh_reset_failed; @@ -1545,8 +1553,8 @@ goto eh_reset_failed; } err = 3; - if (qla2x00_eh_wait_for_pending_commands(vha, sdev->id, - 0, WAIT_TARGET) != QLA_SUCCESS) { + if (qla2x00_eh_wait_for_pending_commands(vha, fcport->d_id.b24, 0, + WAIT_TARGET) != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x800d, "wait for pending cmds failed for cmd=%p.\n", cmd); goto eh_reset_failed; @@ -2999,9 +3007,10 @@ ha->max_exchg = FW_MAX_EXCHANGES_CNT; atomic_set(&ha->num_pend_mbx_stage1, 0); atomic_set(&ha->num_pend_mbx_stage2, 0); - atomic_set(&ha->num_pend_mbx_stage3, 0); atomic_set(&ha->zio_threshold, DEFAULT_ZIO_THRESHOLD); ha->last_zio_threshold = DEFAULT_ZIO_THRESHOLD; + INIT_LIST_HEAD(&ha->tmf_pending); + INIT_LIST_HEAD(&ha->tmf_active); /* Assign ISP specific operations. */ if (IS_QLA2100(ha)) { @@ -3278,6 +3287,13 @@ host->max_id = ha->max_fibre_devices; host->cmd_per_lun = 3; host->unique_id = host->host_no; + + if (ql2xenabledif && ql2xenabledif != 2) { + ql_log(ql_log_warn, base_vha, 0x302d, + "Invalid value for ql2xenabledif, resetting it to default (2)\n"); + ql2xenabledif = 2; + } + if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) host->max_cmd_len = 32; else @@ -3514,8 +3530,6 @@ base_vha->flags.difdix_supported = 1; ql_dbg(ql_dbg_init, base_vha, 0x00f1, "Registering for DIF/DIX type 1 and 3 protection.\n"); - if (ql2xenabledif == 1) - prot = SHOST_DIX_TYPE0_PROTECTION; if (ql2xprotmask) scsi_host_set_prot(host, ql2xprotmask); else diff -u linux-6.2.0/drivers/scsi/scsi_lib.c linux-6.2.0/drivers/scsi/scsi_lib.c --- linux-6.2.0/drivers/scsi/scsi_lib.c +++ linux-6.2.0/drivers/scsi/scsi_lib.c @@ -2444,7 +2444,7 @@ envp[idx++] = "SDEV_MEDIA_CHANGE=1"; break; case SDEV_EVT_INQUIRY_CHANGE_REPORTED: - scsi_rescan_device(&sdev->sdev_gendev); + scsi_rescan_device(sdev); envp[idx++] = "SDEV_UA=INQUIRY_DATA_HAS_CHANGED"; break; case SDEV_EVT_CAPACITY_CHANGE_REPORTED: diff -u linux-6.2.0/drivers/scsi/scsi_scan.c linux-6.2.0/drivers/scsi/scsi_scan.c --- linux-6.2.0/drivers/scsi/scsi_scan.c +++ linux-6.2.0/drivers/scsi/scsi_scan.c @@ -1611,12 +1611,24 @@ } EXPORT_SYMBOL(scsi_add_device); -void scsi_rescan_device(struct device *dev) +int scsi_rescan_device(struct scsi_device *sdev) { - struct scsi_device *sdev = to_scsi_device(dev); + struct device *dev = &sdev->sdev_gendev; + int ret = 0; device_lock(dev); + /* + * Bail out if the device is not running. Otherwise, the rescan may + * block waiting for commands to be executed, with us holding the + * device lock. This can result in a potential deadlock in the power + * management core code when system resume is on-going. + */ + if (sdev->sdev_state != SDEV_RUNNING) { + ret = -EWOULDBLOCK; + goto unlock; + } + scsi_attach_vpd(sdev); if (sdev->handler && sdev->handler->rescan) @@ -1629,7 +1641,11 @@ drv->rescan(dev); module_put(dev->driver->owner); } + +unlock: device_unlock(dev); + + return ret; } EXPORT_SYMBOL(scsi_rescan_device); diff -u linux-6.2.0/drivers/scsi/sd.c linux-6.2.0/drivers/scsi/sd.c --- linux-6.2.0/drivers/scsi/sd.c +++ linux-6.2.0/drivers/scsi/sd.c @@ -213,18 +213,32 @@ } static ssize_t -manage_start_stop_show(struct device *dev, struct device_attribute *attr, - char *buf) +manage_start_stop_show(struct device *dev, + struct device_attribute *attr, char *buf) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; - return sprintf(buf, "%u\n", sdp->manage_start_stop); + return sysfs_emit(buf, "%u\n", + sdp->manage_system_start_stop && + sdp->manage_runtime_start_stop); } +static DEVICE_ATTR_RO(manage_start_stop); static ssize_t -manage_start_stop_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +manage_system_start_stop_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + struct scsi_device *sdp = sdkp->device; + + return sysfs_emit(buf, "%u\n", sdp->manage_system_start_stop); +} + +static ssize_t +manage_system_start_stop_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) { struct scsi_disk *sdkp = to_scsi_disk(dev); struct scsi_device *sdp = sdkp->device; @@ -236,11 +250,42 @@ if (kstrtobool(buf, &v)) return -EINVAL; - sdp->manage_start_stop = v; + sdp->manage_system_start_stop = v; + + return count; +} +static DEVICE_ATTR_RW(manage_system_start_stop); + +static ssize_t +manage_runtime_start_stop_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + struct scsi_device *sdp = sdkp->device; + + return sysfs_emit(buf, "%u\n", sdp->manage_runtime_start_stop); +} + +static ssize_t +manage_runtime_start_stop_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct scsi_disk *sdkp = to_scsi_disk(dev); + struct scsi_device *sdp = sdkp->device; + bool v; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (kstrtobool(buf, &v)) + return -EINVAL; + + sdp->manage_runtime_start_stop = v; return count; } -static DEVICE_ATTR_RW(manage_start_stop); +static DEVICE_ATTR_RW(manage_runtime_start_stop); static ssize_t allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -572,6 +617,8 @@ &dev_attr_FUA.attr, &dev_attr_allow_restart.attr, &dev_attr_manage_start_stop.attr, + &dev_attr_manage_system_start_stop.attr, + &dev_attr_manage_runtime_start_stop.attr, &dev_attr_protection_type.attr, &dev_attr_protection_mode.attr, &dev_attr_app_tag_own.attr, @@ -3620,7 +3667,8 @@ device_del(&sdkp->disk_dev); del_gendisk(sdkp->disk); - sd_shutdown(dev); + if (!sdkp->suspended) + sd_shutdown(dev); put_disk(sdkp->disk); return 0; @@ -3693,13 +3741,20 @@ sd_sync_cache(sdkp, NULL); } - if (system_state != SYSTEM_RESTART && sdkp->device->manage_start_stop) { + if (system_state != SYSTEM_RESTART && + sdkp->device->manage_system_start_stop) { sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); sd_start_stop_device(sdkp, 0); } } -static int sd_suspend_common(struct device *dev, bool ignore_stop_errors) +static inline bool sd_do_start_stop(struct scsi_device *sdev, bool runtime) +{ + return (sdev->manage_system_start_stop && !runtime) || + (sdev->manage_runtime_start_stop && runtime); +} + +static int sd_suspend_common(struct device *dev, bool runtime) { struct scsi_disk *sdkp = dev_get_drvdata(dev); struct scsi_sense_hdr sshdr; @@ -3731,15 +3786,18 @@ } } - if (sdkp->device->manage_start_stop) { + if (sd_do_start_stop(sdkp->device, runtime)) { if (!sdkp->device->silence_suspend) sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); /* an error is not worth aborting a system sleep */ ret = sd_start_stop_device(sdkp, 0); - if (ignore_stop_errors) + if (!runtime) ret = 0; } + if (!ret) + sdkp->suspended = true; + return ret; } @@ -3748,29 +3806,37 @@ if (pm_runtime_suspended(dev)) return 0; - return sd_suspend_common(dev, true); + return sd_suspend_common(dev, false); } static int sd_suspend_runtime(struct device *dev) { - return sd_suspend_common(dev, false); + return sd_suspend_common(dev, true); } -static int sd_resume(struct device *dev) +static int sd_resume(struct device *dev, bool runtime) { struct scsi_disk *sdkp = dev_get_drvdata(dev); - int ret; + int ret = 0; if (!sdkp) /* E.g.: runtime resume at the start of sd_probe() */ return 0; - if (!sdkp->device->manage_start_stop) + if (!sd_do_start_stop(sdkp->device, runtime)) { + sdkp->suspended = false; return 0; + } - sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); - ret = sd_start_stop_device(sdkp, 1); - if (!ret) + if (!sdkp->device->no_start_on_resume) { + sd_printk(KERN_NOTICE, sdkp, "Starting disk\n"); + ret = sd_start_stop_device(sdkp, 1); + } + + if (!ret) { opal_unlock_from_suspend(sdkp->opal_dev); + sdkp->suspended = false; + } + return ret; } @@ -3779,7 +3845,7 @@ if (pm_runtime_suspended(dev)) return 0; - return sd_resume(dev); + return sd_resume(dev, false); } static int sd_resume_runtime(struct device *dev) @@ -3803,7 +3869,7 @@ "Failed to clear sense data\n"); } - return sd_resume(dev); + return sd_resume(dev, true); } /** diff -u linux-6.2.0/drivers/scsi/storvsc_drv.c linux-6.2.0/drivers/scsi/storvsc_drv.c --- linux-6.2.0/drivers/scsi/storvsc_drv.c +++ linux-6.2.0/drivers/scsi/storvsc_drv.c @@ -471,7 +471,7 @@ sdev = scsi_device_lookup(wrk->host, 0, wrk->tgt_id, wrk->lun); if (!sdev) goto done; - scsi_rescan_device(&sdev->sdev_gendev); + scsi_rescan_device(sdev); scsi_device_put(sdev); done: @@ -1568,6 +1568,8 @@ { blk_queue_rq_timeout(sdevice->request_queue, (storvsc_timeout * HZ)); + /* storvsc devices don't support MAINTENANCE_IN SCSI cmd */ + sdevice->no_report_opcodes = 1; sdevice->no_write_same = 1; /* diff -u linux-6.2.0/drivers/staging/media/rkvdec/rkvdec.c linux-6.2.0/drivers/staging/media/rkvdec/rkvdec.c --- linux-6.2.0/drivers/staging/media/rkvdec/rkvdec.c +++ linux-6.2.0/drivers/staging/media/rkvdec/rkvdec.c @@ -120,7 +120,7 @@ .max_width = 4096, .step_width = 16, .min_height = 48, - .max_height = 2304, + .max_height = 2560, .step_height = 16, }, .ctrls = &rkvdec_h264_ctrls, diff -u linux-6.2.0/drivers/target/target_core_device.c linux-6.2.0/drivers/target/target_core_device.c --- linux-6.2.0/drivers/target/target_core_device.c +++ linux-6.2.0/drivers/target/target_core_device.c @@ -884,7 +884,6 @@ EXPORT_SYMBOL(target_to_linux_sector); struct devices_idr_iter { - struct config_item *prev_item; int (*fn)(struct se_device *dev, void *data); void *data; }; @@ -894,11 +893,9 @@ { struct devices_idr_iter *iter = data; struct se_device *dev = p; + struct config_item *item; int ret; - config_item_put(iter->prev_item); - iter->prev_item = NULL; - /* * We add the device early to the idr, so it can be used * by backend modules during configuration. We do not want @@ -908,12 +905,13 @@ if (!target_dev_configured(dev)) return 0; - iter->prev_item = config_item_get_unless_zero(&dev->dev_group.cg_item); - if (!iter->prev_item) + item = config_item_get_unless_zero(&dev->dev_group.cg_item); + if (!item) return 0; mutex_unlock(&device_mutex); ret = iter->fn(dev, iter->data); + config_item_put(item); mutex_lock(&device_mutex); return ret; @@ -936,7 +934,6 @@ mutex_lock(&device_mutex); ret = idr_for_each(&devices_idr, target_devices_idr_iter, &iter); mutex_unlock(&device_mutex); - config_item_put(iter.prev_item); return ret; } diff -u linux-6.2.0/drivers/target/target_core_transport.c linux-6.2.0/drivers/target/target_core_transport.c --- linux-6.2.0/drivers/target/target_core_transport.c +++ linux-6.2.0/drivers/target/target_core_transport.c @@ -264,6 +264,7 @@ percpu_ref_put(&cmd_cnt->refcnt); percpu_ref_exit(&cmd_cnt->refcnt); + kfree(cmd_cnt); } EXPORT_SYMBOL_GPL(target_free_cmd_counter); diff -u linux-6.2.0/drivers/tty/n_gsm.c linux-6.2.0/drivers/tty/n_gsm.c --- linux-6.2.0/drivers/tty/n_gsm.c +++ linux-6.2.0/drivers/tty/n_gsm.c @@ -2851,10 +2851,8 @@ gsm->has_devices = false; } for (i = NUM_DLCI - 1; i >= 0; i--) - if (gsm->dlci[i]) { + if (gsm->dlci[i]) gsm_dlci_release(gsm->dlci[i]); - gsm->dlci[i] = NULL; - } mutex_unlock(&gsm->mutex); /* Now wipe the queues */ tty_ldisc_flush(gsm->tty); diff -u linux-6.2.0/drivers/tty/serial/8250/8250_port.c linux-6.2.0/drivers/tty/serial/8250/8250_port.c --- linux-6.2.0/drivers/tty/serial/8250/8250_port.c +++ linux-6.2.0/drivers/tty/serial/8250/8250_port.c @@ -1952,7 +1952,10 @@ skip_rx = true; if (status & (UART_LSR_DR | UART_LSR_BI) && !skip_rx) { - if (irqd_is_wakeup_set(irq_get_irq_data(port->irq))) + struct irq_data *d; + + d = irq_get_irq_data(port->irq); + if (d && irqd_is_wakeup_set(d)) pm_wakeup_event(tport->tty->dev, 0); if (!up->dma || handle_rx_dma(up, iir)) status = serial8250_rx_chars(up, status); diff -u linux-6.2.0/drivers/tty/serial/sc16is7xx.c linux-6.2.0/drivers/tty/serial/sc16is7xx.c --- linux-6.2.0/drivers/tty/serial/sc16is7xx.c +++ linux-6.2.0/drivers/tty/serial/sc16is7xx.c @@ -236,7 +236,8 @@ /* IOControl register bits (Only 750/760) */ #define SC16IS7XX_IOCONTROL_LATCH_BIT (1 << 0) /* Enable input latching */ -#define SC16IS7XX_IOCONTROL_MODEM_BIT (1 << 1) /* Enable GPIO[7:4] as modem pins */ +#define SC16IS7XX_IOCONTROL_MODEM_A_BIT (1 << 1) /* Enable GPIO[7:4] as modem A pins */ +#define SC16IS7XX_IOCONTROL_MODEM_B_BIT (1 << 2) /* Enable GPIO[3:0] as modem B pins */ #define SC16IS7XX_IOCONTROL_SRESET_BIT (1 << 3) /* Software Reset */ /* EFCR register bits */ @@ -301,12 +302,12 @@ /* Misc definitions */ #define SC16IS7XX_FIFO_SIZE (64) #define SC16IS7XX_REG_SHIFT 2 +#define SC16IS7XX_GPIOS_PER_BANK 4 struct sc16is7xx_devtype { char name[10]; int nr_gpio; int nr_uart; - int has_mctrl; }; #define SC16IS7XX_RECONF_MD (1 << 0) @@ -336,7 +337,9 @@ struct clk *clk; #ifdef CONFIG_GPIOLIB struct gpio_chip gpio; + unsigned long gpio_valid_mask; #endif + u8 mctrl_mask; unsigned char buf[SC16IS7XX_FIFO_SIZE]; struct kthread_worker kworker; struct task_struct *kworker_task; @@ -447,35 +450,30 @@ .name = "SC16IS74X", .nr_gpio = 0, .nr_uart = 1, - .has_mctrl = 0, }; static const struct sc16is7xx_devtype sc16is750_devtype = { .name = "SC16IS750", - .nr_gpio = 4, + .nr_gpio = 8, .nr_uart = 1, - .has_mctrl = 1, }; static const struct sc16is7xx_devtype sc16is752_devtype = { .name = "SC16IS752", - .nr_gpio = 0, + .nr_gpio = 8, .nr_uart = 2, - .has_mctrl = 1, }; static const struct sc16is7xx_devtype sc16is760_devtype = { .name = "SC16IS760", - .nr_gpio = 4, + .nr_gpio = 8, .nr_uart = 1, - .has_mctrl = 1, }; static const struct sc16is7xx_devtype sc16is762_devtype = { .name = "SC16IS762", - .nr_gpio = 0, + .nr_gpio = 8, .nr_uart = 2, - .has_mctrl = 1, }; static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg) @@ -1357,8 +1355,98 @@ return 0; } + +static int sc16is7xx_gpio_init_valid_mask(struct gpio_chip *chip, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct sc16is7xx_port *s = gpiochip_get_data(chip); + + *valid_mask = s->gpio_valid_mask; + + return 0; +} + +static int sc16is7xx_setup_gpio_chip(struct sc16is7xx_port *s) +{ + struct device *dev = s->p[0].port.dev; + + if (!s->devtype->nr_gpio) + return 0; + + switch (s->mctrl_mask) { + case 0: + s->gpio_valid_mask = GENMASK(7, 0); + break; + case SC16IS7XX_IOCONTROL_MODEM_A_BIT: + s->gpio_valid_mask = GENMASK(3, 0); + break; + case SC16IS7XX_IOCONTROL_MODEM_B_BIT: + s->gpio_valid_mask = GENMASK(7, 4); + break; + default: + break; + } + + if (s->gpio_valid_mask == 0) + return 0; + + s->gpio.owner = THIS_MODULE; + s->gpio.parent = dev; + s->gpio.label = dev_name(dev); + s->gpio.init_valid_mask = sc16is7xx_gpio_init_valid_mask; + s->gpio.direction_input = sc16is7xx_gpio_direction_input; + s->gpio.get = sc16is7xx_gpio_get; + s->gpio.direction_output = sc16is7xx_gpio_direction_output; + s->gpio.set = sc16is7xx_gpio_set; + s->gpio.base = -1; + s->gpio.ngpio = s->devtype->nr_gpio; + s->gpio.can_sleep = 1; + + return gpiochip_add_data(&s->gpio, s); +} #endif +/* + * Configure ports designated to operate as modem control lines. + */ +static int sc16is7xx_setup_mctrl_ports(struct sc16is7xx_port *s) +{ + int i; + int ret; + int count; + u32 mctrl_port[2]; + struct device *dev = s->p[0].port.dev; + + count = device_property_count_u32(dev, "nxp,modem-control-line-ports"); + if (count < 0 || count > ARRAY_SIZE(mctrl_port)) + return 0; + + ret = device_property_read_u32_array(dev, "nxp,modem-control-line-ports", + mctrl_port, count); + if (ret) + return ret; + + s->mctrl_mask = 0; + + for (i = 0; i < count; i++) { + /* Use GPIO lines as modem control lines */ + if (mctrl_port[i] == 0) + s->mctrl_mask |= SC16IS7XX_IOCONTROL_MODEM_A_BIT; + else if (mctrl_port[i] == 1) + s->mctrl_mask |= SC16IS7XX_IOCONTROL_MODEM_B_BIT; + } + + if (s->mctrl_mask) + regmap_update_bits( + s->regmap, + SC16IS7XX_IOCONTROL_REG << SC16IS7XX_REG_SHIFT, + SC16IS7XX_IOCONTROL_MODEM_A_BIT | + SC16IS7XX_IOCONTROL_MODEM_B_BIT, s->mctrl_mask); + + return 0; +} + static const struct serial_rs485 sc16is7xx_rs485_supported = { .flags = SER_RS485_ENABLED | SER_RS485_RTS_AFTER_SEND, .delay_rts_before_send = 1, @@ -1471,12 +1559,6 @@ SC16IS7XX_EFCR_RXDISABLE_BIT | SC16IS7XX_EFCR_TXDISABLE_BIT); - /* Use GPIO lines as modem status registers */ - if (devtype->has_mctrl) - sc16is7xx_port_write(&s->p[i].port, - SC16IS7XX_IOCONTROL_REG, - SC16IS7XX_IOCONTROL_MODEM_BIT); - /* Initialize kthread work structs */ kthread_init_work(&s->p[i].tx_work, sc16is7xx_tx_proc); kthread_init_work(&s->p[i].reg_work, sc16is7xx_reg_proc); @@ -1514,23 +1596,14 @@ s->p[u].irda_mode = true; } + ret = sc16is7xx_setup_mctrl_ports(s); + if (ret) + goto out_ports; + #ifdef CONFIG_GPIOLIB - if (devtype->nr_gpio) { - /* Setup GPIO cotroller */ - s->gpio.owner = THIS_MODULE; - s->gpio.parent = dev; - s->gpio.label = dev_name(dev); - s->gpio.direction_input = sc16is7xx_gpio_direction_input; - s->gpio.get = sc16is7xx_gpio_get; - s->gpio.direction_output = sc16is7xx_gpio_direction_output; - s->gpio.set = sc16is7xx_gpio_set; - s->gpio.base = -1; - s->gpio.ngpio = devtype->nr_gpio; - s->gpio.can_sleep = 1; - ret = gpiochip_add_data(&s->gpio, s); - if (ret) - goto out_thread; - } + ret = sc16is7xx_setup_gpio_chip(s); + if (ret) + goto out_ports; #endif /* @@ -1553,10 +1626,8 @@ return 0; #ifdef CONFIG_GPIOLIB - if (devtype->nr_gpio) + if (s->gpio_valid_mask) gpiochip_remove(&s->gpio); - -out_thread: #endif out_ports: @@ -1579,7 +1650,7 @@ int i; #ifdef CONFIG_GPIOLIB - if (s->devtype->nr_gpio) + if (s->gpio_valid_mask) gpiochip_remove(&s->gpio); #endif diff -u linux-6.2.0/drivers/tty/serial/serial-tegra.c linux-6.2.0/drivers/tty/serial/serial-tegra.c --- linux-6.2.0/drivers/tty/serial/serial-tegra.c +++ linux-6.2.0/drivers/tty/serial/serial-tegra.c @@ -998,7 +998,11 @@ tup->ier_shadow = 0; tup->current_baud = 0; - clk_prepare_enable(tup->uart_clk); + ret = clk_prepare_enable(tup->uart_clk); + if (ret) { + dev_err(tup->uport.dev, "could not enable clk\n"); + return ret; + } /* Reset the UART controller to clear all previous status.*/ reset_control_assert(tup->rst); diff -u linux-6.2.0/drivers/ufs/core/ufshcd.c linux-6.2.0/drivers/ufs/core/ufshcd.c --- linux-6.2.0/drivers/ufs/core/ufshcd.c +++ linux-6.2.0/drivers/ufs/core/ufshcd.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -2256,7 +2257,11 @@ */ static inline bool ufshcd_ready_for_uic_cmd(struct ufs_hba *hba) { - return ufshcd_readl(hba, REG_CONTROLLER_STATUS) & UIC_COMMAND_READY; + u32 val; + int ret = read_poll_timeout(ufshcd_readl, val, val & UIC_COMMAND_READY, + 500, UIC_CMD_TIMEOUT * 1000, false, hba, + REG_CONTROLLER_STATUS); + return ret == 0 ? true : false; } /** @@ -2348,7 +2353,6 @@ bool completion) { lockdep_assert_held(&hba->uic_cmd_mutex); - lockdep_assert_held(hba->host->host_lock); if (!ufshcd_ready_for_uic_cmd(hba)) { dev_err(hba->dev, @@ -2375,7 +2379,6 @@ int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) { int ret; - unsigned long flags; if (hba->quirks & UFSHCD_QUIRK_BROKEN_UIC_CMD) return 0; @@ -2384,9 +2387,7 @@ mutex_lock(&hba->uic_cmd_mutex); ufshcd_add_delay_before_dme_cmd(hba); - spin_lock_irqsave(hba->host->host_lock, flags); ret = __ufshcd_send_uic_cmd(hba, uic_cmd, true); - spin_unlock_irqrestore(hba->host->host_lock, flags); if (!ret) ret = ufshcd_wait_for_uic_cmd(hba, uic_cmd); @@ -4078,8 +4079,8 @@ wmb(); reenable_intr = true; } - ret = __ufshcd_send_uic_cmd(hba, cmd, false); spin_unlock_irqrestore(hba->host->host_lock, flags); + ret = __ufshcd_send_uic_cmd(hba, cmd, false); if (ret) { dev_err(hba->dev, "pwr ctrl cmd 0x%x with mode 0x%x uic error %d\n", diff -u linux-6.2.0/drivers/usb/cdns3/cdnsp-pci.c linux-6.2.0/drivers/usb/cdns3/cdnsp-pci.c --- linux-6.2.0/drivers/usb/cdns3/cdnsp-pci.c +++ linux-6.2.0/drivers/usb/cdns3/cdnsp-pci.c @@ -208,8 +208,9 @@ int ret; spin_lock_irqsave(&cdns->lock, flags); - ret = cdns_resume(cdns, 1); + ret = cdns_resume(cdns); spin_unlock_irqrestore(&cdns->lock, flags); + cdns_set_active(cdns, 1); return ret; } diff -u linux-6.2.0/drivers/usb/chipidea/ci.h linux-6.2.0/drivers/usb/chipidea/ci.h --- linux-6.2.0/drivers/usb/chipidea/ci.h +++ linux-6.2.0/drivers/usb/chipidea/ci.h @@ -257,6 +257,7 @@ bool id_event; bool b_sess_valid_event; bool imx28_write_fix; + bool has_portsc_pec_bug; bool supports_runtime_pm; bool in_lpm; bool wakeup_int; diff -u linux-6.2.0/drivers/usb/chipidea/ci_hdrc_imx.c linux-6.2.0/drivers/usb/chipidea/ci_hdrc_imx.c --- linux-6.2.0/drivers/usb/chipidea/ci_hdrc_imx.c +++ linux-6.2.0/drivers/usb/chipidea/ci_hdrc_imx.c @@ -67,11 +67,13 @@ static const struct ci_hdrc_imx_platform_flag imx7ulp_usb_data = { .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | + CI_HDRC_HAS_PORTSC_PEC_MISSED | CI_HDRC_PMQOS, }; static const struct ci_hdrc_imx_platform_flag imx8ulp_usb_data = { - .flags = CI_HDRC_SUPPORTS_RUNTIME_PM, + .flags = CI_HDRC_SUPPORTS_RUNTIME_PM | + CI_HDRC_HAS_PORTSC_PEC_MISSED, }; static const struct of_device_id ci_hdrc_imx_dt_ids[] = { diff -u linux-6.2.0/drivers/usb/chipidea/core.c linux-6.2.0/drivers/usb/chipidea/core.c --- linux-6.2.0/drivers/usb/chipidea/core.c +++ linux-6.2.0/drivers/usb/chipidea/core.c @@ -1045,6 +1045,8 @@ CI_HDRC_IMX28_WRITE_FIX); ci->supports_runtime_pm = !!(ci->platdata->flags & CI_HDRC_SUPPORTS_RUNTIME_PM); + ci->has_portsc_pec_bug = !!(ci->platdata->flags & + CI_HDRC_HAS_PORTSC_PEC_MISSED); platform_set_drvdata(pdev, ci); ret = hw_device_init(ci, base); diff -u linux-6.2.0/drivers/usb/gadget/udc/core.c linux-6.2.0/drivers/usb/gadget/udc/core.c --- linux-6.2.0/drivers/usb/gadget/udc/core.c +++ linux-6.2.0/drivers/usb/gadget/udc/core.c @@ -40,6 +40,7 @@ * @allow_connect: Indicates whether UDC is allowed to be pulled up. * Set/cleared by gadget_(un)bind_driver() after gadget driver is bound or * unbound. + * @vbus_work: work routine to handle VBUS status change notifications. * @connect_lock: protects udc->started, gadget->connect, * gadget->allow_connect and gadget->deactivate. The routines * usb_gadget_connect_locked(), usb_gadget_disconnect_locked(), diff -u linux-6.2.0/drivers/usb/typec/tcpm/tcpm.c linux-6.2.0/drivers/usb/typec/tcpm/tcpm.c --- linux-6.2.0/drivers/usb/typec/tcpm/tcpm.c +++ linux-6.2.0/drivers/usb/typec/tcpm/tcpm.c @@ -1871,7 +1871,8 @@ } break; case ADEV_ATTENTION: - typec_altmode_attention(adev, p[1]); + if (typec_altmode_attention(adev, p[1])) + tcpm_log(port, "typec_altmode_attention no port partner altmode"); break; } } @@ -3929,6 +3930,29 @@ } } +static void tcpm_set_initial_svdm_version(struct tcpm_port *port) +{ + switch (port->negotiated_rev) { + case PD_REV30: + break; + /* + * 6.4.4.2.3 Structured VDM Version + * 2.0 states "At this time, there is only one version (1.0) defined. + * This field Shall be set to zero to indicate Version 1.0." + * 3.0 states "This field Shall be set to 01b to indicate Version 2.0." + * To ensure that we follow the Power Delivery revision we are currently + * operating on, downgrade the SVDM version to the highest one supported + * by the Power Delivery revision. + */ + case PD_REV20: + typec_partner_set_svdm_version(port->partner, SVDM_VER_1_0); + break; + default: + typec_partner_set_svdm_version(port->partner, SVDM_VER_1_0); + break; + } +} + static void run_state_machine(struct tcpm_port *port) { int ret; @@ -4153,10 +4177,12 @@ * For now, this driver only supports SOP for DISCOVER_IDENTITY, thus using * port->explicit_contract to decide whether to send the command. */ - if (port->explicit_contract) + if (port->explicit_contract) { + tcpm_set_initial_svdm_version(port); mod_send_discover_delayed_work(port, 0); - else + } else { port->send_discover = false; + } /* * 6.3.5 @@ -4439,10 +4465,12 @@ * For now, this driver only supports SOP for DISCOVER_IDENTITY, thus using * port->explicit_contract. */ - if (port->explicit_contract) + if (port->explicit_contract) { + tcpm_set_initial_svdm_version(port); mod_send_discover_delayed_work(port, 0); - else + } else { port->send_discover = false; + } power_supply_changed(port->psy); break; diff -u linux-6.2.0/drivers/vfio/vfio_iommu_type1.c linux-6.2.0/drivers/vfio/vfio_iommu_type1.c --- linux-6.2.0/drivers/vfio/vfio_iommu_type1.c +++ linux-6.2.0/drivers/vfio/vfio_iommu_type1.c @@ -2930,7 +2930,7 @@ static int vfio_iommu_migration_build_caps(struct vfio_iommu *iommu, struct vfio_info_cap *caps) { - struct vfio_iommu_type1_info_cap_migration cap_mig; + struct vfio_iommu_type1_info_cap_migration cap_mig = {}; cap_mig.header.id = VFIO_IOMMU_TYPE1_INFO_CAP_MIGRATION; cap_mig.header.version = 1; diff -u linux-6.2.0/drivers/virtio/virtio_ring.c linux-6.2.0/drivers/virtio/virtio_ring.c --- linux-6.2.0/drivers/virtio/virtio_ring.c +++ linux-6.2.0/drivers/virtio/virtio_ring.c @@ -1449,7 +1449,7 @@ } } - if (i < head) + if (i <= head) vq->packed.avail_wrap_counter ^= 1; /* We're using some buffers from the free list. */ diff -u linux-6.2.0/fs/attr.c linux-6.2.0/fs/attr.c --- linux-6.2.0/fs/attr.c +++ linux-6.2.0/fs/attr.c @@ -394,9 +394,25 @@ return error; if ((ia_valid & ATTR_MODE)) { - umode_t amode = attr->ia_mode; + /* + * Don't allow changing the mode of symlinks: + * + * (1) The vfs doesn't take the mode of symlinks into account + * during permission checking. + * (2) This has never worked correctly. Most major filesystems + * did return EOPNOTSUPP due to interactions with POSIX ACLs + * but did still updated the mode of the symlink. + * This inconsistency led system call wrapper providers such + * as libc to block changing the mode of symlinks with + * EOPNOTSUPP already. + * (3) To even do this in the first place one would have to use + * specific file descriptors and quite some effort. + */ + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + /* Flag setting protected by i_mutex */ - if (is_sxid(amode)) + if (is_sxid(attr->ia_mode)) inode->i_flags &= ~S_NOSEC; } diff -u linux-6.2.0/fs/btrfs/block-group.c linux-6.2.0/fs/btrfs/block-group.c --- linux-6.2.0/fs/btrfs/block-group.c +++ linux-6.2.0/fs/btrfs/block-group.c @@ -2894,8 +2894,16 @@ btrfs_mark_buffer_dirty(leaf); fail: btrfs_release_path(path); - /* We didn't update the block group item, need to revert @commit_used. */ - if (ret < 0) { + /* + * We didn't update the block group item, need to revert commit_used + * unless the block group item didn't exist yet - this is to prevent a + * race with a concurrent insertion of the block group item, with + * insert_block_group_item(), that happened just after we attempted to + * update. In that case we would reset commit_used to 0 just after the + * insertion set it to a value greater than 0 - if the block group later + * becomes with 0 used bytes, we would incorrectly skip its update. + */ + if (ret < 0 && ret != -ENOENT) { spin_lock(&cache->lock); cache->commit_used = old_commit_used; spin_unlock(&cache->lock); diff -u linux-6.2.0/fs/btrfs/disk-io.c linux-6.2.0/fs/btrfs/disk-io.c --- linux-6.2.0/fs/btrfs/disk-io.c +++ linux-6.2.0/fs/btrfs/disk-io.c @@ -939,6 +939,7 @@ struct folio *folio) { struct btrfs_fs_info *fs_info = btrfs_sb(mapping->host->i_sb); + struct btrfs_subpage_info *spi = fs_info->subpage_info; struct btrfs_subpage *subpage; struct extent_buffer *eb; int cur_bit = 0; @@ -952,18 +953,19 @@ btrfs_assert_tree_write_locked(eb); return filemap_dirty_folio(mapping, folio); } + + ASSERT(spi); subpage = folio_get_private(folio); - ASSERT(subpage->dirty_bitmap); - while (cur_bit < BTRFS_SUBPAGE_BITMAP_SIZE) { + for (cur_bit = spi->dirty_offset; + cur_bit < spi->dirty_offset + spi->bitmap_nr_bits; + cur_bit++) { unsigned long flags; u64 cur; - u16 tmp = (1 << cur_bit); spin_lock_irqsave(&subpage->lock, flags); - if (!(tmp & subpage->dirty_bitmap)) { + if (!test_bit(cur_bit, subpage->bitmaps)) { spin_unlock_irqrestore(&subpage->lock, flags); - cur_bit++; continue; } spin_unlock_irqrestore(&subpage->lock, flags); @@ -976,7 +978,7 @@ btrfs_assert_tree_write_locked(eb); free_extent_buffer(eb); - cur_bit += (fs_info->nodesize >> fs_info->sectorsize_bits); + cur_bit += (fs_info->nodesize >> fs_info->sectorsize_bits) - 1; } return filemap_dirty_folio(mapping, folio); } @@ -2808,21 +2810,18 @@ ret = -EINVAL; } - if (memcmp(fs_info->fs_devices->fsid, fs_info->super_copy->fsid, - BTRFS_FSID_SIZE)) { + if (memcmp(fs_info->fs_devices->fsid, sb->fsid, BTRFS_FSID_SIZE) != 0) { btrfs_err(fs_info, "superblock fsid doesn't match fsid of fs_devices: %pU != %pU", - fs_info->super_copy->fsid, fs_info->fs_devices->fsid); + sb->fsid, fs_info->fs_devices->fsid); ret = -EINVAL; } - if (btrfs_fs_incompat(fs_info, METADATA_UUID) && - memcmp(fs_info->fs_devices->metadata_uuid, - fs_info->super_copy->metadata_uuid, BTRFS_FSID_SIZE)) { + if (memcmp(fs_info->fs_devices->metadata_uuid, btrfs_sb_fsid_ptr(sb), + BTRFS_FSID_SIZE) != 0) { btrfs_err(fs_info, "superblock metadata_uuid doesn't match metadata uuid of fs_devices: %pU != %pU", - fs_info->super_copy->metadata_uuid, - fs_info->fs_devices->metadata_uuid); + btrfs_sb_fsid_ptr(sb), fs_info->fs_devices->metadata_uuid); ret = -EINVAL; } diff -u linux-6.2.0/fs/btrfs/extent-tree.c linux-6.2.0/fs/btrfs/extent-tree.c --- linux-6.2.0/fs/btrfs/extent-tree.c +++ linux-6.2.0/fs/btrfs/extent-tree.c @@ -870,6 +870,11 @@ err = -ENOENT; goto out; } else if (WARN_ON(ret)) { + btrfs_print_leaf(path->nodes[0]); + btrfs_err(fs_info, +"extent item not found for insert, bytenr %llu num_bytes %llu parent %llu root_objectid %llu owner %llu offset %llu", + bytenr, num_bytes, parent, root_objectid, owner, + offset); err = -EIO; goto out; } @@ -3817,7 +3822,8 @@ fs_info->data_reloc_bg == 0); if (block_group->ro || - test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags)) { + (!ffe_ctl->for_data_reloc && + test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags))) { ret = 1; goto out; } @@ -3860,8 +3866,26 @@ if (ffe_ctl->for_treelog && !fs_info->treelog_bg) fs_info->treelog_bg = block_group->start; - if (ffe_ctl->for_data_reloc && !fs_info->data_reloc_bg) - fs_info->data_reloc_bg = block_group->start; + if (ffe_ctl->for_data_reloc) { + if (!fs_info->data_reloc_bg) + fs_info->data_reloc_bg = block_group->start; + /* + * Do not allow allocations from this block group, unless it is + * for data relocation. Compared to increasing the ->ro, setting + * the ->zoned_data_reloc_ongoing flag still allows nocow + * writers to come in. See btrfs_inc_nocow_writers(). + * + * We need to disable an allocation to avoid an allocation of + * regular (non-relocation data) extent. With mix of relocation + * extents and regular extents, we can dispatch WRITE commands + * (for relocation extents) and ZONE APPEND commands (for + * regular extents) at the same time to the same zone, which + * easily break the write pointer. + * + * Also, this flag avoids this block group to be zone finished. + */ + set_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags); + } ffe_ctl->found_offset = start + block_group->alloc_offset; block_group->alloc_offset += num_bytes; @@ -3879,24 +3903,8 @@ out: if (ret && ffe_ctl->for_treelog) fs_info->treelog_bg = 0; - if (ret && ffe_ctl->for_data_reloc && - fs_info->data_reloc_bg == block_group->start) { - /* - * Do not allow further allocations from this block group. - * Compared to increasing the ->ro, setting the - * ->zoned_data_reloc_ongoing flag still allows nocow - * writers to come in. See btrfs_inc_nocow_writers(). - * - * We need to disable an allocation to avoid an allocation of - * regular (non-relocation data) extent. With mix of relocation - * extents and regular extents, we can dispatch WRITE commands - * (for relocation extents) and ZONE APPEND commands (for - * regular extents) at the same time to the same zone, which - * easily break the write pointer. - */ - set_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags); + if (ret && ffe_ctl->for_data_reloc) fs_info->data_reloc_bg = 0; - } spin_unlock(&fs_info->relocation_bg_lock); spin_unlock(&fs_info->treelog_bg_lock); spin_unlock(&block_group->lock); diff -u linux-6.2.0/fs/btrfs/extent_io.c linux-6.2.0/fs/btrfs/extent_io.c --- linux-6.2.0/fs/btrfs/extent_io.c +++ linux-6.2.0/fs/btrfs/extent_io.c @@ -5084,8 +5084,14 @@ char *dst = (char *)dstv; unsigned long i = get_eb_page_index(start); - if (check_eb_range(eb, start, len)) + if (check_eb_range(eb, start, len)) { + /* + * Invalid range hit, reset the memory, so callers won't get + * some random garbage for their uninitialzed memory. + */ + memset(dstv, 0, len); return; + } offset = get_eb_offset_in_page(eb, start); diff -u linux-6.2.0/fs/btrfs/inode.c linux-6.2.0/fs/btrfs/inode.c --- linux-6.2.0/fs/btrfs/inode.c +++ linux-6.2.0/fs/btrfs/inode.c @@ -3420,6 +3420,13 @@ btrfs_free_reserved_extent(fs_info, ordered_extent->disk_bytenr, ordered_extent->disk_num_bytes, 1); + /* + * Actually free the qgroup rsv which was released when + * the ordered extent was created. + */ + btrfs_qgroup_free_refroot(fs_info, inode->root->root_key.objectid, + ordered_extent->qgroup_rsv, + BTRFS_QGROUP_RSV_DATA); } } diff -u linux-6.2.0/fs/btrfs/ioctl.c linux-6.2.0/fs/btrfs/ioctl.c --- linux-6.2.0/fs/btrfs/ioctl.c +++ linux-6.2.0/fs/btrfs/ioctl.c @@ -1959,6 +1959,13 @@ goto out_put; } + /* + * We don't need the path anymore, so release it and + * avoid deadlocks and lockdep warnings in case + * btrfs_iget() needs to lookup the inode from its root + * btree and lock the same leaf. + */ + btrfs_release_path(path); temp_inode = btrfs_iget(sb, key2.objectid, root); if (IS_ERR(temp_inode)) { ret = PTR_ERR(temp_inode); @@ -1979,7 +1986,6 @@ goto out_put; } - btrfs_release_path(path); key.objectid = key.offset; key.offset = (u64)-1; dirid = key.objectid; diff -u linux-6.2.0/fs/btrfs/relocation.c linux-6.2.0/fs/btrfs/relocation.c --- linux-6.2.0/fs/btrfs/relocation.c +++ linux-6.2.0/fs/btrfs/relocation.c @@ -3006,9 +3006,6 @@ if (!page) return -ENOMEM; } - ret = set_page_extent_mapped(page); - if (ret < 0) - goto release_page; if (PageReadahead(page)) page_cache_async_readahead(inode->i_mapping, ra, NULL, @@ -3024,6 +3021,15 @@ } } + /* + * We could have lost page private when we dropped the lock to read the + * page above, make sure we set_page_extent_mapped here so we have any + * of the subpage blocksize stuff we need in place. + */ + ret = set_page_extent_mapped(page); + if (ret < 0) + goto release_page; + page_start = page_offset(page); page_end = page_start + PAGE_SIZE - 1; diff -u linux-6.2.0/fs/btrfs/space-info.c linux-6.2.0/fs/btrfs/space-info.c --- linux-6.2.0/fs/btrfs/space-info.c +++ linux-6.2.0/fs/btrfs/space-info.c @@ -389,11 +389,7 @@ return 0; used = btrfs_space_info_used(space_info, true); - if (test_bit(BTRFS_FS_ACTIVE_ZONE_TRACKING, &fs_info->flags) && - (space_info->flags & BTRFS_BLOCK_GROUP_METADATA)) - avail = 0; - else - avail = calc_available_free_space(fs_info, space_info, flush); + avail = calc_available_free_space(fs_info, space_info, flush); if (used + bytes < space_info->total_bytes + avail) return 1; diff -u linux-6.2.0/fs/btrfs/super.c linux-6.2.0/fs/btrfs/super.c --- linux-6.2.0/fs/btrfs/super.c +++ linux-6.2.0/fs/btrfs/super.c @@ -2115,7 +2115,7 @@ * calculated f_bavail. */ if (!mixed && block_rsv->space_info->full && - total_free_meta - thresh < block_rsv->size) + (total_free_meta < thresh || total_free_meta - thresh < block_rsv->size)) buf->f_bavail = 0; buf->f_type = BTRFS_SUPER_MAGIC; diff -u linux-6.2.0/fs/btrfs/transaction.c linux-6.2.0/fs/btrfs/transaction.c --- linux-6.2.0/fs/btrfs/transaction.c +++ linux-6.2.0/fs/btrfs/transaction.c @@ -292,10 +292,11 @@ spin_unlock(&fs_info->trans_lock); /* - * If we are ATTACH, we just want to catch the current transaction, - * and commit it. If there is no transaction, just return ENOENT. + * If we are ATTACH or TRANS_JOIN_NOSTART, we just want to catch the + * current transaction, and commit it. If there is no transaction, just + * return ENOENT. */ - if (type == TRANS_ATTACH) + if (type == TRANS_ATTACH || type == TRANS_JOIN_NOSTART) return -ENOENT; /* @@ -593,8 +594,13 @@ u64 delayed_refs_bytes = 0; qgroup_reserved = num_items * fs_info->nodesize; - ret = btrfs_qgroup_reserve_meta_pertrans(root, qgroup_reserved, - enforce_qgroups); + /* + * Use prealloc for now, as there might be a currently running + * transaction that could free this reserved space prematurely + * by committing. + */ + ret = btrfs_qgroup_reserve_meta_prealloc(root, qgroup_reserved, + enforce_qgroups, false); if (ret) return ERR_PTR(ret); @@ -706,6 +712,14 @@ h->reloc_reserved = reloc_reserved; } + /* + * Now that we have found a transaction to be a part of, convert the + * qgroup reservation from prealloc to pertrans. A different transaction + * can't race in and free our pertrans out from under us. + */ + if (qgroup_reserved) + btrfs_qgroup_convert_reserved_meta(root, qgroup_reserved); + got_it: if (!current->journal_info) current->journal_info = h; @@ -753,7 +767,7 @@ btrfs_block_rsv_release(fs_info, &fs_info->trans_block_rsv, num_bytes, NULL); reserve_fail: - btrfs_qgroup_free_meta_pertrans(root, qgroup_reserved); + btrfs_qgroup_free_meta_prealloc(root, qgroup_reserved); return ERR_PTR(ret); } diff -u linux-6.2.0/fs/btrfs/volumes.c linux-6.2.0/fs/btrfs/volumes.c --- linux-6.2.0/fs/btrfs/volumes.c +++ linux-6.2.0/fs/btrfs/volumes.c @@ -661,6 +661,14 @@ return -EINVAL; } +u8 *btrfs_sb_fsid_ptr(struct btrfs_super_block *sb) +{ + bool has_metadata_uuid = (btrfs_super_incompat_flags(sb) & + BTRFS_FEATURE_INCOMPAT_METADATA_UUID); + + return has_metadata_uuid ? sb->metadata_uuid : sb->fsid; +} + /* * Handle scanned device having its CHANGING_FSID_V2 flag set and the fs_devices * being created with a disk that has already completed its fsid change. Such diff -u linux-6.2.0/fs/btrfs/zoned.c linux-6.2.0/fs/btrfs/zoned.c --- linux-6.2.0/fs/btrfs/zoned.c +++ linux-6.2.0/fs/btrfs/zoned.c @@ -2013,6 +2013,10 @@ * and block_group->meta_write_pointer for metadata. */ if (!fully_written) { + if (test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags)) { + spin_unlock(&block_group->lock); + return -EAGAIN; + } spin_unlock(&block_group->lock); ret = btrfs_inc_block_group_ro(block_group, false); @@ -2041,7 +2045,9 @@ return 0; } - if (block_group->reserved) { + if (block_group->reserved || + test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, + &block_group->runtime_flags)) { spin_unlock(&block_group->lock); btrfs_dec_block_group_ro(block_group); return -EAGAIN; @@ -2272,7 +2278,10 @@ /* All relocation extents are written. */ if (block_group->start + block_group->alloc_offset == logical + length) { - /* Now, release this block group for further allocations. */ + /* + * Now, release this block group for further allocations and + * zone finish. + */ clear_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags); } @@ -2296,7 +2305,8 @@ spin_lock(&block_group->lock); if (block_group->reserved || block_group->alloc_offset == 0 || - (block_group->flags & BTRFS_BLOCK_GROUP_SYSTEM)) { + (block_group->flags & BTRFS_BLOCK_GROUP_SYSTEM) || + test_bit(BLOCK_GROUP_FLAG_ZONED_DATA_RELOC, &block_group->runtime_flags)) { spin_unlock(&block_group->lock); continue; } diff -u linux-6.2.0/fs/ceph/caps.c linux-6.2.0/fs/ceph/caps.c --- linux-6.2.0/fs/ceph/caps.c +++ linux-6.2.0/fs/ceph/caps.c @@ -4097,6 +4097,9 @@ dout("handle_caps from mds%d\n", session->s_mds); + if (!ceph_inc_mds_stopping_blocker(mdsc, session)) + return; + /* decode */ end = msg->front.iov_base + msg->front.iov_len; if (msg->front.iov_len < sizeof(*h)) @@ -4193,7 +4196,6 @@ vino.snap, inode); mutex_lock(&session->s_mutex); - inc_session_sequence(session); dout(" mds%d seq %lld cap seq %u\n", session->s_mds, session->s_seq, (unsigned)seq); @@ -4296,6 +4298,8 @@ done_unlocked: iput(inode); out: + ceph_dec_mds_stopping_blocker(mdsc); + ceph_put_string(extra_info.pool_ns); /* Defer closing the sessions after s_mutex lock being released */ diff -u linux-6.2.0/fs/ceph/mds_client.c linux-6.2.0/fs/ceph/mds_client.c --- linux-6.2.0/fs/ceph/mds_client.c +++ linux-6.2.0/fs/ceph/mds_client.c @@ -4546,6 +4546,9 @@ dout("handle_lease from mds%d\n", mds); + if (!ceph_inc_mds_stopping_blocker(mdsc, session)) + return; + /* decode */ if (msg->front.iov_len < sizeof(*h) + sizeof(u32)) goto bad; @@ -4564,8 +4567,6 @@ dname.len, dname.name); mutex_lock(&session->s_mutex); - inc_session_sequence(session); - if (!inode) { dout("handle_lease no inode %llx\n", vino.ino); goto release; @@ -4627,9 +4628,13 @@ out: mutex_unlock(&session->s_mutex); iput(inode); + + ceph_dec_mds_stopping_blocker(mdsc); return; bad: + ceph_dec_mds_stopping_blocker(mdsc); + pr_err("corrupt lease message\n"); ceph_msg_dump(msg); } @@ -4825,6 +4830,9 @@ } init_completion(&mdsc->safe_umount_waiters); + spin_lock_init(&mdsc->stopping_lock); + atomic_set(&mdsc->stopping_blockers, 0); + init_completion(&mdsc->stopping_waiter); init_waitqueue_head(&mdsc->session_close_wq); INIT_LIST_HEAD(&mdsc->waiting_for_map); mdsc->quotarealms_inodes = RB_ROOT; diff -u linux-6.2.0/fs/ceph/mds_client.h linux-6.2.0/fs/ceph/mds_client.h --- linux-6.2.0/fs/ceph/mds_client.h +++ linux-6.2.0/fs/ceph/mds_client.h @@ -381,8 +381,9 @@ }; enum { - CEPH_MDSC_STOPPING_BEGIN = 1, - CEPH_MDSC_STOPPING_FLUSHED = 2, + CEPH_MDSC_STOPPING_BEGIN = 1, + CEPH_MDSC_STOPPING_FLUSHING = 2, + CEPH_MDSC_STOPPING_FLUSHED = 3, }; /* @@ -401,7 +402,11 @@ struct ceph_mds_session **sessions; /* NULL for mds if no session */ atomic_t num_sessions; int max_sessions; /* len of sessions array */ - int stopping; /* true if shutting down */ + + spinlock_t stopping_lock; /* protect snap_empty */ + int stopping; /* the stage of shutting down */ + atomic_t stopping_blockers; + struct completion stopping_waiter; atomic64_t quotarealms_count; /* # realms with quota */ /* diff -u linux-6.2.0/fs/ceph/snap.c linux-6.2.0/fs/ceph/snap.c --- linux-6.2.0/fs/ceph/snap.c +++ linux-6.2.0/fs/ceph/snap.c @@ -1012,6 +1012,9 @@ int locked_rwsem = 0; bool close_sessions = false; + if (!ceph_inc_mds_stopping_blocker(mdsc, session)) + return; + /* decode */ if (msg->front.iov_len < sizeof(*h)) goto bad; @@ -1027,10 +1030,6 @@ dout("%s from mds%d op %s split %llx tracelen %d\n", __func__, mds, ceph_snap_op_name(op), split, trace_len); - mutex_lock(&session->s_mutex); - inc_session_sequence(session); - mutex_unlock(&session->s_mutex); - down_write(&mdsc->snap_rwsem); locked_rwsem = 1; @@ -1148,6 +1147,7 @@ up_write(&mdsc->snap_rwsem); flush_snaps(mdsc); + ceph_dec_mds_stopping_blocker(mdsc); return; bad: @@ -1157,6 +1157,8 @@ if (locked_rwsem) up_write(&mdsc->snap_rwsem); + ceph_dec_mds_stopping_blocker(mdsc); + if (close_sessions) ceph_mdsc_close_sessions(mdsc); return; diff -u linux-6.2.0/fs/ceph/super.c linux-6.2.0/fs/ceph/super.c --- linux-6.2.0/fs/ceph/super.c +++ linux-6.2.0/fs/ceph/super.c @@ -1365,25 +1365,90 @@ return -ENOMEM; } +/* + * Return true if it successfully increases the blocker counter, + * or false if the mdsc is in stopping and flushed state. + */ +static bool __inc_stopping_blocker(struct ceph_mds_client *mdsc) +{ + spin_lock(&mdsc->stopping_lock); + if (mdsc->stopping >= CEPH_MDSC_STOPPING_FLUSHING) { + spin_unlock(&mdsc->stopping_lock); + return false; + } + atomic_inc(&mdsc->stopping_blockers); + spin_unlock(&mdsc->stopping_lock); + return true; +} + +static void __dec_stopping_blocker(struct ceph_mds_client *mdsc) +{ + spin_lock(&mdsc->stopping_lock); + if (!atomic_dec_return(&mdsc->stopping_blockers) && + mdsc->stopping >= CEPH_MDSC_STOPPING_FLUSHING) + complete_all(&mdsc->stopping_waiter); + spin_unlock(&mdsc->stopping_lock); +} + +/* For metadata IO requests */ +bool ceph_inc_mds_stopping_blocker(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session) +{ + mutex_lock(&session->s_mutex); + inc_session_sequence(session); + mutex_unlock(&session->s_mutex); + + return __inc_stopping_blocker(mdsc); +} + +void ceph_dec_mds_stopping_blocker(struct ceph_mds_client *mdsc) +{ + __dec_stopping_blocker(mdsc); +} + static void ceph_kill_sb(struct super_block *s) { struct ceph_fs_client *fsc = ceph_sb_to_client(s); + struct ceph_mds_client *mdsc = fsc->mdsc; + bool wait; dout("kill_sb %p\n", s); - ceph_mdsc_pre_umount(fsc->mdsc); + ceph_mdsc_pre_umount(mdsc); flush_fs_workqueues(fsc); /* * Though the kill_anon_super() will finally trigger the - * sync_filesystem() anyway, we still need to do it here - * and then bump the stage of shutdown to stop the work - * queue as earlier as possible. + * sync_filesystem() anyway, we still need to do it here and + * then bump the stage of shutdown. This will allow us to + * drop any further message, which will increase the inodes' + * i_count reference counters but makes no sense any more, + * from MDSs. + * + * Without this when evicting the inodes it may fail in the + * kill_anon_super(), which will trigger a warning when + * destroying the fscrypt keyring and then possibly trigger + * a further crash in ceph module when the iput() tries to + * evict the inodes later. */ sync_filesystem(s); - fsc->mdsc->stopping = CEPH_MDSC_STOPPING_FLUSHED; + spin_lock(&mdsc->stopping_lock); + mdsc->stopping = CEPH_MDSC_STOPPING_FLUSHING; + wait = !!atomic_read(&mdsc->stopping_blockers); + spin_unlock(&mdsc->stopping_lock); + + if (wait && atomic_read(&mdsc->stopping_blockers)) { + long timeleft = wait_for_completion_killable_timeout( + &mdsc->stopping_waiter, + fsc->client->options->mount_timeout); + if (!timeleft) /* timed out */ + pr_warn("umount timed out, %ld\n", timeleft); + else if (timeleft < 0) /* killed */ + pr_warn("umount was killed, %ld\n", timeleft); + } + mdsc->stopping = CEPH_MDSC_STOPPING_FLUSHED; kill_anon_super(s); fsc->client->extra_mon_dispatch = NULL; diff -u linux-6.2.0/fs/ceph/super.h linux-6.2.0/fs/ceph/super.h --- linux-6.2.0/fs/ceph/super.h +++ linux-6.2.0/fs/ceph/super.h @@ -1376,2 +1376,5 @@ +bool ceph_inc_mds_stopping_blocker(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session); +void ceph_dec_mds_stopping_blocker(struct ceph_mds_client *mdsc); #endif /* _FS_CEPH_SUPER_H */ diff -u linux-6.2.0/fs/dlm/plock.c linux-6.2.0/fs/dlm/plock.c --- linux-6.2.0/fs/dlm/plock.c +++ linux-6.2.0/fs/dlm/plock.c @@ -455,7 +455,8 @@ } } else { list_for_each_entry(iter, &recv_list, list) { - if (!iter->info.wait) { + if (!iter->info.wait && + iter->info.fsid == info.fsid) { op = iter; break; } @@ -467,8 +468,7 @@ if (info.wait) WARN_ON(op->info.optype != DLM_PLOCK_OP_LOCK); else - WARN_ON(op->info.fsid != info.fsid || - op->info.number != info.number || + WARN_ON(op->info.number != info.number || op->info.owner != info.owner || op->info.optype != info.optype); diff -u linux-6.2.0/fs/erofs/decompressor_lzma.c linux-6.2.0/fs/erofs/decompressor_lzma.c --- linux-6.2.0/fs/erofs/decompressor_lzma.c +++ linux-6.2.0/fs/erofs/decompressor_lzma.c @@ -217,9 +217,12 @@ strm->buf.out_size = min_t(u32, outlen, PAGE_SIZE - pageofs); outlen -= strm->buf.out_size; - if (!rq->out[no] && rq->fillgaps) /* deduped */ + if (!rq->out[no] && rq->fillgaps) { /* deduped */ rq->out[no] = erofs_allocpage(pagepool, GFP_KERNEL | __GFP_NOFAIL); + set_page_private(rq->out[no], + Z_EROFS_SHORTLIVED_PAGE); + } if (rq->out[no]) strm->buf.out = kmap(rq->out[no]) + pageofs; pageofs = 0; diff -u linux-6.2.0/fs/ext4/balloc.c linux-6.2.0/fs/ext4/balloc.c --- linux-6.2.0/fs/ext4/balloc.c +++ linux-6.2.0/fs/ext4/balloc.c @@ -910,11 +910,11 @@ } /* - * This function returns the number of file system metadata clusters at + * This function returns the number of file system metadata blocks at * the beginning of a block group, including the reserved gdt blocks. */ -static unsigned ext4_num_base_meta_clusters(struct super_block *sb, - ext4_group_t block_group) +unsigned int ext4_num_base_meta_blocks(struct super_block *sb, + ext4_group_t block_group) { struct ext4_sb_info *sbi = EXT4_SB(sb); unsigned num; @@ -932,8 +932,15 @@ } else { /* For META_BG_BLOCK_GROUPS */ num += ext4_bg_num_gdb(sb, block_group); } - return EXT4_NUM_B2C(sbi, num); + return num; } + +static unsigned int ext4_num_base_meta_clusters(struct super_block *sb, + ext4_group_t block_group) +{ + return EXT4_NUM_B2C(EXT4_SB(sb), ext4_num_base_meta_blocks(sb, block_group)); +} + /** * ext4_inode_to_goal_block - return a hint for block allocation * @inode: inode for block allocation diff -u linux-6.2.0/fs/ext4/ext4.h linux-6.2.0/fs/ext4/ext4.h --- linux-6.2.0/fs/ext4/ext4.h +++ linux-6.2.0/fs/ext4/ext4.h @@ -3121,6 +3121,8 @@ extern void ext4_mark_group_bitmap_corrupted(struct super_block *sb, ext4_group_t block_group, unsigned int flags); +extern unsigned int ext4_num_base_meta_blocks(struct super_block *sb, + ext4_group_t block_group); extern __printf(7, 8) void __ext4_error(struct super_block *, const char *, unsigned int, bool, diff -u linux-6.2.0/fs/ext4/mballoc.c linux-6.2.0/fs/ext4/mballoc.c --- linux-6.2.0/fs/ext4/mballoc.c +++ linux-6.2.0/fs/ext4/mballoc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /* @@ -966,8 +967,9 @@ * Return next linear group for allocation. If linear traversal should not be * performed, this function just returns the same group */ -static int -next_linear_group(struct ext4_allocation_context *ac, int group, int ngroups) +static ext4_group_t +next_linear_group(struct ext4_allocation_context *ac, ext4_group_t group, + ext4_group_t ngroups) { if (!should_optimize_scan(ac)) goto inc_and_return; @@ -2401,7 +2403,7 @@ BUG_ON(cr < 0 || cr >= 4); - if (unlikely(EXT4_MB_GRP_BBITMAP_CORRUPT(grp) || !grp)) + if (unlikely(!grp || EXT4_MB_GRP_BBITMAP_CORRUPT(grp))) return false; free = grp->bb_free; @@ -6413,6 +6415,21 @@ return ret; } +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); +} + +static bool ext4_trim_interrupted(void) +{ + return fatal_signal_pending(current) || freezing(current); +} + static int ext4_try_to_trim_range(struct super_block *sb, struct ext4_buddy *e4b, ext4_grpblk_t start, ext4_grpblk_t max, ext4_grpblk_t minblocks) @@ -6420,11 +6437,13 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) { ext4_grpblk_t next, count, free_count; + bool set_trimmed = false; void *bitmap; bitmap = e4b->bd_bitmap; - start = (e4b->bd_info->bb_first_free > start) ? - e4b->bd_info->bb_first_free : start; + if (start == 0 && max >= ext4_last_grp_cluster(sb, e4b->bd_group)) + set_trimmed = true; + start = max(e4b->bd_info->bb_first_free, start); count = 0; free_count = 0; @@ -6438,16 +6457,14 @@ int ret = ext4_trim_extent(sb, start, next - start, e4b); if (ret && ret != -EOPNOTSUPP) - break; + return count; count += next - start; } free_count += next - start; start = next + 1; - if (fatal_signal_pending(current)) { - count = -ERESTARTSYS; - break; - } + if (ext4_trim_interrupted()) + return count; if (need_resched()) { ext4_unlock_group(sb, e4b->bd_group); @@ -6459,6 +6476,9 @@ break; } + if (set_trimmed) + EXT4_MB_GRP_SET_TRIMMED(e4b->bd_info); + return count; } @@ -6469,7 +6489,6 @@ * @start: first group block to examine * @max: last group block to examine * @minblocks: minimum extent block count - * @set_trimmed: set the trimmed flag if at least one block is trimmed * * ext4_trim_all_free walks through group's block bitmap searching for free * extents. When the free extent is found, mark it as used in group buddy @@ -6479,7 +6498,7 @@ static ext4_grpblk_t ext4_trim_all_free(struct super_block *sb, ext4_group_t group, ext4_grpblk_t start, ext4_grpblk_t max, - ext4_grpblk_t minblocks, bool set_trimmed) + ext4_grpblk_t minblocks) { struct ext4_buddy e4b; int ret; @@ -6496,13 +6515,10 @@ ext4_lock_group(sb, group); if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) || - minblocks < EXT4_SB(sb)->s_last_trim_minblks) { + minblocks < EXT4_SB(sb)->s_last_trim_minblks) ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks); - if (ret >= 0 && set_trimmed) - EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info); - } else { + else ret = 0; - } ext4_unlock_group(sb, group); ext4_mb_unload_buddy(&e4b); @@ -6535,7 +6551,6 @@ ext4_fsblk_t first_data_blk = le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block); ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es); - bool whole_group, eof = false; int ret = 0; start = range->start >> sb->s_blocksize_bits; @@ -6554,10 +6569,8 @@ if (minlen > EXT4_CLUSTERS_PER_GROUP(sb)) goto out; } - if (end >= max_blks - 1) { + if (end >= max_blks - 1) end = max_blks - 1; - eof = true; - } if (end <= first_data_blk) goto out; if (start < first_data_blk) @@ -6571,9 +6584,10 @@ /* end now represents the last cluster to discard in this group */ end = EXT4_CLUSTERS_PER_GROUP(sb) - 1; - whole_group = true; for (group = first_group; group <= last_group; group++) { + if (ext4_trim_interrupted()) + break; grp = ext4_get_group_info(sb, group); if (!grp) continue; @@ -6590,13 +6604,11 @@ * change it for the last group, note that last_cluster is * already computed earlier by ext4_get_group_no_and_offset() */ - if (group == last_group) { + if (group == last_group) end = last_cluster; - whole_group = eof ? true : end == EXT4_CLUSTERS_PER_GROUP(sb) - 1; - } if (grp->bb_free >= minlen) { cnt = ext4_trim_all_free(sb, group, first_cluster, - end, minlen, whole_group); + end, minlen); if (cnt < 0) { ret = cnt; break; @@ -6641,8 +6653,7 @@ ext4_lock_group(sb, group); - start = (e4b.bd_info->bb_first_free > start) ? - e4b.bd_info->bb_first_free : start; + start = max(e4b.bd_info->bb_first_free, start); if (end >= EXT4_CLUSTERS_PER_GROUP(sb)) end = EXT4_CLUSTERS_PER_GROUP(sb) - 1; diff -u linux-6.2.0/fs/ext4/namei.c linux-6.2.0/fs/ext4/namei.c --- linux-6.2.0/fs/ext4/namei.c +++ linux-6.2.0/fs/ext4/namei.c @@ -343,17 +343,17 @@ struct buffer_head *bh) { struct ext4_dir_entry_tail *t; + int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); #ifdef PARANOID struct ext4_dir_entry *d, *top; d = (struct ext4_dir_entry *)bh->b_data; top = (struct ext4_dir_entry *)(bh->b_data + - (EXT4_BLOCK_SIZE(inode->i_sb) - - sizeof(struct ext4_dir_entry_tail))); - while (d < top && d->rec_len) + (blocksize - sizeof(struct ext4_dir_entry_tail))); + while (d < top && ext4_rec_len_from_disk(d->rec_len, blocksize)) d = (struct ext4_dir_entry *)(((void *)d) + - le16_to_cpu(d->rec_len)); + ext4_rec_len_from_disk(d->rec_len, blocksize)); if (d != top) return NULL; @@ -364,7 +364,8 @@ #endif if (t->det_reserved_zero1 || - le16_to_cpu(t->det_rec_len) != sizeof(struct ext4_dir_entry_tail) || + (ext4_rec_len_from_disk(t->det_rec_len, blocksize) != + sizeof(struct ext4_dir_entry_tail)) || t->det_reserved_zero2 || t->det_reserved_ft != EXT4_FT_DIR_CSUM) return NULL; @@ -445,13 +446,14 @@ struct ext4_dir_entry *dp; struct dx_root_info *root; int count_offset; + int blocksize = EXT4_BLOCK_SIZE(inode->i_sb); + unsigned int rlen = ext4_rec_len_from_disk(dirent->rec_len, blocksize); - if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb)) + if (rlen == blocksize) count_offset = 8; - else if (le16_to_cpu(dirent->rec_len) == 12) { + else if (rlen == 12) { dp = (struct ext4_dir_entry *)(((void *)dirent) + 12); - if (le16_to_cpu(dp->rec_len) != - EXT4_BLOCK_SIZE(inode->i_sb) - 12) + if (ext4_rec_len_from_disk(dp->rec_len, blocksize) != blocksize - 12) return NULL; root = (struct dx_root_info *)(((void *)dp + 12)); if (root->reserved_zero || @@ -1315,6 +1317,7 @@ unsigned int buflen = bh->b_size; char *base = bh->b_data; struct dx_hash_info h = *hinfo; + int blocksize = EXT4_BLOCK_SIZE(dir->i_sb); if (ext4_has_metadata_csum(dir->i_sb)) buflen -= sizeof(struct ext4_dir_entry_tail); @@ -1335,11 +1338,12 @@ map_tail--; map_tail->hash = h.hash; map_tail->offs = ((char *) de - base)>>2; - map_tail->size = le16_to_cpu(de->rec_len); + map_tail->size = ext4_rec_len_from_disk(de->rec_len, + blocksize); count++; cond_resched(); } - de = ext4_next_entry(de, dir->i_sb->s_blocksize); + de = ext4_next_entry(de, blocksize); } return count; } @@ -2799,6 +2803,7 @@ return err; } drop_nlink(inode); + ext4_mark_inode_dirty(handle, inode); ext4_orphan_add(handle, inode); unlock_new_inode(inode); return err; @@ -3436,6 +3441,7 @@ err_drop_inode: clear_nlink(inode); + ext4_mark_inode_dirty(handle, inode); ext4_orphan_add(handle, inode); unlock_new_inode(inode); if (handle) @@ -4021,6 +4027,7 @@ ext4_resetent(handle, &old, old.inode->i_ino, old_file_type); drop_nlink(whiteout); + ext4_mark_inode_dirty(handle, whiteout); ext4_orphan_add(handle, whiteout); } unlock_new_inode(whiteout); diff -u linux-6.2.0/fs/f2fs/data.c linux-6.2.0/fs/f2fs/data.c --- linux-6.2.0/fs/f2fs/data.c +++ linux-6.2.0/fs/f2fs/data.c @@ -1344,18 +1344,14 @@ { struct address_space *mapping = inode->i_mapping; struct page *page; -repeat: + page = f2fs_get_read_data_page(inode, index, 0, for_write, NULL); if (IS_ERR(page)) return page; /* wait for read completion */ lock_page(page); - if (unlikely(page->mapping != mapping)) { - f2fs_put_page(page, 1); - goto repeat; - } - if (unlikely(!PageUptodate(page))) { + if (unlikely(page->mapping != mapping || !PageUptodate(page))) { f2fs_put_page(page, 1); return ERR_PTR(-EIO); } diff -u linux-6.2.0/fs/f2fs/f2fs.h linux-6.2.0/fs/f2fs/f2fs.h --- linux-6.2.0/fs/f2fs/f2fs.h +++ linux-6.2.0/fs/f2fs/f2fs.h @@ -2189,15 +2189,6 @@ return down_read_trylock(&sem->internal_rwsem); } -#ifdef CONFIG_DEBUG_LOCK_ALLOC -static inline void f2fs_down_read_nested(struct f2fs_rwsem *sem, int subclass) -{ - down_read_nested(&sem->internal_rwsem, subclass); -} -#else -#define f2fs_down_read_nested(sem, subclass) f2fs_down_read(sem) -#endif - static inline void f2fs_up_read(struct f2fs_rwsem *sem) { up_read(&sem->internal_rwsem); @@ -2208,6 +2199,21 @@ down_write(&sem->internal_rwsem); } +#ifdef CONFIG_DEBUG_LOCK_ALLOC +static inline void f2fs_down_read_nested(struct f2fs_rwsem *sem, int subclass) +{ + down_read_nested(&sem->internal_rwsem, subclass); +} + +static inline void f2fs_down_write_nested(struct f2fs_rwsem *sem, int subclass) +{ + down_write_nested(&sem->internal_rwsem, subclass); +} +#else +#define f2fs_down_read_nested(sem, subclass) f2fs_down_read(sem) +#define f2fs_down_write_nested(sem, subclass) f2fs_down_write(sem) +#endif + static inline int f2fs_down_write_trylock(struct f2fs_rwsem *sem) { return down_write_trylock(&sem->internal_rwsem); @@ -4494,7 +4500,8 @@ static inline bool f2fs_may_compress(struct inode *inode) { if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) || - f2fs_is_atomic_file(inode) || f2fs_has_inline_data(inode)) + f2fs_is_atomic_file(inode) || f2fs_has_inline_data(inode) || + f2fs_is_mmap_file(inode)) return false; return S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode); } diff -u linux-6.2.0/fs/f2fs/file.c linux-6.2.0/fs/f2fs/file.c --- linux-6.2.0/fs/f2fs/file.c +++ linux-6.2.0/fs/f2fs/file.c @@ -530,7 +530,11 @@ file_accessed(file); vma->vm_ops = &f2fs_file_vm_ops; + + f2fs_down_read(&F2FS_I(inode)->i_sem); set_inode_flag(inode, FI_MMAP_FILE); + f2fs_up_read(&F2FS_I(inode)->i_sem); + return 0; } @@ -1929,12 +1933,19 @@ int err = f2fs_convert_inline_inode(inode); if (err) return err; - if (!f2fs_may_compress(inode)) - return -EINVAL; - if (S_ISREG(inode->i_mode) && F2FS_HAS_BLOCKS(inode)) + + f2fs_down_write(&F2FS_I(inode)->i_sem); + if (!f2fs_may_compress(inode) || + (S_ISREG(inode->i_mode) && + F2FS_HAS_BLOCKS(inode))) { + f2fs_up_write(&F2FS_I(inode)->i_sem); return -EINVAL; - if (set_compress_context(inode)) - return -EOPNOTSUPP; + } + err = set_compress_context(inode); + f2fs_up_write(&F2FS_I(inode)->i_sem); + + if (err) + return err; } } @@ -3967,6 +3978,7 @@ file_start_write(filp); inode_lock(inode); + f2fs_down_write(&F2FS_I(inode)->i_sem); if (f2fs_is_mmap_file(inode) || get_dirty_pages(inode)) { ret = -EBUSY; goto out; @@ -3986,6 +3998,7 @@ f2fs_warn(sbi, "compression algorithm is successfully set, " "but current kernel doesn't support this algorithm."); out: + f2fs_up_write(&F2FS_I(inode)->i_sem); inode_unlock(inode); file_end_write(filp); diff -u linux-6.2.0/fs/f2fs/inline.c linux-6.2.0/fs/f2fs/inline.c --- linux-6.2.0/fs/f2fs/inline.c +++ linux-6.2.0/fs/f2fs/inline.c @@ -642,7 +642,8 @@ } if (inode) { - f2fs_down_write(&F2FS_I(inode)->i_sem); + f2fs_down_write_nested(&F2FS_I(inode)->i_sem, + SINGLE_DEPTH_NESTING); page = f2fs_init_inode_metadata(inode, dir, fname, ipage); if (IS_ERR(page)) { err = PTR_ERR(page); diff -u linux-6.2.0/fs/f2fs/inode.c linux-6.2.0/fs/f2fs/inode.c --- linux-6.2.0/fs/f2fs/inode.c +++ linux-6.2.0/fs/f2fs/inode.c @@ -413,6 +413,12 @@ fi->i_inline_xattr_size = 0; } + if (!sanity_check_inode(inode, node_page)) { + f2fs_put_page(node_page, 1); + f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); + return -EFSCORRUPTED; + } + /* check data exist */ if (f2fs_has_inline_data(inode) && !f2fs_exist_data(inode)) __recover_inline_status(inode, node_page); @@ -476,12 +482,6 @@ f2fs_init_read_extent_tree(inode, node_page); f2fs_init_age_extent_tree(inode); - if (!sanity_check_inode(inode, node_page)) { - f2fs_put_page(node_page, 1); - f2fs_handle_error(sbi, ERROR_CORRUPTED_INODE); - return -EFSCORRUPTED; - } - f2fs_put_page(node_page, 1); stat_inc_inline_xattr(inode); diff -u linux-6.2.0/fs/f2fs/segment.c linux-6.2.0/fs/f2fs/segment.c --- linux-6.2.0/fs/f2fs/segment.c +++ linux-6.2.0/fs/f2fs/segment.c @@ -205,6 +205,8 @@ f2fs_i_size_write(inode, fi->original_i_size); fi->original_i_size = 0; } + /* avoid stale dirty inode during eviction */ + sync_inode_metadata(inode, 0); } static int __replace_atomic_write_block(struct inode *inode, pgoff_t index, diff -u linux-6.2.0/fs/f2fs/super.c linux-6.2.0/fs/f2fs/super.c --- linux-6.2.0/fs/f2fs/super.c +++ linux-6.2.0/fs/f2fs/super.c @@ -864,11 +864,6 @@ if (!name) return -ENOMEM; if (!strcmp(name, "adaptive")) { - if (f2fs_sb_has_blkzoned(sbi)) { - f2fs_warn(sbi, "adaptive mode is not allowed with zoned block device feature"); - kfree(name); - return -EINVAL; - } F2FS_OPTION(sbi).fs_mode = FS_MODE_ADAPTIVE; } else if (!strcmp(name, "lfs")) { F2FS_OPTION(sbi).fs_mode = FS_MODE_LFS; @@ -1294,19 +1289,23 @@ * zone alignment optimization. This is optional for host-aware * devices, but mandatory for host-managed zoned block devices. */ -#ifndef CONFIG_BLK_DEV_ZONED - if (f2fs_sb_has_blkzoned(sbi)) { - f2fs_err(sbi, "Zoned block device support is not enabled"); - return -EINVAL; - } -#endif if (f2fs_sb_has_blkzoned(sbi)) { +#ifdef CONFIG_BLK_DEV_ZONED if (F2FS_OPTION(sbi).discard_unit != DISCARD_UNIT_SECTION) { f2fs_info(sbi, "Zoned block device doesn't need small discard, set discard_unit=section by default"); F2FS_OPTION(sbi).discard_unit = DISCARD_UNIT_SECTION; } + + if (F2FS_OPTION(sbi).fs_mode != FS_MODE_LFS) { + f2fs_info(sbi, "Only lfs mode is allowed with zoned block device feature"); + return -EINVAL; + } +#else + f2fs_err(sbi, "Zoned block device support is not enabled"); + return -EINVAL; +#endif } #ifdef CONFIG_F2FS_FS_COMPRESSION diff -u linux-6.2.0/fs/fs_context.c linux-6.2.0/fs/fs_context.c --- linux-6.2.0/fs/fs_context.c +++ linux-6.2.0/fs/fs_context.c @@ -315,10 +315,31 @@ } EXPORT_SYMBOL(fs_context_for_reconfigure); +/** + * fs_context_for_submount: allocate a new fs_context for a submount + * @type: file_system_type of the new context + * @reference: reference dentry from which to copy relevant info + * + * Allocate a new fs_context suitable for a submount. This also ensures that + * the fc->security object is inherited from @reference (if needed). + */ struct fs_context *fs_context_for_submount(struct file_system_type *type, struct dentry *reference) { - return alloc_fs_context(type, reference, 0, 0, FS_CONTEXT_FOR_SUBMOUNT); + struct fs_context *fc; + int ret; + + fc = alloc_fs_context(type, reference, 0, 0, FS_CONTEXT_FOR_SUBMOUNT); + if (IS_ERR(fc)) + return fc; + + ret = security_fs_context_submount(fc, reference->d_sb); + if (ret) { + put_fs_context(fc); + return ERR_PTR(ret); + } + + return fc; } EXPORT_SYMBOL(fs_context_for_submount); diff -u linux-6.2.0/fs/gfs2/aops.c linux-6.2.0/fs/gfs2/aops.c --- linux-6.2.0/fs/gfs2/aops.c +++ linux-6.2.0/fs/gfs2/aops.c @@ -182,13 +182,13 @@ int ret; /* - * Even if we didn't write any pages here, we might still be holding + * Even if we didn't write enough pages here, we might still be holding * dirty pages in the ail. We forcibly flush the ail because we don't * want balance_dirty_pages() to loop indefinitely trying to write out * pages held in the ail that it can't find. */ ret = iomap_writepages(mapping, wbc, &wpc, &gfs2_writeback_ops); - if (ret == 0) + if (ret == 0 && wbc->nr_to_write > 0) set_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags); return ret; } diff -u linux-6.2.0/fs/jbd2/checkpoint.c linux-6.2.0/fs/jbd2/checkpoint.c --- linux-6.2.0/fs/jbd2/checkpoint.c +++ linux-6.2.0/fs/jbd2/checkpoint.c @@ -349,6 +349,8 @@ /* Checkpoint list management */ +enum shrink_type {SHRINK_DESTROY, SHRINK_BUSY_STOP, SHRINK_BUSY_SKIP}; + /* * journal_shrink_one_cp_list * @@ -360,7 +362,8 @@ * Called with j_list_lock held. */ static unsigned long journal_shrink_one_cp_list(struct journal_head *jh, - bool destroy, bool *released) + enum shrink_type type, + bool *released) { struct journal_head *last_jh; struct journal_head *next_jh = jh; @@ -376,12 +379,15 @@ jh = next_jh; next_jh = jh->b_cpnext; - if (destroy) { + if (type == SHRINK_DESTROY) { ret = __jbd2_journal_remove_checkpoint(jh); } else { ret = jbd2_journal_try_remove_checkpoint(jh); - if (ret < 0) - continue; + if (ret < 0) { + if (type == SHRINK_BUSY_SKIP) + continue; + break; + } } nr_freed++; @@ -445,7 +451,7 @@ tid = transaction->t_tid; freed = journal_shrink_one_cp_list(transaction->t_checkpoint_list, - false, &released); + SHRINK_BUSY_SKIP, &released); nr_freed += freed; (*nr_to_scan) -= min(*nr_to_scan, freed); if (*nr_to_scan == 0) @@ -485,19 +491,21 @@ void __jbd2_journal_clean_checkpoint_list(journal_t *journal, bool destroy) { transaction_t *transaction, *last_transaction, *next_transaction; + enum shrink_type type; bool released; transaction = journal->j_checkpoint_transactions; if (!transaction) return; + type = destroy ? SHRINK_DESTROY : SHRINK_BUSY_STOP; last_transaction = transaction->t_cpprev; next_transaction = transaction; do { transaction = next_transaction; next_transaction = transaction->t_cpnext; journal_shrink_one_cp_list(transaction->t_checkpoint_list, - destroy, &released); + type, &released); /* * This function only frees up some memory if possible so we * dont have an obligation to finish processing. Bail out if @@ -631,6 +639,8 @@ { struct buffer_head *bh = jh2bh(jh); + if (jh->b_transaction) + return -EBUSY; if (!trylock_buffer(bh)) return -EBUSY; if (buffer_dirty(bh)) { diff -u linux-6.2.0/fs/jfs/jfs_dmap.c linux-6.2.0/fs/jfs/jfs_dmap.c --- linux-6.2.0/fs/jfs/jfs_dmap.c +++ linux-6.2.0/fs/jfs/jfs_dmap.c @@ -269,6 +269,7 @@ /* free the memory for the in-memory bmap. */ kfree(bmp); + JFS_SBI(ipbmap->i_sb)->bmap = NULL; return (0); } diff -u linux-6.2.0/fs/locks.c linux-6.2.0/fs/locks.c --- linux-6.2.0/fs/locks.c +++ linux-6.2.0/fs/locks.c @@ -1300,6 +1300,7 @@ out: spin_unlock(&ctx->flc_lock); percpu_up_read(&file_rwsem); + trace_posix_lock_inode(inode, request, error); /* * Free any unused locks. */ @@ -1308,7 +1309,6 @@ if (new_fl2) locks_free_lock(new_fl2); locks_dispose_list(&dispose); - trace_posix_lock_inode(inode, request, error); return error; } diff -u linux-6.2.0/fs/namei.c linux-6.2.0/fs/namei.c --- linux-6.2.0/fs/namei.c +++ linux-6.2.0/fs/namei.c @@ -187,7 +187,7 @@ } } - result->refcnt = 1; + atomic_set(&result->refcnt, 1); /* The empty path is special. */ if (unlikely(!len)) { if (empty) @@ -248,7 +248,7 @@ memcpy((char *)result->name, filename, len); result->uptr = NULL; result->aname = NULL; - result->refcnt = 1; + atomic_set(&result->refcnt, 1); audit_getname(result); return result; @@ -259,9 +259,10 @@ if (IS_ERR(name)) return; - BUG_ON(name->refcnt <= 0); + if (WARN_ON_ONCE(!atomic_read(&name->refcnt))) + return; - if (--name->refcnt > 0) + if (!atomic_dec_and_test(&name->refcnt)) return; if (name->name != name->iname) { @@ -2859,7 +2860,7 @@ dput(path->dentry); path->dentry = parent; child = d_hash_and_lookup(parent, &this); - if (!child) + if (IS_ERR_OR_NULL(child)) return -ENOENT; path->dentry = child; diff -u linux-6.2.0/fs/nfs/direct.c linux-6.2.0/fs/nfs/direct.c --- linux-6.2.0/fs/nfs/direct.c +++ linux-6.2.0/fs/nfs/direct.c @@ -474,13 +474,31 @@ return result; } +static void nfs_direct_add_page_head(struct list_head *list, + struct nfs_page *req) +{ + struct nfs_page *head = req->wb_head; + + if (!list_empty(&head->wb_list) || !nfs_lock_request(head)) + return; + if (!list_empty(&head->wb_list)) { + nfs_unlock_request(head); + return; + } + list_add(&head->wb_list, list); + kref_get(&head->wb_kref); + kref_get(&head->wb_kref); +} + static void nfs_direct_join_group(struct list_head *list, struct inode *inode) { struct nfs_page *req, *subreq; list_for_each_entry(req, list, wb_list) { - if (req->wb_head != req) + if (req->wb_head != req) { + nfs_direct_add_page_head(&req->wb_list, req); continue; + } subreq = req->wb_this_page; if (subreq == req) continue; @@ -739,18 +757,23 @@ static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr) { struct nfs_direct_req *dreq = hdr->dreq; + struct nfs_page *req; + struct nfs_commit_info cinfo; trace_nfs_direct_write_reschedule_io(dreq); + nfs_init_cinfo_from_dreq(&cinfo, dreq); spin_lock(&dreq->lock); - if (dreq->error == 0) { + if (dreq->error == 0) dreq->flags = NFS_ODIRECT_RESCHED_WRITES; - /* fake unstable write to let common nfs resend pages */ - hdr->verf.committed = NFS_UNSTABLE; - hdr->good_bytes = hdr->args.offset + hdr->args.count - - hdr->io_start; - } + set_bit(NFS_IOHDR_REDO, &hdr->flags); spin_unlock(&dreq->lock); + while (!list_empty(&hdr->pages)) { + req = nfs_list_entry(hdr->pages.next); + nfs_list_remove_request(req); + nfs_unlock_request(req); + nfs_mark_request_commit(req, NULL, &cinfo, 0); + } } static const struct nfs_pgio_completion_ops nfs_direct_write_completion_ops = { diff -u linux-6.2.0/fs/nfs/internal.h linux-6.2.0/fs/nfs/internal.h --- linux-6.2.0/fs/nfs/internal.h +++ linux-6.2.0/fs/nfs/internal.h @@ -486,6 +486,7 @@ extern void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio, struct inode *inode, bool force_mds, const struct nfs_pgio_completion_ops *compl_ops); +extern bool nfs_read_alloc_scratch(struct nfs_pgio_header *hdr, size_t size); extern void nfs_read_prepare(struct rpc_task *task, void *calldata); extern void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio); diff -u linux-6.2.0/fs/nfs/nfs42proc.c linux-6.2.0/fs/nfs/nfs42proc.c --- linux-6.2.0/fs/nfs/nfs42proc.c +++ linux-6.2.0/fs/nfs/nfs42proc.c @@ -470,8 +470,9 @@ continue; } break; - } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && !args.sync) { - args.sync = true; + } else if (err == -NFS4ERR_OFFLOAD_NO_REQS && + args.sync != res.synchronous) { + args.sync = res.synchronous; dst_exception.retry = 1; continue; } else if ((err == -ESTALE || diff -u linux-6.2.0/fs/nfs/nfs4proc.c linux-6.2.0/fs/nfs/nfs4proc.c --- linux-6.2.0/fs/nfs/nfs4proc.c +++ linux-6.2.0/fs/nfs/nfs4proc.c @@ -2702,8 +2702,12 @@ return status; } if (!(o_res->f_attr->valid & NFS_ATTR_FATTR)) { + struct nfs_fh *fh = &o_res->fh; + nfs4_sequence_free_slot(&o_res->seq_res); - nfs4_proc_getattr(server, &o_res->fh, o_res->f_attr, NULL); + if (o_arg->claim == NFS4_OPEN_CLAIM_FH) + fh = NFS_FH(d_inode(data->dentry)); + nfs4_proc_getattr(server, fh, o_res->f_attr, NULL); } return 0; } @@ -5452,17 +5456,21 @@ } #if defined CONFIG_NFS_V4_2 && defined CONFIG_NFS_V4_2_READ_PLUS -static void nfs42_read_plus_support(struct nfs_pgio_header *hdr, +static bool nfs42_read_plus_support(struct nfs_pgio_header *hdr, struct rpc_message *msg) { /* Note: We don't use READ_PLUS with pNFS yet */ - if (nfs_server_capable(hdr->inode, NFS_CAP_READ_PLUS) && !hdr->ds_clp) + if (nfs_server_capable(hdr->inode, NFS_CAP_READ_PLUS) && !hdr->ds_clp) { msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ_PLUS]; + return nfs_read_alloc_scratch(hdr, READ_PLUS_SCRATCH_SIZE); + } + return false; } #else -static void nfs42_read_plus_support(struct nfs_pgio_header *hdr, +static bool nfs42_read_plus_support(struct nfs_pgio_header *hdr, struct rpc_message *msg) { + return false; } #endif /* CONFIG_NFS_V4_2 */ @@ -5472,8 +5480,8 @@ hdr->timestamp = jiffies; if (!hdr->pgio_done_cb) hdr->pgio_done_cb = nfs4_read_done_cb; - msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; - nfs42_read_plus_support(hdr, msg); + if (!nfs42_read_plus_support(hdr, msg)) + msg->rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_READ]; nfs4_init_sequence(&hdr->args.seq_args, &hdr->res.seq_res, 0, 0); } @@ -7144,7 +7152,6 @@ { struct nfs4_lockdata *data = calldata; struct nfs4_lock_state *lsp = data->lsp; - struct nfs_server *server = NFS_SERVER(d_inode(data->ctx->dentry)); if (!nfs4_sequence_done(task, &data->res.seq_res)) return; @@ -7152,7 +7159,8 @@ data->rpc_status = task->tk_status; switch (task->tk_status) { case 0: - renew_lease(server, data->timestamp); + renew_lease(NFS_SERVER(d_inode(data->ctx->dentry)), + data->timestamp); if (data->arg.new_lock && !data->cancelled) { data->fl.fl_flags &= ~(FL_SLEEP | FL_ACCESS); if (locks_lock_inode_wait(lsp->ls_state->inode, &data->fl) < 0) @@ -7180,8 +7188,6 @@ if (!nfs4_stateid_match(&data->arg.open_stateid, &lsp->ls_state->open_stateid)) goto out_restart; - else if (nfs4_async_handle_error(task, server, lsp->ls_state, NULL) == -EAGAIN) - goto out_restart; } else if (!nfs4_stateid_match(&data->arg.lock_stateid, &lsp->ls_stateid)) goto out_restart; @@ -8785,6 +8791,8 @@ #ifdef CONFIG_NFS_V4_1_MIGRATION calldata->args.flags |= EXCHGID4_FLAG_SUPP_MOVED_MIGR; #endif + if (test_bit(NFS_CS_DS, &clp->cl_flags)) + calldata->args.flags |= EXCHGID4_FLAG_USE_PNFS_DS; msg.rpc_argp = &calldata->args; msg.rpc_resp = &calldata->res; task_setup_data.callback_data = calldata; @@ -8862,6 +8870,8 @@ /* Save the EXCHANGE_ID verifier session trunk tests */ memcpy(clp->cl_confirm.data, argp->verifier.data, sizeof(clp->cl_confirm.data)); + if (resp->flags & EXCHGID4_FLAG_USE_PNFS_DS) + set_bit(NFS_CS_DS, &clp->cl_flags); out: trace_nfs4_exchange_id(clp, status); rpc_put_task(task); @@ -10612,7 +10622,9 @@ */ struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; - nfs4_schedule_state_manager(clp); + set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state); + clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); + wake_up_var(&clp->cl_state); } static const struct inode_operations nfs4_dir_inode_operations = { diff -u linux-6.2.0/fs/nfs/nfs4state.c linux-6.2.0/fs/nfs/nfs4state.c --- linux-6.2.0/fs/nfs/nfs4state.c +++ linux-6.2.0/fs/nfs/nfs4state.c @@ -1209,17 +1209,23 @@ { struct task_struct *task; char buf[INET6_ADDRSTRLEN + sizeof("-manager") + 1]; - struct rpc_clnt *cl = clp->cl_rpcclient; - - while (cl != cl->cl_parent) - cl = cl->cl_parent; + struct rpc_clnt *clnt = clp->cl_rpcclient; + bool swapon = false; set_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state); - if (test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state) != 0) { - wake_up_var(&clp->cl_state); - return; + + if (atomic_read(&clnt->cl_swapper)) { + swapon = !test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, + &clp->cl_state); + if (!swapon) { + wake_up_var(&clp->cl_state); + return; + } } - set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state); + + if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) + return; + __module_get(THIS_MODULE); refcount_inc(&clp->cl_count); @@ -1236,8 +1242,9 @@ __func__, PTR_ERR(task)); if (!nfs_client_init_is_complete(clp)) nfs_mark_client_ready(clp, PTR_ERR(task)); + if (swapon) + clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); nfs4_clear_state_manager_bit(clp); - clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); nfs_put_client(clp); module_put(THIS_MODULE); } @@ -2704,6 +2711,13 @@ nfs4_end_drain_session(clp); nfs4_clear_state_manager_bit(clp); + if (test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) && + !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, + &clp->cl_state)) { + memflags = memalloc_nofs_save(); + continue; + } + if (!test_and_set_bit(NFS4CLNT_RECALL_RUNNING, &clp->cl_state)) { if (test_and_clear_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state)) { nfs_client_return_marked_delegations(clp); @@ -2742,22 +2756,25 @@ allow_signal(SIGKILL); again: - set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state); nfs4_state_manager(clp); - if (atomic_read(&cl->cl_swapper)) { + + if (test_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state) && + !test_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) { wait_var_event_interruptible(&clp->cl_state, test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state)); - if (atomic_read(&cl->cl_swapper) && - test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state)) + if (!atomic_read(&cl->cl_swapper)) + clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); + if (refcount_read(&clp->cl_count) > 1 && !signalled() && + !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) goto again; /* Either no longer a swapper, or were signalled */ + clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); } - clear_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state); if (refcount_read(&clp->cl_count) > 1 && !signalled() && test_bit(NFS4CLNT_RUN_MANAGER, &clp->cl_state) && - !test_and_set_bit(NFS4CLNT_MANAGER_AVAILABLE, &clp->cl_state)) + !test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state)) goto again; nfs_put_client(clp); diff -u linux-6.2.0/fs/nfs/read.c linux-6.2.0/fs/nfs/read.c --- linux-6.2.0/fs/nfs/read.c +++ linux-6.2.0/fs/nfs/read.c @@ -47,6 +47,8 @@ static void nfs_readhdr_free(struct nfs_pgio_header *rhdr) { + if (rhdr->res.scratch != NULL) + kfree(rhdr->res.scratch); kmem_cache_free(nfs_rdata_cachep, rhdr); } @@ -109,6 +111,14 @@ } EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds); +bool nfs_read_alloc_scratch(struct nfs_pgio_header *hdr, size_t size) +{ + WARN_ON(hdr->res.scratch != NULL); + hdr->res.scratch = kmalloc(size, GFP_KERNEL); + return hdr->res.scratch != NULL; +} +EXPORT_SYMBOL_GPL(nfs_read_alloc_scratch); + static void nfs_readpage_release(struct nfs_page *req, int error) { struct inode *inode = d_inode(nfs_req_openctx(req)->dentry); diff -u linux-6.2.0/fs/nfsd/nfs4proc.c linux-6.2.0/fs/nfsd/nfs4proc.c --- linux-6.2.0/fs/nfsd/nfs4proc.c +++ linux-6.2.0/fs/nfsd/nfs4proc.c @@ -1024,8 +1024,8 @@ rename->rn_tname, rename->rn_tnamelen); if (status) return status; - set_change_info(&rename->rn_sinfo, &cstate->current_fh); - set_change_info(&rename->rn_tinfo, &cstate->save_fh); + set_change_info(&rename->rn_sinfo, &cstate->save_fh); + set_change_info(&rename->rn_tinfo, &cstate->current_fh); return nfs_ok; } diff -u linux-6.2.0/fs/nfsd/nfs4xdr.c linux-6.2.0/fs/nfsd/nfs4xdr.c --- linux-6.2.0/fs/nfsd/nfs4xdr.c +++ linux-6.2.0/fs/nfsd/nfs4xdr.c @@ -4678,20 +4678,17 @@ *p++ = cpu_to_be32(gdev->gd_layout_type); - /* If maxcount is 0 then just update notifications */ - if (gdev->gd_maxcount != 0) { - ops = nfsd4_layout_ops[gdev->gd_layout_type]; - nfserr = ops->encode_getdeviceinfo(xdr, gdev); - if (nfserr) { - /* - * We don't bother to burden the layout drivers with - * enforcing gd_maxcount, just tell the client to - * come back with a bigger buffer if it's not enough. - */ - if (xdr->buf->len + 4 > gdev->gd_maxcount) - goto toosmall; - return nfserr; - } + ops = nfsd4_layout_ops[gdev->gd_layout_type]; + nfserr = ops->encode_getdeviceinfo(xdr, gdev); + if (nfserr) { + /* + * We don't bother to burden the layout drivers with + * enforcing gd_maxcount, just tell the client to + * come back with a bigger buffer if it's not enough. + */ + if (xdr->buf->len + 4 > gdev->gd_maxcount) + goto toosmall; + return nfserr; } if (gdev->gd_notify_types) { diff -u linux-6.2.0/fs/ocfs2/namei.c linux-6.2.0/fs/ocfs2/namei.c --- linux-6.2.0/fs/ocfs2/namei.c +++ linux-6.2.0/fs/ocfs2/namei.c @@ -1535,6 +1535,10 @@ status = ocfs2_add_entry(handle, new_dentry, old_inode, OCFS2_I(old_inode)->ip_blkno, new_dir_bh, &target_insert); + if (status < 0) { + mlog_errno(status); + goto bail; + } } old_inode->i_ctime = current_time(old_inode); diff -u linux-6.2.0/fs/overlayfs/copy_up.c linux-6.2.0/fs/overlayfs/copy_up.c --- linux-6.2.0/fs/overlayfs/copy_up.c +++ linux-6.2.0/fs/overlayfs/copy_up.c @@ -618,7 +618,8 @@ if (err) return err; - if (inode->i_flags & OVL_COPY_I_FLAGS_MASK) { + if (inode->i_flags & OVL_COPY_I_FLAGS_MASK && + (S_ISREG(c->stat.mode) || S_ISDIR(c->stat.mode))) { /* * Copy the fileattr inode flags that are the source of already * copied i_flags diff -u linux-6.2.0/fs/overlayfs/file.c linux-6.2.0/fs/overlayfs/file.c --- linux-6.2.0/fs/overlayfs/file.c +++ linux-6.2.0/fs/overlayfs/file.c @@ -19,7 +19,6 @@ struct kiocb iocb; refcount_t ref; struct kiocb *orig_iocb; - struct fd fd; }; static struct kmem_cache *ovl_aio_request_cachep; @@ -260,7 +259,7 @@ static inline void ovl_aio_put(struct ovl_aio_req *aio_req) { if (refcount_dec_and_test(&aio_req->ref)) { - fdput(aio_req->fd); + fput(aio_req->iocb.ki_filp); kmem_cache_free(ovl_aio_request_cachep, aio_req); } } @@ -325,10 +324,9 @@ if (!aio_req) goto out; - aio_req->fd = real; real.flags = 0; aio_req->orig_iocb = iocb; - kiocb_clone(&aio_req->iocb, iocb, real.file); + kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); aio_req->iocb.ki_complete = ovl_aio_rw_complete; refcount_set(&aio_req->ref, 2); ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter); @@ -396,10 +394,9 @@ /* Pacify lockdep, same trick as done in aio_write() */ __sb_writers_release(file_inode(real.file)->i_sb, SB_FREEZE_WRITE); - aio_req->fd = real; real.flags = 0; aio_req->orig_iocb = iocb; - kiocb_clone(&aio_req->iocb, iocb, real.file); + kiocb_clone(&aio_req->iocb, iocb, get_file(real.file)); aio_req->iocb.ki_flags = ifl; aio_req->iocb.ki_complete = ovl_aio_rw_complete; refcount_set(&aio_req->ref, 2); diff -u linux-6.2.0/fs/overlayfs/super.c linux-6.2.0/fs/overlayfs/super.c --- linux-6.2.0/fs/overlayfs/super.c +++ linux-6.2.0/fs/overlayfs/super.c @@ -2070,7 +2070,7 @@ ovl_trusted_xattr_handlers; sb->s_fs_info = ofs; sb->s_flags |= SB_POSIXACL; - sb->s_iflags |= SB_I_SKIP_SYNC; + sb->s_iflags |= SB_I_SKIP_SYNC | SB_I_IMA_UNVERIFIABLE_SIGNATURE; err = -ENOMEM; root_dentry = ovl_get_root(sb, upperpath.dentry, oe); diff -u linux-6.2.0/fs/proc/base.c linux-6.2.0/fs/proc/base.c --- linux-6.2.0/fs/proc/base.c +++ linux-6.2.0/fs/proc/base.c @@ -3582,7 +3582,8 @@ } static const struct inode_operations proc_tid_comm_inode_operations = { - .permission = proc_tid_comm_permission, + .setattr = proc_setattr, + .permission = proc_tid_comm_permission, }; /* diff -u linux-6.2.0/fs/proc/internal.h linux-6.2.0/fs/proc/internal.h --- linux-6.2.0/fs/proc/internal.h +++ linux-6.2.0/fs/proc/internal.h @@ -289,9 +289,7 @@ struct inode *inode; struct task_struct *task; struct mm_struct *mm; -#ifdef CONFIG_MMU struct vma_iterator iter; -#endif #ifdef CONFIG_NUMA struct mempolicy *task_mempolicy; #endif diff -u linux-6.2.0/fs/proc/task_nommu.c linux-6.2.0/fs/proc/task_nommu.c --- linux-6.2.0/fs/proc/task_nommu.c +++ linux-6.2.0/fs/proc/task_nommu.c @@ -191,15 +191,28 @@ return nommu_vma_show(m, _p); } -static void *m_start(struct seq_file *m, loff_t *pos) +static struct vm_area_struct *proc_get_vma(struct proc_maps_private *priv, + loff_t *ppos) +{ + struct vm_area_struct *vma = vma_next(&priv->iter); + + if (vma) { + *ppos = vma->vm_start; + } else { + *ppos = -1UL; + } + + return vma; +} + +static void *m_start(struct seq_file *m, loff_t *ppos) { struct proc_maps_private *priv = m->private; + unsigned long last_addr = *ppos; struct mm_struct *mm; - struct vm_area_struct *vma; - unsigned long addr = *pos; - /* See m_next(). Zero at the start or after lseek. */ - if (addr == -1UL) + /* See proc_get_vma(). Zero at the start or after lseek. */ + if (last_addr == -1UL) return NULL; /* pin the task and mm whilst we play with them */ @@ -208,44 +221,41 @@ return ERR_PTR(-ESRCH); mm = priv->mm; - if (!mm || !mmget_not_zero(mm)) + if (!mm || !mmget_not_zero(mm)) { + put_task_struct(priv->task); + priv->task = NULL; return NULL; + } if (mmap_read_lock_killable(mm)) { mmput(mm); + put_task_struct(priv->task); + priv->task = NULL; return ERR_PTR(-EINTR); } - /* start the next element from addr */ - vma = find_vma(mm, addr); - if (vma) - return vma; + vma_iter_init(&priv->iter, mm, last_addr); - mmap_read_unlock(mm); - mmput(mm); - return NULL; + return proc_get_vma(priv, ppos); } -static void m_stop(struct seq_file *m, void *_vml) +static void m_stop(struct seq_file *m, void *v) { struct proc_maps_private *priv = m->private; + struct mm_struct *mm = priv->mm; - if (!IS_ERR_OR_NULL(_vml)) { - mmap_read_unlock(priv->mm); - mmput(priv->mm); - } - if (priv->task) { - put_task_struct(priv->task); - priv->task = NULL; - } + if (!priv->task) + return; + + mmap_read_unlock(mm); + mmput(mm); + put_task_struct(priv->task); + priv->task = NULL; } -static void *m_next(struct seq_file *m, void *_p, loff_t *pos) +static void *m_next(struct seq_file *m, void *_p, loff_t *ppos) { - struct vm_area_struct *vma = _p; - - *pos = vma->vm_end; - return find_vma(vma->vm_mm, vma->vm_end); + return proc_get_vma(m->private, ppos); } static const struct seq_operations proc_pid_maps_ops = { diff -u linux-6.2.0/fs/pstore/ram_core.c linux-6.2.0/fs/pstore/ram_core.c --- linux-6.2.0/fs/pstore/ram_core.c +++ linux-6.2.0/fs/pstore/ram_core.c @@ -519,7 +519,7 @@ sig ^= PERSISTENT_RAM_SIG; if (prz->buffer->sig == sig) { - if (buffer_size(prz) == 0) { + if (buffer_size(prz) == 0 && buffer_start(prz) == 0) { pr_debug("found existing empty buffer\n"); return 0; } diff -u linux-6.2.0/fs/quota/dquot.c linux-6.2.0/fs/quota/dquot.c --- linux-6.2.0/fs/quota/dquot.c +++ linux-6.2.0/fs/quota/dquot.c @@ -225,13 +225,22 @@ /* * Dquot List Management: - * The quota code uses four lists for dquot management: the inuse_list, - * free_dquots, dqi_dirty_list, and dquot_hash[] array. A single dquot - * structure may be on some of those lists, depending on its current state. + * The quota code uses five lists for dquot management: the inuse_list, + * releasing_dquots, free_dquots, dqi_dirty_list, and dquot_hash[] array. + * A single dquot structure may be on some of those lists, depending on + * its current state. * * All dquots are placed to the end of inuse_list when first created, and this * list is used for invalidate operation, which must look at every dquot. * + * When the last reference of a dquot will be dropped, the dquot will be + * added to releasing_dquots. We'd then queue work item which would call + * synchronize_srcu() and after that perform the final cleanup of all the + * dquots on the list. Both releasing_dquots and free_dquots use the + * dq_free list_head in the dquot struct. When a dquot is removed from + * releasing_dquots, a reference count is always subtracted, and if + * dq_count == 0 at that point, the dquot will be added to the free_dquots. + * * Unused dquots (dq_count == 0) are added to the free_dquots list when freed, * and this list is searched whenever we need an available dquot. Dquots are * removed from the list as soon as they are used again, and @@ -250,6 +259,7 @@ static LIST_HEAD(inuse_list); static LIST_HEAD(free_dquots); +static LIST_HEAD(releasing_dquots); static unsigned int dq_hash_bits, dq_hash_mask; static struct hlist_head *dquot_hash; @@ -260,6 +270,9 @@ static qsize_t __inode_get_rsv_space(struct inode *inode); static int __dquot_initialize(struct inode *inode, int type); +static void quota_release_workfn(struct work_struct *work); +static DECLARE_DELAYED_WORK(quota_release_work, quota_release_workfn); + static inline unsigned int hashfn(const struct super_block *sb, struct kqid qid) { @@ -305,12 +318,18 @@ dqstats_inc(DQST_FREE_DQUOTS); } +static inline void put_releasing_dquots(struct dquot *dquot) +{ + list_add_tail(&dquot->dq_free, &releasing_dquots); +} + static inline void remove_free_dquot(struct dquot *dquot) { if (list_empty(&dquot->dq_free)) return; list_del_init(&dquot->dq_free); - dqstats_dec(DQST_FREE_DQUOTS); + if (!atomic_read(&dquot->dq_count)) + dqstats_dec(DQST_FREE_DQUOTS); } static inline void put_inuse(struct dquot *dquot) @@ -336,6 +355,11 @@ mutex_unlock(&dquot->dq_lock); } +static inline int dquot_active(struct dquot *dquot) +{ + return test_bit(DQ_ACTIVE_B, &dquot->dq_flags); +} + static inline int dquot_dirty(struct dquot *dquot) { return test_bit(DQ_MOD_B, &dquot->dq_flags); @@ -351,14 +375,14 @@ { int ret = 1; - if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + if (!dquot_active(dquot)) return 0; if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NOLIST_DIRTY) return test_and_set_bit(DQ_MOD_B, &dquot->dq_flags); /* If quota is dirty already, we don't have to acquire dq_list_lock */ - if (test_bit(DQ_MOD_B, &dquot->dq_flags)) + if (dquot_dirty(dquot)) return 1; spin_lock(&dq_list_lock); @@ -440,7 +464,7 @@ smp_mb__before_atomic(); set_bit(DQ_READ_B, &dquot->dq_flags); /* Instantiate dquot if needed */ - if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) { + if (!dquot_active(dquot) && !dquot->dq_off) { ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot); /* Write the info if needed */ if (info_dirty(&dqopt->info[dquot->dq_id.type])) { @@ -482,7 +506,7 @@ goto out_lock; /* Inactive dquot can be only if there was error during read/init * => we have better not writing it */ - if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + if (dquot_active(dquot)) ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot); else ret = -EIO; @@ -547,6 +571,8 @@ struct dquot *dquot, *tmp; restart: + flush_delayed_work("a_release_work); + spin_lock(&dq_list_lock); list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) { if (dquot->dq_sb != sb) @@ -555,6 +581,12 @@ continue; /* Wait for dquot users */ if (atomic_read(&dquot->dq_count)) { + /* dquot in releasing_dquots, flush and retry */ + if (!list_empty(&dquot->dq_free)) { + spin_unlock(&dq_list_lock); + goto restart; + } + atomic_inc(&dquot->dq_count); spin_unlock(&dq_list_lock); /* @@ -597,7 +629,7 @@ spin_lock(&dq_list_lock); list_for_each_entry(dquot, &inuse_list, dq_inuse) { - if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) + if (!dquot_active(dquot)) continue; if (dquot->dq_sb != sb) continue; @@ -612,7 +644,7 @@ * outstanding call and recheck the DQ_ACTIVE_B after that. */ wait_on_dquot(dquot); - if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { + if (dquot_active(dquot)) { ret = fn(dquot, priv); if (ret < 0) goto out; @@ -628,6 +660,18 @@ } EXPORT_SYMBOL(dquot_scan_active); +static inline int dquot_write_dquot(struct dquot *dquot) +{ + int ret = dquot->dq_sb->dq_op->write_dquot(dquot); + if (ret < 0) { + quota_error(dquot->dq_sb, "Can't write quota structure " + "(error %d). Quota may get out of sync!", ret); + /* Clear dirty bit anyway to avoid infinite loop. */ + clear_dquot_dirty(dquot); + } + return ret; +} + /* Write all dquot structures to quota files */ int dquot_writeback_dquots(struct super_block *sb, int type) { @@ -651,23 +695,16 @@ dquot = list_first_entry(&dirty, struct dquot, dq_dirty); - WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)); + WARN_ON(!dquot_active(dquot)); /* Now we have active dquot from which someone is * holding reference so we can safely just increase * use count */ dqgrab(dquot); spin_unlock(&dq_list_lock); - err = sb->dq_op->write_dquot(dquot); - if (err) { - /* - * Clear dirty bit anyway to avoid infinite - * loop here. - */ - clear_dquot_dirty(dquot); - if (!ret) - ret = err; - } + err = dquot_write_dquot(dquot); + if (err && !ret) + ret = err; dqput(dquot); spin_lock(&dq_list_lock); } @@ -761,12 +798,53 @@ }; /* + * Safely release dquot and put reference to dquot. + */ +static void quota_release_workfn(struct work_struct *work) +{ + struct dquot *dquot; + struct list_head rls_head; + + spin_lock(&dq_list_lock); + /* Exchange the list head to avoid livelock. */ + list_replace_init(&releasing_dquots, &rls_head); + spin_unlock(&dq_list_lock); + +restart: + synchronize_srcu(&dquot_srcu); + spin_lock(&dq_list_lock); + while (!list_empty(&rls_head)) { + dquot = list_first_entry(&rls_head, struct dquot, dq_free); + /* Dquot got used again? */ + if (atomic_read(&dquot->dq_count) > 1) { + remove_free_dquot(dquot); + atomic_dec(&dquot->dq_count); + continue; + } + if (dquot_dirty(dquot)) { + spin_unlock(&dq_list_lock); + /* Commit dquot before releasing */ + dquot_write_dquot(dquot); + goto restart; + } + if (dquot_active(dquot)) { + spin_unlock(&dq_list_lock); + dquot->dq_sb->dq_op->release_dquot(dquot); + goto restart; + } + /* Dquot is inactive and clean, now move it to free list */ + remove_free_dquot(dquot); + atomic_dec(&dquot->dq_count); + put_dquot_last(dquot); + } + spin_unlock(&dq_list_lock); +} + +/* * Put reference to dquot */ void dqput(struct dquot *dquot) { - int ret; - if (!dquot) return; #ifdef CONFIG_QUOTA_DEBUG @@ -778,7 +856,7 @@ } #endif dqstats_inc(DQST_DROPS); -we_slept: + spin_lock(&dq_list_lock); if (atomic_read(&dquot->dq_count) > 1) { /* We have more than one user... nothing to do */ @@ -790,35 +868,15 @@ spin_unlock(&dq_list_lock); return; } + /* Need to release dquot? */ - if (dquot_dirty(dquot)) { - spin_unlock(&dq_list_lock); - /* Commit dquot before releasing */ - ret = dquot->dq_sb->dq_op->write_dquot(dquot); - if (ret < 0) { - quota_error(dquot->dq_sb, "Can't write quota structure" - " (error %d). Quota may get out of sync!", - ret); - /* - * We clear dirty bit anyway, so that we avoid - * infinite loop here - */ - clear_dquot_dirty(dquot); - } - goto we_slept; - } - if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { - spin_unlock(&dq_list_lock); - dquot->dq_sb->dq_op->release_dquot(dquot); - goto we_slept; - } - atomic_dec(&dquot->dq_count); #ifdef CONFIG_QUOTA_DEBUG /* sanity check */ BUG_ON(!list_empty(&dquot->dq_free)); #endif - put_dquot_last(dquot); + put_releasing_dquots(dquot); spin_unlock(&dq_list_lock); + queue_delayed_work(system_unbound_wq, "a_release_work, 1); } EXPORT_SYMBOL(dqput); @@ -908,7 +966,7 @@ * already finished or it will be canceled due to dq_count > 1 test */ wait_on_dquot(dquot); /* Read the dquot / allocate space in quota file */ - if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { + if (!dquot_active(dquot)) { int err; err = sb->dq_op->acquire_dquot(dquot); @@ -1425,7 +1483,7 @@ return QUOTA_NL_NOWARN; } -static int dquot_active(const struct inode *inode) +static int inode_quota_active(const struct inode *inode) { struct super_block *sb = inode->i_sb; @@ -1448,7 +1506,7 @@ qsize_t rsv; int ret = 0; - if (!dquot_active(inode)) + if (!inode_quota_active(inode)) return 0; dquots = i_dquot(inode); @@ -1556,7 +1614,7 @@ struct dquot **dquots; int i; - if (!dquot_active(inode)) + if (!inode_quota_active(inode)) return false; dquots = i_dquot(inode); @@ -1667,7 +1725,7 @@ int reserve = flags & DQUOT_SPACE_RESERVE; struct dquot **dquots; - if (!dquot_active(inode)) { + if (!inode_quota_active(inode)) { if (reserve) { spin_lock(&inode->i_lock); *inode_reserved_space(inode) += number; @@ -1737,7 +1795,7 @@ struct dquot_warn warn[MAXQUOTAS]; struct dquot * const *dquots; - if (!dquot_active(inode)) + if (!inode_quota_active(inode)) return 0; for (cnt = 0; cnt < MAXQUOTAS; cnt++) warn[cnt].w_type = QUOTA_NL_NOWARN; @@ -1780,7 +1838,7 @@ struct dquot **dquots; int cnt, index; - if (!dquot_active(inode)) { + if (!inode_quota_active(inode)) { spin_lock(&inode->i_lock); *inode_reserved_space(inode) -= number; __inode_add_bytes(inode, number); @@ -1822,7 +1880,7 @@ struct dquot **dquots; int cnt, index; - if (!dquot_active(inode)) { + if (!inode_quota_active(inode)) { spin_lock(&inode->i_lock); *inode_reserved_space(inode) += number; __inode_sub_bytes(inode, number); @@ -1866,7 +1924,7 @@ struct dquot **dquots; int reserve = flags & DQUOT_SPACE_RESERVE, index; - if (!dquot_active(inode)) { + if (!inode_quota_active(inode)) { if (reserve) { spin_lock(&inode->i_lock); *inode_reserved_space(inode) -= number; @@ -1921,7 +1979,7 @@ struct dquot * const *dquots; int index; - if (!dquot_active(inode)) + if (!inode_quota_active(inode)) return; dquots = i_dquot(inode); @@ -2093,7 +2151,7 @@ struct super_block *sb = inode->i_sb; int ret; - if (!dquot_active(inode)) + if (!inode_quota_active(inode)) return 0; if (i_uid_needs_update(mnt_userns, iattr, inode)) { diff -u linux-6.2.0/fs/smb/client/cached_dir.c linux-6.2.0/fs/smb/client/cached_dir.c --- linux-6.2.0/fs/smb/client/cached_dir.c +++ linux-6.2.0/fs/smb/client/cached_dir.c @@ -218,7 +218,7 @@ .tcon = tcon, .path = path, .create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE), - .desired_access = FILE_READ_ATTRIBUTES, + .desired_access = FILE_READ_DATA | FILE_READ_ATTRIBUTES, .disposition = FILE_OPEN, .fid = pfid, }; diff -u linux-6.2.0/fs/smb/client/cifsglob.h linux-6.2.0/fs/smb/client/cifsglob.h --- linux-6.2.0/fs/smb/client/cifsglob.h +++ linux-6.2.0/fs/smb/client/cifsglob.h @@ -735,6 +735,7 @@ */ #define CIFS_SERVER_IS_CHAN(server) (!!(server)->primary_server) struct TCP_Server_Info *primary_server; + __u16 channel_sequence_num; /* incremented on primary channel on each chan reconnect */ #ifdef CONFIG_CIFS_SWN_UPCALL bool use_swn_dstaddr; @@ -976,43 +977,6 @@ kfree(iface); } -/* - * compare two interfaces a and b - * return 0 if everything matches. - * return 1 if a has higher link speed, or rdma capable, or rss capable - * return -1 otherwise. - */ -static inline int -iface_cmp(struct cifs_server_iface *a, struct cifs_server_iface *b) -{ - int cmp_ret = 0; - - WARN_ON(!a || !b); - if (a->speed == b->speed) { - if (a->rdma_capable == b->rdma_capable) { - if (a->rss_capable == b->rss_capable) { - cmp_ret = memcmp(&a->sockaddr, &b->sockaddr, - sizeof(a->sockaddr)); - if (!cmp_ret) - return 0; - else if (cmp_ret > 0) - return 1; - else - return -1; - } else if (a->rss_capable > b->rss_capable) - return 1; - else - return -1; - } else if (a->rdma_capable > b->rdma_capable) - return 1; - else - return -1; - } else if (a->speed > b->speed) - return 1; - else - return -1; -} - struct cifs_chan { unsigned int in_reconnect : 1; /* if session setup in progress for this channel */ struct TCP_Server_Info *server; @@ -1831,6 +1795,7 @@ #define MID_RETRY_NEEDED 8 /* session closed while this request out */ #define MID_RESPONSE_MALFORMED 0x10 #define MID_SHUTDOWN 0x20 +#define MID_RESPONSE_READY 0x40 /* ready for other process handle the rsp */ /* Flags */ #define MID_WAIT_CANCELLED 1 /* Cancelled while waiting for response */ diff -u linux-6.2.0/fs/smb/client/cifsproto.h linux-6.2.0/fs/smb/client/cifsproto.h --- linux-6.2.0/fs/smb/client/cifsproto.h +++ linux-6.2.0/fs/smb/client/cifsproto.h @@ -87,6 +87,7 @@ struct mid_q_entry *mid); extern int smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx); extern int smb3_parse_opt(const char *options, const char *key, char **val); +extern int cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs); extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs); extern int cifs_discard_remaining_data(struct TCP_Server_Info *server); extern int cifs_call_async(struct TCP_Server_Info *server, diff -u linux-6.2.0/fs/smb/client/connect.c linux-6.2.0/fs/smb/client/connect.c --- linux-6.2.0/fs/smb/client/connect.c +++ linux-6.2.0/fs/smb/client/connect.c @@ -1317,6 +1317,56 @@ module_put_and_kthread_exit(0); } +int +cifs_ipaddr_cmp(struct sockaddr *srcaddr, struct sockaddr *rhs) +{ + struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr; + struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs; + struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr; + struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)rhs; + + switch (srcaddr->sa_family) { + case AF_UNSPEC: + switch (rhs->sa_family) { + case AF_UNSPEC: + return 0; + case AF_INET: + case AF_INET6: + return 1; + default: + return -1; + } + case AF_INET: { + switch (rhs->sa_family) { + case AF_UNSPEC: + return -1; + case AF_INET: + return memcmp(saddr4, vaddr4, + sizeof(struct sockaddr_in)); + case AF_INET6: + return 1; + default: + return -1; + } + } + case AF_INET6: { + switch (rhs->sa_family) { + case AF_UNSPEC: + case AF_INET: + return -1; + case AF_INET6: + return memcmp(saddr6, + vaddr6, + sizeof(struct sockaddr_in6)); + default: + return -1; + } + } + default: + return -1; /* don't expect to be here */ + } +} + /* * Returns true if srcaddr isn't specified and rhs isn't specified, or * if srcaddr is specified and matches the IP address of the rhs argument @@ -1669,6 +1719,7 @@ ctx->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL); tcp_ses->session_estab = false; tcp_ses->sequence_number = 0; + tcp_ses->channel_sequence_num = 0; /* only tracked for primary channel */ tcp_ses->reconnect_instance = 1; tcp_ses->lstrp = jiffies; tcp_ses->compress_algorithm = cpu_to_le16(ctx->compression); @@ -2862,9 +2913,9 @@ if (server->srcaddr.ss_family != AF_UNSPEC) { /* Bind to the specified local IP address */ struct socket *socket = server->ssocket; - rc = socket->ops->bind(socket, - (struct sockaddr *) &server->srcaddr, - sizeof(server->srcaddr)); + rc = kernel_bind(socket, + (struct sockaddr *) &server->srcaddr, + sizeof(server->srcaddr)); if (rc < 0) { struct sockaddr_in *saddr4; struct sockaddr_in6 *saddr6; @@ -3012,8 +3063,8 @@ socket->sk->sk_sndbuf, socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); - rc = socket->ops->connect(socket, saddr, slen, - server->noblockcnt ? O_NONBLOCK : 0); + rc = kernel_connect(socket, saddr, slen, + server->noblockcnt ? O_NONBLOCK : 0); /* * When mounting SMB root file systems, we do not want to block in * connect. Otherwise bail out and then let cifs_reconnect() perform diff -u linux-6.2.0/fs/smb/client/fscache.c linux-6.2.0/fs/smb/client/fscache.c --- linux-6.2.0/fs/smb/client/fscache.c +++ linux-6.2.0/fs/smb/client/fscache.c @@ -48,7 +48,7 @@ sharename = extract_sharename(tcon->tree_name); if (IS_ERR(sharename)) { cifs_dbg(FYI, "%s: couldn't extract sharename\n", __func__); - return -EINVAL; + return PTR_ERR(sharename); } slen = strlen(sharename); diff -u linux-6.2.0/fs/smb/client/inode.c linux-6.2.0/fs/smb/client/inode.c --- linux-6.2.0/fs/smb/client/inode.c +++ linux-6.2.0/fs/smb/client/inode.c @@ -2610,7 +2610,7 @@ } cifsFileInfo_put(cfile); - return -ENOTSUPP; + return -EOPNOTSUPP; } int cifs_truncate_page(struct address_space *mapping, loff_t from) diff -u linux-6.2.0/fs/smb/client/misc.c linux-6.2.0/fs/smb/client/misc.c --- linux-6.2.0/fs/smb/client/misc.c +++ linux-6.2.0/fs/smb/client/misc.c @@ -357,6 +357,10 @@ cifs_dbg(VFS, "Length less than smb header size\n"); } return -EIO; + } else if (total_read < sizeof(*smb) + 2 * smb->WordCount) { + cifs_dbg(VFS, "%s: can't read BCC due to invalid WordCount(%u)\n", + __func__, smb->WordCount); + return -EIO; } /* otherwise, there is enough to get to the BCC */ diff -u linux-6.2.0/fs/smb/client/smb2ops.c linux-6.2.0/fs/smb/client/smb2ops.c --- linux-6.2.0/fs/smb/client/smb2ops.c +++ linux-6.2.0/fs/smb/client/smb2ops.c @@ -34,6 +34,8 @@ change_conf(struct TCP_Server_Info *server) { server->credits += server->echo_credits + server->oplock_credits; + if (server->credits > server->max_credits) + server->credits = server->max_credits; server->oplock_credits = server->echo_credits = 0; switch (server->credits) { case 0: @@ -165,8 +167,17 @@ spin_lock(&server->req_lock); server->credits = val; - if (val == 1) + if (val == 1) { server->reconnect_instance++; + /* + * ChannelSequence updated for all channels in primary channel so that consistent + * across SMB3 requests sent on any channel. See MS-SMB2 3.2.4.1 and 3.2.7.1 + */ + if (CIFS_SERVER_IS_CHAN(server)) + server->primary_server->channel_sequence_num++; + else + server->channel_sequence_num++; + } scredits = server->credits; in_flight = server->in_flight; spin_unlock(&server->req_lock); @@ -281,7 +292,7 @@ cifs_server_dbg(VFS, "request has less credits (%d) than required (%d)", credits->value, new_val); - return -ENOTSUPP; + return -EOPNOTSUPP; } spin_lock(&server->req_lock); @@ -511,6 +522,43 @@ return rsize; } +/* + * compare two interfaces a and b + * return 0 if everything matches. + * return 1 if a is rdma capable, or rss capable, or has higher link speed + * return -1 otherwise. + */ +static int +iface_cmp(struct cifs_server_iface *a, struct cifs_server_iface *b) +{ + int cmp_ret = 0; + + WARN_ON(!a || !b); + if (a->rdma_capable == b->rdma_capable) { + if (a->rss_capable == b->rss_capable) { + if (a->speed == b->speed) { + cmp_ret = cifs_ipaddr_cmp((struct sockaddr *) &a->sockaddr, + (struct sockaddr *) &b->sockaddr); + if (!cmp_ret) + return 0; + else if (cmp_ret > 0) + return 1; + else + return -1; + } else if (a->speed > b->speed) + return 1; + else + return -1; + } else if (a->rss_capable > b->rss_capable) + return 1; + else + return -1; + } else if (a->rdma_capable > b->rdma_capable) + return 1; + else + return -1; +} + static int parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, size_t buf_len, struct cifs_ses *ses, bool in_mount) @@ -1107,7 +1155,7 @@ /* Use a fudge factor of 256 bytes in case we collide * with a different set_EAs command. */ - if(CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE - + if (CIFSMaxBufSize - MAX_SMB2_CREATE_RESPONSE_SIZE - MAX_SMB2_CLOSE_RESPONSE_SIZE - 256 < used_len + ea_name_len + ea_value_len + 1) { rc = -ENOSPC; @@ -4674,7 +4722,7 @@ if (shdr->Command != SMB2_READ) { cifs_server_dbg(VFS, "only big read responses are supported\n"); - return -ENOTSUPP; + return -EOPNOTSUPP; } if (server->ops->is_session_expired && diff -u linux-6.2.0/fs/smb/client/smb2pdu.c linux-6.2.0/fs/smb/client/smb2pdu.c --- linux-6.2.0/fs/smb/client/smb2pdu.c +++ linux-6.2.0/fs/smb/client/smb2pdu.c @@ -88,9 +88,20 @@ const struct cifs_tcon *tcon, struct TCP_Server_Info *server) { + struct smb3_hdr_req *smb3_hdr; shdr->ProtocolId = SMB2_PROTO_NUMBER; shdr->StructureSize = cpu_to_le16(64); shdr->Command = smb2_cmd; + if (server->dialect >= SMB30_PROT_ID) { + /* After reconnect SMB3 must set ChannelSequence on subsequent reqs */ + smb3_hdr = (struct smb3_hdr_req *)shdr; + /* if primary channel is not set yet, use default channel for chan sequence num */ + if (CIFS_SERVER_IS_CHAN(server)) + smb3_hdr->ChannelSequence = + cpu_to_le16(server->primary_server->channel_sequence_num); + else + smb3_hdr->ChannelSequence = cpu_to_le16(server->channel_sequence_num); + } if (server) { spin_lock(&server->req_lock); /* Request up to 10 credits but don't go over the limit. */ @@ -1312,7 +1323,12 @@ } /* enough to enable echos and oplocks and one max size write */ - req->hdr.CreditRequest = cpu_to_le16(130); + if (server->credits >= server->max_credits) + req->hdr.CreditRequest = cpu_to_le16(0); + else + req->hdr.CreditRequest = cpu_to_le16( + min_t(int, server->max_credits - + server->credits, 130)); /* only one of SMB2 signing flags may be set in SMB2 request */ if (server->sign) @@ -1907,7 +1923,12 @@ rqst.rq_nvec = 2; /* Need 64 for max size write so ask for more in case not there yet */ - req->hdr.CreditRequest = cpu_to_le16(64); + if (server->credits >= server->max_credits) + req->hdr.CreditRequest = cpu_to_le16(0); + else + req->hdr.CreditRequest = cpu_to_le16( + min_t(int, server->max_credits - + server->credits, 64)); rc = cifs_send_recv(xid, ses, server, &rqst, &resp_buftype, flags, &rsp_iov); @@ -4291,6 +4312,7 @@ struct TCP_Server_Info *server; struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); unsigned int total_len; + int credit_request; cifs_dbg(FYI, "%s: offset=%llu bytes=%u\n", __func__, rdata->offset, rdata->bytes); @@ -4322,7 +4344,13 @@ if (rdata->credits.value > 0) { shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes, SMB2_MAX_BUFFER_SIZE)); - shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8); + credit_request = le16_to_cpu(shdr->CreditCharge) + 8; + if (server->credits >= server->max_credits) + shdr->CreditRequest = cpu_to_le16(0); + else + shdr->CreditRequest = cpu_to_le16( + min_t(int, server->max_credits - + server->credits, credit_request)); rc = adjust_credits(server, &rdata->credits, rdata->bytes); if (rc) @@ -4532,6 +4560,7 @@ unsigned int total_len; struct cifs_io_parms _io_parms; struct cifs_io_parms *io_parms = NULL; + int credit_request; if (!wdata->server) server = wdata->server = cifs_pick_channel(tcon->ses); @@ -4649,7 +4678,13 @@ if (wdata->credits.value > 0) { shdr->CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes, SMB2_MAX_BUFFER_SIZE)); - shdr->CreditRequest = cpu_to_le16(le16_to_cpu(shdr->CreditCharge) + 8); + credit_request = le16_to_cpu(shdr->CreditCharge) + 8; + if (server->credits >= server->max_credits) + shdr->CreditRequest = cpu_to_le16(0); + else + shdr->CreditRequest = cpu_to_le16( + min_t(int, server->max_credits - + server->credits, credit_request)); rc = adjust_credits(server, &wdata->credits, io_parms->length); if (rc) diff -u linux-6.2.0/fs/smb/client/transport.c linux-6.2.0/fs/smb/client/transport.c --- linux-6.2.0/fs/smb/client/transport.c +++ linux-6.2.0/fs/smb/client/transport.c @@ -35,6 +35,8 @@ void cifs_wake_up_task(struct mid_q_entry *mid) { + if (mid->mid_state == MID_RESPONSE_RECEIVED) + mid->mid_state = MID_RESPONSE_READY; wake_up_process(mid->callback_data); } @@ -87,7 +89,8 @@ struct TCP_Server_Info *server = midEntry->server; if (midEntry->resp_buf && (midEntry->mid_flags & MID_WAIT_CANCELLED) && - midEntry->mid_state == MID_RESPONSE_RECEIVED && + (midEntry->mid_state == MID_RESPONSE_RECEIVED || + midEntry->mid_state == MID_RESPONSE_READY) && server->ops->handle_cancelled_mid) server->ops->handle_cancelled_mid(midEntry, server); @@ -759,7 +762,8 @@ int error; error = wait_event_state(server->response_q, - midQ->mid_state != MID_REQUEST_SUBMITTED, + midQ->mid_state != MID_REQUEST_SUBMITTED && + midQ->mid_state != MID_RESPONSE_RECEIVED, (TASK_KILLABLE|TASK_FREEZABLE_UNSAFE)); if (error < 0) return -ERESTARTSYS; @@ -912,7 +916,7 @@ spin_lock(&server->mid_lock); switch (mid->mid_state) { - case MID_RESPONSE_RECEIVED: + case MID_RESPONSE_READY: spin_unlock(&server->mid_lock); return rc; case MID_RETRY_NEEDED: @@ -1011,6 +1015,9 @@ credits.instance = server->reconnect_instance; add_credits(server, &credits, mid->optype); + + if (mid->mid_state == MID_RESPONSE_RECEIVED) + mid->mid_state = MID_RESPONSE_READY; } static void @@ -1206,7 +1213,8 @@ send_cancel(server, &rqst[i], midQ[i]); spin_lock(&server->mid_lock); midQ[i]->mid_flags |= MID_WAIT_CANCELLED; - if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { + if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED || + midQ[i]->mid_state == MID_RESPONSE_RECEIVED) { midQ[i]->callback = cifs_cancelled_callback; cancelled_mid[i] = true; credits[i].value = 0; @@ -1227,7 +1235,7 @@ } if (!midQ[i]->resp_buf || - midQ[i]->mid_state != MID_RESPONSE_RECEIVED) { + midQ[i]->mid_state != MID_RESPONSE_READY) { rc = -EIO; cifs_dbg(FYI, "Bad MID state?\n"); goto out; @@ -1414,7 +1422,8 @@ if (rc != 0) { send_cancel(server, &rqst, midQ); spin_lock(&server->mid_lock); - if (midQ->mid_state == MID_REQUEST_SUBMITTED) { + if (midQ->mid_state == MID_REQUEST_SUBMITTED || + midQ->mid_state == MID_RESPONSE_RECEIVED) { /* no longer considered to be "in-flight" */ midQ->callback = release_mid; spin_unlock(&server->mid_lock); @@ -1431,7 +1440,7 @@ } if (!midQ->resp_buf || !out_buf || - midQ->mid_state != MID_RESPONSE_RECEIVED) { + midQ->mid_state != MID_RESPONSE_READY) { rc = -EIO; cifs_server_dbg(VFS, "Bad MID state?\n"); goto out; @@ -1555,14 +1564,16 @@ /* Wait for a reply - allow signals to interrupt. */ rc = wait_event_interruptible(server->response_q, - (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) || + (!(midQ->mid_state == MID_REQUEST_SUBMITTED || + midQ->mid_state == MID_RESPONSE_RECEIVED)) || ((server->tcpStatus != CifsGood) && (server->tcpStatus != CifsNew))); /* Were we interrupted by a signal ? */ spin_lock(&server->srv_lock); if ((rc == -ERESTARTSYS) && - (midQ->mid_state == MID_REQUEST_SUBMITTED) && + (midQ->mid_state == MID_REQUEST_SUBMITTED || + midQ->mid_state == MID_RESPONSE_RECEIVED) && ((server->tcpStatus == CifsGood) || (server->tcpStatus == CifsNew))) { spin_unlock(&server->srv_lock); @@ -1593,7 +1604,8 @@ if (rc) { send_cancel(server, &rqst, midQ); spin_lock(&server->mid_lock); - if (midQ->mid_state == MID_REQUEST_SUBMITTED) { + if (midQ->mid_state == MID_REQUEST_SUBMITTED || + midQ->mid_state == MID_RESPONSE_RECEIVED) { /* no longer considered to be "in-flight" */ midQ->callback = release_mid; spin_unlock(&server->mid_lock); @@ -1613,7 +1625,7 @@ return rc; /* rcvd frame is ok */ - if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) { + if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_READY) { rc = -EIO; cifs_tcon_dbg(VFS, "Bad MID state?\n"); goto out; diff -u linux-6.2.0/fs/smb/common/smb2pdu.h linux-6.2.0/fs/smb/common/smb2pdu.h --- linux-6.2.0/fs/smb/common/smb2pdu.h +++ linux-6.2.0/fs/smb/common/smb2pdu.h @@ -153,6 +153,28 @@ __u8 Signature[16]; } __packed; +struct smb3_hdr_req { + __le32 ProtocolId; /* 0xFE 'S' 'M' 'B' */ + __le16 StructureSize; /* 64 */ + __le16 CreditCharge; /* MBZ */ + __le16 ChannelSequence; /* See MS-SMB2 3.2.4.1 and 3.2.7.1 */ + __le16 Reserved; + __le16 Command; + __le16 CreditRequest; /* CreditResponse */ + __le32 Flags; + __le32 NextCommand; + __le64 MessageId; + union { + struct { + __le32 ProcessId; + __le32 TreeId; + } __packed SyncId; + __le64 AsyncId; + } __packed Id; + __le64 SessionId; + __u8 Signature[16]; +} __packed; + struct smb2_pdu { struct smb2_hdr hdr; __le16 StructureSize2; /* size of wct area (varies, request specific) */ diff -u linux-6.2.0/fs/smb/server/connection.c linux-6.2.0/fs/smb/server/connection.c --- linux-6.2.0/fs/smb/server/connection.c +++ linux-6.2.0/fs/smb/server/connection.c @@ -84,6 +84,8 @@ spin_lock_init(&conn->llist_lock); INIT_LIST_HEAD(&conn->lock_list); + init_rwsem(&conn->session_lock); + down_write(&conn_list_lock); list_add(&conn->conns_list, &conn_list); up_write(&conn_list_lock); diff -u linux-6.2.0/fs/smb/server/connection.h linux-6.2.0/fs/smb/server/connection.h --- linux-6.2.0/fs/smb/server/connection.h +++ linux-6.2.0/fs/smb/server/connection.h @@ -50,6 +50,7 @@ struct nls_table *local_nls; struct unicode_map *um; struct list_head conns_list; + struct rw_semaphore session_lock; /* smb session 1 per user */ struct xarray sessions; unsigned long last_active; diff -u linux-6.2.0/fs/smb/server/mgmt/user_session.c linux-6.2.0/fs/smb/server/mgmt/user_session.c --- linux-6.2.0/fs/smb/server/mgmt/user_session.c +++ linux-6.2.0/fs/smb/server/mgmt/user_session.c @@ -183,7 +183,7 @@ unsigned long id; struct ksmbd_session *sess; - down_write(&sessions_table_lock); + down_write(&conn->session_lock); xa_for_each(&conn->sessions, id, sess) { if (sess->state != SMB2_SESSION_VALID || time_after(jiffies, @@ -194,7 +194,7 @@ continue; } } - up_write(&sessions_table_lock); + up_write(&conn->session_lock); } int ksmbd_session_register(struct ksmbd_conn *conn, @@ -236,7 +236,9 @@ } } } + up_write(&sessions_table_lock); + down_write(&conn->session_lock); xa_for_each(&conn->sessions, id, sess) { unsigned long chann_id; struct channel *chann; @@ -253,7 +255,7 @@ ksmbd_session_destroy(sess); } } - up_write(&sessions_table_lock); + up_write(&conn->session_lock); } struct ksmbd_session *ksmbd_session_lookup(struct ksmbd_conn *conn, @@ -261,9 +263,11 @@ { struct ksmbd_session *sess; + down_read(&conn->session_lock); sess = xa_load(&conn->sessions, id); if (sess) sess->last_active = jiffies; + up_read(&conn->session_lock); return sess; } diff -u linux-6.2.0/fs/smb/server/server.c linux-6.2.0/fs/smb/server/server.c --- linux-6.2.0/fs/smb/server/server.c +++ linux-6.2.0/fs/smb/server/server.c @@ -286,6 +286,7 @@ static int queue_ksmbd_work(struct ksmbd_conn *conn) { struct ksmbd_work *work; + int err; work = ksmbd_alloc_work_struct(); if (!work) { @@ -297,7 +298,11 @@ work->request_buf = conn->request_buf; conn->request_buf = NULL; - ksmbd_init_smb_server(work); + err = ksmbd_init_smb_server(work); + if (err) { + ksmbd_free_work_struct(work); + return 0; + } ksmbd_conn_enqueue_request(work); atomic_inc(&conn->r_count); diff -u linux-6.2.0/fs/smb/server/smb2pdu.c linux-6.2.0/fs/smb/server/smb2pdu.c --- linux-6.2.0/fs/smb/server/smb2pdu.c +++ linux-6.2.0/fs/smb/server/smb2pdu.c @@ -86,9 +86,9 @@ */ int smb2_get_ksmbd_tcon(struct ksmbd_work *work) { - struct smb2_hdr *req_hdr = smb2_get_msg(work->request_buf); + struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work); unsigned int cmd = le16_to_cpu(req_hdr->Command); - int tree_id; + unsigned int tree_id; if (cmd == SMB2_TREE_CONNECT_HE || cmd == SMB2_CANCEL_HE || @@ -113,7 +113,7 @@ pr_err("The first operation in the compound does not have tcon\n"); return -EINVAL; } - if (work->tcon->id != tree_id) { + if (tree_id != UINT_MAX && work->tcon->id != tree_id) { pr_err("tree id(%u) is different with id(%u) in first operation\n", tree_id, work->tcon->id); return -EINVAL; @@ -565,9 +565,9 @@ */ int smb2_check_user_session(struct ksmbd_work *work) { - struct smb2_hdr *req_hdr = smb2_get_msg(work->request_buf); + struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work); struct ksmbd_conn *conn = work->conn; - unsigned int cmd = conn->ops->get_cmd_val(work); + unsigned int cmd = le16_to_cpu(req_hdr->Command); unsigned long long sess_id; /* @@ -593,7 +593,7 @@ pr_err("The first operation in the compound does not have sess\n"); return -EINVAL; } - if (work->sess->id != sess_id) { + if (sess_id != ULLONG_MAX && work->sess->id != sess_id) { pr_err("session id(%llu) is different with the first operation(%lld)\n", sess_id, work->sess->id); return -EINVAL; @@ -6316,6 +6316,11 @@ unsigned int max_read_size = conn->vals->max_read_size; WORK_BUFFERS(work, req, rsp); + if (work->next_smb2_rcv_hdr_off) { + work->send_no_response = 1; + err = -EOPNOTSUPP; + goto out; + } if (test_share_config_flag(work->tcon->share_conf, KSMBD_SHARE_FLAG_PIPE)) { @@ -8129,10 +8134,10 @@ goto err_out; } - opinfo_put(opinfo); - ksmbd_fd_put(work, fp); opinfo->op_state = OPLOCK_STATE_NONE; wake_up_interruptible_all(&opinfo->oplock_q); + opinfo_put(opinfo); + ksmbd_fd_put(work, fp); rsp->StructureSize = cpu_to_le16(24); rsp->OplockLevel = rsp_oplevel; @@ -8719,7 +8724,8 @@ struct smb2_transform_hdr *tr_hdr = smb2_get_msg(buf); int rc = 0; - if (buf_data_size < sizeof(struct smb2_hdr)) { + if (pdu_length < sizeof(struct smb2_transform_hdr) || + buf_data_size < sizeof(struct smb2_hdr)) { pr_err("Transform message is too small (%u)\n", pdu_length); return -ECONNABORTED; diff -u linux-6.2.0/fs/smb/server/smb_common.c linux-6.2.0/fs/smb/server/smb_common.c --- linux-6.2.0/fs/smb/server/smb_common.c +++ linux-6.2.0/fs/smb/server/smb_common.c @@ -388,26 +388,29 @@ [SMB_COM_NEGOTIATE_EX] = { .proc = smb1_negotiate, }, }; -static void init_smb1_server(struct ksmbd_conn *conn) +static int init_smb1_server(struct ksmbd_conn *conn) { conn->ops = &smb1_server_ops; conn->cmds = smb1_server_cmds; conn->max_cmds = ARRAY_SIZE(smb1_server_cmds); + return 0; } -void ksmbd_init_smb_server(struct ksmbd_work *work) +int ksmbd_init_smb_server(struct ksmbd_work *work) { struct ksmbd_conn *conn = work->conn; __le32 proto; - if (conn->need_neg == false) - return; - proto = *(__le32 *)((struct smb_hdr *)work->request_buf)->Protocol; + if (conn->need_neg == false) { + if (proto == SMB1_PROTO_NUMBER) + return -EINVAL; + return 0; + } + if (proto == SMB1_PROTO_NUMBER) - init_smb1_server(conn); - else - init_smb3_11_server(conn); + return init_smb1_server(conn); + return init_smb3_11_server(conn); } int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level, diff -u linux-6.2.0/fs/smb/server/smb_common.h linux-6.2.0/fs/smb/server/smb_common.h --- linux-6.2.0/fs/smb/server/smb_common.h +++ linux-6.2.0/fs/smb/server/smb_common.h @@ -427,7 +427,7 @@ int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count); -void ksmbd_init_smb_server(struct ksmbd_work *work); +int ksmbd_init_smb_server(struct ksmbd_work *work); struct ksmbd_kstat; int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, diff -u linux-6.2.0/fs/udf/inode.c linux-6.2.0/fs/udf/inode.c --- linux-6.2.0/fs/udf/inode.c +++ linux-6.2.0/fs/udf/inode.c @@ -57,15 +57,15 @@ static int udf_sync_inode(struct inode *inode); static int udf_alloc_i_data(struct inode *inode, size_t size); static sector_t inode_getblk(struct inode *, sector_t, int *, int *); -static int8_t udf_insert_aext(struct inode *, struct extent_position, - struct kernel_lb_addr, uint32_t); +static int udf_insert_aext(struct inode *, struct extent_position, + struct kernel_lb_addr, uint32_t); static void udf_split_extents(struct inode *, int *, int, udf_pblk_t, struct kernel_long_ad *, int *); static void udf_prealloc_extents(struct inode *, int, int, struct kernel_long_ad *, int *); static void udf_merge_extents(struct inode *, struct kernel_long_ad *, int *); -static void udf_update_extents(struct inode *, struct kernel_long_ad *, int, - int, struct extent_position *); +static int udf_update_extents(struct inode *, struct kernel_long_ad *, int, + int, struct extent_position *); static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int); static void __udf_clear_extent_cache(struct inode *inode) @@ -881,7 +881,9 @@ /* write back the new extents, inserting new extents if the new number * of extents is greater than the old number, and deleting extents if * the new number of extents is less than the old number */ - udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); + *err = udf_update_extents(inode, laarr, startnum, endnum, &prev_epos); + if (*err < 0) + goto out_free; newblock = udf_get_pblock(inode->i_sb, newblocknum, iinfo->i_location.partitionReferenceNum, 0); @@ -1149,21 +1151,30 @@ } } -static void udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr, - int startnum, int endnum, - struct extent_position *epos) +static int udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr, + int startnum, int endnum, + struct extent_position *epos) { int start = 0, i; struct kernel_lb_addr tmploc; uint32_t tmplen; + int err; if (startnum > endnum) { for (i = 0; i < (startnum - endnum); i++) udf_delete_aext(inode, *epos); } else if (startnum < endnum) { for (i = 0; i < (endnum - startnum); i++) { - udf_insert_aext(inode, *epos, laarr[i].extLocation, - laarr[i].extLength); + err = udf_insert_aext(inode, *epos, + laarr[i].extLocation, + laarr[i].extLength); + /* + * If we fail here, we are likely corrupting the extent + * list and leaking blocks. At least stop early to + * limit the damage. + */ + if (err < 0) + return err; udf_next_aext(inode, epos, &laarr[i].extLocation, &laarr[i].extLength, 1); start++; @@ -1175,6 +1186,7 @@ udf_write_aext(inode, epos, &laarr[i].extLocation, laarr[i].extLength, 1); } + return 0; } struct buffer_head *udf_bread(struct inode *inode, udf_pblk_t block, @@ -2203,12 +2215,13 @@ return etype; } -static int8_t udf_insert_aext(struct inode *inode, struct extent_position epos, - struct kernel_lb_addr neloc, uint32_t nelen) +static int udf_insert_aext(struct inode *inode, struct extent_position epos, + struct kernel_lb_addr neloc, uint32_t nelen) { struct kernel_lb_addr oeloc; uint32_t oelen; int8_t etype; + int err; if (epos.bh) get_bh(epos.bh); @@ -2218,10 +2231,10 @@ neloc = oeloc; nelen = (etype << 30) | oelen; } - udf_add_aext(inode, &epos, &neloc, nelen, 1); + err = udf_add_aext(inode, &epos, &neloc, nelen, 1); brelse(epos.bh); - return (nelen >> 30); + return err; } int8_t udf_delete_aext(struct inode *inode, struct extent_position epos) diff -u linux-6.2.0/include/asm-generic/hyperv-tlfs.h linux-6.2.0/include/asm-generic/hyperv-tlfs.h --- linux-6.2.0/include/asm-generic/hyperv-tlfs.h +++ linux-6.2.0/include/asm-generic/hyperv-tlfs.h @@ -135,7 +135,7 @@ * */ -#define HV_LINUX_VENDOR_ID 0x80 /* Canonical */ +#define HV_LINUX_VENDOR_ID 0x8180 /* Canonical */ /* * Crash notification flags. diff -u linux-6.2.0/include/crypto/algapi.h linux-6.2.0/include/crypto/algapi.h --- linux-6.2.0/include/crypto/algapi.h +++ linux-6.2.0/include/crypto/algapi.h @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -69,6 +70,8 @@ struct crypto_spawn *spawns; }; + struct work_struct free_work; + void *__ctx[] CRYPTO_MINALIGN_ATTR; }; diff -u linux-6.2.0/include/linux/blkdev.h linux-6.2.0/include/linux/blkdev.h --- linux-6.2.0/include/linux/blkdev.h +++ linux-6.2.0/include/linux/blkdev.h @@ -555,6 +555,7 @@ #define QUEUE_FLAG_NOXMERGES 9 /* No extended merges */ #define QUEUE_FLAG_ADD_RANDOM 10 /* Contributes to random pool */ #define QUEUE_FLAG_SAME_FORCE 12 /* force complete on same CPU */ +#define QUEUE_FLAG_HW_WC 18 /* Write back caching supported */ #define QUEUE_FLAG_INIT_DONE 14 /* queue is initialized */ #define QUEUE_FLAG_STABLE_WRITES 15 /* don't modify blks until WB is done */ #define QUEUE_FLAG_POLL 16 /* IO polling enabled if set */ diff -u linux-6.2.0/include/linux/bpf.h linux-6.2.0/include/linux/bpf.h --- linux-6.2.0/include/linux/bpf.h +++ linux-6.2.0/include/linux/bpf.h @@ -387,7 +387,7 @@ size /= sizeof(long); while (size--) - *ldst++ = *lsrc++; + data_race(*ldst++ = *lsrc++); } /* copy everything but bpf_spin_lock, bpf_timer, and kptrs. There could be one of each. */ @@ -1207,7 +1207,7 @@ static inline struct bpf_trampoline *bpf_trampoline_get(u64 key, struct bpf_attach_target_info *tgt_info) { - return ERR_PTR(-EOPNOTSUPP); + return NULL; } static inline void bpf_trampoline_put(struct bpf_trampoline *tr) {} #define DEFINE_BPF_DISPATCHER(name) diff -u linux-6.2.0/include/linux/fs.h linux-6.2.0/include/linux/fs.h --- linux-6.2.0/include/linux/fs.h +++ linux-6.2.0/include/linux/fs.h @@ -2719,7 +2719,7 @@ struct filename { const char *name; /* pointer to actual string */ const __user char *uptr; /* original userland pointer */ - int refcnt; + atomic_t refcnt; struct audit_names *aname; const char iname[]; }; diff -u linux-6.2.0/include/linux/hid.h linux-6.2.0/include/linux/hid.h --- linux-6.2.0/include/linux/hid.h +++ linux-6.2.0/include/linux/hid.h @@ -357,6 +357,7 @@ #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18) #define HID_QUIRK_HAVE_SPECIAL_DRIVER BIT(19) #define HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE BIT(20) +#define HID_QUIRK_NOINVERT BIT(21) #define HID_QUIRK_FULLSPEED_INTERVAL BIT(28) #define HID_QUIRK_NO_INIT_REPORTS BIT(29) #define HID_QUIRK_NO_IGNORE BIT(30) diff -u linux-6.2.0/include/linux/if_team.h linux-6.2.0/include/linux/if_team.h --- linux-6.2.0/include/linux/if_team.h +++ linux-6.2.0/include/linux/if_team.h @@ -189,6 +189,8 @@ struct net_device *dev; /* associated netdevice */ struct team_pcpu_stats __percpu *pcpu_stats; + const struct header_ops *header_ops_cache; + struct mutex lock; /* used for overall locking, e.g. port lists write */ /* diff -u linux-6.2.0/include/linux/libata.h linux-6.2.0/include/linux/libata.h --- linux-6.2.0/include/linux/libata.h +++ linux-6.2.0/include/linux/libata.h @@ -216,6 +216,10 @@ ATA_HOST_PARALLEL_SCAN = (1 << 2), /* Ports on this host can be scanned in parallel */ ATA_HOST_IGNORE_ATA = (1 << 3), /* Ignore ATA devices on this host. */ + ATA_HOST_NO_PART = (1 << 4), /* Host does not support partial */ + ATA_HOST_NO_SSC = (1 << 5), /* Host does not support slumber */ + ATA_HOST_NO_DEVSLP = (1 << 6), /* Host does not support devslp */ + /* bits 24:31 of host->flags are reserved for LLD specific flags */ /* various lengths of time */ @@ -249,7 +253,7 @@ * advised to wait only for the following duration before * doing SRST. */ - ATA_TMOUT_PMP_SRST_WAIT = 5000, + ATA_TMOUT_PMP_SRST_WAIT = 10000, /* When the LPM policy is set to ATA_LPM_MAX_POWER, there might * be a spurious PHY event, so ignore the first PHY event that @@ -1137,6 +1141,7 @@ struct block_device *bdev, sector_t capacity, int geom[]); extern void ata_scsi_unlock_native_capacity(struct scsi_device *sdev); +extern int ata_scsi_slave_alloc(struct scsi_device *sdev); extern int ata_scsi_slave_config(struct scsi_device *sdev); extern void ata_scsi_slave_destroy(struct scsi_device *sdev); extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, @@ -1385,6 +1390,7 @@ .this_id = ATA_SHT_THIS_ID, \ .emulated = ATA_SHT_EMULATED, \ .proc_name = drv_name, \ + .slave_alloc = ata_scsi_slave_alloc, \ .slave_destroy = ata_scsi_slave_destroy, \ .bios_param = ata_std_bios_param, \ .unlock_native_capacity = ata_scsi_unlock_native_capacity,\ diff -u linux-6.2.0/include/linux/lsm_hook_defs.h linux-6.2.0/include/linux/lsm_hook_defs.h --- linux-6.2.0/include/linux/lsm_hook_defs.h +++ linux-6.2.0/include/linux/lsm_hook_defs.h @@ -54,6 +54,7 @@ LSM_HOOK(int, 0, bprm_check_security, struct linux_binprm *bprm) LSM_HOOK(void, LSM_RET_VOID, bprm_committing_creds, struct linux_binprm *bprm) LSM_HOOK(void, LSM_RET_VOID, bprm_committed_creds, struct linux_binprm *bprm) +LSM_HOOK(int, 0, fs_context_submount, struct fs_context *fc, struct super_block *reference) LSM_HOOK(int, 0, fs_context_dup, struct fs_context *fc, struct fs_context *src_sc) LSM_HOOK(int, -ENOPARAM, fs_context_parse_param, struct fs_context *fc, diff -u linux-6.2.0/include/linux/mm.h linux-6.2.0/include/linux/mm.h --- linux-6.2.0/include/linux/mm.h +++ linux-6.2.0/include/linux/mm.h @@ -2011,6 +2011,8 @@ extern int user_shm_lock(size_t, struct ucounts *); extern void user_shm_unlock(size_t, struct ucounts *); +struct folio *vm_normal_folio(struct vm_area_struct *vma, unsigned long addr, + pte_t pte); struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_t pte); struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, diff -u linux-6.2.0/include/linux/pci.h linux-6.2.0/include/linux/pci.h --- linux-6.2.0/include/linux/pci.h +++ linux-6.2.0/include/linux/pci.h @@ -469,6 +469,7 @@ pci_dev_flags_t dev_flags; atomic_t enable_cnt; /* pci_enable_device has been called */ + spinlock_t pcie_cap_lock; /* Protects RMW ops in capability accessors */ u32 saved_config_space[16]; /* Config space saved at suspend time */ struct hlist_head saved_cap_space; int rom_attr_enabled; /* Display of ROM attribute enabled? */ @@ -1215,11 +1216,40 @@ int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val); int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val); int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val); -int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, - u16 clear, u16 set); +int pcie_capability_clear_and_set_word_unlocked(struct pci_dev *dev, int pos, + u16 clear, u16 set); +int pcie_capability_clear_and_set_word_locked(struct pci_dev *dev, int pos, + u16 clear, u16 set); int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos, u32 clear, u32 set); +/** + * pcie_capability_clear_and_set_word - RMW accessor for PCI Express Capability Registers + * @dev: PCI device structure of the PCI Express device + * @pos: PCI Express Capability Register + * @clear: Clear bitmask + * @set: Set bitmask + * + * Perform a Read-Modify-Write (RMW) operation using @clear and @set + * bitmasks on PCI Express Capability Register at @pos. Certain PCI Express + * Capability Registers are accessed concurrently in RMW fashion, hence + * require locking which is handled transparently to the caller. + */ +static inline int pcie_capability_clear_and_set_word(struct pci_dev *dev, + int pos, + u16 clear, u16 set) +{ + switch (pos) { + case PCI_EXP_LNKCTL: + case PCI_EXP_RTCTL: + return pcie_capability_clear_and_set_word_locked(dev, pos, + clear, set); + default: + return pcie_capability_clear_and_set_word_unlocked(dev, pos, + clear, set); + } +} + static inline int pcie_capability_set_word(struct pci_dev *dev, int pos, u16 set) { diff -u linux-6.2.0/include/linux/perf_event.h linux-6.2.0/include/linux/perf_event.h --- linux-6.2.0/include/linux/perf_event.h +++ linux-6.2.0/include/linux/perf_event.h @@ -1203,15 +1203,31 @@ struct pt_regs *regs); static inline bool -is_default_overflow_handler(struct perf_event *event) +__is_default_overflow_handler(perf_overflow_handler_t overflow_handler) { - if (likely(event->overflow_handler == perf_event_output_forward)) + if (likely(overflow_handler == perf_event_output_forward)) return true; - if (unlikely(event->overflow_handler == perf_event_output_backward)) + if (unlikely(overflow_handler == perf_event_output_backward)) return true; return false; } +#define is_default_overflow_handler(event) \ + __is_default_overflow_handler((event)->overflow_handler) + +#ifdef CONFIG_BPF_SYSCALL +static inline bool uses_default_overflow_handler(struct perf_event *event) +{ + if (likely(is_default_overflow_handler(event))) + return true; + + return __is_default_overflow_handler(event->orig_overflow_handler); +} +#else +#define uses_default_overflow_handler(event) \ + is_default_overflow_handler(event) +#endif + extern void perf_event_header__init_id(struct perf_event_header *header, struct perf_sample_data *data, diff -u linux-6.2.0/include/linux/security.h linux-6.2.0/include/linux/security.h --- linux-6.2.0/include/linux/security.h +++ linux-6.2.0/include/linux/security.h @@ -466,6 +466,7 @@ int security_bprm_check(struct linux_binprm *bprm); void security_bprm_committing_creds(struct linux_binprm *bprm); void security_bprm_committed_creds(struct linux_binprm *bprm); +int security_fs_context_submount(struct fs_context *fc, struct super_block *reference); int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc); int security_fs_context_parse_param(struct fs_context *fc, struct fs_parameter *param); int security_sb_alloc(struct super_block *sb); @@ -808,6 +809,11 @@ { } +static inline int security_fs_context_submount(struct fs_context *fc, + struct super_block *reference) +{ + return 0; +} static inline int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) { diff -u linux-6.2.0/include/net/cfg80211.h linux-6.2.0/include/net/cfg80211.h --- linux-6.2.0/include/net/cfg80211.h +++ linux-6.2.0/include/net/cfg80211.h @@ -5623,12 +5623,17 @@ * wiphy_lock - lock the wiphy * @wiphy: the wiphy to lock * - * This is mostly exposed so it can be done around registering and - * unregistering netdevs that aren't created through cfg80211 calls, - * since that requires locking in cfg80211 when the notifiers is - * called, but that cannot differentiate which way it's called. + * This is needed around registering and unregistering netdevs that + * aren't created through cfg80211 calls, since that requires locking + * in cfg80211 when the notifiers is called, but that cannot + * differentiate which way it's called. + * + * It can also be used by drivers for their own purposes. * * When cfg80211 ops are called, the wiphy is already locked. + * + * Note that this makes sure that no workers that have been queued + * with wiphy_queue_work() are running. */ static inline void wiphy_lock(struct wiphy *wiphy) __acquires(&wiphy->mtx) @@ -5648,6 +5653,88 @@ mutex_unlock(&wiphy->mtx); } +struct wiphy_work; +typedef void (*wiphy_work_func_t)(struct wiphy *, struct wiphy_work *); + +struct wiphy_work { + struct list_head entry; + wiphy_work_func_t func; +}; + +static inline void wiphy_work_init(struct wiphy_work *work, + wiphy_work_func_t func) +{ + INIT_LIST_HEAD(&work->entry); + work->func = func; +} + +/** + * wiphy_work_queue - queue work for the wiphy + * @wiphy: the wiphy to queue for + * @work: the work item + * + * This is useful for work that must be done asynchronously, and work + * queued here has the special property that the wiphy mutex will be + * held as if wiphy_lock() was called, and that it cannot be running + * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can + * use just cancel_work() instead of cancel_work_sync(), it requires + * being in a section protected by wiphy_lock(). + */ +void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work); + +/** + * wiphy_work_cancel - cancel previously queued work + * @wiphy: the wiphy, for debug purposes + * @work: the work to cancel + * + * Cancel the work *without* waiting for it, this assumes being + * called under the wiphy mutex acquired by wiphy_lock(). + */ +void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work); + +struct wiphy_delayed_work { + struct wiphy_work work; + struct wiphy *wiphy; + struct timer_list timer; +}; + +void wiphy_delayed_work_timer(struct timer_list *t); + +static inline void wiphy_delayed_work_init(struct wiphy_delayed_work *dwork, + wiphy_work_func_t func) +{ + timer_setup(&dwork->timer, wiphy_delayed_work_timer, 0); + wiphy_work_init(&dwork->work, func); +} + +/** + * wiphy_delayed_work_queue - queue delayed work for the wiphy + * @wiphy: the wiphy to queue for + * @dwork: the delayable worker + * @delay: number of jiffies to wait before queueing + * + * This is useful for work that must be done asynchronously, and work + * queued here has the special property that the wiphy mutex will be + * held as if wiphy_lock() was called, and that it cannot be running + * after wiphy_lock() was called. Therefore, wiphy_cancel_work() can + * use just cancel_work() instead of cancel_work_sync(), it requires + * being in a section protected by wiphy_lock(). + */ +void wiphy_delayed_work_queue(struct wiphy *wiphy, + struct wiphy_delayed_work *dwork, + unsigned long delay); + +/** + * wiphy_delayed_work_cancel - cancel previously queued delayed work + * @wiphy: the wiphy, for debug purposes + * @dwork: the delayed work to cancel + * + * Cancel the work *without* waiting for it, this assumes being + * called under the wiphy mutex acquired by wiphy_lock(). + */ +void wiphy_delayed_work_cancel(struct wiphy *wiphy, + struct wiphy_delayed_work *dwork); + /** * struct wireless_dev - wireless device state * @@ -5720,6 +5807,7 @@ * @event_lock: (private) lock for event list * @owner_nlportid: (private) owner socket port ID * @nl_owner_dead: (private) owner socket went away + * @cqm_rssi_work: (private) CQM RSSI reporting work * @cqm_config: (private) nl80211 RSSI monitor state * @pmsr_list: (private) peer measurement requests * @pmsr_lock: (private) peer measurements requests/results lock @@ -5792,7 +5880,8 @@ } wext; #endif - struct cfg80211_cqm_config *cqm_config; + struct wiphy_work cqm_rssi_work; + struct cfg80211_cqm_config __rcu *cqm_config; struct list_head pmsr_list; spinlock_t pmsr_lock; @@ -6949,7 +7038,7 @@ int uapsd_queues; const u8 *ap_mld_addr; struct { - const u8 *addr; + u8 addr[ETH_ALEN] __aligned(2); struct cfg80211_bss *bss; u16 status; } links[IEEE80211_MLD_MAX_NUM_LINKS]; diff -u linux-6.2.0/include/net/ip.h linux-6.2.0/include/net/ip.h --- linux-6.2.0/include/net/ip.h +++ linux-6.2.0/include/net/ip.h @@ -57,6 +57,7 @@ #define IPSKB_FRAG_PMTU BIT(6) #define IPSKB_L3SLAVE BIT(7) #define IPSKB_NOPOLICY BIT(8) +#define IPSKB_MULTIPATH BIT(9) u16 frag_max_size; }; @@ -94,7 +95,7 @@ ipcm_init(ipcm); ipcm->sockc.mark = READ_ONCE(inet->sk.sk_mark); - ipcm->sockc.tsflags = inet->sk.sk_tsflags; + ipcm->sockc.tsflags = READ_ONCE(inet->sk.sk_tsflags); ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if); ipcm->addr = inet->inet_saddr; ipcm->protocol = inet->inet_num; diff -u linux-6.2.0/include/net/ip_tunnels.h linux-6.2.0/include/net/ip_tunnels.h --- linux-6.2.0/include/net/ip_tunnels.h +++ linux-6.2.0/include/net/ip_tunnels.h @@ -501,15 +501,14 @@ u64_stats_inc(&tstats->tx_packets); u64_stats_update_end(&tstats->syncp); put_cpu_ptr(tstats); - } else { - struct net_device_stats *err_stats = &dev->stats; + return; + } - if (pkt_len < 0) { - err_stats->tx_errors++; - err_stats->tx_aborted_errors++; - } else { - err_stats->tx_dropped++; - } + if (pkt_len < 0) { + DEV_STATS_INC(dev, tx_errors); + DEV_STATS_INC(dev, tx_aborted_errors); + } else { + DEV_STATS_INC(dev, tx_dropped); } } diff -u linux-6.2.0/include/net/ipv6.h linux-6.2.0/include/net/ipv6.h --- linux-6.2.0/include/net/ipv6.h +++ linux-6.2.0/include/net/ipv6.h @@ -783,6 +783,11 @@ cpu_to_be32(0x0000ffff))) == 0UL; } +static inline bool ipv6_addr_v4mapped_any(const struct in6_addr *a) +{ + return ipv6_addr_v4mapped(a) && ipv4_is_zeronet(a->s6_addr32[3]); +} + static inline bool ipv6_addr_v4mapped_loopback(const struct in6_addr *a) { return ipv6_addr_v4mapped(a) && ipv4_is_loopback(a->s6_addr32[3]); @@ -1355,7 +1360,7 @@ return 0; } -static inline int ip6_sock_set_addr_preferences(struct sock *sk, bool val) +static inline int ip6_sock_set_addr_preferences(struct sock *sk, int val) { int ret; diff -u linux-6.2.0/include/net/mac80211.h linux-6.2.0/include/net/mac80211.h --- linux-6.2.0/include/net/mac80211.h +++ linux-6.2.0/include/net/mac80211.h @@ -1142,9 +1142,11 @@ u8 ampdu_ack_len; u8 ampdu_len; u8 antenna; + u8 pad; u16 tx_time; u8 flags; - void *status_driver_data[18 / sizeof(void *)]; + u8 pad2; + void *status_driver_data[16 / sizeof(void *)]; } status; struct { struct ieee80211_tx_rate driver_rates[ diff -u linux-6.2.0/include/net/neighbour.h linux-6.2.0/include/net/neighbour.h --- linux-6.2.0/include/net/neighbour.h +++ linux-6.2.0/include/net/neighbour.h @@ -299,14 +299,14 @@ const void *pkey, struct net_device *dev) { - struct neigh_hash_table *nht = rcu_dereference_bh(tbl->nht); + struct neigh_hash_table *nht = rcu_dereference(tbl->nht); struct neighbour *n; u32 hash_val; hash_val = hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); - for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); + for (n = rcu_dereference(nht->hash_buckets[hash_val]); n != NULL; - n = rcu_dereference_bh(n->next)) { + n = rcu_dereference(n->next)) { if (n->dev == dev && key_eq(n, pkey)) return n; } @@ -464,7 +464,7 @@ if (READ_ONCE(neigh->used) != now) WRITE_ONCE(neigh->used, now); - if (!(neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))) + if (!(READ_ONCE(neigh->nud_state) & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE))) return __neigh_event_send(neigh, skb, immediate_ok); return 0; } @@ -541,7 +541,7 @@ READ_ONCE(hh->hh_len)) return neigh_hh_output(hh, skb); - return n->output(n, skb); + return READ_ONCE(n->output)(n, skb); } static inline struct neighbour * diff -u linux-6.2.0/include/net/netfilter/nf_tables.h linux-6.2.0/include/net/netfilter/nf_tables.h --- linux-6.2.0/include/net/netfilter/nf_tables.h +++ linux-6.2.0/include/net/netfilter/nf_tables.h @@ -1665,7 +1665,7 @@ struct net *net; struct nft_set *set; u32 seq; - u8 count; + u16 count; void *priv[NFT_TRANS_GC_BATCHCOUNT]; struct rcu_head rcu; }; @@ -1683,8 +1683,9 @@ void nft_trans_gc_elem_add(struct nft_trans_gc *gc, void *priv); -struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc, - unsigned int gc_seq); +struct nft_trans_gc *nft_trans_gc_catchall_async(struct nft_trans_gc *gc, + unsigned int gc_seq); +struct nft_trans_gc *nft_trans_gc_catchall_sync(struct nft_trans_gc *gc); void nft_setelem_data_deactivate(const struct net *net, const struct nft_set *set, diff -u linux-6.2.0/include/net/sock.h linux-6.2.0/include/net/sock.h --- linux-6.2.0/include/net/sock.h +++ linux-6.2.0/include/net/sock.h @@ -1053,6 +1053,12 @@ WRITE_ONCE(sk->sk_wmem_queued, sk->sk_wmem_queued + val); } +static inline void sk_forward_alloc_add(struct sock *sk, int val) +{ + /* Paired with lockless reads of sk->sk_forward_alloc */ + WRITE_ONCE(sk->sk_forward_alloc, sk->sk_forward_alloc + val); +} + void sk_stream_write_space(struct sock *sk); /* OOB backlog add */ @@ -1405,7 +1411,7 @@ if (sk->sk_prot->forward_alloc_get) return sk->sk_prot->forward_alloc_get(sk); #endif - return sk->sk_forward_alloc; + return READ_ONCE(sk->sk_forward_alloc); } static inline bool __sk_stream_memory_free(const struct sock *sk, int wake) @@ -1701,14 +1707,14 @@ { if (!sk_has_account(sk)) return; - sk->sk_forward_alloc -= size; + sk_forward_alloc_add(sk, -size); } static inline void sk_mem_uncharge(struct sock *sk, int size) { if (!sk_has_account(sk)) return; - sk->sk_forward_alloc += size; + sk_forward_alloc_add(sk, size); sk_mem_reclaim(sk); } @@ -1928,7 +1934,9 @@ static inline void sockcm_init(struct sockcm_cookie *sockc, const struct sock *sk) { - *sockc = (struct sockcm_cookie) { .tsflags = sk->sk_tsflags }; + *sockc = (struct sockcm_cookie) { + .tsflags = READ_ONCE(sk->sk_tsflags) + }; } int __sock_cmsg_send(struct sock *sk, struct cmsghdr *cmsg, @@ -2727,9 +2735,9 @@ static inline void sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) { - ktime_t kt = skb->tstamp; struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); - + u32 tsflags = READ_ONCE(sk->sk_tsflags); + ktime_t kt = skb->tstamp; /* * generate control messages if * - receive time stamping in software requested @@ -2737,10 +2745,10 @@ * - hardware time stamps available and wanted */ if (sock_flag(sk, SOCK_RCVTSTAMP) || - (sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) || - (kt && sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) || + (tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) || + (kt && tsflags & SOF_TIMESTAMPING_SOFTWARE) || (hwtstamps->hwtstamp && - (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE))) + (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE))) __sock_recv_timestamp(msg, sk, skb); else sock_write_timestamp(sk, kt); @@ -2762,7 +2770,8 @@ #define TSFLAGS_ANY (SOF_TIMESTAMPING_SOFTWARE | \ SOF_TIMESTAMPING_RAW_HARDWARE) - if (sk->sk_flags & FLAGS_RECV_CMSGS || sk->sk_tsflags & TSFLAGS_ANY) + if (sk->sk_flags & FLAGS_RECV_CMSGS || + READ_ONCE(sk->sk_tsflags) & TSFLAGS_ANY) __sock_recv_cmsgs(msg, sk, skb); else if (unlikely(sock_flag(sk, SOCK_TIMESTAMP))) sock_write_timestamp(sk, skb->tstamp); diff -u linux-6.2.0/include/net/tcp.h linux-6.2.0/include/net/tcp.h --- linux-6.2.0/include/net/tcp.h +++ linux-6.2.0/include/net/tcp.h @@ -355,13 +355,14 @@ struct sk_buff *tcp_stream_alloc_skb(struct sock *sk, int size, gfp_t gfp, bool force_schedule); -void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks); -static inline void tcp_dec_quickack_mode(struct sock *sk, - const unsigned int pkts) +static inline void tcp_dec_quickack_mode(struct sock *sk) { struct inet_connection_sock *icsk = inet_csk(sk); if (icsk->icsk_ack.quick) { + /* How many ACKs S/ACKing new data have we sent? */ + const unsigned int pkts = inet_csk_ack_scheduled(sk) ? 1 : 0; + if (pkts >= icsk->icsk_ack.quick) { icsk->icsk_ack.quick = 0; /* Leaving quickack mode we deflate ATO. */ diff -u linux-6.2.0/include/scsi/scsi_device.h linux-6.2.0/include/scsi/scsi_device.h --- linux-6.2.0/include/scsi/scsi_device.h +++ linux-6.2.0/include/scsi/scsi_device.h @@ -161,6 +161,10 @@ * pass settings from slave_alloc to scsi * core. */ unsigned int eh_timeout; /* Error handling timeout */ + + bool manage_system_start_stop; /* Let HLD (sd) manage system start/stop */ + bool manage_runtime_start_stop; /* Let HLD (sd) manage runtime start/stop */ + unsigned removable:1; unsigned changed:1; /* Data invalid due to media change */ unsigned busy:1; /* Used to prevent races */ @@ -193,7 +197,7 @@ unsigned use_192_bytes_for_3f:1; /* ask for 192 bytes from page 0x3f */ unsigned no_start_on_add:1; /* do not issue start on add */ unsigned allow_restart:1; /* issue START_UNIT in error handler */ - unsigned manage_start_stop:1; /* Let HLD (sd) manage start/stop */ + unsigned no_start_on_resume:1; /* Do not issue START_STOP_UNIT on resume */ unsigned start_stop_pwr_cond:1; /* Set power cond. in START_STOP_UNIT */ unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ unsigned select_no_atn:1; diff -u linux-6.2.0/include/uapi/linux/bpf.h linux-6.2.0/include/uapi/linux/bpf.h --- linux-6.2.0/include/uapi/linux/bpf.h +++ linux-6.2.0/include/uapi/linux/bpf.h @@ -1845,7 +1845,9 @@ * performed again, if the helper is used in combination with * direct packet access. * Return - * 0 on success, or a negative error in case of failure. + * 0 on success, or a negative error in case of failure. Positive + * error indicates a potential drop or congestion in the target + * device. The particular positive error codes are not defined. * * u64 bpf_get_current_pid_tgid(void) * Description @@ -3121,6 +3123,11 @@ * **BPF_FIB_LOOKUP_OUTPUT** * Perform lookup from an egress perspective (default is * ingress). + * **BPF_FIB_LOOKUP_SKIP_NEIGH** + * Skip the neighbour table lookup. *params*->dmac + * and *params*->smac will not be set as output. A common + * use case is to call **bpf_redirect_neigh**\ () after + * doing **bpf_fib_lookup**\ (). * * *ctx* is either **struct xdp_md** for XDP programs or * **struct sk_buff** tc cls_act programs. @@ -6734,6 +6741,7 @@ enum { BPF_FIB_LOOKUP_DIRECT = (1U << 0), BPF_FIB_LOOKUP_OUTPUT = (1U << 1), + BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2), }; enum { diff -u linux-6.2.0/init/Kconfig linux-6.2.0/init/Kconfig --- linux-6.2.0/init/Kconfig +++ linux-6.2.0/init/Kconfig @@ -639,6 +639,7 @@ config PSI bool "Pressure stall information tracking" + select KERNFS help Collect metrics that indicate how overcommitted the CPU, memory, and IO capacity are in the system. diff -u linux-6.2.0/io_uring/io_uring.c linux-6.2.0/io_uring/io_uring.c --- linux-6.2.0/io_uring/io_uring.c +++ linux-6.2.0/io_uring/io_uring.c @@ -1619,6 +1619,9 @@ break; nr_events += ret; ret = 0; + + if (task_sigpending(current)) + return -EINTR; } while (nr_events < min && !need_resched()); return ret; @@ -1975,6 +1978,8 @@ if (!needs_poll) { if (!(req->ctx->flags & IORING_SETUP_IOPOLL)) break; + if (io_wq_worker_stopped()) + break; cond_resched(); continue; } @@ -2395,7 +2400,9 @@ } /* drop invalid entries */ + spin_lock(&ctx->completion_lock); ctx->cq_extra--; + spin_unlock(&ctx->completion_lock); WRITE_ONCE(ctx->rings->sq_dropped, READ_ONCE(ctx->rings->sq_dropped) + 1); return NULL; @@ -4000,16 +4007,28 @@ return 0; } +static __cold int __io_register_iowq_aff(struct io_ring_ctx *ctx, + cpumask_var_t new_mask) +{ + int ret; + + if (!(ctx->flags & IORING_SETUP_SQPOLL)) { + ret = io_wq_cpu_affinity(current->io_uring, new_mask); + } else { + mutex_unlock(&ctx->uring_lock); + ret = io_sqpoll_wq_cpu_affinity(ctx, new_mask); + mutex_lock(&ctx->uring_lock); + } + + return ret; +} + static __cold int io_register_iowq_aff(struct io_ring_ctx *ctx, void __user *arg, unsigned len) { - struct io_uring_task *tctx = current->io_uring; cpumask_var_t new_mask; int ret; - if (!tctx || !tctx->io_wq) - return -EINVAL; - if (!alloc_cpumask_var(&new_mask, GFP_KERNEL)) return -ENOMEM; @@ -4030,19 +4049,14 @@ return -EFAULT; } - ret = io_wq_cpu_affinity(tctx->io_wq, new_mask); + ret = __io_register_iowq_aff(ctx, new_mask); free_cpumask_var(new_mask); return ret; } static __cold int io_unregister_iowq_aff(struct io_ring_ctx *ctx) { - struct io_uring_task *tctx = current->io_uring; - - if (!tctx || !tctx->io_wq) - return -EINVAL; - - return io_wq_cpu_affinity(tctx->io_wq, NULL); + return __io_register_iowq_aff(ctx, NULL); } static __cold int io_register_iowq_max_workers(struct io_ring_ctx *ctx, diff -u linux-6.2.0/io_uring/net.c linux-6.2.0/io_uring/net.c --- linux-6.2.0/io_uring/net.c +++ linux-6.2.0/io_uring/net.c @@ -183,6 +183,10 @@ memcpy(async_msg, kmsg, sizeof(*kmsg)); if (async_msg->msg.msg_name) async_msg->msg.msg_name = &async_msg->addr; + + if ((req->flags & REQ_F_BUFFER_SELECT) && !async_msg->msg.msg_iter.nr_segs) + return -EAGAIN; + /* if were using fast_iov, set it to the new one */ if (!kmsg->free_iov) { size_t fast_idx = kmsg->msg.msg_iter.iov - kmsg->fast_iov; @@ -542,6 +546,7 @@ struct io_async_msghdr *iomsg) { iomsg->msg.msg_name = &iomsg->addr; + iomsg->msg.msg_iter.nr_segs = 0; #ifdef CONFIG_COMPAT if (req->ctx->compat) @@ -1366,7 +1371,7 @@ if (ret < 0) return ret; if (io_aux_cqe(ctx, issue_flags & IO_URING_F_COMPLETE_DEFER, - req->cqe.user_data, ret, IORING_CQE_F_MORE, true)) + req->cqe.user_data, ret, IORING_CQE_F_MORE, false)) goto retry; return -ECANCELED; diff -u linux-6.2.0/io_uring/rsrc.h linux-6.2.0/io_uring/rsrc.h --- linux-6.2.0/io_uring/rsrc.h +++ linux-6.2.0/io_uring/rsrc.h @@ -80,17 +80,10 @@ int __io_scm_file_account(struct io_ring_ctx *ctx, struct file *file); -#if defined(CONFIG_UNIX) -static inline bool io_file_need_scm(struct file *filp) -{ - return !!unix_get_socket(filp); -} -#else static inline bool io_file_need_scm(struct file *filp) { return false; } -#endif static inline int io_scm_file_account(struct io_ring_ctx *ctx, struct file *file) diff -u linux-6.2.0/io_uring/sqpoll.c linux-6.2.0/io_uring/sqpoll.c --- linux-6.2.0/io_uring/sqpoll.c +++ linux-6.2.0/io_uring/sqpoll.c @@ -425,0 +426,17 @@ + +__cold int io_sqpoll_wq_cpu_affinity(struct io_ring_ctx *ctx, + cpumask_var_t mask) +{ + struct io_sq_data *sqd = ctx->sq_data; + int ret = -EINVAL; + + if (sqd) { + io_sq_thread_park(sqd); + /* Don't set affinity for a dying thread */ + if (sqd->thread) + ret = io_wq_cpu_affinity(sqd->thread->io_uring, mask); + io_sq_thread_unpark(sqd); + } + + return ret; +} diff -u linux-6.2.0/kernel/auditsc.c linux-6.2.0/kernel/auditsc.c --- linux-6.2.0/kernel/auditsc.c +++ linux-6.2.0/kernel/auditsc.c @@ -2188,7 +2188,7 @@ if (!n->name) continue; if (n->name->uptr == uptr) { - n->name->refcnt++; + atomic_inc(&n->name->refcnt); return n->name; } } @@ -2217,7 +2217,7 @@ n->name = name; n->name_len = AUDIT_NAME_FULL; name->aname = n; - name->refcnt++; + atomic_inc(&name->refcnt); } static inline int audit_copy_fcaps(struct audit_names *name, @@ -2349,7 +2349,7 @@ return; if (name) { n->name = name; - name->refcnt++; + atomic_inc(&name->refcnt); } out: @@ -2436,6 +2436,8 @@ } } + cond_resched(); + /* is there a matching child entry? */ list_for_each_entry(n, &context->names_list, list) { /* can only match entries that have a name */ @@ -2474,7 +2476,7 @@ if (found_parent) { found_child->name = found_parent->name; found_child->name_len = AUDIT_NAME_FULL; - found_child->name->refcnt++; + atomic_inc(&found_child->name->refcnt); } } diff -u linux-6.2.0/kernel/bpf/btf.c linux-6.2.0/kernel/bpf/btf.c --- linux-6.2.0/kernel/bpf/btf.c +++ linux-6.2.0/kernel/bpf/btf.c @@ -6325,7 +6325,7 @@ * that also allows using an array of int as a scratch * space. e.g. skb->cb[]. */ - if (off + size > mtrue_end) { + if (off + size > mtrue_end && !(*flag & PTR_UNTRUSTED)) { bpf_log(log, "access beyond the end of member %s (mend:%u) in struct %s with off %u size %u\n", mname, mtrue_end, tname, off, size); diff -u linux-6.2.0/kernel/bpf/queue_stack_maps.c linux-6.2.0/kernel/bpf/queue_stack_maps.c --- linux-6.2.0/kernel/bpf/queue_stack_maps.c +++ linux-6.2.0/kernel/bpf/queue_stack_maps.c @@ -102,7 +102,12 @@ int err = 0; void *ptr; - raw_spin_lock_irqsave(&qs->lock, flags); + if (in_nmi()) { + if (!raw_spin_trylock_irqsave(&qs->lock, flags)) + return -EBUSY; + } else { + raw_spin_lock_irqsave(&qs->lock, flags); + } if (queue_stack_map_is_empty(qs)) { memset(value, 0, qs->map.value_size); @@ -132,7 +137,12 @@ void *ptr; u32 index; - raw_spin_lock_irqsave(&qs->lock, flags); + if (in_nmi()) { + if (!raw_spin_trylock_irqsave(&qs->lock, flags)) + return -EBUSY; + } else { + raw_spin_lock_irqsave(&qs->lock, flags); + } if (queue_stack_map_is_empty(qs)) { memset(value, 0, qs->map.value_size); @@ -197,7 +207,12 @@ if (flags & BPF_NOEXIST || flags > BPF_EXIST) return -EINVAL; - raw_spin_lock_irqsave(&qs->lock, irq_flags); + if (in_nmi()) { + if (!raw_spin_trylock_irqsave(&qs->lock, irq_flags)) + return -EBUSY; + } else { + raw_spin_lock_irqsave(&qs->lock, irq_flags); + } if (queue_stack_map_is_full(qs)) { if (!replace) { diff -u linux-6.2.0/kernel/bpf/syscall.c linux-6.2.0/kernel/bpf/syscall.c --- linux-6.2.0/kernel/bpf/syscall.c +++ linux-6.2.0/kernel/bpf/syscall.c @@ -5151,9 +5151,9 @@ } run_ctx.bpf_cookie = 0; - run_ctx.saved_run_ctx = NULL; if (!__bpf_prog_enter_sleepable_recur(prog, &run_ctx)) { /* recursion detected */ + __bpf_prog_exit_sleepable_recur(prog, 0, &run_ctx); bpf_prog_put(prog); return -EBUSY; } diff -u linux-6.2.0/kernel/bpf/trampoline.c linux-6.2.0/kernel/bpf/trampoline.c --- linux-6.2.0/kernel/bpf/trampoline.c +++ linux-6.2.0/kernel/bpf/trampoline.c @@ -954,13 +954,12 @@ migrate_disable(); might_fault(); + run_ctx->saved_run_ctx = bpf_set_run_ctx(&run_ctx->run_ctx); + if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) { bpf_prog_inc_misses_counter(prog); return 0; } - - run_ctx->saved_run_ctx = bpf_set_run_ctx(&run_ctx->run_ctx); - return bpf_prog_start_time(); } diff -u linux-6.2.0/kernel/bpf/verifier.c linux-6.2.0/kernel/bpf/verifier.c --- linux-6.2.0/kernel/bpf/verifier.c +++ linux-6.2.0/kernel/bpf/verifier.c @@ -6571,17 +6571,6 @@ if (arg_type_is_dynptr(arg_type) && type == PTR_TO_STACK) return 0; - if ((type_is_ptr_alloc_obj(type) || type_is_non_owning_ref(type)) && reg->off) { - if (reg_find_field_offset(reg, reg->off, BPF_GRAPH_NODE_OR_ROOT)) - return __check_ptr_off_reg(env, reg, regno, true); - - verbose(env, "R%d must have zero offset when passed to release func\n", - regno); - verbose(env, "No graph node or root found at R%d type:%s off:%d\n", regno, - kernel_type_name(reg->btf, reg->btf_id), reg->off); - return -EINVAL; - } - /* Doing check_ptr_off_reg check for the offset will catch this * because fixed_off_ok is false, but checking here allows us * to give the user a better error message. @@ -12334,6 +12323,12 @@ return -EINVAL; } + /* check src2 operand */ + err = check_reg_arg(env, insn->dst_reg, SRC_OP); + if (err) + return err; + + dst_reg = ®s[insn->dst_reg]; if (BPF_SRC(insn->code) == BPF_X) { if (insn->imm != 0) { verbose(env, "BPF_JMP/JMP32 uses reserved fields\n"); @@ -12345,12 +12340,13 @@ if (err) return err; - if (is_pointer_value(env, insn->src_reg)) { + src_reg = ®s[insn->src_reg]; + if (!(reg_is_pkt_pointer_any(dst_reg) && reg_is_pkt_pointer_any(src_reg)) && + is_pointer_value(env, insn->src_reg)) { verbose(env, "R%d pointer comparison prohibited\n", insn->src_reg); return -EACCES; } - src_reg = ®s[insn->src_reg]; } else { if (insn->src_reg != BPF_REG_0) { verbose(env, "BPF_JMP/JMP32 uses reserved fields\n"); @@ -12358,12 +12354,6 @@ } } - /* check src2 operand */ - err = check_reg_arg(env, insn->dst_reg, SRC_OP); - if (err) - return err; - - dst_reg = ®s[insn->dst_reg]; is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32; if (BPF_SRC(insn->code) == BPF_K) { diff -u linux-6.2.0/kernel/cgroup/cpuset.c linux-6.2.0/kernel/cgroup/cpuset.c --- linux-6.2.0/kernel/cgroup/cpuset.c +++ linux-6.2.0/kernel/cgroup/cpuset.c @@ -1606,11 +1606,16 @@ } /* - * Skip the whole subtree if the cpumask remains the same - * and has no partition root state and force flag not set. + * Skip the whole subtree if + * 1) the cpumask remains the same, + * 2) has no partition root state, + * 3) force flag not set, and + * 4) for v2 load balance state same as its parent. */ if (!cp->partition_root_state && !force && - cpumask_equal(tmp->new_cpus, cp->effective_cpus)) { + cpumask_equal(tmp->new_cpus, cp->effective_cpus) && + (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) || + (is_sched_load_balance(parent) == is_sched_load_balance(cp)))) { pos_css = css_rightmost_descendant(pos_css); continue; } @@ -1694,6 +1699,20 @@ update_tasks_cpumask(cp, tmp->new_cpus); /* + * On default hierarchy, inherit the CS_SCHED_LOAD_BALANCE + * from parent if current cpuset isn't a valid partition root + * and their load balance states differ. + */ + if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && + !is_partition_valid(cp) && + (is_sched_load_balance(parent) != is_sched_load_balance(cp))) { + if (is_sched_load_balance(parent)) + set_bit(CS_SCHED_LOAD_BALANCE, &cp->flags); + else + clear_bit(CS_SCHED_LOAD_BALANCE, &cp->flags); + } + + /* * On legacy hierarchy, if the effective cpumask of any non- * empty cpuset is changed, we need to rebuild sched domains. * On default hierarchy, the cpuset needs to be a partition @@ -3239,6 +3258,14 @@ cs->use_parent_ecpus = true; parent->child_ecpus_count++; } + + /* + * For v2, clear CS_SCHED_LOAD_BALANCE if parent is isolated + */ + if (cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && + !is_sched_load_balance(parent)) + clear_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); + spin_unlock_irq(&callback_lock); if (!test_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags)) diff -u linux-6.2.0/kernel/dma/swiotlb.c linux-6.2.0/kernel/dma/swiotlb.c --- linux-6.2.0/kernel/dma/swiotlb.c +++ linux-6.2.0/kernel/dma/swiotlb.c @@ -401,14 +401,14 @@ } mem->areas = memblock_alloc(array_size(sizeof(struct io_tlb_area), - default_nareas), SMP_CACHE_BYTES); + nareas), SMP_CACHE_BYTES); if (!mem->areas) { pr_warn("%s: Failed to allocate mem->areas.\n", __func__); return; } swiotlb_init_io_tlb_mem(mem, __pa(tlb), nslabs, flags, false, - default_nareas); + nareas); if (flags & SWIOTLB_VERBOSE) swiotlb_print_info(); diff -u linux-6.2.0/kernel/events/core.c linux-6.2.0/kernel/events/core.c --- linux-6.2.0/kernel/events/core.c +++ linux-6.2.0/kernel/events/core.c @@ -1808,31 +1808,34 @@ PERF_EVENT_STATE_INACTIVE; } -static void __perf_event_read_size(struct perf_event *event, int nr_siblings) +static int __perf_event_read_size(u64 read_format, int nr_siblings) { int entry = sizeof(u64); /* value */ int size = 0; int nr = 1; - if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) + if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) size += sizeof(u64); - if (event->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) + if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) size += sizeof(u64); - if (event->attr.read_format & PERF_FORMAT_ID) + if (read_format & PERF_FORMAT_ID) entry += sizeof(u64); - if (event->attr.read_format & PERF_FORMAT_LOST) + if (read_format & PERF_FORMAT_LOST) entry += sizeof(u64); - if (event->attr.read_format & PERF_FORMAT_GROUP) { + if (read_format & PERF_FORMAT_GROUP) { nr += nr_siblings; size += sizeof(u64); } - size += entry * nr; - event->read_size = size; + /* + * Since perf_event_validate_size() limits this to 16k and inhibits + * adding more siblings, this will never overflow. + */ + return size + nr * entry; } static void __perf_event_header_size(struct perf_event *event, u64 sample_type) @@ -1882,8 +1885,9 @@ */ static void perf_event__header_size(struct perf_event *event) { - __perf_event_read_size(event, - event->group_leader->nr_siblings); + event->read_size = + __perf_event_read_size(event->attr.read_format, + event->group_leader->nr_siblings); __perf_event_header_size(event, event->attr.sample_type); } @@ -1914,23 +1918,44 @@ event->id_header_size = size; } +/* + * Check that adding an event to the group does not result in anybody + * overflowing the 64k event limit imposed by the output buffer. + * + * Specifically, check that the read_size for the event does not exceed 16k, + * read_size being the one term that grows with groups size. Since read_size + * depends on per-event read_format, also (re)check the existing events. + * + * This leaves 48k for the constant size fields and things like callchains, + * branch stacks and register sets. + */ static bool perf_event_validate_size(struct perf_event *event) { - /* - * The values computed here will be over-written when we actually - * attach the event. - */ - __perf_event_read_size(event, event->group_leader->nr_siblings + 1); - __perf_event_header_size(event, event->attr.sample_type & ~PERF_SAMPLE_READ); - perf_event__id_header_size(event); + struct perf_event *sibling, *group_leader = event->group_leader; + + if (__perf_event_read_size(event->attr.read_format, + group_leader->nr_siblings + 1) > 16*1024) + return false; + + if (__perf_event_read_size(group_leader->attr.read_format, + group_leader->nr_siblings + 1) > 16*1024) + return false; /* - * Sum the lot; should not exceed the 64k limit we have on records. - * Conservative limit to allow for callchains and other variable fields. + * When creating a new group leader, group_leader->ctx is initialized + * after the size has been validated, but we cannot safely use + * for_each_sibling_event() until group_leader->ctx is set. A new group + * leader cannot have any siblings yet, so we can safely skip checking + * the non-existent siblings. */ - if (event->read_size + event->header_size + - event->id_header_size + sizeof(struct perf_event_header) >= 16*1024) - return false; + if (event == group_leader) + return true; + + for_each_sibling_event(sibling, group_leader) { + if (__perf_event_read_size(sibling->attr.read_format, + group_leader->nr_siblings + 1) > 16*1024) + return false; + } return true; } diff -u linux-6.2.0/kernel/fork.c linux-6.2.0/kernel/fork.c --- linux-6.2.0/kernel/fork.c +++ linux-6.2.0/kernel/fork.c @@ -867,6 +867,14 @@ } EXPORT_SYMBOL_GPL(__put_task_struct); +void __put_task_struct_rcu_cb(struct rcu_head *rhp) +{ + struct task_struct *task = container_of(rhp, struct task_struct, rcu); + + __put_task_struct(task); +} +EXPORT_SYMBOL_GPL(__put_task_struct_rcu_cb); + void __init __weak arch_task_cache_init(void) { } /* diff -u linux-6.2.0/kernel/kprobes.c linux-6.2.0/kernel/kprobes.c --- linux-6.2.0/kernel/kprobes.c +++ linux-6.2.0/kernel/kprobes.c @@ -1545,6 +1545,17 @@ return 0; } +static bool is_cfi_preamble_symbol(unsigned long addr) +{ + char symbuf[KSYM_NAME_LEN]; + + if (lookup_symbol_name(addr, symbuf)) + return false; + + return str_has_prefix("__cfi_", symbuf) || + str_has_prefix("__pfx_", symbuf); +} + static int check_kprobe_address_safe(struct kprobe *p, struct module **probed_mod) { @@ -1563,7 +1574,8 @@ within_kprobe_blacklist((unsigned long) p->addr) || jump_label_text_reserved(p->addr, p->addr) || static_call_text_reserved(p->addr, p->addr) || - find_bug((unsigned long)p->addr)) { + find_bug((unsigned long)p->addr) || + is_cfi_preamble_symbol((unsigned long)p->addr)) { ret = -EINVAL; goto out; } diff -u linux-6.2.0/kernel/panic.c linux-6.2.0/kernel/panic.c --- linux-6.2.0/kernel/panic.c +++ linux-6.2.0/kernel/panic.c @@ -696,6 +696,7 @@ if (!fmt) { __warn(file, line, __builtin_return_address(0), taint, NULL, NULL); + warn_rcu_exit(rcu); return; } diff -u linux-6.2.0/kernel/rcu/rcuscale.c linux-6.2.0/kernel/rcu/rcuscale.c --- linux-6.2.0/kernel/rcu/rcuscale.c +++ linux-6.2.0/kernel/rcu/rcuscale.c @@ -424,7 +424,7 @@ sched_set_fifo_low(current); if (holdoff) - schedule_timeout_uninterruptible(holdoff * HZ); + schedule_timeout_idle(holdoff * HZ); /* * Wait until rcu_end_inkernel_boot() is called for normal GP tests diff -u linux-6.2.0/kernel/rcu/refscale.c linux-6.2.0/kernel/rcu/refscale.c --- linux-6.2.0/kernel/rcu/refscale.c +++ linux-6.2.0/kernel/rcu/refscale.c @@ -867,12 +867,11 @@ VERBOSE_SCALEOUT("Starting %d reader threads", nreaders); for (i = 0; i < nreaders; i++) { + init_waitqueue_head(&reader_tasks[i].wq); firsterr = torture_create_kthread(ref_scale_reader, (void *)i, reader_tasks[i].task); if (torture_init_error(firsterr)) goto unwind; - - init_waitqueue_head(&(reader_tasks[i].wq)); } // Main Task diff -u linux-6.2.0/kernel/sched/core.c linux-6.2.0/kernel/sched/core.c --- linux-6.2.0/kernel/sched/core.c +++ linux-6.2.0/kernel/sched/core.c @@ -9126,7 +9126,7 @@ * PF_KTHREAD should already be set at this point; regardless, make it * look like a proper per-CPU kthread. */ - idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY; + idle->flags |= PF_KTHREAD | PF_NO_SETAFFINITY; kthread_set_per_cpu(idle, cpu); #ifdef CONFIG_SMP diff -u linux-6.2.0/kernel/sched/rt.c linux-6.2.0/kernel/sched/rt.c --- linux-6.2.0/kernel/sched/rt.c +++ linux-6.2.0/kernel/sched/rt.c @@ -25,7 +25,7 @@ int sysctl_sched_rt_runtime = 950000; #ifdef CONFIG_SYSCTL -static int sysctl_sched_rr_timeslice = (MSEC_PER_SEC / HZ) * RR_TIMESLICE; +static int sysctl_sched_rr_timeslice = (MSEC_PER_SEC * RR_TIMESLICE) / HZ; static int sched_rt_handler(struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos); static int sched_rr_handler(struct ctl_table *table, int write, void *buffer, diff -u linux-6.2.0/kernel/time/tick-sched.c linux-6.2.0/kernel/time/tick-sched.c --- linux-6.2.0/kernel/time/tick-sched.c +++ linux-6.2.0/kernel/time/tick-sched.c @@ -1050,7 +1050,7 @@ return false; /* On RT, softirqs handling may be waiting on some lock */ - if (!local_bh_blocked()) + if (local_bh_blocked()) return false; pr_warn("NOHZ tick-stop error: local softirq work is pending, handler #%02x!!!\n", diff -u linux-6.2.0/kernel/trace/bpf_trace.c linux-6.2.0/kernel/trace/bpf_trace.c --- linux-6.2.0/kernel/trace/bpf_trace.c +++ linux-6.2.0/kernel/trace/bpf_trace.c @@ -2399,7 +2399,7 @@ #ifdef CONFIG_UPROBE_EVENTS if (flags & TRACE_EVENT_FL_UPROBE) err = bpf_get_uprobe_info(event, fd_type, buf, - probe_offset, + probe_offset, probe_addr, event->attr.type == PERF_TYPE_TRACEPOINT); #endif } @@ -2770,6 +2770,17 @@ return args.mods_cnt; } +static int addrs_check_error_injection_list(unsigned long *addrs, u32 cnt) +{ + u32 i; + + for (i = 0; i < cnt; i++) { + if (!within_error_injection_list(addrs[i])) + return -EINVAL; + } + return 0; +} + int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) { struct bpf_kprobe_multi_link *link = NULL; @@ -2847,6 +2858,11 @@ goto error; } + if (prog->kprobe_override && addrs_check_error_injection_list(addrs, cnt)) { + err = -EINVAL; + goto error; + } + link = kzalloc(sizeof(*link), GFP_KERNEL); if (!link) { err = -ENOMEM; diff -u linux-6.2.0/kernel/trace/ring_buffer.c linux-6.2.0/kernel/trace/ring_buffer.c --- linux-6.2.0/kernel/trace/ring_buffer.c +++ linux-6.2.0/kernel/trace/ring_buffer.c @@ -354,10 +354,11 @@ local_set(&bpage->commit, 0); } -/* - * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing - * this issue out. - */ +static __always_inline unsigned int rb_page_commit(struct buffer_page *bpage) +{ + return local_read(&bpage->page->commit); +} + static void free_buffer_page(struct buffer_page *bpage) { free_page((unsigned long)bpage->page); @@ -1142,6 +1143,9 @@ if (full) { poll_wait(filp, &work->full_waiters, poll_table); work->full_waiters_pending = true; + if (!cpu_buffer->shortest_full || + cpu_buffer->shortest_full > full) + cpu_buffer->shortest_full = full; } else { poll_wait(filp, &work->waiters, poll_table); work->waiters_pending = true; @@ -2021,7 +2025,7 @@ * Increment overrun to account for the lost events. */ local_add(page_entries, &cpu_buffer->overrun); - local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); + local_sub(rb_page_commit(to_remove_page), &cpu_buffer->entries_bytes); local_inc(&cpu_buffer->pages_lost); } @@ -2214,6 +2218,8 @@ err = -ENOMEM; goto out_err; } + + cond_resched(); } cpus_read_lock(); @@ -2381,11 +2387,6 @@ cpu_buffer->reader_page->read); } -static __always_inline unsigned rb_page_commit(struct buffer_page *bpage) -{ - return local_read(&bpage->page->commit); -} - static struct ring_buffer_event * rb_iter_head_event(struct ring_buffer_iter *iter) { @@ -2404,6 +2405,11 @@ */ commit = rb_page_commit(iter_head_page); smp_rmb(); + + /* An event needs to be at least 8 bytes in size */ + if (iter->head > commit - 8) + goto reset; + event = __rb_page_index(iter_head_page, iter->head); length = rb_event_length(event); @@ -2526,7 +2532,7 @@ * the counters. */ local_add(entries, &cpu_buffer->overrun); - local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); + local_sub(rb_page_commit(next_page), &cpu_buffer->entries_bytes); local_inc(&cpu_buffer->pages_lost); /* @@ -2669,9 +2675,6 @@ event = __rb_page_index(tail_page, tail); - /* account for padding bytes */ - local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes); - /* * Save the original length to the meta data. * This will be used by the reader to add lost event @@ -2685,7 +2688,8 @@ * write counter enough to allow another writer to slip * in on this page. * We put in a discarded commit instead, to make sure - * that this space is not used again. + * that this space is not used again, and this space will + * not be accounted into 'entries_bytes'. * * If we are less than the minimum size, we don't need to * worry about it. @@ -2710,6 +2714,9 @@ /* time delta must be non zero */ event->time_delta = 1; + /* account for padding bytes */ + local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes); + /* Make sure the padding is visible before the tail_page->write update */ smp_wmb(); @@ -4225,7 +4232,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_oldest_event_ts); /** - * ring_buffer_bytes_cpu - get the number of bytes consumed in a cpu buffer + * ring_buffer_bytes_cpu - get the number of bytes unconsumed in a cpu buffer * @buffer: The ring buffer * @cpu: The per CPU buffer to read from. */ @@ -4735,6 +4742,7 @@ length = rb_event_length(event); cpu_buffer->reader_page->read += length; + cpu_buffer->read_bytes += length; } static void rb_advance_iter(struct ring_buffer_iter *iter) @@ -5830,7 +5838,7 @@ } else { /* update the entry counter */ cpu_buffer->read += rb_page_entries(reader); - cpu_buffer->read_bytes += BUF_PAGE_SIZE; + cpu_buffer->read_bytes += rb_page_commit(reader); /* swap the pages */ rb_init_page(bpage); diff -u linux-6.2.0/kernel/trace/trace.c linux-6.2.0/kernel/trace/trace.c --- linux-6.2.0/kernel/trace/trace.c +++ linux-6.2.0/kernel/trace/trace.c @@ -1728,7 +1728,7 @@ init_irq_work(&tr->fsnotify_irqwork, latency_fsnotify_workfn_irq); tr->d_max_latency = trace_create_file("tracing_max_latency", TRACE_MODE_WRITE, - d_tracer, &tr->max_latency, + d_tracer, tr, &tracing_max_lat_fops); } @@ -1761,7 +1761,7 @@ #define trace_create_maxlat_file(tr, d_tracer) \ trace_create_file("tracing_max_latency", TRACE_MODE_WRITE, \ - d_tracer, &tr->max_latency, &tracing_max_lat_fops) + d_tracer, tr, &tracing_max_lat_fops) #endif @@ -4898,6 +4898,33 @@ return 0; } +/* + * The private pointer of the inode is the trace_event_file. + * Update the tr ref count associated to it. + */ +int tracing_open_file_tr(struct inode *inode, struct file *filp) +{ + struct trace_event_file *file = inode->i_private; + int ret; + + ret = tracing_check_open_get_tr(file->tr); + if (ret) + return ret; + + filp->private_data = inode->i_private; + + return 0; +} + +int tracing_release_file_tr(struct inode *inode, struct file *filp) +{ + struct trace_event_file *file = inode->i_private; + + trace_array_put(file->tr); + + return 0; +} + static int tracing_mark_open(struct inode *inode, struct file *filp) { stream_open(inode, filp); @@ -6606,22 +6633,52 @@ tracing_max_lat_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos) { - return tracing_nsecs_read(filp->private_data, ubuf, cnt, ppos); + struct trace_array *tr = filp->private_data; + + return tracing_nsecs_read(&tr->max_latency, ubuf, cnt, ppos); } static ssize_t tracing_max_lat_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { - return tracing_nsecs_write(filp->private_data, ubuf, cnt, ppos); + struct trace_array *tr = filp->private_data; + + return tracing_nsecs_write(&tr->max_latency, ubuf, cnt, ppos); } #endif +static int open_pipe_on_cpu(struct trace_array *tr, int cpu) +{ + if (cpu == RING_BUFFER_ALL_CPUS) { + if (cpumask_empty(tr->pipe_cpumask)) { + cpumask_setall(tr->pipe_cpumask); + return 0; + } + } else if (!cpumask_test_cpu(cpu, tr->pipe_cpumask)) { + cpumask_set_cpu(cpu, tr->pipe_cpumask); + return 0; + } + return -EBUSY; +} + +static void close_pipe_on_cpu(struct trace_array *tr, int cpu) +{ + if (cpu == RING_BUFFER_ALL_CPUS) { + WARN_ON(!cpumask_full(tr->pipe_cpumask)); + cpumask_clear(tr->pipe_cpumask); + } else { + WARN_ON(!cpumask_test_cpu(cpu, tr->pipe_cpumask)); + cpumask_clear_cpu(cpu, tr->pipe_cpumask); + } +} + static int tracing_open_pipe(struct inode *inode, struct file *filp) { struct trace_array *tr = inode->i_private; struct trace_iterator *iter; + int cpu; int ret; ret = tracing_check_open_get_tr(tr); @@ -6629,13 +6686,16 @@ return ret; mutex_lock(&trace_types_lock); + cpu = tracing_get_cpu(inode); + ret = open_pipe_on_cpu(tr, cpu); + if (ret) + goto fail_pipe_on_cpu; /* create a buffer to store the information to pass to userspace */ iter = kzalloc(sizeof(*iter), GFP_KERNEL); if (!iter) { ret = -ENOMEM; - __trace_array_put(tr); - goto out; + goto fail_alloc_iter; } trace_seq_init(&iter->seq); @@ -6658,7 +6718,7 @@ iter->tr = tr; iter->array_buffer = &tr->array_buffer; - iter->cpu_file = tracing_get_cpu(inode); + iter->cpu_file = cpu; mutex_init(&iter->mutex); filp->private_data = iter; @@ -6668,12 +6728,15 @@ nonseekable_open(inode, filp); tr->trace_ref++; -out: + mutex_unlock(&trace_types_lock); return ret; fail: kfree(iter); +fail_alloc_iter: + close_pipe_on_cpu(tr, cpu); +fail_pipe_on_cpu: __trace_array_put(tr); mutex_unlock(&trace_types_lock); return ret; @@ -6690,7 +6753,7 @@ if (iter->trace->pipe_close) iter->trace->pipe_close(iter); - + close_pipe_on_cpu(tr, iter->cpu_file); mutex_unlock(&trace_types_lock); free_cpumask_var(iter->started); @@ -7486,6 +7549,11 @@ return ret; } +static void tracing_swap_cpu_buffer(void *tr) +{ + update_max_tr_single((struct trace_array *)tr, current, smp_processor_id()); +} + static ssize_t tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) @@ -7544,13 +7612,15 @@ ret = tracing_alloc_snapshot_instance(tr); if (ret < 0) break; - local_irq_disable(); /* Now, we're going to swap */ - if (iter->cpu_file == RING_BUFFER_ALL_CPUS) + if (iter->cpu_file == RING_BUFFER_ALL_CPUS) { + local_irq_disable(); update_max_tr(tr, current, smp_processor_id(), NULL); - else - update_max_tr_single(tr, current, iter->cpu_file); - local_irq_enable(); + local_irq_enable(); + } else { + smp_call_function_single(iter->cpu_file, tracing_swap_cpu_buffer, + (void *)tr, 1); + } break; default: if (tr->allocated_snapshot) { @@ -7631,18 +7701,20 @@ #ifdef CONFIG_TRACER_MAX_TRACE static const struct file_operations tracing_max_lat_fops = { - .open = tracing_open_generic, + .open = tracing_open_generic_tr, .read = tracing_max_lat_read, .write = tracing_max_lat_write, .llseek = generic_file_llseek, + .release = tracing_release_generic_tr, }; #endif static const struct file_operations set_tracer_fops = { - .open = tracing_open_generic, + .open = tracing_open_generic_tr, .read = tracing_set_trace_read, .write = tracing_set_trace_write, .llseek = generic_file_llseek, + .release = tracing_release_generic_tr, }; static const struct file_operations tracing_pipe_fops = { @@ -8835,12 +8907,33 @@ return cnt; } +static int tracing_open_options(struct inode *inode, struct file *filp) +{ + struct trace_option_dentry *topt = inode->i_private; + int ret; + + ret = tracing_check_open_get_tr(topt->tr); + if (ret) + return ret; + + filp->private_data = inode->i_private; + return 0; +} + +static int tracing_release_options(struct inode *inode, struct file *file) +{ + struct trace_option_dentry *topt = file->private_data; + + trace_array_put(topt->tr); + return 0; +} static const struct file_operations trace_options_fops = { - .open = tracing_open_generic, + .open = tracing_open_options, .read = trace_options_read, .write = trace_options_write, .llseek = generic_file_llseek, + .release = tracing_release_options, }; /* @@ -9358,6 +9451,9 @@ if (!alloc_cpumask_var(&tr->tracing_cpumask, GFP_KERNEL)) goto out_free_tr; + if (!zalloc_cpumask_var(&tr->pipe_cpumask, GFP_KERNEL)) + goto out_free_tr; + tr->trace_flags = global_trace.trace_flags & ~ZEROED_TRACE_FLAGS; cpumask_copy(tr->tracing_cpumask, cpu_all_mask); @@ -9399,6 +9495,7 @@ out_free_tr: ftrace_free_ftrace_ops(tr); free_trace_buffers(tr); + free_cpumask_var(tr->pipe_cpumask); free_cpumask_var(tr->tracing_cpumask); kfree(tr->name); kfree(tr); @@ -9501,6 +9598,7 @@ } kfree(tr->topts); + free_cpumask_var(tr->pipe_cpumask); free_cpumask_var(tr->tracing_cpumask); kfree(tr->name); kfree(tr); @@ -10225,12 +10323,14 @@ if (trace_create_savedcmd() < 0) goto out_free_temp_buffer; + if (!zalloc_cpumask_var(&global_trace.pipe_cpumask, GFP_KERNEL)) + goto out_free_savedcmd; + /* TODO: make the number of buffers hot pluggable with CPUS */ if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) { MEM_FAIL(1, "tracer: failed to allocate ring buffer!\n"); - goto out_free_savedcmd; + goto out_free_pipe_cpumask; } - if (global_trace.buffer_disabled) tracing_off(); @@ -10283,6 +10383,8 @@ return 0; +out_free_pipe_cpumask: + free_cpumask_var(global_trace.pipe_cpumask); out_free_savedcmd: free_saved_cmdlines_buffer(savedcmd); out_free_temp_buffer: diff -u linux-6.2.0/kernel/trace/trace.h linux-6.2.0/kernel/trace/trace.h --- linux-6.2.0/kernel/trace/trace.h +++ linux-6.2.0/kernel/trace/trace.h @@ -366,6 +366,8 @@ struct list_head events; struct trace_event_file *trace_marker_file; cpumask_var_t tracing_cpumask; /* only trace on set CPUs */ + /* one per_cpu trace_pipe can be opened by only one user */ + cpumask_var_t pipe_cpumask; int ref; int trace_ref; #ifdef CONFIG_FUNCTION_TRACER @@ -588,6 +590,8 @@ void tracing_reset_all_online_cpus_unlocked(void); int tracing_open_generic(struct inode *inode, struct file *filp); int tracing_open_generic_tr(struct inode *inode, struct file *filp); +int tracing_open_file_tr(struct inode *inode, struct file *filp); +int tracing_release_file_tr(struct inode *inode, struct file *filp); bool tracing_is_disabled(void); bool tracer_tracing_is_on(struct trace_array *tr); void tracer_tracing_on(struct trace_array *tr); diff -u linux-6.2.0/kernel/trace/trace_events.c linux-6.2.0/kernel/trace/trace_events.c --- linux-6.2.0/kernel/trace/trace_events.c +++ linux-6.2.0/kernel/trace/trace_events.c @@ -2101,9 +2101,10 @@ }; static const struct file_operations ftrace_enable_fops = { - .open = tracing_open_generic, + .open = tracing_open_file_tr, .read = event_enable_read, .write = event_enable_write, + .release = tracing_release_file_tr, .llseek = default_llseek, }; @@ -2120,9 +2121,10 @@ }; static const struct file_operations ftrace_event_filter_fops = { - .open = tracing_open_generic, + .open = tracing_open_file_tr, .read = event_filter_read, .write = event_filter_write, + .release = tracing_release_file_tr, .llseek = default_llseek, }; diff -u linux-6.2.0/kernel/trace/trace_hwlat.c linux-6.2.0/kernel/trace/trace_hwlat.c --- linux-6.2.0/kernel/trace/trace_hwlat.c +++ linux-6.2.0/kernel/trace/trace_hwlat.c @@ -635,7 +635,7 @@ else seq_printf(s, "%s", thread_mode_str[mode]); - if (mode != MODE_MAX) + if (mode < MODE_MAX - 1) /* if mode is any but last */ seq_puts(s, " "); return 0; diff -u linux-6.2.0/kernel/trace/trace_uprobe.c linux-6.2.0/kernel/trace/trace_uprobe.c --- linux-6.2.0/kernel/trace/trace_uprobe.c +++ linux-6.2.0/kernel/trace/trace_uprobe.c @@ -1419,7 +1419,7 @@ int bpf_get_uprobe_info(const struct perf_event *event, u32 *fd_type, const char **filename, u64 *probe_offset, - bool perf_type_tracepoint) + u64 *probe_addr, bool perf_type_tracepoint) { const char *pevent = trace_event_name(event->tp_event); const char *group = event->tp_event->class->system; @@ -1436,6 +1436,7 @@ : BPF_FD_TYPE_UPROBE; *filename = tu->filename; *probe_offset = tu->offset; + *probe_addr = 0; return 0; } #endif /* CONFIG_PERF_EVENTS */ diff -u linux-6.2.0/lib/kobject.c linux-6.2.0/lib/kobject.c --- linux-6.2.0/lib/kobject.c +++ linux-6.2.0/lib/kobject.c @@ -853,6 +853,11 @@ if (!k) return -EINVAL; + if (!k->kobj.ktype) { + pr_err("must have a ktype to be initialized properly!\n"); + return -EINVAL; + } + kset_init(k); err = kobject_add_internal(&k->kobj); if (err) { diff -u linux-6.2.0/lib/kunit/test.c linux-6.2.0/lib/kunit/test.c --- linux-6.2.0/lib/kunit/test.c +++ linux-6.2.0/lib/kunit/test.c @@ -674,12 +674,13 @@ switch (val) { case MODULE_STATE_LIVE: - kunit_module_init(mod); break; case MODULE_STATE_GOING: kunit_module_exit(mod); break; case MODULE_STATE_COMING: + kunit_module_init(mod); + break; case MODULE_STATE_UNFORMED: break; } diff -u linux-6.2.0/mm/hugetlb_vmemmap.c linux-6.2.0/mm/hugetlb_vmemmap.c --- linux-6.2.0/mm/hugetlb_vmemmap.c +++ linux-6.2.0/mm/hugetlb_vmemmap.c @@ -36,14 +36,22 @@ struct list_head *vmemmap_pages; }; -static int __split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start) +static int split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start) { pmd_t __pmd; int i; unsigned long addr = start; - struct page *page = pmd_page(*pmd); - pte_t *pgtable = pte_alloc_one_kernel(&init_mm); + struct page *head; + pte_t *pgtable; + + spin_lock(&init_mm.page_table_lock); + head = pmd_leaf(*pmd) ? pmd_page(*pmd) : NULL; + spin_unlock(&init_mm.page_table_lock); + if (!head) + return 0; + + pgtable = pte_alloc_one_kernel(&init_mm); if (!pgtable) return -ENOMEM; @@ -53,7 +61,7 @@ pte_t entry, *pte; pgprot_t pgprot = PAGE_KERNEL; - entry = mk_pte(page + i, pgprot); + entry = mk_pte(head + i, pgprot); pte = pte_offset_kernel(&__pmd, addr); set_pte_at(&init_mm, addr, pte, entry); } @@ -65,8 +73,8 @@ * be treated as indepdenent small pages (as they can be freed * individually). */ - if (!PageReserved(page)) - split_page(page, get_order(PMD_SIZE)); + if (!PageReserved(head)) + split_page(head, get_order(PMD_SIZE)); /* Make pte visible before pmd. See comment in pmd_install(). */ smp_wmb(); @@ -80,20 +88,6 @@ return 0; } -static int split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start) -{ - int leaf; - - spin_lock(&init_mm.page_table_lock); - leaf = pmd_leaf(*pmd); - spin_unlock(&init_mm.page_table_lock); - - if (!leaf) - return 0; - - return __split_vmemmap_huge_pmd(pmd, start); -} - static void vmemmap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, struct vmemmap_remap_walk *walk) diff -u linux-6.2.0/mm/memcontrol.c linux-6.2.0/mm/memcontrol.c --- linux-6.2.0/mm/memcontrol.c +++ linux-6.2.0/mm/memcontrol.c @@ -2549,7 +2549,7 @@ * Scheduled by try_charge() to be executed from the userland return path * and reclaims memory over the high limit. */ -void mem_cgroup_handle_over_high(void) +void mem_cgroup_handle_over_high(gfp_t gfp_mask) { unsigned long penalty_jiffies; unsigned long pflags; @@ -2577,7 +2577,7 @@ */ nr_reclaimed = reclaim_high(memcg, in_retry ? SWAP_CLUSTER_MAX : nr_pages, - GFP_KERNEL); + gfp_mask); /* * memory.high is breached and reclaim is unable to keep up. Throttle @@ -2813,7 +2813,7 @@ if (current->memcg_nr_pages_over_high > MEMCG_CHARGE_BATCH && !(current->flags & PF_MEMALLOC) && gfpflags_allow_blocking(gfp_mask)) { - mem_cgroup_handle_over_high(); + mem_cgroup_handle_over_high(gfp_mask); } return 0; } @@ -3846,8 +3846,11 @@ ret = mem_cgroup_resize_max(memcg, nr_pages, true); break; case _KMEM: - /* kmem.limit_in_bytes is deprecated. */ - ret = -EOPNOTSUPP; + pr_warn_once("kmem.limit_in_bytes is deprecated and will be removed. " + "Writing any value to this file has no effect. " + "Please report your usecase to linux-mm@kvack.org if you " + "depend on this functionality.\n"); + ret = 0; break; case _TCP: ret = memcg_update_tcp_max(memcg, nr_pages); diff -u linux-6.2.0/mm/memory.c linux-6.2.0/mm/memory.c --- linux-6.2.0/mm/memory.c +++ linux-6.2.0/mm/memory.c @@ -625,6 +625,16 @@ return pfn_to_page(pfn); } +struct folio *vm_normal_folio(struct vm_area_struct *vma, unsigned long addr, + pte_t pte) +{ + struct page *page = vm_normal_page(vma, addr, pte); + + if (page) + return page_folio(page); + return NULL; +} + #ifdef CONFIG_TRANSPARENT_HUGEPAGE struct page *vm_normal_page_pmd(struct vm_area_struct *vma, unsigned long addr, pmd_t pmd) diff -u linux-6.2.0/mm/mempolicy.c linux-6.2.0/mm/mempolicy.c --- linux-6.2.0/mm/mempolicy.c +++ linux-6.2.0/mm/mempolicy.c @@ -414,7 +414,7 @@ }, }; -static int migrate_page_add(struct page *page, struct list_head *pagelist, +static int migrate_folio_add(struct folio *folio, struct list_head *foliolist, unsigned long flags); struct queue_pages { @@ -424,6 +424,7 @@ unsigned long start; unsigned long end; struct vm_area_struct *first; + bool has_unmovable; }; /* @@ -442,21 +443,20 @@ } /* - * queue_pages_pmd() has three possible return values: - * 0 - pages are placed on the right node or queued successfully, or - * special page is met, i.e. huge zero page. - * 1 - there is unmovable page, and MPOL_MF_MOVE* & MPOL_MF_STRICT were - * specified. + * queue_folios_pmd() has three possible return values: + * 0 - folios are placed on the right node or queued successfully, or + * special page is met, i.e. zero page, or unmovable page is found + * but continue walking (indicated by queue_pages.has_unmovable). * -EIO - is migration entry or only MPOL_MF_STRICT was specified and an - * existing page was already on a node that does not follow the + * existing folio was already on a node that does not follow the * policy. */ -static int queue_pages_pmd(pmd_t *pmd, spinlock_t *ptl, unsigned long addr, +static int queue_folios_pmd(pmd_t *pmd, spinlock_t *ptl, unsigned long addr, unsigned long end, struct mm_walk *walk) __releases(ptl) { int ret = 0; - struct page *page; + struct folio *folio; struct queue_pages *qp = walk->private; unsigned long flags; @@ -464,20 +464,20 @@ ret = -EIO; goto unlock; } - page = pmd_page(*pmd); - if (is_huge_zero_page(page)) { + folio = pfn_folio(pmd_pfn(*pmd)); + if (is_huge_zero_page(&folio->page)) { walk->action = ACTION_CONTINUE; goto unlock; } - if (!queue_pages_required(page, qp)) + if (!queue_pages_required(&folio->page, qp)) goto unlock; flags = qp->flags; - /* go to thp migration */ + /* go to folio migration */ if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) { if (!vma_migratable(walk->vma) || - migrate_page_add(page, qp->pagelist, flags)) { - ret = 1; + migrate_folio_add(folio, qp->pagelist, flags)) { + qp->has_unmovable = true; goto unlock; } } else @@ -491,28 +491,26 @@ * Scan through pages checking if pages follow certain conditions, * and move them to the pagelist if they do. * - * queue_pages_pte_range() has three possible return values: - * 0 - pages are placed on the right node or queued successfully, or - * special page is met, i.e. zero page. - * 1 - there is unmovable page, and MPOL_MF_MOVE* & MPOL_MF_STRICT were - * specified. - * -EIO - only MPOL_MF_STRICT was specified and an existing page was already + * queue_folios_pte_range() has three possible return values: + * 0 - folios are placed on the right node or queued successfully, or + * special page is met, i.e. zero page, or unmovable page is found + * but continue walking (indicated by queue_pages.has_unmovable). + * -EIO - only MPOL_MF_STRICT was specified and an existing folio was already * on a node that does not follow the policy. */ -static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr, +static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, struct mm_walk *walk) { struct vm_area_struct *vma = walk->vma; - struct page *page; + struct folio *folio; struct queue_pages *qp = walk->private; unsigned long flags = qp->flags; - bool has_unmovable = false; pte_t *pte, *mapped_pte; spinlock_t *ptl; ptl = pmd_trans_huge_lock(pmd, vma); if (ptl) - return queue_pages_pmd(pmd, ptl, addr, end, walk); + return queue_folios_pmd(pmd, ptl, addr, end, walk); if (pmd_trans_unstable(pmd)) return 0; @@ -521,40 +519,38 @@ for (; addr != end; pte++, addr += PAGE_SIZE) { if (!pte_present(*pte)) continue; - page = vm_normal_page(vma, addr, *pte); - if (!page || is_zone_device_page(page)) + folio = vm_normal_folio(vma, addr, *pte); + if (!folio || folio_is_zone_device(folio)) continue; /* - * vm_normal_page() filters out zero pages, but there might - * still be PageReserved pages to skip, perhaps in a VDSO. + * vm_normal_folio() filters out zero pages, but there might + * still be reserved folios to skip, perhaps in a VDSO. */ - if (PageReserved(page)) + if (folio_test_reserved(folio)) continue; - if (!queue_pages_required(page, qp)) + if (!queue_pages_required(&folio->page, qp)) continue; if (flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) { - /* MPOL_MF_STRICT must be specified if we get here */ - if (!vma_migratable(vma)) { - has_unmovable = true; - break; - } + /* + * MPOL_MF_STRICT must be specified if we get here. + * Continue walking vmas due to MPOL_MF_MOVE* flags. + */ + if (!vma_migratable(vma)) + qp->has_unmovable = true; /* * Do not abort immediately since there may be * temporary off LRU pages in the range. Still * need migrate other LRU pages. */ - if (migrate_page_add(page, qp->pagelist, flags)) - has_unmovable = true; + if (migrate_folio_add(folio, qp->pagelist, flags)) + qp->has_unmovable = true; } else break; } pte_unmap_unlock(mapped_pte, ptl); cond_resched(); - if (has_unmovable) - return 1; - return addr != end ? -EIO : 0; } @@ -594,7 +590,7 @@ * Detecting misplaced page but allow migrating pages which * have been queued. */ - ret = 1; + qp->has_unmovable = true; goto unlock; } @@ -608,7 +604,7 @@ * Failed to isolate page but allow migrating pages * which have been queued. */ - ret = 1; + qp->has_unmovable = true; } unlock: spin_unlock(ptl); @@ -705,7 +701,7 @@ static const struct mm_walk_ops queue_pages_walk_ops = { .hugetlb_entry = queue_pages_hugetlb, - .pmd_entry = queue_pages_pte_range, + .pmd_entry = queue_folios_pte_range, .test_walk = queue_pages_test_walk, }; @@ -737,10 +733,13 @@ .start = start, .end = end, .first = NULL, + .has_unmovable = false, }; err = walk_page_range(mm, start, end, &queue_pages_walk_ops, &qp); + if (qp.has_unmovable) + err = 1; if (!qp.first) /* whole range in hole */ err = -EFAULT; @@ -1012,27 +1011,28 @@ } #ifdef CONFIG_MIGRATION -/* - * page migration, thp tail pages can be passed. - */ -static int migrate_page_add(struct page *page, struct list_head *pagelist, +static int migrate_folio_add(struct folio *folio, struct list_head *foliolist, unsigned long flags) { - struct page *head = compound_head(page); /* - * Avoid migrating a page that is shared with others. + * We try to migrate only unshared folios. If it is shared it + * is likely not worth migrating. + * + * To check if the folio is shared, ideally we want to make sure + * every page is mapped to the same process. Doing that is very + * expensive, so check the estimated mapcount of the folio instead. */ - if ((flags & MPOL_MF_MOVE_ALL) || page_mapcount(head) == 1) { - if (!isolate_lru_page(head)) { - list_add_tail(&head->lru, pagelist); - mod_node_page_state(page_pgdat(head), - NR_ISOLATED_ANON + page_is_file_lru(head), - thp_nr_pages(head)); + if ((flags & MPOL_MF_MOVE_ALL) || folio_estimated_sharers(folio) == 1) { + if (!folio_isolate_lru(folio)) { + list_add_tail(&folio->lru, foliolist); + node_stat_mod_folio(folio, + NR_ISOLATED_ANON + folio_is_file_lru(folio), + folio_nr_pages(folio)); } else if (flags & MPOL_MF_STRICT) { /* - * Non-movable page may reach here. And, there may be - * temporary off LRU pages or non-LRU movable pages. - * Treat them as unmovable pages since they can't be + * Non-movable folio may reach here. And, there may be + * temporary off LRU folios or non-LRU movable folios. + * Treat them as unmovable folios since they can't be * isolated, so they can't be moved at the moment. It * should return -EIO for this case too. */ @@ -1224,7 +1224,7 @@ } #else -static int migrate_page_add(struct page *page, struct list_head *pagelist, +static int migrate_folio_add(struct folio *folio, struct list_head *foliolist, unsigned long flags) { return -EIO; @@ -1337,7 +1337,7 @@ putback_movable_pages(&pagelist); } - if ((ret > 0) || (nr_failed && (flags & MPOL_MF_STRICT))) + if (((ret > 0) || nr_failed) && (flags & MPOL_MF_STRICT)) err = -EIO; } else { up_out: diff -u linux-6.2.0/mm/page_alloc.c linux-6.2.0/mm/page_alloc.c --- linux-6.2.0/mm/page_alloc.c +++ linux-6.2.0/mm/page_alloc.c @@ -3460,7 +3460,7 @@ struct per_cpu_pages *pcp; struct zone *zone; unsigned long pfn = page_to_pfn(page); - int migratetype; + int migratetype, pcpmigratetype; if (!free_unref_page_prepare(page, pfn, order)) return; @@ -3468,24 +3468,24 @@ /* * We only track unmovable, reclaimable and movable on pcp lists. * Place ISOLATE pages on the isolated list because they are being - * offlined but treat HIGHATOMIC as movable pages so we can get those - * areas back if necessary. Otherwise, we may have to free + * offlined but treat HIGHATOMIC and CMA as movable pages so we can + * get those areas back if necessary. Otherwise, we may have to free * excessively into the page allocator */ - migratetype = get_pcppage_migratetype(page); + migratetype = pcpmigratetype = get_pcppage_migratetype(page); if (unlikely(migratetype >= MIGRATE_PCPTYPES)) { if (unlikely(is_migrate_isolate(migratetype))) { free_one_page(page_zone(page), page, pfn, order, migratetype, FPI_NONE); return; } - migratetype = MIGRATE_MOVABLE; + pcpmigratetype = MIGRATE_MOVABLE; } zone = page_zone(page); pcp_trylock_prepare(UP_flags); pcp = pcp_spin_trylock(zone->per_cpu_pageset); if (pcp) { - free_unref_page_commit(zone, pcp, page, migratetype, order); + free_unref_page_commit(zone, pcp, page, pcpmigratetype, order); pcp_spin_unlock(pcp); } else { free_one_page(zone, page, pfn, order, migratetype, FPI_NONE); diff -u linux-6.2.0/mm/shmem.c linux-6.2.0/mm/shmem.c --- linux-6.2.0/mm/shmem.c +++ linux-6.2.0/mm/shmem.c @@ -3488,6 +3488,8 @@ unsigned long long size; char *rest; int opt; + kuid_t kuid; + kgid_t kgid; opt = fs_parse(fc, shmem_fs_parameters, param, &result); if (opt < 0) @@ -3523,14 +3525,32 @@ ctx->mode = result.uint_32 & 07777; break; case Opt_uid: - ctx->uid = make_kuid(current_user_ns(), result.uint_32); - if (!uid_valid(ctx->uid)) + kuid = make_kuid(current_user_ns(), result.uint_32); + if (!uid_valid(kuid)) goto bad_value; + + /* + * The requested uid must be representable in the + * filesystem's idmapping. + */ + if (!kuid_has_mapping(fc->user_ns, kuid)) + goto bad_value; + + ctx->uid = kuid; break; case Opt_gid: - ctx->gid = make_kgid(current_user_ns(), result.uint_32); - if (!gid_valid(ctx->gid)) + kgid = make_kgid(current_user_ns(), result.uint_32); + if (!gid_valid(kgid)) goto bad_value; + + /* + * The requested gid must be representable in the + * filesystem's idmapping. + */ + if (!kgid_has_mapping(fc->user_ns, kgid)) + goto bad_value; + + ctx->gid = kgid; break; case Opt_huge: ctx->huge = result.uint_32; diff -u linux-6.2.0/mm/vmalloc.c linux-6.2.0/mm/vmalloc.c --- linux-6.2.0/mm/vmalloc.c +++ linux-6.2.0/mm/vmalloc.c @@ -4056,14 +4056,32 @@ #ifdef CONFIG_PRINTK bool vmalloc_dump_obj(void *object) { - struct vm_struct *vm; void *objp = (void *)PAGE_ALIGN((unsigned long)object); + const void *caller; + struct vm_struct *vm; + struct vmap_area *va; + unsigned long addr; + unsigned int nr_pages; + + if (!spin_trylock(&vmap_area_lock)) + return false; + va = __find_vmap_area((unsigned long)objp, &vmap_area_root); + if (!va) { + spin_unlock(&vmap_area_lock); + return false; + } - vm = find_vm_area(objp); - if (!vm) + vm = va->vm; + if (!vm) { + spin_unlock(&vmap_area_lock); return false; + } + addr = (unsigned long)vm->addr; + caller = vm->caller; + nr_pages = vm->nr_pages; + spin_unlock(&vmap_area_lock); pr_cont(" %u-page vmalloc region starting at %#lx allocated at %pS\n", - vm->nr_pages, (unsigned long)vm->addr, vm->caller); + nr_pages, addr, caller); return true; } #endif diff -u linux-6.2.0/mm/vmscan.c linux-6.2.0/mm/vmscan.c --- linux-6.2.0/mm/vmscan.c +++ linux-6.2.0/mm/vmscan.c @@ -4288,7 +4288,7 @@ /* prevent cold/hot inversion if force_scan is true */ for (zone = 0; zone < MAX_NR_ZONES; zone++) { - struct list_head *head = &lrugen->lists[old_gen][type][zone]; + struct list_head *head = &lrugen->folios[old_gen][type][zone]; while (!list_empty(head)) { struct folio *folio = lru_to_folio(head); @@ -4299,7 +4299,7 @@ VM_WARN_ON_ONCE_FOLIO(folio_zonenum(folio) != zone, folio); new_gen = folio_inc_gen(lruvec, folio, false); - list_move_tail(&folio->lru, &lrugen->lists[new_gen][type][zone]); + list_move_tail(&folio->lru, &lrugen->folios[new_gen][type][zone]); if (!--remaining) return false; @@ -4327,7 +4327,7 @@ gen = lru_gen_from_seq(min_seq[type]); for (zone = 0; zone < MAX_NR_ZONES; zone++) { - if (!list_empty(&lrugen->lists[gen][type][zone])) + if (!list_empty(&lrugen->folios[gen][type][zone])) goto next; } @@ -4361,6 +4361,7 @@ int type, zone; struct lru_gen_struct *lrugen = &lruvec->lrugen; +restart: spin_lock_irq(&lruvec->lru_lock); VM_WARN_ON_ONCE(!seq_is_valid(lruvec)); @@ -4371,11 +4372,12 @@ VM_WARN_ON_ONCE(!force_scan && (type == LRU_GEN_FILE || can_swap)); - while (!inc_min_seq(lruvec, type, can_swap)) { - spin_unlock_irq(&lruvec->lru_lock); - cond_resched(); - spin_lock_irq(&lruvec->lru_lock); - } + if (inc_min_seq(lruvec, type, can_swap)) + continue; + + spin_unlock_irq(&lruvec->lru_lock); + cond_resched(); + goto restart; } /* @@ -4758,7 +4760,8 @@ * the eviction ******************************************************************************/ -static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx) +static bool sort_folio(struct lruvec *lruvec, struct folio *folio, struct scan_control *sc, + int tier_idx) { bool success; int gen = folio_lru_gen(folio); @@ -4792,7 +4795,7 @@ /* promoted */ if (gen != lru_gen_from_seq(lrugen->min_seq[type])) { - list_move(&folio->lru, &lrugen->lists[gen][type][zone]); + list_move(&folio->lru, &lrugen->folios[gen][type][zone]); return true; } @@ -4801,7 +4804,7 @@ int hist = lru_hist_from_seq(lrugen->min_seq[type]); gen = folio_inc_gen(lruvec, folio, false); - list_move_tail(&folio->lru, &lrugen->lists[gen][type][zone]); + list_move_tail(&folio->lru, &lrugen->folios[gen][type][zone]); WRITE_ONCE(lrugen->protected[hist][type][tier - 1], lrugen->protected[hist][type][tier - 1] + delta); @@ -4809,11 +4812,18 @@ return true; } + /* ineligible */ + if (zone > sc->reclaim_idx) { + gen = folio_inc_gen(lruvec, folio, false); + list_move_tail(&folio->lru, &lrugen->folios[gen][type][zone]); + return true; + } + /* waiting for writeback */ if (folio_test_locked(folio) || folio_test_writeback(folio) || (type == LRU_GEN_FILE && folio_test_dirty(folio))) { gen = folio_inc_gen(lruvec, folio, true); - list_move(&folio->lru, &lrugen->lists[gen][type][zone]); + list_move(&folio->lru, &lrugen->folios[gen][type][zone]); return true; } @@ -4861,7 +4871,8 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc, int type, int tier, struct list_head *list) { - int gen, zone; + int i; + int gen; enum vm_event_item item; int sorted = 0; int scanned = 0; @@ -4877,10 +4888,11 @@ gen = lru_gen_from_seq(lrugen->min_seq[type]); - for (zone = sc->reclaim_idx; zone >= 0; zone--) { + for (i = MAX_NR_ZONES; i > 0; i--) { LIST_HEAD(moved); int skipped = 0; - struct list_head *head = &lrugen->lists[gen][type][zone]; + int zone = (sc->reclaim_idx + i) % MAX_NR_ZONES; + struct list_head *head = &lrugen->folios[gen][type][zone]; while (!list_empty(head)) { struct folio *folio = lru_to_folio(head); @@ -4893,7 +4905,7 @@ scanned += delta; - if (sort_folio(lruvec, folio, tier)) + if (sort_folio(lruvec, folio, sc, tier)) sorted += delta; else if (isolate_folio(lruvec, folio, sc)) { list_add(&folio->lru, list); @@ -5281,7 +5293,7 @@ int gen, type, zone; for_each_gen_type_zone(gen, type, zone) { - if (!list_empty(&lrugen->lists[gen][type][zone])) + if (!list_empty(&lrugen->folios[gen][type][zone])) return false; } } @@ -5326,7 +5338,7 @@ int remaining = MAX_LRU_BATCH; for_each_gen_type_zone(gen, type, zone) { - struct list_head *head = &lruvec->lrugen.lists[gen][type][zone]; + struct list_head *head = &lruvec->lrugen.folios[gen][type][zone]; while (!list_empty(head)) { bool success; @@ -5860,7 +5872,7 @@ lrugen->timestamps[i] = jiffies; for_each_gen_type_zone(gen, type, zone) - INIT_LIST_HEAD(&lrugen->lists[gen][type][zone]); + INIT_LIST_HEAD(&lrugen->folios[gen][type][zone]); lruvec->mm_state.seq = MIN_NR_GENS; init_waitqueue_head(&lruvec->mm_state.wait); diff -u linux-6.2.0/net/bluetooth/hci_core.c linux-6.2.0/net/bluetooth/hci_core.c --- linux-6.2.0/net/bluetooth/hci_core.c +++ linux-6.2.0/net/bluetooth/hci_core.c @@ -1074,9 +1074,9 @@ void hci_link_keys_clear(struct hci_dev *hdev) { - struct link_key *key; + struct link_key *key, *tmp; - list_for_each_entry(key, &hdev->link_keys, list) { + list_for_each_entry_safe(key, tmp, &hdev->link_keys, list) { list_del_rcu(&key->list); kfree_rcu(key, rcu); } @@ -1084,9 +1084,9 @@ void hci_smp_ltks_clear(struct hci_dev *hdev) { - struct smp_ltk *k; + struct smp_ltk *k, *tmp; - list_for_each_entry(k, &hdev->long_term_keys, list) { + list_for_each_entry_safe(k, tmp, &hdev->long_term_keys, list) { list_del_rcu(&k->list); kfree_rcu(k, rcu); } @@ -1094,9 +1094,9 @@ void hci_smp_irks_clear(struct hci_dev *hdev) { - struct smp_irk *k; + struct smp_irk *k, *tmp; - list_for_each_entry(k, &hdev->identity_resolving_keys, list) { + list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) { list_del_rcu(&k->list); kfree_rcu(k, rcu); } @@ -1104,9 +1104,9 @@ void hci_blocked_keys_clear(struct hci_dev *hdev) { - struct blocked_key *b; + struct blocked_key *b, *tmp; - list_for_each_entry(b, &hdev->blocked_keys, list) { + list_for_each_entry_safe(b, tmp, &hdev->blocked_keys, list) { list_del_rcu(&b->list); kfree_rcu(b, rcu); } @@ -1949,15 +1949,15 @@ switch (hci_get_adv_monitor_offload_ext(hdev)) { case HCI_ADV_MONITOR_EXT_NONE: - bt_dev_dbg(hdev, "%s add monitor %d status %d", hdev->name, + bt_dev_dbg(hdev, "add monitor %d status %d", monitor->handle, status); /* Message was not forwarded to controller - not an error */ break; case HCI_ADV_MONITOR_EXT_MSFT: status = msft_add_monitor_pattern(hdev, monitor); - bt_dev_dbg(hdev, "%s add monitor %d msft status %d", hdev->name, - monitor->handle, status); + bt_dev_dbg(hdev, "add monitor %d msft status %d", + handle, status); break; } @@ -1976,15 +1976,15 @@ switch (hci_get_adv_monitor_offload_ext(hdev)) { case HCI_ADV_MONITOR_EXT_NONE: /* also goes here when powered off */ - bt_dev_dbg(hdev, "%s remove monitor %d status %d", hdev->name, + bt_dev_dbg(hdev, "remove monitor %d status %d", monitor->handle, status); goto free_monitor; case HCI_ADV_MONITOR_EXT_MSFT: handle = monitor->handle; status = msft_remove_monitor(hdev, monitor); - bt_dev_dbg(hdev, "%s remove monitor %d msft status %d", - hdev->name, handle, status); + bt_dev_dbg(hdev, "remove monitor %d msft status %d", + handle, status); break; } @@ -2436,6 +2436,9 @@ if (hci_dev_test_flag(hdev, HCI_USER_CHANNEL)) return NOTIFY_DONE; + /* To avoid a potential race with hci_unregister_dev. */ + hci_dev_hold(hdev); + if (action == PM_SUSPEND_PREPARE) ret = hci_suspend_dev(hdev); else if (action == PM_POST_SUSPEND) @@ -2445,6 +2448,7 @@ bt_dev_err(hdev, "Suspend notifier action (%lu) failed: %d", action, ret); + hci_dev_put(hdev); return NOTIFY_DONE; } @@ -2779,6 +2783,7 @@ hci_conn_params_clear_all(hdev); hci_discovery_filter_clear(hdev); hci_blocked_keys_clear(hdev); + hci_codec_list_clear(&hdev->local_codecs); hci_dev_unlock(hdev); ida_simple_remove(&hci_index_ida, hdev->id); diff -u linux-6.2.0/net/bluetooth/hci_event.c linux-6.2.0/net/bluetooth/hci_event.c --- linux-6.2.0/net/bluetooth/hci_event.c +++ linux-6.2.0/net/bluetooth/hci_event.c @@ -33,6 +33,7 @@ #include "hci_request.h" #include "hci_debugfs.h" +#include "hci_codec.h" #include "a2mp.h" #include "amp.h" #include "smp.h" diff -u linux-6.2.0/net/bluetooth/hci_sync.c linux-6.2.0/net/bluetooth/hci_sync.c --- linux-6.2.0/net/bluetooth/hci_sync.c +++ linux-6.2.0/net/bluetooth/hci_sync.c @@ -412,11 +412,6 @@ LE_SCAN_FILTER_DUP_ENABLE); } -static int le_scan_restart_sync(struct hci_dev *hdev, void *data) -{ - return hci_le_scan_restart_sync(hdev); -} - static void le_scan_restart(struct work_struct *work) { struct hci_dev *hdev = container_of(work, struct hci_dev, @@ -426,15 +421,15 @@ bt_dev_dbg(hdev, ""); - hci_dev_lock(hdev); - - status = hci_cmd_sync_queue(hdev, le_scan_restart_sync, NULL, NULL); + status = hci_le_scan_restart_sync(hdev); if (status) { bt_dev_err(hdev, "failed to restart LE scan: status %d", status); - goto unlock; + return; } + hci_dev_lock(hdev); + if (!test_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks) || !hdev->discovery.scan_start) goto unlock; @@ -5051,6 +5046,7 @@ memset(hdev->eir, 0, sizeof(hdev->eir)); memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); bacpy(&hdev->random_addr, BDADDR_ANY); + hci_codec_list_clear(&hdev->local_codecs); hci_dev_put(hdev); return err; diff -u linux-6.2.0/net/bluetooth/iso.c linux-6.2.0/net/bluetooth/iso.c --- linux-6.2.0/net/bluetooth/iso.c +++ linux-6.2.0/net/bluetooth/iso.c @@ -480,7 +480,7 @@ } /* -------- Socket interface ---------- */ -static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *ba) +static struct sock *__iso_get_sock_listen_by_addr(bdaddr_t *src, bdaddr_t *dst) { struct sock *sk; @@ -488,7 +488,10 @@ if (sk->sk_state != BT_LISTEN) continue; - if (!bacmp(&iso_pi(sk)->src, ba)) + if (bacmp(&iso_pi(sk)->dst, dst)) + continue; + + if (!bacmp(&iso_pi(sk)->src, src)) return sk; } @@ -946,7 +949,7 @@ write_lock(&iso_sk_list.lock); - if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src)) + if (__iso_get_sock_listen_by_addr(&iso_pi(sk)->src, &iso_pi(sk)->dst)) err = -EADDRINUSE; write_unlock(&iso_sk_list.lock); @@ -1466,7 +1469,7 @@ iso_sock_close(sk); - if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime && + if (sock_flag(sk, SOCK_LINGER) && READ_ONCE(sk->sk_lingertime) && !(current->flags & PF_EXITING)) { lock_sock(sk); err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); diff -u linux-6.2.0/net/bluetooth/sco.c linux-6.2.0/net/bluetooth/sco.c --- linux-6.2.0/net/bluetooth/sco.c +++ linux-6.2.0/net/bluetooth/sco.c @@ -1255,7 +1255,7 @@ sco_sock_close(sk); - if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime && + if (sock_flag(sk, SOCK_LINGER) && READ_ONCE(sk->sk_lingertime) && !(current->flags & PF_EXITING)) { lock_sock(sk); err = bt_sock_wait_state(sk, BT_CLOSED, sk->sk_lingertime); diff -u linux-6.2.0/net/bridge/br_forward.c linux-6.2.0/net/bridge/br_forward.c --- linux-6.2.0/net/bridge/br_forward.c +++ linux-6.2.0/net/bridge/br_forward.c @@ -124,7 +124,7 @@ skb = skb_clone(skb, GFP_ATOMIC); if (!skb) { - dev->stats.tx_dropped++; + DEV_STATS_INC(dev, tx_dropped); return -ENOMEM; } @@ -263,7 +263,7 @@ skb = skb_copy(skb, GFP_ATOMIC); if (!skb) { - dev->stats.tx_dropped++; + DEV_STATS_INC(dev, tx_dropped); return; } diff -u linux-6.2.0/net/bridge/br_netfilter_hooks.c linux-6.2.0/net/bridge/br_netfilter_hooks.c --- linux-6.2.0/net/bridge/br_netfilter_hooks.c +++ linux-6.2.0/net/bridge/br_netfilter_hooks.c @@ -277,7 +277,8 @@ struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); int ret; - if ((neigh->nud_state & NUD_CONNECTED) && neigh->hh.hh_len) { + if ((READ_ONCE(neigh->nud_state) & NUD_CONNECTED) && + READ_ONCE(neigh->hh.hh_len)) { neigh_hh_bridge(&neigh->hh, skb); skb->dev = nf_bridge->physindev; ret = br_handle_frame_finish(net, sk, skb); @@ -293,7 +294,7 @@ /* tell br_dev_xmit to continue with forwarding */ nf_bridge->bridged_dnat = 1; /* FIXME Need to refragment */ - ret = neigh->output(neigh, skb); + ret = READ_ONCE(neigh->output)(neigh, skb); } neigh_release(neigh); return ret; diff -u linux-6.2.0/net/bridge/netfilter/ebtables.c linux-6.2.0/net/bridge/netfilter/ebtables.c --- linux-6.2.0/net/bridge/netfilter/ebtables.c +++ linux-6.2.0/net/bridge/netfilter/ebtables.c @@ -2115,8 +2115,7 @@ return ret; offsets[0] = sizeof(struct ebt_entry); /* matches come first */ - memcpy(&offsets[1], &entry->watchers_offset, - sizeof(offsets) - sizeof(offsets[0])); + memcpy(&offsets[1], &entry->offsets, sizeof(entry->offsets)); if (state->buf_kern_start) { buf_start = state->buf_kern_start + state->buf_kern_offset; diff -u linux-6.2.0/net/can/j1939/socket.c linux-6.2.0/net/can/j1939/socket.c --- linux-6.2.0/net/can/j1939/socket.c +++ linux-6.2.0/net/can/j1939/socket.c @@ -974,6 +974,7 @@ struct sock_exterr_skb *serr; struct sk_buff *skb; char *state = "UNK"; + u32 tsflags; int err; jsk = j1939_sk(sk); @@ -981,13 +982,14 @@ if (!(jsk->state & J1939_SOCK_ERRQUEUE)) return; + tsflags = READ_ONCE(sk->sk_tsflags); switch (type) { case J1939_ERRQUEUE_TX_ACK: - if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_ACK)) + if (!(tsflags & SOF_TIMESTAMPING_TX_ACK)) return; break; case J1939_ERRQUEUE_TX_SCHED: - if (!(sk->sk_tsflags & SOF_TIMESTAMPING_TX_SCHED)) + if (!(tsflags & SOF_TIMESTAMPING_TX_SCHED)) return; break; case J1939_ERRQUEUE_TX_ABORT: @@ -997,7 +999,7 @@ case J1939_ERRQUEUE_RX_DPO: fallthrough; case J1939_ERRQUEUE_RX_ABORT: - if (!(sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE)) + if (!(tsflags & SOF_TIMESTAMPING_RX_SOFTWARE)) return; break; default: @@ -1054,7 +1056,7 @@ } serr->opt_stats = true; - if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) + if (tsflags & SOF_TIMESTAMPING_OPT_ID) serr->ee.ee_data = session->tskey; netdev_dbg(session->priv->ndev, "%s: 0x%p tskey: %i, state: %s\n", diff -u linux-6.2.0/net/core/filter.c linux-6.2.0/net/core/filter.c --- linux-6.2.0/net/core/filter.c +++ linux-6.2.0/net/core/filter.c @@ -2193,7 +2193,7 @@ return -ENOMEM; } - rcu_read_lock_bh(); + rcu_read_lock(); if (!nh) { dst = skb_dst(skb); nexthop = rt6_nexthop(container_of(dst, struct rt6_info, dst), @@ -2206,10 +2206,12 @@ int ret; sock_confirm_neigh(skb, neigh); + local_bh_disable(); dev_xmit_recursion_inc(); ret = neigh_output(neigh, skb, false); dev_xmit_recursion_dec(); - rcu_read_unlock_bh(); + local_bh_enable(); + rcu_read_unlock(); return ret; } rcu_read_unlock_bh(); @@ -2291,7 +2293,7 @@ return -ENOMEM; } - rcu_read_lock_bh(); + rcu_read_lock(); if (!nh) { struct dst_entry *dst = skb_dst(skb); struct rtable *rt = container_of(dst, struct rtable, dst); @@ -2303,7 +2305,7 @@ } else if (nh->nh_family == AF_INET) { neigh = ip_neigh_gw4(dev, nh->ipv4_nh); } else { - rcu_read_unlock_bh(); + rcu_read_unlock(); goto out_drop; } @@ -2311,13 +2313,15 @@ int ret; sock_confirm_neigh(skb, neigh); + local_bh_disable(); dev_xmit_recursion_inc(); ret = neigh_output(neigh, skb, is_v6gw); dev_xmit_recursion_dec(); - rcu_read_unlock_bh(); + local_bh_enable(); + rcu_read_unlock(); return ret; } - rcu_read_unlock_bh(); + rcu_read_unlock(); out_drop: kfree_skb(skb); return -ENETDOWN; @@ -5683,12 +5687,8 @@ #endif #if IS_ENABLED(CONFIG_INET) || IS_ENABLED(CONFIG_IPV6) -static int bpf_fib_set_fwd_params(struct bpf_fib_lookup *params, - const struct neighbour *neigh, - const struct net_device *dev, u32 mtu) +static int bpf_fib_set_fwd_params(struct bpf_fib_lookup *params, u32 mtu) { - memcpy(params->dmac, neigh->ha, ETH_ALEN); - memcpy(params->smac, dev->dev_addr, ETH_ALEN); params->h_vlan_TCI = 0; params->h_vlan_proto = 0; if (mtu) @@ -5799,21 +5799,29 @@ if (likely(nhc->nhc_gw_family != AF_INET6)) { if (nhc->nhc_gw_family) params->ipv4_dst = nhc->nhc_gw.ipv4; - - neigh = __ipv4_neigh_lookup_noref(dev, - (__force u32)params->ipv4_dst); } else { struct in6_addr *dst = (struct in6_addr *)params->ipv6_dst; params->family = AF_INET6; *dst = nhc->nhc_gw.ipv6; - neigh = __ipv6_neigh_lookup_noref_stub(dev, dst); } - if (!neigh || !(neigh->nud_state & NUD_VALID)) + if (flags & BPF_FIB_LOOKUP_SKIP_NEIGH) + goto set_fwd_params; + + if (likely(nhc->nhc_gw_family != AF_INET6)) + neigh = __ipv4_neigh_lookup_noref(dev, + (__force u32)params->ipv4_dst); + else + neigh = __ipv6_neigh_lookup_noref_stub(dev, params->ipv6_dst); + + if (!neigh || !(READ_ONCE(neigh->nud_state) & NUD_VALID)) return BPF_FIB_LKUP_RET_NO_NEIGH; + memcpy(params->dmac, neigh->ha, ETH_ALEN); + memcpy(params->smac, dev->dev_addr, ETH_ALEN); - return bpf_fib_set_fwd_params(params, neigh, dev, mtu); +set_fwd_params: + return bpf_fib_set_fwd_params(params, mtu); } #endif @@ -5921,24 +5929,33 @@ params->rt_metric = res.f6i->fib6_metric; params->ifindex = dev->ifindex; + if (flags & BPF_FIB_LOOKUP_SKIP_NEIGH) + goto set_fwd_params; + /* xdp and cls_bpf programs are run in RCU-bh so rcu_read_lock_bh is * not needed here. */ neigh = __ipv6_neigh_lookup_noref_stub(dev, dst); - if (!neigh || !(neigh->nud_state & NUD_VALID)) + if (!neigh || !(READ_ONCE(neigh->nud_state) & NUD_VALID)) return BPF_FIB_LKUP_RET_NO_NEIGH; + memcpy(params->dmac, neigh->ha, ETH_ALEN); + memcpy(params->smac, dev->dev_addr, ETH_ALEN); - return bpf_fib_set_fwd_params(params, neigh, dev, mtu); +set_fwd_params: + return bpf_fib_set_fwd_params(params, mtu); } #endif +#define BPF_FIB_LOOKUP_MASK (BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT | \ + BPF_FIB_LOOKUP_SKIP_NEIGH) + BPF_CALL_4(bpf_xdp_fib_lookup, struct xdp_buff *, ctx, struct bpf_fib_lookup *, params, int, plen, u32, flags) { if (plen < sizeof(*params)) return -EINVAL; - if (flags & ~(BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT)) + if (flags & ~BPF_FIB_LOOKUP_MASK) return -EINVAL; switch (params->family) { @@ -5976,7 +5993,7 @@ if (plen < sizeof(*params)) return -EINVAL; - if (flags & ~(BPF_FIB_LOOKUP_DIRECT | BPF_FIB_LOOKUP_OUTPUT)) + if (flags & ~BPF_FIB_LOOKUP_MASK) return -EINVAL; if (params->tot_len) @@ -7268,6 +7285,8 @@ return -ENETUNREACH; if (unlikely(sk_fullsock(sk) && sk->sk_reuseport)) return -ESOCKTNOSUPPORT; + if (sk_unhashed(sk)) + return -EOPNOTSUPP; if (sk_is_refcounted(sk) && unlikely(!refcount_inc_not_zero(&sk->sk_refcnt))) return -ENOENT; diff -u linux-6.2.0/net/core/neighbour.c linux-6.2.0/net/core/neighbour.c --- linux-6.2.0/net/core/neighbour.c +++ linux-6.2.0/net/core/neighbour.c @@ -410,7 +410,7 @@ */ __skb_queue_purge(&n->arp_queue); n->arp_queue_len_bytes = 0; - n->output = neigh_blackhole; + WRITE_ONCE(n->output, neigh_blackhole); if (n->nud_state & NUD_VALID) n->nud_state = NUD_NOARP; else @@ -614,7 +614,7 @@ NEIGH_CACHE_STAT_INC(tbl, lookups); - rcu_read_lock_bh(); + rcu_read_lock(); n = __neigh_lookup_noref(tbl, pkey, dev); if (n) { if (!refcount_inc_not_zero(&n->refcnt)) @@ -622,7 +622,7 @@ NEIGH_CACHE_STAT_INC(tbl, hits); } - rcu_read_unlock_bh(); + rcu_read_unlock(); return n; } EXPORT_SYMBOL(neigh_lookup); @@ -920,7 +920,7 @@ { neigh_dbg(2, "neigh %p is suspected\n", neigh); - neigh->output = neigh->ops->output; + WRITE_ONCE(neigh->output, neigh->ops->output); } /* Neighbour state is OK; @@ -932,7 +932,7 @@ { neigh_dbg(2, "neigh %p is connected\n", neigh); - neigh->output = neigh->ops->connected_output; + WRITE_ONCE(neigh->output, neigh->ops->connected_output); } static void neigh_periodic_work(struct work_struct *work) @@ -988,7 +988,9 @@ (state == NUD_FAILED || !time_in_range_open(jiffies, n->used, n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) { - *np = n->next; + rcu_assign_pointer(*np, + rcu_dereference_protected(n->next, + lockdep_is_held(&tbl->lock))); neigh_mark_dead(n); write_unlock(&n->lock); neigh_cleanup_and_release(n); @@ -1093,13 +1095,13 @@ neigh->used + NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME))) { neigh_dbg(2, "neigh %p is delayed\n", neigh); - neigh->nud_state = NUD_DELAY; + WRITE_ONCE(neigh->nud_state, NUD_DELAY); neigh->updated = jiffies; neigh_suspect(neigh); next = now + NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME); } else { neigh_dbg(2, "neigh %p is suspected\n", neigh); - neigh->nud_state = NUD_STALE; + WRITE_ONCE(neigh->nud_state, NUD_STALE); neigh->updated = jiffies; neigh_suspect(neigh); notify = 1; @@ -1109,14 +1111,14 @@ neigh->confirmed + NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME))) { neigh_dbg(2, "neigh %p is now reachable\n", neigh); - neigh->nud_state = NUD_REACHABLE; + WRITE_ONCE(neigh->nud_state, NUD_REACHABLE); neigh->updated = jiffies; neigh_connect(neigh); notify = 1; next = neigh->confirmed + neigh->parms->reachable_time; } else { neigh_dbg(2, "neigh %p is probed\n", neigh); - neigh->nud_state = NUD_PROBE; + WRITE_ONCE(neigh->nud_state, NUD_PROBE); neigh->updated = jiffies; atomic_set(&neigh->probes, 0); notify = 1; @@ -1130,7 +1132,7 @@ if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) { - neigh->nud_state = NUD_FAILED; + WRITE_ONCE(neigh->nud_state, NUD_FAILED); notify = 1; neigh_invalidate(neigh); goto out; @@ -1179,7 +1181,7 @@ atomic_set(&neigh->probes, NEIGH_VAR(neigh->parms, UCAST_PROBES)); neigh_del_timer(neigh); - neigh->nud_state = NUD_INCOMPLETE; + WRITE_ONCE(neigh->nud_state, NUD_INCOMPLETE); neigh->updated = now; if (!immediate_ok) { next = now + 1; @@ -1191,7 +1193,7 @@ } neigh_add_timer(neigh, next); } else { - neigh->nud_state = NUD_FAILED; + WRITE_ONCE(neigh->nud_state, NUD_FAILED); neigh->updated = jiffies; write_unlock_bh(&neigh->lock); @@ -1201,7 +1203,7 @@ } else if (neigh->nud_state & NUD_STALE) { neigh_dbg(2, "neigh %p is delayed\n", neigh); neigh_del_timer(neigh); - neigh->nud_state = NUD_DELAY; + WRITE_ONCE(neigh->nud_state, NUD_DELAY); neigh->updated = jiffies; neigh_add_timer(neigh, jiffies + NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME)); @@ -1313,7 +1315,7 @@ neigh_update_flags(neigh, flags, ¬ify, &gc_update, &managed_update); if (flags & (NEIGH_UPDATE_F_USE | NEIGH_UPDATE_F_MANAGED)) { new = old & ~NUD_PERMANENT; - neigh->nud_state = new; + WRITE_ONCE(neigh->nud_state, new); err = 0; goto out; } @@ -1322,7 +1324,7 @@ neigh_del_timer(neigh); if (old & NUD_CONNECTED) neigh_suspect(neigh); - neigh->nud_state = new; + WRITE_ONCE(neigh->nud_state, new); err = 0; notify = old & NUD_VALID; if ((old & (NUD_INCOMPLETE | NUD_PROBE)) && @@ -1401,7 +1403,7 @@ ((new & NUD_REACHABLE) ? neigh->parms->reachable_time : 0))); - neigh->nud_state = new; + WRITE_ONCE(neigh->nud_state, new); notify = 1; } @@ -1447,7 +1449,7 @@ if (n2) n1 = n2; } - n1->output(n1, skb); + READ_ONCE(n1->output)(n1, skb); if (n2) neigh_release(n2); rcu_read_unlock(); @@ -1488,7 +1490,7 @@ neigh->updated = jiffies; if (!(neigh->nud_state & NUD_FAILED)) return; - neigh->nud_state = NUD_INCOMPLETE; + WRITE_ONCE(neigh->nud_state, NUD_INCOMPLETE); atomic_set(&neigh->probes, neigh_max_probes(neigh)); neigh_add_timer(neigh, jiffies + max(NEIGH_VAR(neigh->parms, RETRANS_TIME), @@ -2174,11 +2176,11 @@ .ndtc_proxy_qlen = tbl->proxy_queue.qlen, }; - rcu_read_lock_bh(); - nht = rcu_dereference_bh(tbl->nht); + rcu_read_lock(); + nht = rcu_dereference(tbl->nht); ndc.ndtc_hash_rnd = nht->hash_rnd[0]; ndc.ndtc_hash_mask = ((1 << nht->hash_shift) - 1); - rcu_read_unlock_bh(); + rcu_read_unlock(); if (nla_put(skb, NDTA_CONFIG, sizeof(ndc), &ndc)) goto nla_put_failure; @@ -2693,15 +2695,15 @@ if (filter->dev_idx || filter->master_idx) flags |= NLM_F_DUMP_FILTERED; - rcu_read_lock_bh(); - nht = rcu_dereference_bh(tbl->nht); + rcu_read_lock(); + nht = rcu_dereference(tbl->nht); for (h = s_h; h < (1 << nht->hash_shift); h++) { if (h > s_h) s_idx = 0; - for (n = rcu_dereference_bh(nht->hash_buckets[h]), idx = 0; + for (n = rcu_dereference(nht->hash_buckets[h]), idx = 0; n != NULL; - n = rcu_dereference_bh(n->next)) { + n = rcu_dereference(n->next)) { if (idx < s_idx || !net_eq(dev_net(n->dev), net)) goto next; if (neigh_ifindex_filtered(n->dev, filter->dev_idx) || @@ -2720,7 +2722,7 @@ } rc = skb->len; out: - rcu_read_unlock_bh(); + rcu_read_unlock(); cb->args[1] = h; cb->args[2] = idx; return rc; @@ -3065,20 +3067,20 @@ int chain; struct neigh_hash_table *nht; - rcu_read_lock_bh(); - nht = rcu_dereference_bh(tbl->nht); + rcu_read_lock(); + nht = rcu_dereference(tbl->nht); - read_lock(&tbl->lock); /* avoid resizes */ + read_lock_bh(&tbl->lock); /* avoid resizes */ for (chain = 0; chain < (1 << nht->hash_shift); chain++) { struct neighbour *n; - for (n = rcu_dereference_bh(nht->hash_buckets[chain]); + for (n = rcu_dereference(nht->hash_buckets[chain]); n != NULL; - n = rcu_dereference_bh(n->next)) + n = rcu_dereference(n->next)) cb(n, cookie); } - read_unlock(&tbl->lock); - rcu_read_unlock_bh(); + read_unlock_bh(&tbl->lock); + rcu_read_unlock(); } EXPORT_SYMBOL(neigh_for_each); @@ -3128,7 +3130,7 @@ tbl = neigh_tables[index]; if (!tbl) goto out; - rcu_read_lock_bh(); + rcu_read_lock(); if (index == NEIGH_ARP_TABLE) { u32 key = *((u32 *)addr); @@ -3140,11 +3142,11 @@ neigh = __neigh_create(tbl, addr, dev, false); err = PTR_ERR(neigh); if (IS_ERR(neigh)) { - rcu_read_unlock_bh(); + rcu_read_unlock(); goto out_kfree_skb; } - err = neigh->output(neigh, skb); - rcu_read_unlock_bh(); + err = READ_ONCE(neigh->output)(neigh, skb); + rcu_read_unlock(); } else if (index == NEIGH_LINK_TABLE) { err = dev_hard_header(skb, dev, ntohs(skb->protocol), @@ -3173,7 +3175,7 @@ state->flags &= ~NEIGH_SEQ_IS_PNEIGH; for (bucket = 0; bucket < (1 << nht->hash_shift); bucket++) { - n = rcu_dereference_bh(nht->hash_buckets[bucket]); + n = rcu_dereference(nht->hash_buckets[bucket]); while (n) { if (!net_eq(dev_net(n->dev), net)) @@ -3188,10 +3190,10 @@ } if (!(state->flags & NEIGH_SEQ_SKIP_NOARP)) break; - if (n->nud_state & ~NUD_NOARP) + if (READ_ONCE(n->nud_state) & ~NUD_NOARP) break; next: - n = rcu_dereference_bh(n->next); + n = rcu_dereference(n->next); } if (n) @@ -3215,7 +3217,7 @@ if (v) return n; } - n = rcu_dereference_bh(n->next); + n = rcu_dereference(n->next); while (1) { while (n) { @@ -3230,10 +3232,10 @@ if (!(state->flags & NEIGH_SEQ_SKIP_NOARP)) break; - if (n->nud_state & ~NUD_NOARP) + if (READ_ONCE(n->nud_state) & ~NUD_NOARP) break; next: - n = rcu_dereference_bh(n->next); + n = rcu_dereference(n->next); } if (n) @@ -3242,7 +3244,7 @@ if (++state->bucket >= (1 << nht->hash_shift)) break; - n = rcu_dereference_bh(nht->hash_buckets[state->bucket]); + n = rcu_dereference(nht->hash_buckets[state->bucket]); } if (n && pos) @@ -3344,7 +3346,7 @@ void *neigh_seq_start(struct seq_file *seq, loff_t *pos, struct neigh_table *tbl, unsigned int neigh_seq_flags) __acquires(tbl->lock) - __acquires(rcu_bh) + __acquires(rcu) { struct neigh_seq_state *state = seq->private; @@ -3352,9 +3354,9 @@ state->bucket = 0; state->flags = (neigh_seq_flags & ~NEIGH_SEQ_IS_PNEIGH); - rcu_read_lock_bh(); - state->nht = rcu_dereference_bh(tbl->nht); - read_lock(&tbl->lock); + rcu_read_lock(); + state->nht = rcu_dereference(tbl->nht); + read_lock_bh(&tbl->lock); return *pos ? neigh_get_idx_any(seq, pos) : SEQ_START_TOKEN; } @@ -3389,13 +3391,13 @@ void neigh_seq_stop(struct seq_file *seq, void *v) __releases(tbl->lock) - __releases(rcu_bh) + __releases(rcu) { struct neigh_seq_state *state = seq->private; struct neigh_table *tbl = state->tbl; - read_unlock(&tbl->lock); - rcu_read_unlock_bh(); + read_unlock_bh(&tbl->lock); + rcu_read_unlock(); } EXPORT_SYMBOL(neigh_seq_stop); diff -u linux-6.2.0/net/core/scm.c linux-6.2.0/net/core/scm.c --- linux-6.2.0/net/core/scm.c +++ linux-6.2.0/net/core/scm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -103,6 +104,11 @@ if (fd < 0 || !(file = fget_raw(fd))) return -EBADF; + /* don't allow io_uring files */ + if (io_uring_get_socket(file)) { + fput(file); + return -EINVAL; + } *fpp++ = file; fpl->count++; } diff -u linux-6.2.0/net/core/skbuff.c linux-6.2.0/net/core/skbuff.c --- linux-6.2.0/net/core/skbuff.c +++ linux-6.2.0/net/core/skbuff.c @@ -4198,21 +4198,20 @@ struct sk_buff *segs = NULL; struct sk_buff *tail = NULL; struct sk_buff *list_skb = skb_shinfo(head_skb)->frag_list; - skb_frag_t *frag = skb_shinfo(head_skb)->frags; unsigned int mss = skb_shinfo(head_skb)->gso_size; unsigned int doffset = head_skb->data - skb_mac_header(head_skb); - struct sk_buff *frag_skb = head_skb; unsigned int offset = doffset; unsigned int tnl_hlen = skb_tnl_header_len(head_skb); unsigned int partial_segs = 0; unsigned int headroom; unsigned int len = head_skb->len; + struct sk_buff *frag_skb; + skb_frag_t *frag; __be16 proto; bool csum, sg; - int nfrags = skb_shinfo(head_skb)->nr_frags; int err = -ENOMEM; int i = 0; - int pos; + int nfrags, pos; if ((skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY) && mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb)) { @@ -4289,6 +4288,13 @@ headroom = skb_headroom(head_skb); pos = skb_headlen(head_skb); + if (skb_orphan_frags(head_skb, GFP_ATOMIC)) + return ERR_PTR(-ENOMEM); + + nfrags = skb_shinfo(head_skb)->nr_frags; + frag = skb_shinfo(head_skb)->frags; + frag_skb = head_skb; + do { struct sk_buff *nskb; skb_frag_t *nskb_frag; @@ -4309,6 +4315,10 @@ (skb_headlen(list_skb) == len || sg)) { BUG_ON(skb_headlen(list_skb) > len); + nskb = skb_clone(list_skb, GFP_ATOMIC); + if (unlikely(!nskb)) + goto err; + i = 0; nfrags = skb_shinfo(list_skb)->nr_frags; frag = skb_shinfo(list_skb)->frags; @@ -4327,12 +4337,8 @@ frag++; } - nskb = skb_clone(list_skb, GFP_ATOMIC); list_skb = list_skb->next; - if (unlikely(!nskb)) - goto err; - if (unlikely(pskb_trim(nskb, len))) { kfree_skb(nskb); goto err; @@ -4408,12 +4414,16 @@ skb_shinfo(nskb)->flags |= skb_shinfo(head_skb)->flags & SKBFL_SHARED_FRAG; - if (skb_orphan_frags(frag_skb, GFP_ATOMIC) || - skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC)) + if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC)) goto err; while (pos < offset + len) { if (i >= nfrags) { + if (skb_orphan_frags(list_skb, GFP_ATOMIC) || + skb_zerocopy_clone(nskb, list_skb, + GFP_ATOMIC)) + goto err; + i = 0; nfrags = skb_shinfo(list_skb)->nr_frags; frag = skb_shinfo(list_skb)->frags; @@ -4427,10 +4437,6 @@ i--; frag--; } - if (skb_orphan_frags(frag_skb, GFP_ATOMIC) || - skb_zerocopy_clone(nskb, frag_skb, - GFP_ATOMIC)) - goto err; list_skb = list_skb->next; } @@ -4970,7 +4976,7 @@ serr->ee.ee_info = tstype; serr->opt_stats = opt_stats; serr->header.h4.iif = skb->dev ? skb->dev->ifindex : 0; - if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) { + if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID) { serr->ee.ee_data = skb_shinfo(skb)->tskey; if (sk_is_tcp(sk)) serr->ee.ee_data -= atomic_read(&sk->sk_tskey); @@ -5026,21 +5032,23 @@ { struct sk_buff *skb; bool tsonly, opt_stats = false; + u32 tsflags; if (!sk) return; - if (!hwtstamps && !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TX_SWHW) && + tsflags = READ_ONCE(sk->sk_tsflags); + if (!hwtstamps && !(tsflags & SOF_TIMESTAMPING_OPT_TX_SWHW) && skb_shinfo(orig_skb)->tx_flags & SKBTX_IN_PROGRESS) return; - tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY; + tsonly = tsflags & SOF_TIMESTAMPING_OPT_TSONLY; if (!skb_may_tx_timestamp(sk, tsonly)) return; if (tsonly) { #ifdef CONFIG_INET - if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS) && + if ((tsflags & SOF_TIMESTAMPING_OPT_STATS) && sk_is_tcp(sk)) { skb = tcp_get_timestamping_opt_stats(sk, orig_skb, ack_skb); diff -u linux-6.2.0/net/core/skmsg.c linux-6.2.0/net/core/skmsg.c --- linux-6.2.0/net/core/skmsg.c +++ linux-6.2.0/net/core/skmsg.c @@ -611,12 +611,18 @@ static int sk_psock_handle_skb(struct sk_psock *psock, struct sk_buff *skb, u32 off, u32 len, bool ingress) { + int err = 0; + if (!ingress) { if (!sock_writeable(psock->sk)) return -EAGAIN; return skb_send_sock(psock->sk, skb, off, len); } - return sk_psock_skb_ingress(psock, skb, off, len); + skb_get(skb); + err = sk_psock_skb_ingress(psock, skb, off, len); + if (err < 0) + kfree_skb(skb); + return err; } static void sk_psock_skb_state(struct sk_psock *psock, @@ -684,9 +690,7 @@ } while (len); skb = skb_dequeue(&psock->ingress_skb); - if (!ingress) { - kfree_skb(skb); - } + kfree_skb(skb); } end: mutex_unlock(&psock->work_mutex); diff -u linux-6.2.0/net/core/sock.c linux-6.2.0/net/core/sock.c --- linux-6.2.0/net/core/sock.c +++ linux-6.2.0/net/core/sock.c @@ -425,6 +425,7 @@ { struct __kernel_sock_timeval tv; int err = sock_copy_user_timeval(&tv, optval, optlen, old_timeval); + long val; if (err) return err; @@ -435,7 +436,7 @@ if (tv.tv_sec < 0) { static int warned __read_mostly; - *timeo_p = 0; + WRITE_ONCE(*timeo_p, 0); if (warned < 10 && net_ratelimit()) { warned++; pr_info("%s: `%s' (pid %d) tries to set negative timeout\n", @@ -443,11 +444,12 @@ } return 0; } - *timeo_p = MAX_SCHEDULE_TIMEOUT; - if (tv.tv_sec == 0 && tv.tv_usec == 0) - return 0; - if (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1)) - *timeo_p = tv.tv_sec * HZ + DIV_ROUND_UP((unsigned long)tv.tv_usec, USEC_PER_SEC / HZ); + val = MAX_SCHEDULE_TIMEOUT; + if ((tv.tv_sec || tv.tv_usec) && + (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1))) + val = tv.tv_sec * HZ + DIV_ROUND_UP((unsigned long)tv.tv_usec, + USEC_PER_SEC / HZ); + WRITE_ONCE(*timeo_p, val); return 0; } @@ -759,7 +761,8 @@ return false; if (!sk) return true; - switch (sk->sk_family) { + /* IPV6_ADDRFORM can change sk->sk_family under us. */ + switch (READ_ONCE(sk->sk_family)) { case AF_INET: return inet_sk(sk)->mc_loop; #if IS_ENABLED(CONFIG_IPV6) @@ -791,7 +794,7 @@ void sock_no_linger(struct sock *sk) { lock_sock(sk); - sk->sk_lingertime = 0; + WRITE_ONCE(sk->sk_lingertime, 0); sock_set_flag(sk, SOCK_LINGER); release_sock(sk); } @@ -809,9 +812,9 @@ { lock_sock(sk); if (secs && secs < MAX_SCHEDULE_TIMEOUT / HZ - 1) - sk->sk_sndtimeo = secs * HZ; + WRITE_ONCE(sk->sk_sndtimeo, secs * HZ); else - sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT; + WRITE_ONCE(sk->sk_sndtimeo, MAX_SCHEDULE_TIMEOUT); release_sock(sk); } EXPORT_SYMBOL(sock_set_sndtimeo); @@ -887,7 +890,7 @@ if (!match) return -EINVAL; - sk->sk_bind_phc = phc_index; + WRITE_ONCE(sk->sk_bind_phc, phc_index); return 0; } @@ -930,7 +933,7 @@ return ret; } - sk->sk_tsflags = val; + WRITE_ONCE(sk->sk_tsflags, val); sock_valbool_flag(sk, SOCK_TSTAMP_NEW, optname == SO_TIMESTAMPING_NEW); if (val & SOF_TIMESTAMPING_RX_SOFTWARE) @@ -1038,7 +1041,7 @@ mem_cgroup_uncharge_skmem(sk->sk_memcg, pages); return -ENOMEM; } - sk->sk_forward_alloc += pages << PAGE_SHIFT; + sk_forward_alloc_add(sk, pages << PAGE_SHIFT); WRITE_ONCE(sk->sk_reserved_mem, sk->sk_reserved_mem + (pages << PAGE_SHIFT)); @@ -1224,15 +1227,15 @@ ret = -EFAULT; break; } - if (!ling.l_onoff) + if (!ling.l_onoff) { sock_reset_flag(sk, SOCK_LINGER); - else { -#if (BITS_PER_LONG == 32) - if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ) - sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT; + } else { + unsigned long t_sec = ling.l_linger; + + if (t_sec >= MAX_SCHEDULE_TIMEOUT / HZ) + WRITE_ONCE(sk->sk_lingertime, MAX_SCHEDULE_TIMEOUT); else -#endif - sk->sk_lingertime = (unsigned int)ling.l_linger * HZ; + WRITE_ONCE(sk->sk_lingertime, t_sec * HZ); sock_set_flag(sk, SOCK_LINGER); } break; @@ -1683,7 +1686,7 @@ case SO_LINGER: lv = sizeof(v.ling); v.ling.l_onoff = sock_flag(sk, SOCK_LINGER); - v.ling.l_linger = sk->sk_lingertime / HZ; + v.ling.l_linger = READ_ONCE(sk->sk_lingertime) / HZ; break; case SO_BSDCOMPAT: @@ -1709,18 +1712,20 @@ case SO_TIMESTAMPING_OLD: lv = sizeof(v.timestamping); - v.timestamping.flags = sk->sk_tsflags; - v.timestamping.bind_phc = sk->sk_bind_phc; + v.timestamping.flags = READ_ONCE(sk->sk_tsflags); + v.timestamping.bind_phc = READ_ONCE(sk->sk_bind_phc); break; case SO_RCVTIMEO_OLD: case SO_RCVTIMEO_NEW: - lv = sock_get_timeout(sk->sk_rcvtimeo, &v, SO_RCVTIMEO_OLD == optname); + lv = sock_get_timeout(READ_ONCE(sk->sk_rcvtimeo), &v, + SO_RCVTIMEO_OLD == optname); break; case SO_SNDTIMEO_OLD: case SO_SNDTIMEO_NEW: - lv = sock_get_timeout(sk->sk_sndtimeo, &v, SO_SNDTIMEO_OLD == optname); + lv = sock_get_timeout(READ_ONCE(sk->sk_sndtimeo), &v, + SO_SNDTIMEO_OLD == optname); break; case SO_RCVLOWAT: @@ -1776,14 +1781,14 @@ case SO_PEERNAME: { - char address[128]; + struct sockaddr_storage address; - lv = sock->ops->getname(sock, (struct sockaddr *)address, 2); + lv = sock->ops->getname(sock, (struct sockaddr *)&address, 2); if (lv < 0) return -ENOTCONN; if (lv < len) return -EINVAL; - if (copy_to_sockptr(optval, address, len)) + if (copy_to_sockptr(optval, &address, len)) return -EFAULT; goto lenout; } @@ -2707,9 +2712,9 @@ prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); if (refcount_read(&sk->sk_wmem_alloc) < READ_ONCE(sk->sk_sndbuf)) break; - if (sk->sk_shutdown & SEND_SHUTDOWN) + if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) break; - if (sk->sk_err) + if (READ_ONCE(sk->sk_err)) break; timeo = schedule_timeout(timeo); } @@ -2737,7 +2742,7 @@ goto failure; err = -EPIPE; - if (sk->sk_shutdown & SEND_SHUTDOWN) + if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN) goto failure; if (sk_wmem_alloc_get(sk) < READ_ONCE(sk->sk_sndbuf)) @@ -3099,10 +3104,10 @@ { int ret, amt = sk_mem_pages(size); - sk->sk_forward_alloc += amt << PAGE_SHIFT; + sk_forward_alloc_add(sk, amt << PAGE_SHIFT); ret = __sk_mem_raise_allocated(sk, size, amt, kind); if (!ret) - sk->sk_forward_alloc -= amt << PAGE_SHIFT; + sk_forward_alloc_add(sk, -(amt << PAGE_SHIFT)); return ret; } EXPORT_SYMBOL(__sk_mem_schedule); @@ -3134,7 +3139,7 @@ void __sk_mem_reclaim(struct sock *sk, int amount) { amount >>= PAGE_SHIFT; - sk->sk_forward_alloc -= amount << PAGE_SHIFT; + sk_forward_alloc_add(sk, -(amount << PAGE_SHIFT)); __sk_mem_reduce_allocated(sk, amount); } EXPORT_SYMBOL(__sk_mem_reclaim); @@ -3733,7 +3738,7 @@ mem[SK_MEMINFO_RCVBUF] = READ_ONCE(sk->sk_rcvbuf); mem[SK_MEMINFO_WMEM_ALLOC] = sk_wmem_alloc_get(sk); mem[SK_MEMINFO_SNDBUF] = READ_ONCE(sk->sk_sndbuf); - mem[SK_MEMINFO_FWD_ALLOC] = sk->sk_forward_alloc; + mem[SK_MEMINFO_FWD_ALLOC] = sk_forward_alloc_get(sk); mem[SK_MEMINFO_WMEM_QUEUED] = READ_ONCE(sk->sk_wmem_queued); mem[SK_MEMINFO_OPTMEM] = atomic_read(&sk->sk_omem_alloc); mem[SK_MEMINFO_BACKLOG] = READ_ONCE(sk->sk_backlog.len); diff -u linux-6.2.0/net/core/sock_map.c linux-6.2.0/net/core/sock_map.c --- linux-6.2.0/net/core/sock_map.c +++ linux-6.2.0/net/core/sock_map.c @@ -670,6 +670,8 @@ sk = __sock_map_lookup_elem(map, key); if (unlikely(!sk || !sock_map_redirect_allowed(sk))) return SK_DROP; + if (!(flags & BPF_F_INGRESS) && !sk_is_tcp(sk)) + return SK_DROP; msg->flags = flags; msg->sk_redir = sk; @@ -1262,6 +1264,8 @@ sk = __sock_hash_lookup_elem(map, key); if (unlikely(!sk || !sock_map_redirect_allowed(sk))) return SK_DROP; + if (!(flags & BPF_F_INGRESS) && !sk_is_tcp(sk)) + return SK_DROP; msg->flags = flags; msg->sk_redir = sk; diff -u linux-6.2.0/net/dccp/ipv4.c linux-6.2.0/net/dccp/ipv4.c --- linux-6.2.0/net/dccp/ipv4.c +++ linux-6.2.0/net/dccp/ipv4.c @@ -255,12 +255,12 @@ int err; struct net *net = dev_net(skb->dev); - /* Only need dccph_dport & dccph_sport which are the first - * 4 bytes in dccp header. - * Our caller (icmp_socket_deliver()) already pulled 8 bytes for us. - */ - BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8); - BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8); + if (!pskb_may_pull(skb, offset + sizeof(*dh))) + return -EINVAL; + dh = (struct dccp_hdr *)(skb->data + offset); + if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) + return -EINVAL; + iph = (struct iphdr *)skb->data; dh = (struct dccp_hdr *)(skb->data + offset); sk = __inet_lookup_established(net, &dccp_hashinfo, diff -u linux-6.2.0/net/dccp/ipv6.c linux-6.2.0/net/dccp/ipv6.c --- linux-6.2.0/net/dccp/ipv6.c +++ linux-6.2.0/net/dccp/ipv6.c @@ -74,7 +74,7 @@ static int dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, u8 type, u8 code, int offset, __be32 info) { - const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; + const struct ipv6hdr *hdr; const struct dccp_hdr *dh; struct dccp_sock *dp; struct ipv6_pinfo *np; @@ -83,12 +83,12 @@ __u64 seq; struct net *net = dev_net(skb->dev); - /* Only need dccph_dport & dccph_sport which are the first - * 4 bytes in dccp header. - * Our caller (icmpv6_notify()) already pulled 8 bytes for us. - */ - BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8); - BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8); + if (!pskb_may_pull(skb, offset + sizeof(*dh))) + return -EINVAL; + dh = (struct dccp_hdr *)(skb->data + offset); + if (!pskb_may_pull(skb, offset + __dccp_basic_hdr_len(dh))) + return -EINVAL; + hdr = (const struct ipv6hdr *)skb->data; dh = (struct dccp_hdr *)(skb->data + offset); sk = __inet6_lookup_established(net, &dccp_hashinfo, diff -u linux-6.2.0/net/devlink/leftover.c linux-6.2.0/net/devlink/leftover.c --- linux-6.2.0/net/devlink/leftover.c +++ linux-6.2.0/net/devlink/leftover.c @@ -5467,7 +5467,7 @@ const struct devlink_param *param, struct devlink_param_gset_ctx *ctx) { - if (!param->get || devlink->reload_failed) + if (!param->get) return -EOPNOTSUPP; return param->get(devlink, param->id, ctx); } @@ -5476,7 +5476,7 @@ const struct devlink_param *param, struct devlink_param_gset_ctx *ctx) { - if (!param->set || devlink->reload_failed) + if (!param->set) return -EOPNOTSUPP; return param->set(devlink, param->id, ctx); } diff -u linux-6.2.0/net/ethtool/ioctl.c linux-6.2.0/net/ethtool/ioctl.c --- linux-6.2.0/net/ethtool/ioctl.c +++ linux-6.2.0/net/ethtool/ioctl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -3127,7 +3128,6 @@ ethtool_rx_flow_rule_create(const struct ethtool_rx_flow_spec_input *input) { const struct ethtool_rx_flow_spec *fs = input->fs; - static struct in6_addr zero_addr = {}; struct ethtool_rx_flow_match *match; struct ethtool_rx_flow_rule *flow; struct flow_action_entry *act; @@ -3233,20 +3233,20 @@ v6_spec = &fs->h_u.tcp_ip6_spec; v6_m_spec = &fs->m_u.tcp_ip6_spec; - if (memcmp(v6_m_spec->ip6src, &zero_addr, sizeof(zero_addr))) { + if (!ipv6_addr_any((struct in6_addr *)v6_m_spec->ip6src)) { memcpy(&match->key.ipv6.src, v6_spec->ip6src, sizeof(match->key.ipv6.src)); memcpy(&match->mask.ipv6.src, v6_m_spec->ip6src, sizeof(match->mask.ipv6.src)); } - if (memcmp(v6_m_spec->ip6dst, &zero_addr, sizeof(zero_addr))) { + if (!ipv6_addr_any((struct in6_addr *)v6_m_spec->ip6dst)) { memcpy(&match->key.ipv6.dst, v6_spec->ip6dst, sizeof(match->key.ipv6.dst)); memcpy(&match->mask.ipv6.dst, v6_m_spec->ip6dst, sizeof(match->mask.ipv6.dst)); } - if (memcmp(v6_m_spec->ip6src, &zero_addr, sizeof(zero_addr)) || - memcmp(v6_m_spec->ip6dst, &zero_addr, sizeof(zero_addr))) { + if (!ipv6_addr_any((struct in6_addr *)v6_m_spec->ip6src) || + !ipv6_addr_any((struct in6_addr *)v6_m_spec->ip6dst)) { match->dissector.used_keys |= BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS); match->dissector.offset[FLOW_DISSECTOR_KEY_IPV6_ADDRS] = diff -u linux-6.2.0/net/hsr/hsr_framereg.c linux-6.2.0/net/hsr/hsr_framereg.c --- linux-6.2.0/net/hsr/hsr_framereg.c +++ linux-6.2.0/net/hsr/hsr_framereg.c @@ -288,13 +288,13 @@ /* And leave the HSR tag. */ if (ethhdr->h_proto == htons(ETH_P_HSR)) { - pull_size = sizeof(struct ethhdr); + pull_size = sizeof(struct hsr_tag); skb_pull(skb, pull_size); total_pull_size += pull_size; } /* And leave the HSR sup tag. */ - pull_size = sizeof(struct hsr_tag); + pull_size = sizeof(struct hsr_sup_tag); skb_pull(skb, pull_size); total_pull_size += pull_size; diff -u linux-6.2.0/net/ipv4/igmp.c linux-6.2.0/net/ipv4/igmp.c --- linux-6.2.0/net/ipv4/igmp.c +++ linux-6.2.0/net/ipv4/igmp.c @@ -216,8 +216,10 @@ int tv = get_random_u32_below(max_delay); im->tm_running = 1; - if (!mod_timer(&im->timer, jiffies+tv+2)) - refcount_inc(&im->refcnt); + if (refcount_inc_not_zero(&im->refcnt)) { + if (mod_timer(&im->timer, jiffies + tv + 2)) + ip_ma_put(im); + } } static void igmp_gq_start_timer(struct in_device *in_dev) diff -u linux-6.2.0/net/ipv4/inet_hashtables.c linux-6.2.0/net/ipv4/inet_hashtables.c --- linux-6.2.0/net/ipv4/inet_hashtables.c +++ linux-6.2.0/net/ipv4/inet_hashtables.c @@ -795,43 +795,45 @@ const struct net *net, unsigned short port, int l3mdev, const struct sock *sk) { + if (!net_eq(ib2_net(tb), net) || tb->port != port || + tb->l3mdev != l3mdev) + return false; + #if IS_ENABLED(CONFIG_IPV6) - if (sk->sk_family != tb->family) + if (sk->sk_family != tb->family) { + if (sk->sk_family == AF_INET) + return ipv6_addr_v4mapped(&tb->v6_rcv_saddr) && + tb->v6_rcv_saddr.s6_addr32[3] == sk->sk_rcv_saddr; + return false; + } if (sk->sk_family == AF_INET6) - return net_eq(ib2_net(tb), net) && tb->port == port && - tb->l3mdev == l3mdev && - ipv6_addr_equal(&tb->v6_rcv_saddr, &sk->sk_v6_rcv_saddr); - else + return ipv6_addr_equal(&tb->v6_rcv_saddr, &sk->sk_v6_rcv_saddr); #endif - return net_eq(ib2_net(tb), net) && tb->port == port && - tb->l3mdev == l3mdev && tb->rcv_saddr == sk->sk_rcv_saddr; + return tb->rcv_saddr == sk->sk_rcv_saddr; } bool inet_bind2_bucket_match_addr_any(const struct inet_bind2_bucket *tb, const struct net *net, unsigned short port, int l3mdev, const struct sock *sk) { -#if IS_ENABLED(CONFIG_IPV6) - struct in6_addr addr_any = {}; + if (!net_eq(ib2_net(tb), net) || tb->port != port || + tb->l3mdev != l3mdev) + return false; +#if IS_ENABLED(CONFIG_IPV6) if (sk->sk_family != tb->family) { if (sk->sk_family == AF_INET) - return net_eq(ib2_net(tb), net) && tb->port == port && - tb->l3mdev == l3mdev && - ipv6_addr_equal(&tb->v6_rcv_saddr, &addr_any); + return ipv6_addr_any(&tb->v6_rcv_saddr) || + ipv6_addr_v4mapped_any(&tb->v6_rcv_saddr); return false; } if (sk->sk_family == AF_INET6) - return net_eq(ib2_net(tb), net) && tb->port == port && - tb->l3mdev == l3mdev && - ipv6_addr_equal(&tb->v6_rcv_saddr, &addr_any); - else + return ipv6_addr_any(&tb->v6_rcv_saddr); #endif - return net_eq(ib2_net(tb), net) && tb->port == port && - tb->l3mdev == l3mdev && tb->rcv_saddr == 0; + return tb->rcv_saddr == 0; } /* The socket's bhash2 hashbucket spinlock must be held when this is called */ @@ -853,11 +855,10 @@ { struct inet_hashinfo *hinfo = tcp_or_dccp_get_hashinfo(sk); u32 hash; -#if IS_ENABLED(CONFIG_IPV6) - struct in6_addr addr_any = {}; +#if IS_ENABLED(CONFIG_IPV6) if (sk->sk_family == AF_INET6) - hash = ipv6_portaddr_hash(net, &addr_any, port); + hash = ipv6_portaddr_hash(net, &in6addr_any, port); else #endif hash = ipv4_portaddr_hash(net, 0, port); diff -u linux-6.2.0/net/ipv4/ip_output.c linux-6.2.0/net/ipv4/ip_output.c --- linux-6.2.0/net/ipv4/ip_output.c +++ linux-6.2.0/net/ipv4/ip_output.c @@ -214,11 +214,11 @@ if (lwtunnel_xmit_redirect(dst->lwtstate)) { int res = lwtunnel_xmit(skb); - if (res < 0 || res == LWTUNNEL_XMIT_DONE) + if (res != LWTUNNEL_XMIT_CONTINUE) return res; } - rcu_read_lock_bh(); + rcu_read_lock(); neigh = ip_neigh_for_gw(rt, skb, &is_v6gw); if (!IS_ERR(neigh)) { int res; @@ -226,15 +226,15 @@ sock_confirm_neigh(skb, neigh); /* if crossing protocols, can not use the cached header */ res = neigh_output(neigh, skb, is_v6gw); - rcu_read_unlock_bh(); + rcu_read_unlock(); return res; } - rcu_read_unlock_bh(); + rcu_read_unlock(); net_dbg_ratelimited("%s: No header cache and no neighbour!\n", __func__); kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL); - return -EINVAL; + return PTR_ERR(neigh); } static int ip_finish_output_gso(struct net *net, struct sock *sk, @@ -991,7 +991,7 @@ paged = !!cork->gso_size; if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP && - sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) + READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID) tskey = atomic_inc_return(&sk->sk_tskey) - 1; hh_len = LL_RESERVED_SPACE(rt->dst.dev); diff -u linux-6.2.0/net/ipv4/ip_sockglue.c linux-6.2.0/net/ipv4/ip_sockglue.c --- linux-6.2.0/net/ipv4/ip_sockglue.c +++ linux-6.2.0/net/ipv4/ip_sockglue.c @@ -512,7 +512,7 @@ * or without payload (SOF_TIMESTAMPING_OPT_TSONLY). */ info = PKTINFO_SKB_CB(skb); - if (!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG) || + if (!(READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_CMSG) || !info->ipi_ifindex) return false; diff -u linux-6.2.0/net/ipv4/nexthop.c linux-6.2.0/net/ipv4/nexthop.c --- linux-6.2.0/net/ipv4/nexthop.c +++ linux-6.2.0/net/ipv4/nexthop.c @@ -1124,13 +1124,13 @@ int state = NUD_REACHABLE; struct neighbour *n; - rcu_read_lock_bh(); + rcu_read_lock(); n = __ipv6_neigh_lookup_noref_stub(nh->fib_nh_dev, &nh->fib_nh_gw6); if (n) - state = n->nud_state; + state = READ_ONCE(n->nud_state); - rcu_read_unlock_bh(); + rcu_read_unlock(); return !!(state & NUD_VALID); } @@ -1140,14 +1140,14 @@ int state = NUD_REACHABLE; struct neighbour *n; - rcu_read_lock_bh(); + rcu_read_lock(); n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev, (__force u32)nh->fib_nh_gw4); if (n) - state = n->nud_state; + state = READ_ONCE(n->nud_state); - rcu_read_unlock_bh(); + rcu_read_unlock(); return !!(state & NUD_VALID); } diff -u linux-6.2.0/net/ipv4/route.c linux-6.2.0/net/ipv4/route.c --- linux-6.2.0/net/ipv4/route.c +++ linux-6.2.0/net/ipv4/route.c @@ -408,7 +408,7 @@ struct net_device *dev = dst->dev; struct neighbour *n; - rcu_read_lock_bh(); + rcu_read_lock(); if (likely(rt->rt_gw_family == AF_INET)) { n = ip_neigh_gw4(dev, rt->rt_gw4); @@ -424,7 +424,7 @@ if (!IS_ERR(n) && !refcount_inc_not_zero(&n->refcnt)) n = NULL; - rcu_read_unlock_bh(); + rcu_read_unlock(); return n; } @@ -784,7 +784,7 @@ if (!n) n = neigh_create(&arp_tbl, &new_gw, rt->dst.dev); if (!IS_ERR(n)) { - if (!(n->nud_state & NUD_VALID)) { + if (!(READ_ONCE(n->nud_state) & NUD_VALID)) { neigh_event_send(n, NULL); } else { if (fib_lookup(net, fl4, &res, 0) == 0) { @@ -2148,6 +2148,7 @@ int h = fib_multipath_hash(res->fi->fib_net, NULL, skb, hkeys); fib_select_multipath(res, h); + IPCB(skb)->flags |= IPSKB_MULTIPATH; } #endif @@ -3420,6 +3421,8 @@ fa->fa_type == fri.type) { fri.offload = READ_ONCE(fa->offload); fri.trap = READ_ONCE(fa->trap); + fri.offload_failed = + READ_ONCE(fa->offload_failed); break; } } diff -u linux-6.2.0/net/ipv4/tcp.c linux-6.2.0/net/ipv4/tcp.c --- linux-6.2.0/net/ipv4/tcp.c +++ linux-6.2.0/net/ipv4/tcp.c @@ -1755,16 +1755,13 @@ int tcp_read_skb(struct sock *sk, skb_read_actor_t recv_actor) { - struct tcp_sock *tp = tcp_sk(sk); - u32 seq = tp->copied_seq; struct sk_buff *skb; int copied = 0; - u32 offset; if (sk->sk_state == TCP_LISTEN) return -ENOTCONN; - while ((skb = tcp_recv_skb(sk, seq, &offset)) != NULL) { + while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) { u8 tcp_flags; int used; @@ -1777,13 +1774,10 @@ copied = used; break; } - seq += used; copied += used; - if (tcp_flags & TCPHDR_FIN) { - ++seq; + if (tcp_flags & TCPHDR_FIN) break; - } } return copied; } @@ -2363,14 +2357,14 @@ } } - if (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) + if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_SOFTWARE) has_timestamping = true; else tss->ts[0] = (struct timespec64) {0}; } if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) { - if (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) + if (READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_RAW_HARDWARE) has_timestamping = true; else tss->ts[2] = (struct timespec64) {0}; diff -u linux-6.2.0/net/ipv4/tcp_bpf.c linux-6.2.0/net/ipv4/tcp_bpf.c --- linux-6.2.0/net/ipv4/tcp_bpf.c +++ linux-6.2.0/net/ipv4/tcp_bpf.c @@ -217,6 +217,7 @@ int *addr_len) { struct tcp_sock *tcp = tcp_sk(sk); + int peek = flags & MSG_PEEK; u32 seq = tcp->copied_seq; struct sk_psock *psock; int copied = 0; @@ -306,7 +307,8 @@ copied = -EAGAIN; } out: - WRITE_ONCE(tcp->copied_seq, seq); + if (!peek) + WRITE_ONCE(tcp->copied_seq, seq); tcp_rcv_space_adjust(sk); if (copied > 0) __tcp_cleanup_rbuf(sk, copied); diff -u linux-6.2.0/net/ipv4/tcp_input.c linux-6.2.0/net/ipv4/tcp_input.c --- linux-6.2.0/net/ipv4/tcp_input.c +++ linux-6.2.0/net/ipv4/tcp_input.c @@ -243,6 +243,19 @@ if (unlikely(len > icsk->icsk_ack.rcv_mss + MAX_TCP_OPTION_SPACE)) tcp_gro_dev_warn(sk, skb, len); + /* If the skb has a len of exactly 1*MSS and has the PSH bit + * set then it is likely the end of an application write. So + * more data may not be arriving soon, and yet the data sender + * may be waiting for an ACK if cwnd-bound or using TX zero + * copy. So we set ICSK_ACK_PUSHED here so that + * tcp_cleanup_rbuf() will send an ACK immediately if the app + * reads all of the data and is not ping-pong. If len > MSS + * then this logic does not matter (and does not hurt) because + * tcp_cleanup_rbuf() will always ACK immediately if the app + * reads data and there is more than an MSS of unACKed data. + */ + if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_PSH) + icsk->icsk_ack.pending |= ICSK_ACK_PUSHED; } else { /* Otherwise, we make more careful check taking into account, * that SACKs block is variable. @@ -287,7 +300,7 @@ icsk->icsk_ack.quick = quickacks; } -void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks) +static void tcp_enter_quickack_mode(struct sock *sk, unsigned int max_quickacks) { struct inet_connection_sock *icsk = inet_csk(sk); @@ -295,7 +308,6 @@ inet_csk_exit_pingpong_mode(sk); icsk->icsk_ack.ato = TCP_ATO_MIN; } -EXPORT_SYMBOL(tcp_enter_quickack_mode); /* Send ACKs quickly, if "quick" count is not exhausted * and the session is not interactive. diff -u linux-6.2.0/net/ipv4/tcp_output.c linux-6.2.0/net/ipv4/tcp_output.c --- linux-6.2.0/net/ipv4/tcp_output.c +++ linux-6.2.0/net/ipv4/tcp_output.c @@ -177,8 +177,7 @@ } /* Account for an ACK we sent. */ -static inline void tcp_event_ack_sent(struct sock *sk, unsigned int pkts, - u32 rcv_nxt) +static inline void tcp_event_ack_sent(struct sock *sk, u32 rcv_nxt) { struct tcp_sock *tp = tcp_sk(sk); @@ -192,7 +191,7 @@ if (unlikely(rcv_nxt != tp->rcv_nxt)) return; /* Special ACK sent by DCTCP to reflect ECN */ - tcp_dec_quickack_mode(sk, pkts); + tcp_dec_quickack_mode(sk); inet_csk_clear_xmit_timer(sk, ICSK_TIME_DACK); } @@ -1370,7 +1369,7 @@ sk, skb); if (likely(tcb->tcp_flags & TCPHDR_ACK)) - tcp_event_ack_sent(sk, tcp_skb_pcount(skb), rcv_nxt); + tcp_event_ack_sent(sk, rcv_nxt); if (skb->len != tcp_header_size) { tcp_event_data_sent(tp, sk); @@ -3377,7 +3376,7 @@ if (delta <= 0) return; amt = sk_mem_pages(delta); - sk->sk_forward_alloc += amt << PAGE_SHIFT; + sk_forward_alloc_add(sk, amt << PAGE_SHIFT); sk_memory_allocated_add(sk, amt); if (mem_cgroup_sockets_enabled && sk->sk_memcg) diff -u linux-6.2.0/net/ipv4/tcp_timer.c linux-6.2.0/net/ipv4/tcp_timer.c --- linux-6.2.0/net/ipv4/tcp_timer.c +++ linux-6.2.0/net/ipv4/tcp_timer.c @@ -441,6 +441,22 @@ req->timeout << req->num_timeout, TCP_RTO_MAX); } +static bool tcp_rtx_probe0_timed_out(const struct sock *sk, + const struct sk_buff *skb) +{ + const struct tcp_sock *tp = tcp_sk(sk); + const int timeout = TCP_RTO_MAX * 2; + u32 rcv_delta, rtx_delta; + + rcv_delta = inet_csk(sk)->icsk_timeout - tp->rcv_tstamp; + if (rcv_delta <= timeout) + return false; + + rtx_delta = (u32)msecs_to_jiffies(tcp_time_stamp(tp) - + (tp->retrans_stamp ?: tcp_skb_timestamp(skb))); + + return rtx_delta > timeout; +} /** * tcp_retransmit_timer() - The TCP retransmit timeout handler @@ -506,7 +522,7 @@ tp->snd_una, tp->snd_nxt); } #endif - if (tcp_jiffies32 - tp->rcv_tstamp > TCP_RTO_MAX) { + if (tcp_rtx_probe0_timed_out(sk, skb)) { tcp_write_err(sk); goto out; } diff -u linux-6.2.0/net/ipv4/udp.c linux-6.2.0/net/ipv4/udp.c --- linux-6.2.0/net/ipv4/udp.c +++ linux-6.2.0/net/ipv4/udp.c @@ -451,14 +451,24 @@ score = compute_score(sk, net, saddr, sport, daddr, hnum, dif, sdif); if (score > badness) { - result = lookup_reuseport(net, sk, skb, - saddr, sport, daddr, hnum); + badness = score; + result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); + if (!result) { + result = sk; + continue; + } + /* Fall back to scoring if group has connections */ - if (result && !reuseport_has_conns(sk)) + if (!reuseport_has_conns(sk)) return result; - result = result ? : sk; - badness = score; + /* Reuseport logic returned an error, keep original score. */ + if (IS_ERR(result)) + continue; + + badness = compute_score(result, net, saddr, sport, + daddr, hnum, dif, sdif); + } } return result; @@ -1475,9 +1485,9 @@ spin_lock(&sk_queue->lock); - sk->sk_forward_alloc += size; + sk_forward_alloc_add(sk, size); amt = (sk->sk_forward_alloc - partial) & ~(PAGE_SIZE - 1); - sk->sk_forward_alloc -= amt; + sk_forward_alloc_add(sk, -amt); if (amt) __sk_mem_reduce_allocated(sk, amt >> PAGE_SHIFT); @@ -1583,7 +1593,7 @@ sk->sk_forward_alloc += delta; } - sk->sk_forward_alloc -= size; + sk_forward_alloc_add(sk, -size); /* no need to setup a destructor, we will explicitly release the * forward allocated memory on dequeue diff -u linux-6.2.0/net/ipv6/addrconf.c linux-6.2.0/net/ipv6/addrconf.c --- linux-6.2.0/net/ipv6/addrconf.c +++ linux-6.2.0/net/ipv6/addrconf.c @@ -202,6 +202,7 @@ .ra_defrtr_metric = IP6_RT_PRIO_USER, .accept_ra_from_local = 0, .accept_ra_min_hop_limit= 1, + .accept_ra_min_lft = 0, .accept_ra_pinfo = 1, #ifdef CONFIG_IPV6_ROUTER_PREF .accept_ra_rtr_pref = 1, @@ -262,6 +263,7 @@ .ra_defrtr_metric = IP6_RT_PRIO_USER, .accept_ra_from_local = 0, .accept_ra_min_hop_limit= 1, + .accept_ra_min_lft = 0, .accept_ra_pinfo = 1, #ifdef CONFIG_IPV6_ROUTER_PREF .accept_ra_rtr_pref = 1, @@ -1033,7 +1035,7 @@ unsigned int hash = inet6_addr_hash(net, &ifa->addr); int err = 0; - spin_lock(&net->ipv6.addrconf_hash_lock); + spin_lock_bh(&net->ipv6.addrconf_hash_lock); /* Ignore adding duplicate addresses on an interface */ if (ipv6_chk_same_addr(net, &ifa->addr, dev, hash)) { @@ -1043,7 +1045,7 @@ hlist_add_head_rcu(&ifa->addr_lst, &net->ipv6.inet6_addr_lst[hash]); } - spin_unlock(&net->ipv6.addrconf_hash_lock); + spin_unlock_bh(&net->ipv6.addrconf_hash_lock); return err; } @@ -1138,15 +1140,15 @@ /* For caller */ refcount_set(&ifa->refcnt, 1); - rcu_read_lock_bh(); + rcu_read_lock(); err = ipv6_add_addr_hash(idev->dev, ifa); if (err < 0) { - rcu_read_unlock_bh(); + rcu_read_unlock(); goto out; } - write_lock(&idev->lock); + write_lock_bh(&idev->lock); /* Add to inet6_dev unicast addr list. */ ipv6_link_dev_addr(idev, ifa); @@ -1157,9 +1159,9 @@ } in6_ifa_hold(ifa); - write_unlock(&idev->lock); + write_unlock_bh(&idev->lock); - rcu_read_unlock_bh(); + rcu_read_unlock(); inet6addr_notifier_call_chain(NETDEV_UP, ifa); out: @@ -1368,7 +1370,7 @@ * idev->desync_factor if it's larger */ cnf_temp_preferred_lft = READ_ONCE(idev->cnf.temp_prefered_lft); - max_desync_factor = min_t(__u32, + max_desync_factor = min_t(long, idev->cnf.max_desync_factor, cnf_temp_preferred_lft - regen_advance); @@ -2731,6 +2733,9 @@ return; } + if (valid_lft != 0 && valid_lft < in6_dev->cnf.accept_ra_min_lft) + goto put; + /* * Two things going on here: * 1) Add routes for on-link prefixes @@ -5601,6 +5606,7 @@ array[DEVCONF_IOAM6_ID_WIDE] = cnf->ioam6_id_wide; array[DEVCONF_NDISC_EVICT_NOCARRIER] = cnf->ndisc_evict_nocarrier; array[DEVCONF_ACCEPT_UNTRACKED_NA] = cnf->accept_untracked_na; + array[DEVCONF_ACCEPT_RA_MIN_LFT] = cnf->accept_ra_min_lft; } static inline size_t inet6_ifla6_size(void) @@ -6793,6 +6799,13 @@ .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec, + }, + { + .procname = "accept_ra_min_lft", + .data = &ipv6_devconf.accept_ra_min_lft, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, }, { .procname = "accept_ra_pinfo", diff -u linux-6.2.0/net/ipv6/ip6_input.c linux-6.2.0/net/ipv6/ip6_input.c --- linux-6.2.0/net/ipv6/ip6_input.c +++ linux-6.2.0/net/ipv6/ip6_input.c @@ -99,7 +99,8 @@ static struct sk_buff *ip6_extract_route_hint(const struct net *net, struct sk_buff *skb) { - if (fib6_routes_require_src(net) || fib6_has_custom_rules(net)) + if (fib6_routes_require_src(net) || fib6_has_custom_rules(net) || + IP6CB(skb)->flags & IP6SKB_MULTIPATH) return NULL; return skb; diff -u linux-6.2.0/net/ipv6/ip6_output.c linux-6.2.0/net/ipv6/ip6_output.c --- linux-6.2.0/net/ipv6/ip6_output.c +++ linux-6.2.0/net/ipv6/ip6_output.c @@ -112,11 +112,11 @@ if (lwtunnel_xmit_redirect(dst->lwtstate)) { int res = lwtunnel_xmit(skb); - if (res < 0 || res == LWTUNNEL_XMIT_DONE) + if (res != LWTUNNEL_XMIT_CONTINUE) return res; } - rcu_read_lock_bh(); + rcu_read_lock(); nexthop = rt6_nexthop((struct rt6_info *)dst, daddr); neigh = __ipv6_neigh_lookup_noref(dev, nexthop); @@ -124,7 +124,7 @@ if (unlikely(!neigh)) neigh = __neigh_create(&nd_tbl, nexthop, dev, false); if (IS_ERR(neigh)) { - rcu_read_unlock_bh(); + rcu_read_unlock(); IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTNOROUTES); kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL); return -EINVAL; @@ -132,7 +132,7 @@ } sock_confirm_neigh(skb, neigh); ret = neigh_output(neigh, skb, false); - rcu_read_unlock_bh(); + rcu_read_unlock(); return ret; } @@ -1153,11 +1153,11 @@ * dst entry of the nexthop router */ rt = (struct rt6_info *) *dst; - rcu_read_lock_bh(); + rcu_read_lock(); n = __ipv6_neigh_lookup_noref(rt->dst.dev, rt6_nexthop(rt, &fl6->daddr)); - err = n && !(n->nud_state & NUD_VALID) ? -EINVAL : 0; - rcu_read_unlock_bh(); + err = n && !(READ_ONCE(n->nud_state) & NUD_VALID) ? -EINVAL : 0; + rcu_read_unlock(); if (err) { struct inet6_ifaddr *ifp; @@ -1504,7 +1504,7 @@ orig_mtu = mtu; if (cork->tx_flags & SKBTX_ANY_SW_TSTAMP && - sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) + READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID) tskey = atomic_inc_return(&sk->sk_tskey) - 1; hh_len = LL_RESERVED_SPACE(rt->dst.dev); diff -u linux-6.2.0/net/ipv6/ndisc.c linux-6.2.0/net/ipv6/ndisc.c --- linux-6.2.0/net/ipv6/ndisc.c +++ linux-6.2.0/net/ipv6/ndisc.c @@ -746,7 +746,7 @@ saddr = &ipv6_hdr(skb)->saddr; probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES); if (probes < 0) { - if (!(neigh->nud_state & NUD_VALID)) { + if (!(READ_ONCE(neigh->nud_state) & NUD_VALID)) { ND_PRINTK(1, dbg, "%s: trying to ucast probe in NUD_INVALID: %pI6\n", __func__, target); @@ -1092,7 +1092,7 @@ u8 old_flags = neigh->flags; struct net *net = dev_net(dev); - if (neigh->nud_state & NUD_FAILED) + if (READ_ONCE(neigh->nud_state) & NUD_FAILED) goto out; /* @@ -1331,6 +1331,14 @@ goto skip_defrtr; } + lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); + if (lifetime != 0 && lifetime < in6_dev->cnf.accept_ra_min_lft) { + ND_PRINTK(2, info, + "RA: router lifetime (%ds) is too short: %s\n", + lifetime, skb->dev->name); + goto skip_defrtr; + } + /* Do not accept RA with source-addr found on local machine unless * accept_ra_from_local is set to true. */ @@ -1343,8 +1351,6 @@ goto skip_defrtr; } - lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); - #ifdef CONFIG_IPV6_ROUTER_PREF pref = ra_msg->icmph.icmp6_router_pref; /* 10b is handled as if it were 00b (medium) */ @@ -1519,6 +1525,9 @@ if (ri->prefix_len == 0 && !in6_dev->cnf.accept_ra_defrtr) continue; + if (ri->lifetime != 0 && + ntohl(ri->lifetime) < in6_dev->cnf.accept_ra_min_lft) + continue; if (ri->prefix_len < in6_dev->cnf.accept_ra_rt_info_min_plen) continue; if (ri->prefix_len > in6_dev->cnf.accept_ra_rt_info_max_plen) diff -u linux-6.2.0/net/ipv6/ping.c linux-6.2.0/net/ipv6/ping.c --- linux-6.2.0/net/ipv6/ping.c +++ linux-6.2.0/net/ipv6/ping.c @@ -119,7 +119,7 @@ return -EINVAL; ipcm6_init_sk(&ipc6, np); - ipc6.sockc.tsflags = sk->sk_tsflags; + ipc6.sockc.tsflags = READ_ONCE(sk->sk_tsflags); ipc6.sockc.mark = READ_ONCE(sk->sk_mark); fl6.flowi6_oif = oif; diff -u linux-6.2.0/net/ipv6/raw.c linux-6.2.0/net/ipv6/raw.c --- linux-6.2.0/net/ipv6/raw.c +++ linux-6.2.0/net/ipv6/raw.c @@ -776,7 +776,7 @@ fl6.flowi6_uid = sk->sk_uid; ipcm6_init(&ipc6); - ipc6.sockc.tsflags = sk->sk_tsflags; + ipc6.sockc.tsflags = READ_ONCE(sk->sk_tsflags); ipc6.sockc.mark = fl6.flowi6_mark; if (sin6) { diff -u linux-6.2.0/net/ipv6/route.c linux-6.2.0/net/ipv6/route.c --- linux-6.2.0/net/ipv6/route.c +++ linux-6.2.0/net/ipv6/route.c @@ -425,6 +425,9 @@ if (match->nh && have_oif_match && res->nh) return; + if (skb) + IP6CB(skb)->flags |= IP6SKB_MULTIPATH; + /* We might have already computed the hash for ICMPv6 errors. In such * case it will always be non-zero. Otherwise now is the time to do it. */ @@ -633,15 +636,15 @@ nh_gw = &fib6_nh->fib_nh_gw6; dev = fib6_nh->fib_nh_dev; - rcu_read_lock_bh(); + rcu_read_lock(); last_probe = READ_ONCE(fib6_nh->last_probe); idev = __in6_dev_get(dev); neigh = __ipv6_neigh_lookup_noref(dev, nh_gw); if (neigh) { - if (neigh->nud_state & NUD_VALID) + if (READ_ONCE(neigh->nud_state) & NUD_VALID) goto out; - write_lock(&neigh->lock); + write_lock_bh(&neigh->lock); if (!(neigh->nud_state & NUD_VALID) && time_after(jiffies, neigh->updated + idev->cnf.rtr_probe_interval)) { @@ -649,7 +652,7 @@ if (work) __neigh_set_probe_once(neigh); } - write_unlock(&neigh->lock); + write_unlock_bh(&neigh->lock); } else if (time_after(jiffies, last_probe + idev->cnf.rtr_probe_interval)) { work = kmalloc(sizeof(*work), GFP_ATOMIC); @@ -667,7 +670,7 @@ } out: - rcu_read_unlock_bh(); + rcu_read_unlock(); } #else static inline void rt6_probe(struct fib6_nh *fib6_nh) @@ -683,25 +686,25 @@ enum rt6_nud_state ret = RT6_NUD_FAIL_HARD; struct neighbour *neigh; - rcu_read_lock_bh(); + rcu_read_lock(); neigh = __ipv6_neigh_lookup_noref(fib6_nh->fib_nh_dev, &fib6_nh->fib_nh_gw6); if (neigh) { - read_lock(&neigh->lock); - if (neigh->nud_state & NUD_VALID) + u8 nud_state = READ_ONCE(neigh->nud_state); + + if (nud_state & NUD_VALID) ret = RT6_NUD_SUCCEED; #ifdef CONFIG_IPV6_ROUTER_PREF - else if (!(neigh->nud_state & NUD_FAILED)) + else if (!(nud_state & NUD_FAILED)) ret = RT6_NUD_SUCCEED; else ret = RT6_NUD_FAIL_PROBE; #endif - read_unlock(&neigh->lock); } else { ret = IS_ENABLED(CONFIG_IPV6_ROUTER_PREF) ? RT6_NUD_SUCCEED : RT6_NUD_FAIL_DO_RR; } - rcu_read_unlock_bh(); + rcu_read_unlock(); return ret; } diff -u linux-6.2.0/net/ipv6/tcp_ipv6.c linux-6.2.0/net/ipv6/tcp_ipv6.c --- linux-6.2.0/net/ipv6/tcp_ipv6.c +++ linux-6.2.0/net/ipv6/tcp_ipv6.c @@ -1643,9 +1643,12 @@ struct sock *nsk; sk = req->rsk_listener; - drop_reason = tcp_inbound_md5_hash(sk, skb, - &hdr->saddr, &hdr->daddr, - AF_INET6, dif, sdif); + if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) + drop_reason = SKB_DROP_REASON_XFRM_POLICY; + else + drop_reason = tcp_inbound_md5_hash(sk, skb, + &hdr->saddr, &hdr->daddr, + AF_INET6, dif, sdif); if (drop_reason) { sk_drops_add(sk, skb); reqsk_put(req); @@ -1692,6 +1695,7 @@ } goto discard_and_relse; } + nf_reset_ct(skb); if (nsk == sk) { reqsk_put(req); tcp_v6_restore_cb(skb); diff -u linux-6.2.0/net/ipv6/udp.c linux-6.2.0/net/ipv6/udp.c --- linux-6.2.0/net/ipv6/udp.c +++ linux-6.2.0/net/ipv6/udp.c @@ -195,14 +195,23 @@ score = compute_score(sk, net, saddr, sport, daddr, hnum, dif, sdif); if (score > badness) { - result = lookup_reuseport(net, sk, skb, - saddr, sport, daddr, hnum); + badness = score; + result = lookup_reuseport(net, sk, skb, saddr, sport, daddr, hnum); + if (!result) { + result = sk; + continue; + } + /* Fall back to scoring if group has connections */ - if (result && !reuseport_has_conns(sk)) + if (!reuseport_has_conns(sk)) return result; - result = result ? : sk; - badness = score; + /* Reuseport logic returned an error, keep original score. */ + if (IS_ERR(result)) + continue; + + badness = compute_score(sk, net, saddr, sport, + daddr, hnum, dif, sdif); } } return result; @@ -1359,7 +1368,7 @@ ipcm6_init(&ipc6); ipc6.gso_size = READ_ONCE(up->gso_size); - ipc6.sockc.tsflags = sk->sk_tsflags; + ipc6.sockc.tsflags = READ_ONCE(sk->sk_tsflags); ipc6.sockc.mark = READ_ONCE(sk->sk_mark); /* destination address check */ diff -u linux-6.2.0/net/l2tp/l2tp_ip6.c linux-6.2.0/net/l2tp/l2tp_ip6.c --- linux-6.2.0/net/l2tp/l2tp_ip6.c +++ linux-6.2.0/net/l2tp/l2tp_ip6.c @@ -510,7 +510,6 @@ */ if (len > INT_MAX - transhdrlen) return -EMSGSIZE; - ulen = len + transhdrlen; /* Mirror BSD error message compatibility */ if (msg->msg_flags & MSG_OOB) @@ -631,6 +630,7 @@ back_from_confirm: lock_sock(sk); + ulen = len + skb_queue_empty(&sk->sk_write_queue) ? transhdrlen : 0; err = ip6_append_data(sk, ip_generic_getfrag, msg, ulen, transhdrlen, &ipc6, &fl6, (struct rt6_info *)dst, diff -u linux-6.2.0/net/mac80211/cfg.c linux-6.2.0/net/mac80211/cfg.c --- linux-6.2.0/net/mac80211/cfg.c +++ linux-6.2.0/net/mac80211/cfg.c @@ -566,6 +566,9 @@ } err = ieee80211_key_link(key, link, sta); + /* KRACK protection, shouldn't happen but just silently accept key */ + if (err == -EALREADY) + err = 0; out_unlock: mutex_unlock(&local->sta_mtx); @@ -3994,19 +3997,20 @@ mutex_lock(&local->mtx); rcu_read_lock(); + sta = sta_info_get_bss(sdata, peer); + if (!sta) { + ret = -ENOLINK; + goto unlock; + } + + qos = sta->sta.wme; + chanctx_conf = rcu_dereference(sdata->vif.bss_conf.chanctx_conf); if (WARN_ON(!chanctx_conf)) { ret = -EINVAL; goto unlock; } band = chanctx_conf->def.chan->band; - sta = sta_info_get_bss(sdata, peer); - if (sta) { - qos = sta->sta.wme; - } else { - ret = -ENOLINK; - goto unlock; - } if (qos) { fc = cpu_to_le16(IEEE80211_FTYPE_DATA | diff -u linux-6.2.0/net/mac80211/mlme.c linux-6.2.0/net/mac80211/mlme.c --- linux-6.2.0/net/mac80211/mlme.c +++ linux-6.2.0/net/mac80211/mlme.c @@ -5243,17 +5243,18 @@ for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) { struct ieee80211_link_data *link; - link = sdata_dereference(sdata->link[link_id], sdata); - if (!link) - continue; - if (!assoc_data->link[link_id].bss) continue; resp.links[link_id].bss = assoc_data->link[link_id].bss; - resp.links[link_id].addr = link->conf->addr; + ether_addr_copy(resp.links[link_id].addr, + assoc_data->link[link_id].addr); resp.links[link_id].status = assoc_data->link[link_id].status; + link = sdata_dereference(sdata->link[link_id], sdata); + if (!link) + continue; + /* get uapsd queues configuration - same for all links */ resp.uapsd_queues = 0; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) diff -u linux-6.2.0/net/mac80211/rx.c linux-6.2.0/net/mac80211/rx.c --- linux-6.2.0/net/mac80211/rx.c +++ linux-6.2.0/net/mac80211/rx.c @@ -3604,6 +3604,10 @@ break; goto queue; case WLAN_CATEGORY_S1G: + if (len < offsetofend(typeof(*mgmt), + u.action.u.s1g.action_code)) + break; + switch (mgmt->u.action.u.s1g.action_code) { case WLAN_S1G_TWT_SETUP: case WLAN_S1G_TWT_TEARDOWN: diff -u linux-6.2.0/net/mac80211/tx.c linux-6.2.0/net/mac80211/tx.c --- linux-6.2.0/net/mac80211/tx.c +++ linux-6.2.0/net/mac80211/tx.c @@ -4430,7 +4430,7 @@ struct sk_buff *skb) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - unsigned long links = sdata->vif.valid_links; + unsigned long links = sdata->vif.active_links; unsigned int link; u32 ctrl_flags = IEEE80211_TX_CTRL_MCAST_MLO_FIRST_TX; @@ -5893,7 +5893,7 @@ rcu_read_unlock(); if (WARN_ON_ONCE(link == ARRAY_SIZE(sdata->vif.link_conf))) - link = ffs(sdata->vif.valid_links) - 1; + link = ffs(sdata->vif.active_links) - 1; } IEEE80211_SKB_CB(skb)->control.flags |= @@ -5929,7 +5929,7 @@ band = chanctx_conf->def.chan->band; } else { WARN_ON(link_id >= 0 && - !(sdata->vif.valid_links & BIT(link_id))); + !(sdata->vif.active_links & BIT(link_id))); /* MLD transmissions must not rely on the band */ band = 0; } diff -u linux-6.2.0/net/mptcp/options.c linux-6.2.0/net/mptcp/options.c --- linux-6.2.0/net/mptcp/options.c +++ linux-6.2.0/net/mptcp/options.c @@ -1257,12 +1257,13 @@ if (rcv_wnd == rcv_wnd_old) break; - if (before64(rcv_wnd_new, rcv_wnd)) { + + rcv_wnd_old = rcv_wnd; + if (before64(rcv_wnd_new, rcv_wnd_old)) { MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDCONFLICTUPDATE); goto raise_win; } MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_RCVWNDCONFLICT); - rcv_wnd_old = rcv_wnd; } return; } diff -u linux-6.2.0/net/mptcp/pm_netlink.c linux-6.2.0/net/mptcp/pm_netlink.c --- linux-6.2.0/net/mptcp/pm_netlink.c +++ linux-6.2.0/net/mptcp/pm_netlink.c @@ -2051,7 +2051,7 @@ nla_put_s32(skb, MPTCP_ATTR_IF_IDX, ssk->sk_bound_dev_if)) return -EMSGSIZE; - sk_err = ssk->sk_err; + sk_err = READ_ONCE(ssk->sk_err); if (sk_err && sk->sk_state == TCP_ESTABLISHED && nla_put_u8(skb, MPTCP_ATTR_ERROR, sk_err)) return -EMSGSIZE; diff -u linux-6.2.0/net/mptcp/pm_userspace.c linux-6.2.0/net/mptcp/pm_userspace.c --- linux-6.2.0/net/mptcp/pm_userspace.c +++ linux-6.2.0/net/mptcp/pm_userspace.c @@ -309,12 +309,6 @@ goto create_err; } - if (addr_l.id == 0) { - NL_SET_ERR_MSG_ATTR(info->extack, laddr, "missing local addr id"); - err = -EINVAL; - goto create_err; - } - err = mptcp_pm_parse_addr(raddr, info, &addr_r); if (err < 0) { NL_SET_ERR_MSG_ATTR(info->extack, raddr, "error parsing remote addr"); diff -u linux-6.2.0/net/mptcp/protocol.c linux-6.2.0/net/mptcp/protocol.c --- linux-6.2.0/net/mptcp/protocol.c +++ linux-6.2.0/net/mptcp/protocol.c @@ -122,9 +122,15 @@ __kfree_skb(skb); } +static void mptcp_rmem_fwd_alloc_add(struct sock *sk, int size) +{ + WRITE_ONCE(mptcp_sk(sk)->rmem_fwd_alloc, + mptcp_sk(sk)->rmem_fwd_alloc + size); +} + static void mptcp_rmem_charge(struct sock *sk, int size) { - mptcp_sk(sk)->rmem_fwd_alloc -= size; + mptcp_rmem_fwd_alloc_add(sk, -size); } static bool mptcp_try_coalesce(struct sock *sk, struct sk_buff *to, @@ -165,7 +171,7 @@ static void __mptcp_rmem_reclaim(struct sock *sk, int amount) { amount >>= PAGE_SHIFT; - mptcp_sk(sk)->rmem_fwd_alloc -= amount << PAGE_SHIFT; + mptcp_rmem_charge(sk, amount << PAGE_SHIFT); __sk_mem_reduce_allocated(sk, amount); } @@ -174,7 +180,7 @@ struct mptcp_sock *msk = mptcp_sk(sk); int reclaimable; - msk->rmem_fwd_alloc += size; + mptcp_rmem_fwd_alloc_add(sk, size); reclaimable = msk->rmem_fwd_alloc - sk_unused_reserved_mem(sk); /* see sk_mem_uncharge() for the rationale behind the following schema */ @@ -329,7 +335,7 @@ if (!__sk_mem_raise_allocated(sk, size, amt, SK_MEM_RECV)) return false; - msk->rmem_fwd_alloc += amount; + mptcp_rmem_fwd_alloc_add(sk, amount); return true; } @@ -386,7 +392,7 @@ return false; } -static void mptcp_stop_timer(struct sock *sk) +static void mptcp_stop_rtx_timer(struct sock *sk) { struct inet_connection_sock *icsk = inet_csk(sk); @@ -750,6 +756,46 @@ return moved; } +static bool __mptcp_subflow_error_report(struct sock *sk, struct sock *ssk) +{ + int err = sock_error(ssk); + int ssk_state; + + if (!err) + return false; + + /* only propagate errors on fallen-back sockets or + * on MPC connect + */ + if (sk->sk_state != TCP_SYN_SENT && !__mptcp_check_fallback(mptcp_sk(sk))) + return false; + + /* We need to propagate only transition to CLOSE state. + * Orphaned socket will see such state change via + * subflow_sched_work_if_closed() and that path will properly + * destroy the msk as needed. + */ + ssk_state = inet_sk_state_load(ssk); + if (ssk_state == TCP_CLOSE && !sock_flag(sk, SOCK_DEAD)) + inet_sk_state_store(sk, ssk_state); + WRITE_ONCE(sk->sk_err, -err); + + /* This barrier is coupled with smp_rmb() in mptcp_poll() */ + smp_wmb(); + sk_error_report(sk); + return true; +} + +void __mptcp_error_report(struct sock *sk) +{ + struct mptcp_subflow_context *subflow; + struct mptcp_sock *msk = mptcp_sk(sk); + + mptcp_for_each_subflow(msk, subflow) + if (__mptcp_subflow_error_report(sk, mptcp_subflow_tcp_sock(subflow))) + break; +} + /* In most cases we will be able to lock the mptcp socket. If its already * owned, we need to defer to the work queue to avoid ABBA deadlock. */ @@ -831,6 +877,7 @@ mptcp_sockopt_sync_locked(msk, ssk); mptcp_subflow_joined(msk, ssk); + mptcp_stop_tout_timer(sk); return true; } @@ -850,12 +897,12 @@ } } -static bool mptcp_timer_pending(struct sock *sk) +static bool mptcp_rtx_timer_pending(struct sock *sk) { return timer_pending(&inet_csk(sk)->icsk_retransmit_timer); } -static void mptcp_reset_timer(struct sock *sk) +static void mptcp_reset_rtx_timer(struct sock *sk) { struct inet_connection_sock *icsk = inet_csk(sk); unsigned long tout; @@ -1039,10 +1086,10 @@ out: if (snd_una == READ_ONCE(msk->snd_nxt) && snd_una == READ_ONCE(msk->write_seq)) { - if (mptcp_timer_pending(sk) && !mptcp_data_fin_enabled(msk)) - mptcp_stop_timer(sk); + if (mptcp_rtx_timer_pending(sk) && !mptcp_data_fin_enabled(msk)) + mptcp_stop_rtx_timer(sk); } else { - mptcp_reset_timer(sk); + mptcp_reset_rtx_timer(sk); } } @@ -1591,8 +1638,8 @@ out: /* ensure the rtx timer is running */ - if (!mptcp_timer_pending(sk)) - mptcp_reset_timer(sk); + if (!mptcp_rtx_timer_pending(sk)) + mptcp_reset_rtx_timer(sk); if (do_check_data_fin) mptcp_check_send_data_fin(sk); } @@ -1648,8 +1695,8 @@ if (copied) { tcp_push(ssk, 0, info.mss_now, tcp_sk(ssk)->nonagle, info.size_goal); - if (!mptcp_timer_pending(sk)) - mptcp_reset_timer(sk); + if (!mptcp_rtx_timer_pending(sk)) + mptcp_reset_rtx_timer(sk); if (msk->snd_data_fin_enable && msk->snd_nxt + 1 == msk->write_seq) @@ -1788,7 +1835,7 @@ } /* data successfully copied into the write queue */ - sk->sk_forward_alloc -= total_ts; + sk_forward_alloc_add(sk, -total_ts); copied += psize; dfrag->data_len += psize; frag_truesize += psize; @@ -2207,7 +2254,7 @@ sock_put(sk); } -static void mptcp_timeout_timer(struct timer_list *t) +static void mptcp_tout_timer(struct timer_list *t) { struct sock *sk = from_timer(sk, t, sk_timer); @@ -2329,18 +2376,14 @@ bool dispose_it, need_push = false; /* If the first subflow moved to a close state before accept, e.g. due - * to an incoming reset, mptcp either: - * - if either the subflow or the msk are dead, destroy the context - * (the subflow socket is deleted by inet_child_forget) and the msk - * - otherwise do nothing at the moment and take action at accept and/or - * listener shutdown - user-space must be able to accept() the closed - * socket. + * to an incoming reset or listener shutdown, the subflow socket is + * already deleted by inet_child_forget() and the mptcp socket can't + * survive too. */ - if (msk->in_accept_queue && msk->first == ssk) { - if (!sock_flag(sk, SOCK_DEAD) && !sock_flag(ssk, SOCK_DEAD)) - return; - + if (msk->in_accept_queue && msk->first == ssk && + (sock_flag(sk, SOCK_DEAD) || sock_flag(ssk, SOCK_DEAD))) { /* ensure later check in mptcp_worker() will dispose the msk */ + mptcp_set_close_tout(sk, tcp_jiffies32 - (TCP_TIMEWAIT_LEN + 1)); sock_set_flag(sk, SOCK_DEAD); lock_sock_nested(ssk, SINGLE_DEPTH_NESTING); mptcp_subflow_drop_ctx(ssk); @@ -2393,6 +2436,7 @@ } out_release: + __mptcp_subflow_error_report(sk, ssk); release_sock(ssk); sock_put(ssk); @@ -2406,6 +2450,22 @@ if (need_push) __mptcp_push_pending(sk, 0); + + /* Catch every 'all subflows closed' scenario, including peers silently + * closing them, e.g. due to timeout. + * For established sockets, allow an additional timeout before closing, + * as the protocol can still create more subflows. + */ + if (list_is_singular(&msk->conn_list) && msk->first && + inet_sk_state_load(msk->first) == TCP_CLOSE) { + if (sk->sk_state != TCP_ESTABLISHED || + msk->in_accept_queue || sock_flag(sk, SOCK_DEAD)) { + inet_sk_state_store(sk, TCP_CLOSE); + mptcp_close_wake_up(sk); + } else { + mptcp_start_tout_timer(sk); + } + } } void mptcp_close_ssk(struct sock *sk, struct sock *ssk, @@ -2449,23 +2509,14 @@ } -static bool mptcp_should_close(const struct sock *sk) +static bool mptcp_close_tout_expired(const struct sock *sk) { - s32 delta = tcp_jiffies32 - inet_csk(sk)->icsk_mtup.probe_timestamp; - struct mptcp_subflow_context *subflow; - - if (delta >= TCP_TIMEWAIT_LEN || mptcp_sk(sk)->in_accept_queue) - return true; + if (!inet_csk(sk)->icsk_mtup.probe_timestamp || + sk->sk_state == TCP_CLOSE) + return false; - /* if all subflows are in closed status don't bother with additional - * timeout - */ - mptcp_for_each_subflow(mptcp_sk(sk), subflow) { - if (inet_sk_state_load(mptcp_subflow_tcp_sock(subflow)) != - TCP_CLOSE) - return false; - } - return true; + return time_after32(tcp_jiffies32, + inet_csk(sk)->icsk_mtup.probe_timestamp + TCP_TIMEWAIT_LEN); } static void mptcp_check_fastclose(struct mptcp_sock *msk) @@ -2493,15 +2544,15 @@ /* Mirror the tcp_reset() error propagation */ switch (sk->sk_state) { case TCP_SYN_SENT: - sk->sk_err = ECONNREFUSED; + WRITE_ONCE(sk->sk_err, ECONNREFUSED); break; case TCP_CLOSE_WAIT: - sk->sk_err = EPIPE; + WRITE_ONCE(sk->sk_err, EPIPE); break; case TCP_CLOSE: return; default: - sk->sk_err = ECONNRESET; + WRITE_ONCE(sk->sk_err, ECONNRESET); } inet_sk_state_store(sk, TCP_CLOSE); @@ -2577,27 +2628,28 @@ reset_timer: mptcp_check_and_set_pending(sk); - if (!mptcp_timer_pending(sk)) - mptcp_reset_timer(sk); + if (!mptcp_rtx_timer_pending(sk)) + mptcp_reset_rtx_timer(sk); } /* schedule the timeout timer for the relevant event: either close timeout * or mp_fail timeout. The close timeout takes precedence on the mp_fail one */ -void mptcp_reset_timeout(struct mptcp_sock *msk, unsigned long fail_tout) +void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout) { struct sock *sk = (struct sock *)msk; unsigned long timeout, close_timeout; - if (!fail_tout && !sock_flag(sk, SOCK_DEAD)) + if (!fail_tout && !inet_csk(sk)->icsk_mtup.probe_timestamp) return; - close_timeout = inet_csk(sk)->icsk_mtup.probe_timestamp - tcp_jiffies32 + jiffies + TCP_TIMEWAIT_LEN; + close_timeout = inet_csk(sk)->icsk_mtup.probe_timestamp - tcp_jiffies32 + jiffies + + TCP_TIMEWAIT_LEN; /* the close timeout takes precedence on the fail one, and here at least one of * them is active */ - timeout = sock_flag(sk, SOCK_DEAD) ? close_timeout : fail_tout; + timeout = inet_csk(sk)->icsk_mtup.probe_timestamp ? close_timeout : fail_tout; sk_reset_timer(sk, &sk->sk_timer, timeout); } @@ -2616,8 +2668,6 @@ mptcp_subflow_reset(ssk); WRITE_ONCE(mptcp_subflow_ctx(ssk)->fail_tout, 0); unlock_sock_fast(ssk, slow); - - mptcp_reset_timeout(msk, 0); } static void mptcp_do_fastclose(struct sock *sk) @@ -2656,19 +2706,15 @@ if (test_and_clear_bit(MPTCP_WORK_CLOSE_SUBFLOW, &msk->flags)) __mptcp_close_subflow(sk); - /* There is no point in keeping around an orphaned sk timedout or - * closed, but we need the msk around to reply to incoming DATA_FIN, - * even if it is orphaned and in FIN_WAIT2 state - */ - if (sock_flag(sk, SOCK_DEAD)) { - if (mptcp_should_close(sk)) { - inet_sk_state_store(sk, TCP_CLOSE); - mptcp_do_fastclose(sk); - } - if (sk->sk_state == TCP_CLOSE) { - __mptcp_destroy_sock(sk); - goto unlock; - } + if (mptcp_close_tout_expired(sk)) { + inet_sk_state_store(sk, TCP_CLOSE); + mptcp_do_fastclose(sk); + mptcp_close_wake_up(sk); + } + + if (sock_flag(sk, SOCK_DEAD) && sk->sk_state == TCP_CLOSE) { + __mptcp_destroy_sock(sk); + goto unlock; } if (test_and_clear_bit(MPTCP_WORK_RTX, &msk->flags)) @@ -2708,7 +2754,7 @@ /* re-use the csk retrans timer for MPTCP-level retrans */ timer_setup(&msk->sk.icsk_retransmit_timer, mptcp_retransmit_timer, 0); - timer_setup(&sk->sk_timer, mptcp_timeout_timer, 0); + timer_setup(&sk->sk_timer, mptcp_tout_timer, 0); return 0; } @@ -2802,8 +2848,8 @@ } else { pr_debug("Sending DATA_FIN on subflow %p", ssk); tcp_send_ack(ssk); - if (!mptcp_timer_pending(sk)) - mptcp_reset_timer(sk); + if (!mptcp_rtx_timer_pending(sk)) + mptcp_reset_rtx_timer(sk); } break; } @@ -2886,7 +2932,7 @@ might_sleep(); - mptcp_stop_timer(sk); + mptcp_stop_rtx_timer(sk); sk_stop_timer(sk, &sk->sk_timer); msk->pm.status = 0; @@ -2966,7 +3012,6 @@ cleanup: /* orphan all the subflows */ - inet_csk(sk)->icsk_mtup.probe_timestamp = tcp_jiffies32; mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); bool slow = lock_sock_fast_nested(ssk); @@ -3003,7 +3048,7 @@ __mptcp_destroy_sock(sk); do_cancel_work = true; } else { - mptcp_reset_timeout(msk, 0); + mptcp_start_tout_timer(sk); } return do_cancel_work; @@ -3066,8 +3111,8 @@ mptcp_check_listen_stop(sk); inet_sk_state_store(sk, TCP_CLOSE); - mptcp_stop_timer(sk); - sk_stop_timer(sk, &sk->sk_timer); + mptcp_stop_rtx_timer(sk); + mptcp_stop_tout_timer(sk); if (msk->token) mptcp_event(MPTCP_EVENT_CLOSED, msk, NULL, GFP_KERNEL); @@ -3256,8 +3301,8 @@ /* move all the rx fwd alloc into the sk_mem_reclaim_final in * inet_sock_destruct() will dispose it */ - sk->sk_forward_alloc += msk->rmem_fwd_alloc; - msk->rmem_fwd_alloc = 0; + sk_forward_alloc_add(sk, msk->rmem_fwd_alloc); + WRITE_ONCE(msk->rmem_fwd_alloc, 0); mptcp_token_destroy(msk); mptcp_pm_free_anno_list(msk); mptcp_free_local_addr_list(msk); @@ -3383,24 +3428,21 @@ sk_reset_timer(ssk, &icsk->icsk_delack_timer, timeout); } -void mptcp_subflow_process_delegated(struct sock *ssk) +void mptcp_subflow_process_delegated(struct sock *ssk, long status) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); struct sock *sk = subflow->conn; - if (test_bit(MPTCP_DELEGATE_SEND, &subflow->delegated_status)) { + if (status & BIT(MPTCP_DELEGATE_SEND)) { mptcp_data_lock(sk); if (!sock_owned_by_user(sk)) __mptcp_subflow_push_pending(sk, ssk, true); else __set_bit(MPTCP_PUSH_PENDING, &mptcp_sk(sk)->cb_flags); mptcp_data_unlock(sk); - mptcp_subflow_delegated_done(subflow, MPTCP_DELEGATE_SEND); } - if (test_bit(MPTCP_DELEGATE_ACK, &subflow->delegated_status)) { + if (status & BIT(MPTCP_DELEGATE_ACK)) schedule_3rdack_retransmission(ssk); - mptcp_subflow_delegated_done(subflow, MPTCP_DELEGATE_ACK); - } } static int mptcp_hash(struct sock *sk) @@ -3527,7 +3569,8 @@ static int mptcp_forward_alloc_get(const struct sock *sk) { - return sk->sk_forward_alloc + mptcp_sk(sk)->rmem_fwd_alloc; + return READ_ONCE(sk->sk_forward_alloc) + + READ_ONCE(mptcp_sk(sk)->rmem_fwd_alloc); } static int mptcp_ioctl_outq(const struct mptcp_sock *msk, u64 v) @@ -3856,7 +3899,7 @@ /* This barrier is coupled with smp_wmb() in __mptcp_error_report() */ smp_rmb(); - if (sk->sk_err) + if (READ_ONCE(sk->sk_err)) mask |= EPOLLERR; return mask; @@ -3903,14 +3946,17 @@ struct sock *ssk = mptcp_subflow_tcp_sock(subflow); bh_lock_sock_nested(ssk); - if (!sock_owned_by_user(ssk) && - mptcp_subflow_has_delegated_action(subflow)) - mptcp_subflow_process_delegated(ssk); - /* ... elsewhere tcp_release_cb_override already processed - * the action or will do at next release_sock(). - * In both case must dequeue the subflow here - on the same - * CPU that scheduled it. - */ + if (!sock_owned_by_user(ssk)) { + mptcp_subflow_process_delegated(ssk, xchg(&subflow->delegated_status, 0)); + } else { + /* tcp_release_cb_override already processed + * the action or will do at next release_sock(). + * In both case must dequeue the subflow here - on the same + * CPU that scheduled it. + */ + smp_wmb(); + clear_bit(MPTCP_DELEGATE_SCHEDULED, &subflow->delegated_status); + } bh_unlock_sock(ssk); sock_put(ssk); diff -u linux-6.2.0/net/mptcp/protocol.h linux-6.2.0/net/mptcp/protocol.h --- linux-6.2.0/net/mptcp/protocol.h +++ linux-6.2.0/net/mptcp/protocol.h @@ -439,9 +439,11 @@ DECLARE_PER_CPU(struct mptcp_delegated_action, mptcp_delegated_actions); -#define MPTCP_DELEGATE_SEND 0 -#define MPTCP_DELEGATE_ACK 1 +#define MPTCP_DELEGATE_SCHEDULED 0 +#define MPTCP_DELEGATE_SEND 1 +#define MPTCP_DELEGATE_ACK 2 +#define MPTCP_DELEGATE_ACTIONS_MASK (~BIT(MPTCP_DELEGATE_SCHEDULED)) /* MPTCP subflow context */ struct mptcp_subflow_context { struct list_head node;/* conn_list of subflows */ @@ -557,23 +559,24 @@ return subflow->map_seq + mptcp_subflow_get_map_offset(subflow); } -void mptcp_subflow_process_delegated(struct sock *ssk); +void mptcp_subflow_process_delegated(struct sock *ssk, long actions); static inline void mptcp_subflow_delegate(struct mptcp_subflow_context *subflow, int action) { + long old, set_bits = BIT(MPTCP_DELEGATE_SCHEDULED) | BIT(action); struct mptcp_delegated_action *delegated; bool schedule; /* the caller held the subflow bh socket lock */ lockdep_assert_in_softirq(); - /* The implied barrier pairs with mptcp_subflow_delegated_done(), and - * ensures the below list check sees list updates done prior to status - * bit changes + /* The implied barrier pairs with tcp_release_cb_override() + * mptcp_napi_poll(), and ensures the below list check sees list + * updates done prior to delegated status bits changes */ - if (!test_and_set_bit(action, &subflow->delegated_status)) { - /* still on delegated list from previous scheduling */ - if (!list_empty(&subflow->delegated_node)) + old = set_mask_bits(&subflow->delegated_status, 0, set_bits); + if (!(old & BIT(MPTCP_DELEGATE_SCHEDULED))) { + if (WARN_ON_ONCE(!list_empty(&subflow->delegated_node))) return; delegated = this_cpu_ptr(&mptcp_delegated_actions); @@ -598,20 +601,6 @@ return ret; } -static inline bool mptcp_subflow_has_delegated_action(const struct mptcp_subflow_context *subflow) -{ - return !!READ_ONCE(subflow->delegated_status); -} - -static inline void mptcp_subflow_delegated_done(struct mptcp_subflow_context *subflow, int action) -{ - /* pairs with mptcp_subflow_delegate, ensures delegate_node is updated before - * touching the status bit - */ - smp_wmb(); - clear_bit(action, &subflow->delegated_status); -} - int mptcp_is_enabled(const struct net *net); unsigned int mptcp_get_add_addr_timeout(const struct net *net); int mptcp_is_checksum_enabled(const struct net *net); @@ -696,7 +685,29 @@ void mptcp_finish_connect(struct sock *sk); void __mptcp_set_connected(struct sock *sk); -void mptcp_reset_timeout(struct mptcp_sock *msk, unsigned long fail_tout); +void mptcp_reset_tout_timer(struct mptcp_sock *msk, unsigned long fail_tout); + +static inline void mptcp_stop_tout_timer(struct sock *sk) +{ + if (!inet_csk(sk)->icsk_mtup.probe_timestamp) + return; + + sk_stop_timer(sk, &sk->sk_timer); + inet_csk(sk)->icsk_mtup.probe_timestamp = 0; +} + +static inline void mptcp_set_close_tout(struct sock *sk, unsigned long tout) +{ + /* avoid 0 timestamp, as that means no close timeout */ + inet_csk(sk)->icsk_mtup.probe_timestamp = tout ? : 1; +} + +static inline void mptcp_start_tout_timer(struct sock *sk) +{ + mptcp_set_close_tout(sk, tcp_jiffies32); + mptcp_reset_tout_timer(mptcp_sk(sk), 0); +} + static inline bool mptcp_is_fully_established(struct sock *sk) { return inet_sk_state_load(sk) == TCP_ESTABLISHED && diff -u linux-6.2.0/net/mptcp/subflow.c linux-6.2.0/net/mptcp/subflow.c --- linux-6.2.0/net/mptcp/subflow.c +++ linux-6.2.0/net/mptcp/subflow.c @@ -1224,7 +1224,7 @@ WRITE_ONCE(subflow->fail_tout, fail_tout); tcp_send_ack(ssk); - mptcp_reset_timeout(msk, subflow->fail_tout); + mptcp_reset_tout_timer(msk, subflow->fail_tout); } static bool subflow_check_data_avail(struct sock *ssk) @@ -1303,7 +1303,7 @@ subflow->reset_reason = MPTCP_RST_EMPTCP; reset: - ssk->sk_err = EBADMSG; + WRITE_ONCE(ssk->sk_err, EBADMSG); tcp_set_state(ssk, TCP_CLOSE); while ((skb = skb_peek(&ssk->sk_receive_queue))) sk_eat_skb(ssk, skb); @@ -1360,42 +1360,6 @@ *full_space = tcp_full_space(sk); } -void __mptcp_error_report(struct sock *sk) -{ - struct mptcp_subflow_context *subflow; - struct mptcp_sock *msk = mptcp_sk(sk); - - mptcp_for_each_subflow(msk, subflow) { - struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - int err = sock_error(ssk); - int ssk_state; - - if (!err) - continue; - - /* only propagate errors on fallen-back sockets or - * on MPC connect - */ - if (sk->sk_state != TCP_SYN_SENT && !__mptcp_check_fallback(msk)) - continue; - - /* We need to propagate only transition to CLOSE state. - * Orphaned socket will see such state change via - * subflow_sched_work_if_closed() and that path will properly - * destroy the msk as needed. - */ - ssk_state = inet_sk_state_load(ssk); - if (ssk_state == TCP_CLOSE && !sock_flag(sk, SOCK_DEAD)) - inet_sk_state_store(sk, ssk_state); - sk->sk_err = -err; - - /* This barrier is coupled with smp_rmb() in mptcp_poll() */ - smp_wmb(); - sk_error_report(sk); - break; - } -} - static void subflow_error_report(struct sock *ssk) { struct sock *sk = mptcp_subflow_ctx(ssk)->conn; @@ -1583,6 +1547,7 @@ mptcp_sock_graft(ssk, sk->sk_socket); iput(SOCK_INODE(sf)); WRITE_ONCE(msk->allow_infinite_fallback, false); + mptcp_stop_tout_timer(sk); return 0; failed_unlink: @@ -1980,9 +1945,15 @@ static void tcp_release_cb_override(struct sock *ssk) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); + long status; - if (mptcp_subflow_has_delegated_action(subflow)) - mptcp_subflow_process_delegated(ssk); + /* process and clear all the pending actions, but leave the subflow into + * the napi queue. To respect locking, only the same CPU that originated + * the action can touch the list. mptcp_napi_poll will take care of it. + */ + status = set_mask_bits(&subflow->delegated_status, MPTCP_DELEGATE_ACTIONS_MASK, 0); + if (status) + mptcp_subflow_process_delegated(ssk, status); tcp_release_cb(ssk); } diff -u linux-6.2.0/net/netfilter/ipvs/ip_vs_sync.c linux-6.2.0/net/netfilter/ipvs/ip_vs_sync.c --- linux-6.2.0/net/netfilter/ipvs/ip_vs_sync.c +++ linux-6.2.0/net/netfilter/ipvs/ip_vs_sync.c @@ -1507,8 +1507,8 @@ } get_mcast_sockaddr(&mcast_addr, &salen, &ipvs->mcfg, id); - result = sock->ops->connect(sock, (struct sockaddr *) &mcast_addr, - salen, 0); + result = kernel_connect(sock, (struct sockaddr *)&mcast_addr, + salen, 0); if (result < 0) { pr_err("Error connecting to the multicast addr\n"); goto error; diff -u linux-6.2.0/net/netfilter/nf_conntrack_proto_sctp.c linux-6.2.0/net/netfilter/nf_conntrack_proto_sctp.c --- linux-6.2.0/net/netfilter/nf_conntrack_proto_sctp.c +++ linux-6.2.0/net/netfilter/nf_conntrack_proto_sctp.c @@ -112,7 +112,7 @@ /* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA}, /* error */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't have Stale cookie*/ /* cookie_echo */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL},/* 5.2.4 - Big TODO */ -/* cookie_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */ +/* cookie_ack */ {sCL, sCL, sCW, sES, sES, sSS, sSR, sSA, sCL},/* Can't come in orig dir */ /* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL}, /* heartbeat */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, /* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, @@ -126,7 +126,7 @@ /* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV}, /* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV}, /* error */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV}, -/* cookie_echo */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */ +/* cookie_echo */ {sIV, sCL, sCE, sCE, sES, sSS, sSR, sSA, sIV},/* Can't come in reply dir */ /* cookie_ack */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV}, /* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV}, /* heartbeat */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS}, @@ -427,6 +427,9 @@ /* (D) vtag must be same as init_vtag as found in INIT_ACK */ if (sh->vtag != ct->proto.sctp.vtag[dir]) goto out_unlock; + } else if (sch->type == SCTP_CID_COOKIE_ACK) { + ct->proto.sctp.init[dir] = 0; + ct->proto.sctp.init[!dir] = 0; } else if (sch->type == SCTP_CID_HEARTBEAT) { if (ct->proto.sctp.vtag[dir] == 0) { pr_debug("Setting %d vtag %x for dir %d\n", sch->type, sh->vtag, dir); @@ -475,16 +478,18 @@ } /* If it is an INIT or an INIT ACK note down the vtag */ - if (sch->type == SCTP_CID_INIT || - sch->type == SCTP_CID_INIT_ACK) { - struct sctp_inithdr _inithdr, *ih; + if (sch->type == SCTP_CID_INIT) { + struct sctp_inithdr _ih, *ih; - ih = skb_header_pointer(skb, offset + sizeof(_sch), - sizeof(_inithdr), &_inithdr); - if (ih == NULL) + ih = skb_header_pointer(skb, offset + sizeof(_sch), sizeof(*ih), &_ih); + if (!ih) goto out_unlock; - pr_debug("Setting vtag %x for dir %d\n", - ih->init_tag, !dir); + + if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir]) + ct->proto.sctp.init[!dir] = 0; + ct->proto.sctp.init[dir] = 1; + + pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !dir); ct->proto.sctp.vtag[!dir] = ih->init_tag; /* don't renew timeout on init retransmit so @@ -495,6 +500,24 @@ old_state == SCTP_CONNTRACK_CLOSED && nf_ct_is_confirmed(ct)) ignore = true; + } else if (sch->type == SCTP_CID_INIT_ACK) { + struct sctp_inithdr _ih, *ih; + __be32 vtag; + + ih = skb_header_pointer(skb, offset + sizeof(_sch), sizeof(*ih), &_ih); + if (!ih) + goto out_unlock; + + vtag = ct->proto.sctp.vtag[!dir]; + if (!ct->proto.sctp.init[!dir] && vtag && vtag != ih->init_tag) + goto out_unlock; + /* collision */ + if (ct->proto.sctp.init[dir] && ct->proto.sctp.init[!dir] && + vtag != ih->init_tag) + goto out_unlock; + + pr_debug("Setting vtag %x for dir %d\n", ih->init_tag, !dir); + ct->proto.sctp.vtag[!dir] = ih->init_tag; } ct->proto.sctp.state = new_state; diff -u linux-6.2.0/net/netfilter/nf_tables_api.c linux-6.2.0/net/netfilter/nf_tables_api.c --- linux-6.2.0/net/netfilter/nf_tables_api.c +++ linux-6.2.0/net/netfilter/nf_tables_api.c @@ -1211,6 +1211,10 @@ flags & NFT_TABLE_F_OWNER)) return -EOPNOTSUPP; + /* No dormant off/on/off/on games in single transaction */ + if (ctx->table->flags & __NFT_TABLE_F_UPDATE) + return -EINVAL; + trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE, sizeof(struct nft_trans_table)); if (trans == NULL) @@ -1437,8 +1441,7 @@ if (!nft_is_active_next(ctx->net, set)) continue; - if (nft_set_is_anonymous(set) && - !list_empty(&set->bindings)) + if (nft_set_is_anonymous(set)) continue; err = nft_delset(ctx, set); @@ -3040,7 +3043,7 @@ if (err < 0) return err; - if (!tb[NFTA_EXPR_DATA]) + if (!tb[NFTA_EXPR_DATA] || !tb[NFTA_EXPR_NAME]) return -EINVAL; type = __nft_expr_type_get(ctx->family, tb[NFTA_EXPR_NAME]); @@ -6253,6 +6256,12 @@ return ret; } +static void nft_setelem_catchall_destroy(struct nft_set_elem_catchall *catchall) +{ + list_del_rcu(&catchall->list); + kfree_rcu(catchall, rcu); +} + static void nft_setelem_catchall_remove(const struct net *net, const struct nft_set *set, const struct nft_set_elem *elem) @@ -6261,8 +6270,7 @@ list_for_each_entry_safe(catchall, next, &set->catchall_list, list) { if (catchall->elem == elem->priv) { - list_del_rcu(&catchall->list); - kfree_rcu(catchall, rcu); + nft_setelem_catchall_destroy(catchall); break; } } @@ -6973,8 +6981,10 @@ if (IS_ERR(set)) return PTR_ERR(set); - if (!list_empty(&set->bindings) && - (set->flags & (NFT_SET_CONSTANT | NFT_SET_ANONYMOUS))) + if (nft_set_is_anonymous(set)) + return -EOPNOTSUPP; + + if (!list_empty(&set->bindings) && (set->flags & NFT_SET_CONSTANT)) return -EBUSY; nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla); @@ -7629,24 +7639,14 @@ return nft_delobj(&ctx, obj); } -void nft_obj_notify(struct net *net, const struct nft_table *table, - struct nft_object *obj, u32 portid, u32 seq, int event, - u16 flags, int family, int report, gfp_t gfp) +static void +__nft_obj_notify(struct net *net, const struct nft_table *table, + struct nft_object *obj, u32 portid, u32 seq, int event, + u16 flags, int family, int report, gfp_t gfp) { struct nftables_pernet *nft_net = nft_pernet(net); struct sk_buff *skb; int err; - char *buf = kasprintf(gfp, "%s:%u", - table->name, nft_net->base_seq); - - audit_log_nfcfg(buf, - family, - obj->handle, - event == NFT_MSG_NEWOBJ ? - AUDIT_NFT_OP_OBJ_REGISTER : - AUDIT_NFT_OP_OBJ_UNREGISTER, - gfp); - kfree(buf); if (!report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES)) @@ -7669,13 +7669,35 @@ err: nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS); } + +void nft_obj_notify(struct net *net, const struct nft_table *table, + struct nft_object *obj, u32 portid, u32 seq, int event, + u16 flags, int family, int report, gfp_t gfp) +{ + struct nftables_pernet *nft_net = nft_pernet(net); + char *buf = kasprintf(gfp, "%s:%u", + table->name, nft_net->base_seq); + + audit_log_nfcfg(buf, + family, + obj->handle, + event == NFT_MSG_NEWOBJ ? + AUDIT_NFT_OP_OBJ_REGISTER : + AUDIT_NFT_OP_OBJ_UNREGISTER, + gfp); + kfree(buf); + + __nft_obj_notify(net, table, obj, portid, seq, event, + flags, family, report, gfp); +} EXPORT_SYMBOL_GPL(nft_obj_notify); static void nf_tables_obj_notify(const struct nft_ctx *ctx, struct nft_object *obj, int event) { - nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event, - ctx->flags, ctx->family, ctx->report, GFP_KERNEL); + __nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, + ctx->seq, event, ctx->flags, ctx->family, + ctx->report, GFP_KERNEL); } /* @@ -9269,12 +9291,15 @@ struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc, unsigned int gc_seq, gfp_t gfp) { + struct nft_set *set; + if (nft_trans_gc_space(gc)) return gc; + set = gc->set; nft_trans_gc_queue_work(gc); - return nft_trans_gc_alloc(gc->set, gc_seq, gfp); + return nft_trans_gc_alloc(set, gc_seq, gfp); } void nft_trans_gc_queue_async_done(struct nft_trans_gc *trans) @@ -9289,15 +9314,18 @@ struct nft_trans_gc *nft_trans_gc_queue_sync(struct nft_trans_gc *gc, gfp_t gfp) { + struct nft_set *set; + if (WARN_ON_ONCE(!lockdep_commit_lock_is_held(gc->net))) return NULL; if (nft_trans_gc_space(gc)) return gc; + set = gc->set; call_rcu(&gc->rcu, nft_trans_gc_trans_free); - return nft_trans_gc_alloc(gc->set, 0, gfp); + return nft_trans_gc_alloc(set, 0, gfp); } void nft_trans_gc_queue_sync_done(struct nft_trans_gc *trans) @@ -9312,14 +9340,16 @@ call_rcu(&trans->rcu, nft_trans_gc_trans_free); } -struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc, - unsigned int gc_seq) +static struct nft_trans_gc *nft_trans_gc_catchall(struct nft_trans_gc *gc, + unsigned int gc_seq, + bool sync) { - struct nft_set_elem_catchall *catchall; + struct nft_set_elem_catchall *catchall, *next; const struct nft_set *set = gc->set; + struct nft_set_elem *elem; struct nft_set_ext *ext; - list_for_each_entry_rcu(catchall, &set->catchall_list, list) { + list_for_each_entry_safe(catchall, next, &set->catchall_list, list) { ext = nft_set_elem_ext(set, catchall->elem); if (!nft_set_elem_expired(ext)) @@ -9329,16 +9359,37 @@ nft_set_elem_dead(ext); dead_elem: - gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); + if (sync) + gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); + else + gc = nft_trans_gc_queue_async(gc, gc_seq, GFP_ATOMIC); + if (!gc) return NULL; - nft_trans_gc_elem_add(gc, catchall->elem); + elem = catchall->elem; + if (sync) { + nft_setelem_data_deactivate(gc->net, gc->set, elem); + nft_setelem_catchall_destroy(catchall); + } + + nft_trans_gc_elem_add(gc, elem->priv); } return gc; } +struct nft_trans_gc *nft_trans_gc_catchall_async(struct nft_trans_gc *gc, + unsigned int gc_seq) +{ + return nft_trans_gc_catchall(gc, gc_seq, false); +} + +struct nft_trans_gc *nft_trans_gc_catchall_sync(struct nft_trans_gc *gc) +{ + return nft_trans_gc_catchall(gc, 0, true); +} + static void nf_tables_module_autoload_cleanup(struct net *net) { struct nftables_pernet *nft_net = nft_pernet(net); @@ -9490,7 +9541,7 @@ list_for_each_entry_safe(set, next, set_update_list, pending_update) { list_del_init(&set->pending_update); - if (!set->ops->commit) + if (!set->ops->commit || set->dead) continue; set->ops->commit(set); diff -u linux-6.2.0/net/netfilter/nft_dynset.c linux-6.2.0/net/netfilter/nft_dynset.c --- linux-6.2.0/net/netfilter/nft_dynset.c +++ linux-6.2.0/net/netfilter/nft_dynset.c @@ -279,10 +279,15 @@ priv->expr_array[i] = dynset_expr; priv->num_exprs++; - if (set->num_exprs && - dynset_expr->ops != set->exprs[i]->ops) { - err = -EOPNOTSUPP; - goto err_expr_free; + if (set->num_exprs) { + if (i >= set->num_exprs) { + err = -EINVAL; + goto err_expr_free; + } + if (dynset_expr->ops != set->exprs[i]->ops) { + err = -EOPNOTSUPP; + goto err_expr_free; + } } i++; } diff -u linux-6.2.0/net/netfilter/nft_exthdr.c linux-6.2.0/net/netfilter/nft_exthdr.c --- linux-6.2.0/net/netfilter/nft_exthdr.c +++ linux-6.2.0/net/netfilter/nft_exthdr.c @@ -244,7 +244,12 @@ if (!tcph) goto err; + if (skb_ensure_writable(pkt->skb, nft_thoff(pkt) + tcphdr_len)) + goto err; + + tcph = (struct tcphdr *)(pkt->skb->data + nft_thoff(pkt)); opt = (u8 *)tcph; + for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) { union { __be16 v16; @@ -259,15 +264,6 @@ if (i + optl > tcphdr_len || priv->len + priv->offset > optl) goto err; - if (skb_ensure_writable(pkt->skb, - nft_thoff(pkt) + i + priv->len)) - goto err; - - tcph = nft_tcp_header_pointer(pkt, sizeof(buff), buff, - &tcphdr_len); - if (!tcph) - goto err; - offset = i + priv->offset; switch (priv->len) { @@ -331,9 +327,9 @@ if (skb_ensure_writable(pkt->skb, nft_thoff(pkt) + tcphdr_len)) goto drop; - opt = (u8 *)nft_tcp_header_pointer(pkt, sizeof(buff), buff, &tcphdr_len); - if (!opt) - goto err; + tcph = (struct tcphdr *)(pkt->skb->data + nft_thoff(pkt)); + opt = (u8 *)tcph; + for (i = sizeof(*tcph); i < tcphdr_len - 1; i += optl) { unsigned int j; diff -u linux-6.2.0/net/netfilter/nft_set_hash.c linux-6.2.0/net/netfilter/nft_set_hash.c --- linux-6.2.0/net/netfilter/nft_set_hash.c +++ linux-6.2.0/net/netfilter/nft_set_hash.c @@ -338,12 +338,9 @@ while ((he = rhashtable_walk_next(&hti))) { if (IS_ERR(he)) { - if (PTR_ERR(he) != -EAGAIN) { - nft_trans_gc_destroy(gc); - gc = NULL; - goto try_later; - } - continue; + nft_trans_gc_destroy(gc); + gc = NULL; + goto try_later; } /* Ruleset has been updated, try later. */ @@ -372,7 +369,7 @@ nft_trans_gc_elem_add(gc, he); } - gc = nft_trans_gc_catchall(gc, gc_seq); + gc = nft_trans_gc_catchall_async(gc, gc_seq); try_later: /* catchall list iteration requires rcu read side lock. */ diff -u linux-6.2.0/net/netfilter/nft_set_pipapo.c linux-6.2.0/net/netfilter/nft_set_pipapo.c --- linux-6.2.0/net/netfilter/nft_set_pipapo.c +++ linux-6.2.0/net/netfilter/nft_set_pipapo.c @@ -1597,7 +1597,7 @@ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); if (!gc) - break; + return; nft_pipapo_gc_deactivate(net, set, e); pipapo_drop(m, rulemap); @@ -1611,7 +1611,7 @@ } } - gc = nft_trans_gc_catchall(gc, 0); + gc = nft_trans_gc_catchall_sync(gc); if (gc) { nft_trans_gc_queue_sync_done(gc); priv->last_gc = jiffies; @@ -2043,4 +2043,7 @@ e = f->mt[r].e; + if (!nft_set_elem_active(&e->ext, iter->genmask)) + goto cont; + elem.priv = e; diff -u linux-6.2.0/net/netfilter/nft_set_rbtree.c linux-6.2.0/net/netfilter/nft_set_rbtree.c --- linux-6.2.0/net/netfilter/nft_set_rbtree.c +++ linux-6.2.0/net/netfilter/nft_set_rbtree.c @@ -233,10 +233,9 @@ rb_erase(&rbe->node, &priv->root); } -static int nft_rbtree_gc_elem(const struct nft_set *__set, - struct nft_rbtree *priv, - struct nft_rbtree_elem *rbe, - u8 genmask) +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_set *set = (struct nft_set *)__set; struct rb_node *prev = rb_prev(&rbe->node); @@ -246,7 +245,7 @@ gc = nft_trans_gc_alloc(set, 0, GFP_ATOMIC); if (!gc) - return -ENOMEM; + return ERR_PTR(-ENOMEM); /* search for end interval coming before this element. * end intervals don't carry a timeout extension, they @@ -261,6 +260,7 @@ prev = rb_prev(prev); } + rbe_prev = NULL; if (prev) { rbe_prev = rb_entry(prev, struct nft_rbtree_elem, node); nft_rbtree_gc_remove(net, set, priv, rbe_prev); @@ -272,7 +272,7 @@ */ gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); if (WARN_ON_ONCE(!gc)) - return -ENOMEM; + return ERR_PTR(-ENOMEM); nft_trans_gc_elem_add(gc, rbe_prev); } @@ -280,13 +280,13 @@ nft_rbtree_gc_remove(net, set, priv, rbe); gc = nft_trans_gc_queue_sync(gc, GFP_ATOMIC); if (WARN_ON_ONCE(!gc)) - return -ENOMEM; + return ERR_PTR(-ENOMEM); nft_trans_gc_elem_add(gc, rbe); nft_trans_gc_queue_sync_done(gc); - return 0; + return rbe_prev; } static bool nft_rbtree_update_first(const struct nft_set *set, @@ -314,7 +314,7 @@ struct nft_rbtree *priv = nft_set_priv(set); u8 cur_genmask = nft_genmask_cur(net); u8 genmask = nft_genmask_next(net); - int d, err; + int d; /* Descend the tree to search for an existing element greater than the * key value to insert that is greater than the new element. This is the @@ -363,9 +363,14 @@ */ if (nft_set_elem_expired(&rbe->ext) && nft_set_elem_active(&rbe->ext, cur_genmask)) { - err = nft_rbtree_gc_elem(set, priv, rbe, genmask); - if (err < 0) - return err; + const struct nft_rbtree_elem *removed_end; + + removed_end = nft_rbtree_gc_elem(set, priv, rbe, genmask); + if (IS_ERR(removed_end)) + return PTR_ERR(removed_end); + + if (removed_end == rbe_le || removed_end == rbe_ge) + return -EAGAIN; continue; } @@ -486,11 +491,18 @@ struct nft_rbtree_elem *rbe = elem->priv; int err; - write_lock_bh(&priv->lock); - write_seqcount_begin(&priv->count); - err = __nft_rbtree_insert(net, set, rbe, ext); - write_seqcount_end(&priv->count); - write_unlock_bh(&priv->lock); + do { + if (fatal_signal_pending(current)) + return -EINTR; + + cond_resched(); + + write_lock_bh(&priv->lock); + write_seqcount_begin(&priv->count); + err = __nft_rbtree_insert(net, set, rbe, ext); + write_seqcount_end(&priv->count); + write_unlock_bh(&priv->lock); + } while (err == -EAGAIN); return err; } @@ -622,8 +634,7 @@ if (!gc) goto done; - write_lock_bh(&priv->lock); - write_seqcount_begin(&priv->count); + read_lock_bh(&priv->lock); for (node = rb_first(&priv->root); node != NULL; node = rb_next(node)) { /* Ruleset has been updated, try later. */ @@ -670,11 +681,10 @@ nft_trans_gc_elem_add(gc, rbe); } - gc = nft_trans_gc_catchall(gc, gc_seq); + gc = nft_trans_gc_catchall_async(gc, gc_seq); try_later: - write_seqcount_end(&priv->count); - write_unlock_bh(&priv->lock); + read_unlock_bh(&priv->lock); if (gc) nft_trans_gc_queue_async_done(gc); diff -u linux-6.2.0/net/netlabel/netlabel_kapi.c linux-6.2.0/net/netlabel/netlabel_kapi.c --- linux-6.2.0/net/netlabel/netlabel_kapi.c +++ linux-6.2.0/net/netlabel/netlabel_kapi.c @@ -857,7 +857,8 @@ offset -= iter->startbit; idx = offset / NETLBL_CATMAP_MAPSIZE; - iter->bitmap[idx] |= bitmap << (offset % NETLBL_CATMAP_MAPSIZE); + iter->bitmap[idx] |= (NETLBL_CATMAP_MAPTYPE)bitmap + << (offset % NETLBL_CATMAP_MAPSIZE); return 0; } diff -u linux-6.2.0/net/netlink/af_netlink.c linux-6.2.0/net/netlink/af_netlink.c --- linux-6.2.0/net/netlink/af_netlink.c +++ linux-6.2.0/net/netlink/af_netlink.c @@ -84,7 +84,7 @@ static inline int netlink_is_kernel(struct sock *sk) { - return nlk_sk(sk)->flags & NETLINK_F_KERNEL_SOCKET; + return nlk_test_bit(KERNEL_SOCKET, sk); } struct netlink_table *nl_table __read_mostly; @@ -349,12 +349,10 @@ static void netlink_overrun(struct sock *sk) { - struct netlink_sock *nlk = nlk_sk(sk); - - if (!(nlk->flags & NETLINK_F_RECV_NO_ENOBUFS)) { + if (!nlk_test_bit(RECV_NO_ENOBUFS, sk)) { if (!test_and_set_bit(NETLINK_S_CONGESTED, &nlk_sk(sk)->state)) { - sk->sk_err = ENOBUFS; + WRITE_ONCE(sk->sk_err, ENOBUFS); sk_error_report(sk); } } @@ -1402,9 +1400,7 @@ bool netlink_strict_get_check(struct sk_buff *skb) { - const struct netlink_sock *nlk = nlk_sk(NETLINK_CB(skb).sk); - - return nlk->flags & NETLINK_F_STRICT_CHK; + return nlk_test_bit(STRICT_CHK, NETLINK_CB(skb).sk); } EXPORT_SYMBOL_GPL(netlink_strict_get_check); @@ -1448,7 +1444,7 @@ return; if (!net_eq(sock_net(sk), p->net)) { - if (!(nlk->flags & NETLINK_F_LISTEN_ALL_NSID)) + if (!nlk_test_bit(LISTEN_ALL_NSID, sk)) return; if (!peernet_has_id(sock_net(sk), p->net)) @@ -1481,7 +1477,7 @@ netlink_overrun(sk); /* Clone failed. Notify ALL listeners. */ p->failure = 1; - if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR) + if (nlk_test_bit(BROADCAST_SEND_ERROR, sk)) p->delivery_failure = 1; goto out; } @@ -1496,7 +1492,7 @@ val = netlink_broadcast_deliver(sk, p->skb2); if (val < 0) { netlink_overrun(sk); - if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR) + if (nlk_test_bit(BROADCAST_SEND_ERROR, sk)) p->delivery_failure = 1; } else { p->congested |= val; @@ -1576,12 +1572,12 @@ !test_bit(p->group - 1, nlk->groups)) goto out; - if (p->code == ENOBUFS && nlk->flags & NETLINK_F_RECV_NO_ENOBUFS) { + if (p->code == ENOBUFS && nlk_test_bit(RECV_NO_ENOBUFS, sk)) { ret = 1; goto out; } - sk->sk_err = p->code; + WRITE_ONCE(sk->sk_err, p->code); sk_error_report(sk); out: return ret; @@ -1643,7 +1639,7 @@ struct sock *sk = sock->sk; struct netlink_sock *nlk = nlk_sk(sk); unsigned int val = 0; - int err; + int nr = -1; if (level != SOL_NETLINK) return -ENOPROTOOPT; @@ -1654,14 +1650,12 @@ switch (optname) { case NETLINK_PKTINFO: - if (val) - nlk->flags |= NETLINK_F_RECV_PKTINFO; - else - nlk->flags &= ~NETLINK_F_RECV_PKTINFO; - err = 0; + nr = NETLINK_F_RECV_PKTINFO; break; case NETLINK_ADD_MEMBERSHIP: case NETLINK_DROP_MEMBERSHIP: { + int err; + if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV)) return -EPERM; err = netlink_realloc_groups(sk); @@ -1681,61 +1675,38 @@ if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind) nlk->netlink_unbind(sock_net(sk), val); - err = 0; break; } case NETLINK_BROADCAST_ERROR: - if (val) - nlk->flags |= NETLINK_F_BROADCAST_SEND_ERROR; - else - nlk->flags &= ~NETLINK_F_BROADCAST_SEND_ERROR; - err = 0; + nr = NETLINK_F_BROADCAST_SEND_ERROR; break; case NETLINK_NO_ENOBUFS: + assign_bit(NETLINK_F_RECV_NO_ENOBUFS, &nlk->flags, val); if (val) { - nlk->flags |= NETLINK_F_RECV_NO_ENOBUFS; clear_bit(NETLINK_S_CONGESTED, &nlk->state); wake_up_interruptible(&nlk->wait); - } else { - nlk->flags &= ~NETLINK_F_RECV_NO_ENOBUFS; } - err = 0; break; case NETLINK_LISTEN_ALL_NSID: if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_BROADCAST)) return -EPERM; - - if (val) - nlk->flags |= NETLINK_F_LISTEN_ALL_NSID; - else - nlk->flags &= ~NETLINK_F_LISTEN_ALL_NSID; - err = 0; + nr = NETLINK_F_LISTEN_ALL_NSID; break; case NETLINK_CAP_ACK: - if (val) - nlk->flags |= NETLINK_F_CAP_ACK; - else - nlk->flags &= ~NETLINK_F_CAP_ACK; - err = 0; + nr = NETLINK_F_CAP_ACK; break; case NETLINK_EXT_ACK: - if (val) - nlk->flags |= NETLINK_F_EXT_ACK; - else - nlk->flags &= ~NETLINK_F_EXT_ACK; - err = 0; + nr = NETLINK_F_EXT_ACK; break; case NETLINK_GET_STRICT_CHK: - if (val) - nlk->flags |= NETLINK_F_STRICT_CHK; - else - nlk->flags &= ~NETLINK_F_STRICT_CHK; - err = 0; + nr = NETLINK_F_STRICT_CHK; break; default: - err = -ENOPROTOOPT; + return -ENOPROTOOPT; } - return err; + if (nr >= 0) + assign_bit(nr, &nlk->flags, val); + return 0; } static int netlink_getsockopt(struct socket *sock, int level, int optname, @@ -1802,7 +1773,7 @@ return -EINVAL; len = sizeof(int); - val = nlk->flags & flag ? 1 : 0; + val = test_bit(flag, &nlk->flags); if (put_user(len, optlen) || copy_to_user(optval, &val, len)) @@ -1979,9 +1950,9 @@ msg->msg_namelen = sizeof(*addr); } - if (nlk->flags & NETLINK_F_RECV_PKTINFO) + if (nlk_test_bit(RECV_PKTINFO, sk)) netlink_cmsg_recv_pktinfo(msg, skb); - if (nlk->flags & NETLINK_F_LISTEN_ALL_NSID) + if (nlk_test_bit(LISTEN_ALL_NSID, sk)) netlink_cmsg_listen_all_nsid(sk, msg, skb); memset(&scm, 0, sizeof(scm)); @@ -1995,7 +1966,7 @@ atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) { ret = netlink_dump(sk); if (ret) { - sk->sk_err = -ret; + WRITE_ONCE(sk->sk_err, -ret); sk_error_report(sk); } } @@ -2058,7 +2029,7 @@ goto out_sock_release; nlk = nlk_sk(sk); - nlk->flags |= NETLINK_F_KERNEL_SOCKET; + set_bit(NETLINK_F_KERNEL_SOCKET, &nlk->flags); netlink_table_grab(); if (!nl_table[unit].registered) { @@ -2194,7 +2165,7 @@ nl_dump_check_consistent(cb, nlh); memcpy(nlmsg_data(nlh), &nlk->dump_done_errno, sizeof(nlk->dump_done_errno)); - if (extack->_msg && nlk->flags & NETLINK_F_EXT_ACK) { + if (extack->_msg && test_bit(NETLINK_F_EXT_ACK, &nlk->flags)) { nlh->nlmsg_flags |= NLM_F_ACK_TLVS; if (!nla_put_string(skb, NLMSGERR_ATTR_MSG, extack->_msg)) nlmsg_end(skb, nlh); @@ -2323,8 +2294,8 @@ const struct nlmsghdr *nlh, struct netlink_dump_control *control) { - struct netlink_sock *nlk, *nlk2; struct netlink_callback *cb; + struct netlink_sock *nlk; struct sock *sk; int ret; @@ -2359,8 +2330,7 @@ cb->min_dump_alloc = control->min_dump_alloc; cb->skb = skb; - nlk2 = nlk_sk(NETLINK_CB(skb).sk); - cb->strict_check = !!(nlk2->flags & NETLINK_F_STRICT_CHK); + cb->strict_check = nlk_test_bit(STRICT_CHK, NETLINK_CB(skb).sk); if (control->start) { ret = control->start(cb); @@ -2402,7 +2372,7 @@ { size_t tlvlen; - if (!extack || !(nlk->flags & NETLINK_F_EXT_ACK)) + if (!extack || !test_bit(NETLINK_F_EXT_ACK, &nlk->flags)) return 0; tlvlen = 0; @@ -2474,7 +2444,7 @@ * requests to cap the error message, and get extra error data if * requested. */ - if (err && !(nlk->flags & NETLINK_F_CAP_ACK)) + if (err && !test_bit(NETLINK_F_CAP_ACK, &nlk->flags)) payload += nlmsg_len(nlh); else flags |= NLM_F_CAPPED; @@ -2515,7 +2485,7 @@ err_bad_put: nlmsg_free(skb); err_skb: - NETLINK_CB(in_skb).sk->sk_err = ENOBUFS; + WRITE_ONCE(NETLINK_CB(in_skb).sk->sk_err, ENOBUFS); sk_error_report(NETLINK_CB(in_skb).sk); } EXPORT_SYMBOL(netlink_ack); diff -u linux-6.2.0/net/netlink/diag.c linux-6.2.0/net/netlink/diag.c --- linux-6.2.0/net/netlink/diag.c +++ linux-6.2.0/net/netlink/diag.c @@ -27,15 +27,15 @@ if (nlk->cb_running) flags |= NDIAG_FLAG_CB_RUNNING; - if (nlk->flags & NETLINK_F_RECV_PKTINFO) + if (nlk_test_bit(RECV_PKTINFO, sk)) flags |= NDIAG_FLAG_PKTINFO; - if (nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR) + if (nlk_test_bit(BROADCAST_SEND_ERROR, sk)) flags |= NDIAG_FLAG_BROADCAST_ERROR; - if (nlk->flags & NETLINK_F_RECV_NO_ENOBUFS) + if (nlk_test_bit(RECV_NO_ENOBUFS, sk)) flags |= NDIAG_FLAG_NO_ENOBUFS; - if (nlk->flags & NETLINK_F_LISTEN_ALL_NSID) + if (nlk_test_bit(LISTEN_ALL_NSID, sk)) flags |= NDIAG_FLAG_LISTEN_ALL_NSID; - if (nlk->flags & NETLINK_F_CAP_ACK) + if (nlk_test_bit(CAP_ACK, sk)) flags |= NDIAG_FLAG_CAP_ACK; return nla_put_u32(skb, NETLINK_DIAG_FLAGS, flags); diff -u linux-6.2.0/net/nfc/llcp_core.c linux-6.2.0/net/nfc/llcp_core.c --- linux-6.2.0/net/nfc/llcp_core.c +++ linux-6.2.0/net/nfc/llcp_core.c @@ -1636,7 +1636,9 @@ timer_setup(&local->sdreq_timer, nfc_llcp_sdreq_timer, 0); INIT_WORK(&local->sdreq_timeout_work, nfc_llcp_sdreq_timeout_work); + spin_lock(&llcp_devices_lock); list_add(&local->list, &llcp_devices); + spin_unlock(&llcp_devices_lock); return 0; } diff -u linux-6.2.0/net/sched/sch_fq_pie.c linux-6.2.0/net/sched/sch_fq_pie.c --- linux-6.2.0/net/sched/sch_fq_pie.c +++ linux-6.2.0/net/sched/sch_fq_pie.c @@ -61,6 +61,7 @@ struct pie_params p_params; u32 ecn_prob; u32 flows_cnt; + u32 flows_cursor; u32 quantum; u32 memory_limit; u32 new_flow_count; @@ -375,22 +376,32 @@ static void fq_pie_timer(struct timer_list *t) { struct fq_pie_sched_data *q = from_timer(q, t, adapt_timer); + unsigned long next, tupdate; struct Qdisc *sch = q->sch; spinlock_t *root_lock; /* to lock qdisc for probability calculations */ - u32 idx; + int max_cnt, i; rcu_read_lock(); root_lock = qdisc_lock(qdisc_root_sleeping(sch)); spin_lock(root_lock); - for (idx = 0; idx < q->flows_cnt; idx++) - pie_calculate_probability(&q->p_params, &q->flows[idx].vars, - q->flows[idx].backlog); - - /* reset the timer to fire after 'tupdate' jiffies. */ - if (q->p_params.tupdate) - mod_timer(&q->adapt_timer, jiffies + q->p_params.tupdate); + /* Limit this expensive loop to 2048 flows per round. */ + max_cnt = min_t(int, q->flows_cnt - q->flows_cursor, 2048); + for (i = 0; i < max_cnt; i++) { + pie_calculate_probability(&q->p_params, + &q->flows[q->flows_cursor].vars, + q->flows[q->flows_cursor].backlog); + q->flows_cursor++; + } + tupdate = q->p_params.tupdate; + next = 0; + if (q->flows_cursor >= q->flows_cnt) { + q->flows_cursor = 0; + next = tupdate; + } + if (tupdate) + mod_timer(&q->adapt_timer, jiffies + next); spin_unlock(root_lock); rcu_read_unlock(); } diff -u linux-6.2.0/net/sctp/socket.c linux-6.2.0/net/sctp/socket.c --- linux-6.2.0/net/sctp/socket.c +++ linux-6.2.0/net/sctp/socket.c @@ -68,7 +68,7 @@ #include /* Forward declarations for internal helper functions. */ -static bool sctp_writeable(struct sock *sk); +static bool sctp_writeable(const struct sock *sk); static void sctp_wfree(struct sk_buff *skb); static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, size_t msg_len); @@ -139,7 +139,7 @@ refcount_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc); asoc->sndbuf_used += chunk->skb->truesize + sizeof(struct sctp_chunk); - sk->sk_wmem_queued += chunk->skb->truesize + sizeof(struct sctp_chunk); + sk_wmem_queued_add(sk, chunk->skb->truesize + sizeof(struct sctp_chunk)); sk_mem_charge(sk, chunk->skb->truesize); } @@ -2449,6 +2449,7 @@ if (trans) { trans->hbinterval = msecs_to_jiffies(params->spp_hbinterval); + sctp_transport_reset_hb_timer(trans); } else if (asoc) { asoc->hbinterval = msecs_to_jiffies(params->spp_hbinterval); @@ -9142,7 +9143,7 @@ struct sock *sk = asoc->base.sk; sk_mem_uncharge(sk, skb->truesize); - sk->sk_wmem_queued -= skb->truesize + sizeof(struct sctp_chunk); + sk_wmem_queued_add(sk, -(skb->truesize + sizeof(struct sctp_chunk))); asoc->sndbuf_used -= skb->truesize + sizeof(struct sctp_chunk); WARN_ON(refcount_sub_and_test(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc)); @@ -9295,9 +9296,9 @@ * UDP-style sockets or TCP-style sockets, this code should work. * - Daisy */ -static bool sctp_writeable(struct sock *sk) +static bool sctp_writeable(const struct sock *sk) { - return sk->sk_sndbuf > sk->sk_wmem_queued; + return READ_ONCE(sk->sk_sndbuf) > READ_ONCE(sk->sk_wmem_queued); } /* Wait for an association to go into ESTABLISHED state. If timeout is 0, diff -u linux-6.2.0/net/smc/af_smc.c linux-6.2.0/net/smc/af_smc.c --- linux-6.2.0/net/smc/af_smc.c +++ linux-6.2.0/net/smc/af_smc.c @@ -1774,7 +1774,7 @@ lock_sock(sk); if (!sk->sk_lingertime) /* wait for peer closing */ - sk->sk_lingertime = SMC_MAX_STREAM_WAIT_TIMEOUT; + WRITE_ONCE(sk->sk_lingertime, SMC_MAX_STREAM_WAIT_TIMEOUT); __smc_release(smc); release_sock(sk); sock_put(sk); /* sock_hold above */ diff -u linux-6.2.0/net/smc/smc_core.c linux-6.2.0/net/smc/smc_core.c --- linux-6.2.0/net/smc/smc_core.c +++ linux-6.2.0/net/smc/smc_core.c @@ -1650,6 +1650,7 @@ { struct smc_link_group *lgr, *n; + spin_lock_bh(&smc_lgr_list.lock); list_for_each_entry_safe(lgr, n, &smc_lgr_list.list, list) { struct smc_link *link; @@ -1665,6 +1666,7 @@ if (link) smc_llc_add_link_local(link); } + spin_unlock_bh(&smc_lgr_list.lock); } /* link is down - switch connections to alternate link, diff -u linux-6.2.0/net/smc/smc_stats.h linux-6.2.0/net/smc/smc_stats.h --- linux-6.2.0/net/smc/smc_stats.h +++ linux-6.2.0/net/smc/smc_stats.h @@ -248,8 +248,9 @@ #define SMC_STAT_SERV_SUCC_INC(net, _ini) \ do { \ typeof(_ini) i = (_ini); \ - bool is_v2 = (i->smcd_version & SMC_V2); \ bool is_smcd = (i->is_smcd); \ + u8 version = is_smcd ? i->smcd_version : i->smcr_version; \ + bool is_v2 = (version & SMC_V2); \ typeof(net->smc.smc_stats) smc_stats = (net)->smc.smc_stats; \ if (is_v2 && is_smcd) \ this_cpu_inc(smc_stats->smc[SMC_TYPE_D].srv_v2_succ_cnt); \ diff -u linux-6.2.0/net/socket.c linux-6.2.0/net/socket.c --- linux-6.2.0/net/socket.c +++ linux-6.2.0/net/socket.c @@ -720,6 +720,14 @@ return ret; } +static int __sock_sendmsg(struct socket *sock, struct msghdr *msg) +{ + int err = security_socket_sendmsg(sock, msg, + msg_data_left(msg)); + + return err ?: sock_sendmsg_nosec(sock, msg); +} + /** * sock_sendmsg - send a message through @sock * @sock: socket @@ -730,10 +738,19 @@ */ int sock_sendmsg(struct socket *sock, struct msghdr *msg) { - int err = security_socket_sendmsg(sock, msg, - msg_data_left(msg)); + struct sockaddr_storage *save_addr = (struct sockaddr_storage *)msg->msg_name; + struct sockaddr_storage address; + int ret; - return err ?: sock_sendmsg_nosec(sock, msg); + if (msg->msg_name) { + memcpy(&address, msg->msg_name, msg->msg_namelen); + msg->msg_name = &address; + } + + ret = __sock_sendmsg(sock, msg); + msg->msg_name = save_addr; + + return ret; } EXPORT_SYMBOL(sock_sendmsg); @@ -809,7 +826,7 @@ static ktime_t get_timestamp(struct sock *sk, struct sk_buff *skb, int *if_index) { - bool cycles = sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC; + bool cycles = READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_BIND_PHC; struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); struct net_device *orig_dev; ktime_t hwtstamp; @@ -861,12 +878,12 @@ int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP); int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW); struct scm_timestamping_internal tss; - int empty = 1, false_tstamp = 0; struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); int if_index; ktime_t hwtstamp; + u32 tsflags; /* Race occurred between timestamp enabling and packet receiving. Fill in the current time for now. */ @@ -908,11 +925,12 @@ } memset(&tss, 0, sizeof(tss)); - if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) && + tsflags = READ_ONCE(sk->sk_tsflags); + if ((tsflags & SOF_TIMESTAMPING_SOFTWARE) && ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0)) empty = 0; if (shhwtstamps && - (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && + (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && !skb_is_swtx_tstamp(skb, false_tstamp)) { if_index = 0; if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP_NETDEV) @@ -920,14 +938,14 @@ else hwtstamp = shhwtstamps->hwtstamp; - if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC) + if (tsflags & SOF_TIMESTAMPING_BIND_PHC) hwtstamp = ptp_convert_timestamp(&hwtstamp, - sk->sk_bind_phc); + READ_ONCE(sk->sk_bind_phc)); if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) { empty = 0; - if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) && + if ((tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) && !skb_is_err_queue(skb)) put_ts_pktinfo(msg, skb, if_index); } @@ -1110,7 +1128,7 @@ if (sock->type == SOCK_SEQPACKET) msg.msg_flags |= MSG_EOR; - res = sock_sendmsg(sock, &msg); + res = __sock_sendmsg(sock, &msg); *from = msg.msg_iter; return res; } @@ -2114,7 +2132,7 @@ if (sock->file->f_flags & O_NONBLOCK) flags |= MSG_DONTWAIT; msg.msg_flags = flags; - err = sock_sendmsg(sock, &msg); + err = __sock_sendmsg(sock, &msg); out_put: fput_light(sock->file, fput_needed); @@ -2473,7 +2491,7 @@ err = sock_sendmsg_nosec(sock, msg_sys); goto out_freectl; } - err = sock_sendmsg(sock, msg_sys); + err = __sock_sendmsg(sock, msg_sys); /* * If this is sendmmsg() and sending to current destination address was * successful, remember it. diff -u linux-6.2.0/net/sunrpc/clnt.c linux-6.2.0/net/sunrpc/clnt.c --- linux-6.2.0/net/sunrpc/clnt.c +++ linux-6.2.0/net/sunrpc/clnt.c @@ -2462,8 +2462,7 @@ goto out_exit; } task->tk_action = call_encode; - if (status != -ECONNRESET && status != -ECONNABORTED) - rpc_check_timeout(task); + rpc_check_timeout(task); return; out_exit: rpc_call_rpcerror(task, status); @@ -2710,7 +2709,7 @@ out_verifier: trace_rpc_bad_verifier(task); - goto out_err; + goto out_garbage; out_msg_denied: error = -EACCES; @@ -2736,6 +2735,7 @@ case rpc_autherr_rejectedverf: case rpcsec_gsserr_credproblem: case rpcsec_gsserr_ctxproblem: + rpcauth_invalcred(task); if (!task->tk_cred_retry) break; task->tk_cred_retry--; @@ -2889,19 +2889,22 @@ * @clnt: pointer to struct rpc_clnt * @xps: pointer to struct rpc_xprt_switch, * @xprt: pointer struct rpc_xprt - * @dummy: unused + * @in_max_connect: pointer to the max_connect value for the passed in xprt transport */ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, struct rpc_xprt_switch *xps, struct rpc_xprt *xprt, - void *dummy) + void *in_max_connect) { struct rpc_cb_add_xprt_calldata *data; struct rpc_task *task; + int max_connect = clnt->cl_max_connect; - if (xps->xps_nunique_destaddr_xprts + 1 > clnt->cl_max_connect) { + if (in_max_connect) + max_connect = *(int *)in_max_connect; + if (xps->xps_nunique_destaddr_xprts + 1 > max_connect) { rcu_read_lock(); pr_warn("SUNRPC: reached max allowed number (%d) did not add " - "transport to server: %s\n", clnt->cl_max_connect, + "transport to server: %s\n", max_connect, rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR)); rcu_read_unlock(); return -EINVAL; diff -u linux-6.2.0/net/tipc/crypto.c linux-6.2.0/net/tipc/crypto.c --- linux-6.2.0/net/tipc/crypto.c +++ linux-6.2.0/net/tipc/crypto.c @@ -1441,14 +1441,14 @@ struct tipc_crypto *tx = tipc_net(net)->crypto_tx; struct tipc_key key; - spin_lock(&tx->lock); + spin_lock_bh(&tx->lock); key = tx->key; WARN_ON(!key.active || tx_key != key.active); /* Free the active key */ tipc_crypto_key_set_state(tx, key.passive, 0, key.pending); tipc_crypto_key_detach(tx->aead[key.active], &tx->lock); - spin_unlock(&tx->lock); + spin_unlock_bh(&tx->lock); pr_warn("%s: key is revoked\n", tx->name); return -EKEYREVOKED; diff -u linux-6.2.0/net/tls/tls_sw.c linux-6.2.0/net/tls/tls_sw.c --- linux-6.2.0/net/tls/tls_sw.c +++ linux-6.2.0/net/tls/tls_sw.c @@ -802,7 +802,7 @@ psock = sk_psock_get(sk); if (!psock || !policy) { err = tls_push_record(sk, flags, record_type); - if (err && sk->sk_err == EBADMSG) { + if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) { *copied -= sk_msg_free(sk, msg); tls_free_open_rec(sk); err = -sk->sk_err; @@ -831,7 +831,7 @@ switch (psock->eval) { case __SK_PASS: err = tls_push_record(sk, flags, record_type); - if (err && sk->sk_err == EBADMSG) { + if (err && err != -EINPROGRESS && sk->sk_err == EBADMSG) { *copied -= sk_msg_free(sk, msg); tls_free_open_rec(sk); err = -sk->sk_err; diff -u linux-6.2.0/net/unix/af_unix.c linux-6.2.0/net/unix/af_unix.c --- linux-6.2.0/net/unix/af_unix.c +++ linux-6.2.0/net/unix/af_unix.c @@ -667,7 +667,7 @@ * What the above comment does talk about? --ANK(980817) */ - if (unix_tot_inflight) + if (READ_ONCE(unix_tot_inflight)) unix_gc(); /* Garbage collect fds */ } diff -u linux-6.2.0/net/wireless/core.c linux-6.2.0/net/wireless/core.c --- linux-6.2.0/net/wireless/core.c +++ linux-6.2.0/net/wireless/core.c @@ -408,6 +408,34 @@ rtnl_unlock(); } +static void cfg80211_wiphy_work(struct work_struct *work) +{ + struct cfg80211_registered_device *rdev; + struct wiphy_work *wk; + + rdev = container_of(work, struct cfg80211_registered_device, wiphy_work); + + wiphy_lock(&rdev->wiphy); + if (rdev->suspended) + goto out; + + spin_lock_irq(&rdev->wiphy_work_lock); + wk = list_first_entry_or_null(&rdev->wiphy_work_list, + struct wiphy_work, entry); + if (wk) { + list_del_init(&wk->entry); + if (!list_empty(&rdev->wiphy_work_list)) + schedule_work(work); + spin_unlock_irq(&rdev->wiphy_work_lock); + + wk->func(&rdev->wiphy, wk); + } else { + spin_unlock_irq(&rdev->wiphy_work_lock); + } +out: + wiphy_unlock(&rdev->wiphy); +} + /* exported functions */ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, @@ -533,6 +561,9 @@ return NULL; } + INIT_WORK(&rdev->wiphy_work, cfg80211_wiphy_work); + INIT_LIST_HEAD(&rdev->wiphy_work_list); + spin_lock_init(&rdev->wiphy_work_lock); INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); INIT_WORK(&rdev->conn_work, cfg80211_conn_work); INIT_WORK(&rdev->event_work, cfg80211_event_work); @@ -1011,6 +1042,31 @@ } EXPORT_SYMBOL(wiphy_rfkill_start_polling); +void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev) +{ + unsigned int runaway_limit = 100; + unsigned long flags; + + lockdep_assert_held(&rdev->wiphy.mtx); + + spin_lock_irqsave(&rdev->wiphy_work_lock, flags); + while (!list_empty(&rdev->wiphy_work_list)) { + struct wiphy_work *wk; + + wk = list_first_entry(&rdev->wiphy_work_list, + struct wiphy_work, entry); + list_del_init(&wk->entry); + spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); + + wk->func(&rdev->wiphy, wk); + + spin_lock_irqsave(&rdev->wiphy_work_lock, flags); + if (WARN_ON(--runaway_limit == 0)) + INIT_LIST_HEAD(&rdev->wiphy_work_list); + } + spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); +} + void wiphy_unregister(struct wiphy *wiphy) { struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); @@ -1049,9 +1105,19 @@ cfg80211_rdev_list_generation++; device_del(&rdev->wiphy.dev); +#ifdef CONFIG_PM + if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) + rdev_set_wakeup(rdev, false); +#endif + + /* surely nothing is reachable now, clean up work */ + cfg80211_process_wiphy_works(rdev); wiphy_unlock(&rdev->wiphy); rtnl_unlock(); + /* this has nothing to do now but make sure it's gone */ + cancel_work_sync(&rdev->wiphy_work); + flush_work(&rdev->scan_done_wk); cancel_work_sync(&rdev->conn_work); flush_work(&rdev->event_work); @@ -1064,10 +1130,6 @@ flush_work(&rdev->mgmt_registrations_update_wk); flush_work(&rdev->background_cac_abort_wk); -#ifdef CONFIG_PM - if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) - rdev_set_wakeup(rdev, false); -#endif cfg80211_rdev_free_wowlan(rdev); cfg80211_rdev_free_coalesce(rdev); } @@ -1114,16 +1176,11 @@ } EXPORT_SYMBOL(wiphy_rfkill_set_hw_state_reason); -void cfg80211_cqm_config_free(struct wireless_dev *wdev) -{ - kfree(wdev->cqm_config); - wdev->cqm_config = NULL; -} - static void _cfg80211_unregister_wdev(struct wireless_dev *wdev, bool unregister_netdev) { struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); + struct cfg80211_cqm_config *cqm_config; unsigned int link_id; ASSERT_RTNL(); @@ -1162,11 +1219,10 @@ kfree_sensitive(wdev->wext.keys); wdev->wext.keys = NULL; #endif - /* only initialized if we have a netdev */ - if (wdev->netdev) - flush_work(&wdev->disconnect_wk); - - cfg80211_cqm_config_free(wdev); + wiphy_work_cancel(wdev->wiphy, &wdev->cqm_rssi_work); + /* deleted from the list, so can't be found from nl80211 any more */ + cqm_config = rcu_access_pointer(wdev->cqm_config); + kfree_rcu(cqm_config, rcu_head); /* * Ensure that all events have been processed and @@ -1318,6 +1374,8 @@ wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; #endif + wiphy_work_init(&wdev->cqm_rssi_work, cfg80211_cqm_rssi_notify_work); + if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT) wdev->ps = true; else @@ -1439,6 +1497,8 @@ cfg80211_leave(rdev, wdev); cfg80211_remove_links(wdev); wiphy_unlock(&rdev->wiphy); + /* since we just did cfg80211_leave() nothing to do there */ + cancel_work_sync(&wdev->disconnect_wk); break; case NETDEV_DOWN: wiphy_lock(&rdev->wiphy); @@ -1548,6 +1608,66 @@ .exit = cfg80211_pernet_exit, }; +void wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + unsigned long flags; + + spin_lock_irqsave(&rdev->wiphy_work_lock, flags); + if (list_empty(&work->entry)) + list_add_tail(&work->entry, &rdev->wiphy_work_list); + spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); + + schedule_work(&rdev->wiphy_work); +} +EXPORT_SYMBOL_GPL(wiphy_work_queue); + +void wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + unsigned long flags; + + lockdep_assert_held(&wiphy->mtx); + + spin_lock_irqsave(&rdev->wiphy_work_lock, flags); + if (!list_empty(&work->entry)) + list_del_init(&work->entry); + spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags); +} +EXPORT_SYMBOL_GPL(wiphy_work_cancel); + +void wiphy_delayed_work_timer(struct timer_list *t) +{ + struct wiphy_delayed_work *dwork = from_timer(dwork, t, timer); + + wiphy_work_queue(dwork->wiphy, &dwork->work); +} +EXPORT_SYMBOL(wiphy_delayed_work_timer); + +void wiphy_delayed_work_queue(struct wiphy *wiphy, + struct wiphy_delayed_work *dwork, + unsigned long delay) +{ + if (!delay) { + wiphy_work_queue(wiphy, &dwork->work); + return; + } + + dwork->wiphy = wiphy; + mod_timer(&dwork->timer, jiffies + delay); +} +EXPORT_SYMBOL_GPL(wiphy_delayed_work_queue); + +void wiphy_delayed_work_cancel(struct wiphy *wiphy, + struct wiphy_delayed_work *dwork) +{ + lockdep_assert_held(&wiphy->mtx); + + del_timer_sync(&dwork->timer); + wiphy_work_cancel(wiphy, &dwork->work); +} +EXPORT_SYMBOL_GPL(wiphy_delayed_work_cancel); + static int __init cfg80211_init(void) { int err; diff -u linux-6.2.0/net/wireless/nl80211.c linux-6.2.0/net/wireless/nl80211.c --- linux-6.2.0/net/wireless/nl80211.c +++ linux-6.2.0/net/wireless/nl80211.c @@ -323,6 +323,7 @@ [NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED] = { .type = NLA_FLAG }, [NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED] = { .type = NLA_FLAG }, [NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK] = { .type = NLA_FLAG }, + [NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR] = { .type = NLA_U8 }, }; static const struct nla_policy @@ -12565,7 +12566,8 @@ } static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, - struct net_device *dev) + struct net_device *dev, + struct cfg80211_cqm_config *cqm_config) { struct wireless_dev *wdev = dev->ieee80211_ptr; s32 last, low, high; @@ -12574,7 +12576,7 @@ int err; /* RSSI reporting disabled? */ - if (!wdev->cqm_config) + if (!cqm_config) return rdev_set_cqm_rssi_range_config(rdev, dev, 0, 0); /* @@ -12583,7 +12585,7 @@ * connection is established and enough beacons received to calculate * the average. */ - if (!wdev->cqm_config->last_rssi_event_value && + if (!cqm_config->last_rssi_event_value && wdev->links[0].client.current_bss && rdev->ops->get_station) { struct station_info sinfo = {}; @@ -12597,30 +12599,30 @@ cfg80211_sinfo_release_content(&sinfo); if (sinfo.filled & BIT_ULL(NL80211_STA_INFO_BEACON_SIGNAL_AVG)) - wdev->cqm_config->last_rssi_event_value = + cqm_config->last_rssi_event_value = (s8) sinfo.rx_beacon_signal_avg; } - last = wdev->cqm_config->last_rssi_event_value; - hyst = wdev->cqm_config->rssi_hyst; - n = wdev->cqm_config->n_rssi_thresholds; + last = cqm_config->last_rssi_event_value; + hyst = cqm_config->rssi_hyst; + n = cqm_config->n_rssi_thresholds; for (i = 0; i < n; i++) { i = array_index_nospec(i, n); - if (last < wdev->cqm_config->rssi_thresholds[i]) + if (last < cqm_config->rssi_thresholds[i]) break; } low_index = i - 1; if (low_index >= 0) { low_index = array_index_nospec(low_index, n); - low = wdev->cqm_config->rssi_thresholds[low_index] - hyst; + low = cqm_config->rssi_thresholds[low_index] - hyst; } else { low = S32_MIN; } if (i < n) { i = array_index_nospec(i, n); - high = wdev->cqm_config->rssi_thresholds[i] + hyst - 1; + high = cqm_config->rssi_thresholds[i] + hyst - 1; } else { high = S32_MAX; } @@ -12633,6 +12635,7 @@ u32 hysteresis) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct cfg80211_cqm_config *cqm_config = NULL, *old; struct net_device *dev = info->user_ptr[1]; struct wireless_dev *wdev = dev->ieee80211_ptr; int i, err; @@ -12650,10 +12653,6 @@ wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) return -EOPNOTSUPP; - wdev_lock(wdev); - cfg80211_cqm_config_free(wdev); - wdev_unlock(wdev); - if (n_thresholds <= 1 && rdev->ops->set_cqm_rssi_config) { if (n_thresholds == 0 || thresholds[0] == 0) /* Disabling */ return rdev_set_cqm_rssi_config(rdev, dev, 0, 0); @@ -12670,9 +12669,10 @@ n_thresholds = 0; wdev_lock(wdev); - if (n_thresholds) { - struct cfg80211_cqm_config *cqm_config; + old = rcu_dereference_protected(wdev->cqm_config, + lockdep_is_held(&wdev->mtx)); + if (n_thresholds) { cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds, n_thresholds), GFP_KERNEL); @@ -12687,11 +12687,18 @@ flex_array_size(cqm_config, rssi_thresholds, n_thresholds)); - wdev->cqm_config = cqm_config; + rcu_assign_pointer(wdev->cqm_config, cqm_config); + } else { + RCU_INIT_POINTER(wdev->cqm_config, NULL); } - err = cfg80211_cqm_rssi_update(rdev, dev); - + err = cfg80211_cqm_rssi_update(rdev, dev, cqm_config); + if (err) { + rcu_assign_pointer(wdev->cqm_config, old); + kfree_rcu(cqm_config, rcu_head); + } else { + kfree_rcu(old, rcu_head); + } unlock: wdev_unlock(wdev); @@ -18731,9 +18738,8 @@ enum nl80211_cqm_rssi_threshold_event rssi_event, s32 rssi_level, gfp_t gfp) { - struct sk_buff *msg; struct wireless_dev *wdev = dev->ieee80211_ptr; - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); + struct cfg80211_cqm_config *cqm_config; trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level); @@ -18741,18 +18747,41 @@ rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH)) return; - if (wdev->cqm_config) { - wdev->cqm_config->last_rssi_event_value = rssi_level; + rcu_read_lock(); + cqm_config = rcu_dereference(wdev->cqm_config); + if (cqm_config) { + cqm_config->last_rssi_event_value = rssi_level; + cqm_config->last_rssi_event_type = rssi_event; + wiphy_work_queue(wdev->wiphy, &wdev->cqm_rssi_work); + } + rcu_read_unlock(); +} +EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); + +void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, struct wiphy_work *work) +{ + struct wireless_dev *wdev = container_of(work, struct wireless_dev, + cqm_rssi_work); + struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); + enum nl80211_cqm_rssi_threshold_event rssi_event; + struct cfg80211_cqm_config *cqm_config; + struct sk_buff *msg; + s32 rssi_level; + + wdev_lock(wdev); + cqm_config = rcu_dereference_protected(wdev->cqm_config, + lockdep_is_held(&wdev->mtx)); + if (!wdev->cqm_config) + goto unlock; - cfg80211_cqm_rssi_update(rdev, dev); + cfg80211_cqm_rssi_update(rdev, wdev->netdev, cqm_config); - if (rssi_level == 0) - rssi_level = wdev->cqm_config->last_rssi_event_value; - } + rssi_level = cqm_config->last_rssi_event_value; + rssi_event = cqm_config->last_rssi_event_type; - msg = cfg80211_prepare_cqm(dev, NULL, gfp); + msg = cfg80211_prepare_cqm(wdev->netdev, NULL, GFP_KERNEL); if (!msg) - return; + goto unlock; if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, rssi_event)) @@ -18762,14 +18791,15 @@ rssi_level)) goto nla_put_failure; - cfg80211_send_cqm(msg, gfp); + cfg80211_send_cqm(msg, GFP_KERNEL); - return; + goto unlock; nla_put_failure: nlmsg_free(msg); + unlock: + wdev_unlock(wdev); } -EXPORT_SYMBOL(cfg80211_cqm_rssi_notify); void cfg80211_cqm_txe_notify(struct net_device *dev, const u8 *peer, u32 num_packets, diff -u linux-6.2.0/net/wireless/sme.c linux-6.2.0/net/wireless/sme.c --- linux-6.2.0/net/wireless/sme.c +++ linux-6.2.0/net/wireless/sme.c @@ -5,7 +5,7 @@ * (for nl80211's connect() and wext) * * Copyright 2009 Johannes Berg - * Copyright (C) 2009, 2020, 2022 Intel Corporation. All rights reserved. + * Copyright (C) 2009, 2020, 2022-2023 Intel Corporation. All rights reserved. * Copyright 2017 Intel Deutschland GmbH */ @@ -1573,6 +1573,7 @@ container_of(work, struct wireless_dev, disconnect_wk); struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); + wiphy_lock(wdev->wiphy); wdev_lock(wdev); if (wdev->conn_owner_nlportid) { @@ -1613,2 +1614,3 @@ wdev_unlock(wdev); + wiphy_unlock(wdev->wiphy); } diff -u linux-6.2.0/scripts/rust_is_available.sh linux-6.2.0/scripts/rust_is_available.sh --- linux-6.2.0/scripts/rust_is_available.sh +++ linux-6.2.0/scripts/rust_is_available.sh @@ -2,8 +2,6 @@ # SPDX-License-Identifier: GPL-2.0 # # Tests whether a suitable Rust toolchain is available. -# -# Pass `-v` for human output and more checks (as warnings). set -e @@ -23,21 +21,17 @@ # Check that the Rust compiler exists. if ! command -v "$RUSTC" >/dev/null; then - if [ "$1" = -v ]; then - echo >&2 "***" - echo >&2 "*** Rust compiler '$RUSTC' could not be found." - echo >&2 "***" - fi + echo >&2 "***" + echo >&2 "*** Rust compiler '$RUSTC' could not be found." + echo >&2 "***" exit 1 fi # Check that the Rust bindings generator exists. if ! command -v "$BINDGEN" >/dev/null; then - if [ "$1" = -v ]; then - echo >&2 "***" - echo >&2 "*** Rust bindings generator '$BINDGEN' could not be found." - echo >&2 "***" - fi + echo >&2 "***" + echo >&2 "*** Rust bindings generator '$BINDGEN' could not be found." + echo >&2 "***" exit 1 fi @@ -53,16 +47,14 @@ rust_compiler_cversion=$(get_canonical_version $rust_compiler_version) rust_compiler_min_cversion=$(get_canonical_version $rust_compiler_min_version) if [ "$rust_compiler_cversion" -lt "$rust_compiler_min_cversion" ]; then - if [ "$1" = -v ]; then - echo >&2 "***" - echo >&2 "*** Rust compiler '$RUSTC' is too old." - echo >&2 "*** Your version: $rust_compiler_version" - echo >&2 "*** Minimum version: $rust_compiler_min_version" - echo >&2 "***" - fi + echo >&2 "***" + echo >&2 "*** Rust compiler '$RUSTC' is too old." + echo >&2 "*** Your version: $rust_compiler_version" + echo >&2 "*** Minimum version: $rust_compiler_min_version" + echo >&2 "***" exit 1 fi -if [ "$1" = -v ] && [ "$rust_compiler_cversion" -gt "$rust_compiler_min_cversion" ]; then +if [ "$rust_compiler_cversion" -gt "$rust_compiler_min_cversion" ]; then echo >&2 "***" echo >&2 "*** Rust compiler '$RUSTC' is too new. This may or may not work." echo >&2 "*** Your version: $rust_compiler_version" @@ -82,16 +74,14 @@ rust_bindings_generator_cversion=$(get_canonical_version $rust_bindings_generator_version) rust_bindings_generator_min_cversion=$(get_canonical_version $rust_bindings_generator_min_version) if [ "$rust_bindings_generator_cversion" -lt "$rust_bindings_generator_min_cversion" ]; then - if [ "$1" = -v ]; then - echo >&2 "***" - echo >&2 "*** Rust bindings generator '$BINDGEN' is too old." - echo >&2 "*** Your version: $rust_bindings_generator_version" - echo >&2 "*** Minimum version: $rust_bindings_generator_min_version" - echo >&2 "***" - fi + echo >&2 "***" + echo >&2 "*** Rust bindings generator '$BINDGEN' is too old." + echo >&2 "*** Your version: $rust_bindings_generator_version" + echo >&2 "*** Minimum version: $rust_bindings_generator_min_version" + echo >&2 "***" exit 1 fi -if [ "$1" = -v ] && [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cversion" ]; then +if [ "$rust_bindings_generator_cversion" -gt "$rust_bindings_generator_min_cversion" ]; then echo >&2 "***" echo >&2 "*** Rust bindings generator '$BINDGEN' is too new. This may or may not work." echo >&2 "*** Your version: $rust_bindings_generator_version" @@ -100,21 +90,39 @@ fi # Check that the `libclang` used by the Rust bindings generator is suitable. +# +# In order to do that, first invoke `bindgen` to get the `libclang` version +# found by `bindgen`. This step may already fail if, for instance, `libclang` +# is not found, thus inform the user in such a case. +bindgen_libclang_output=$( \ + LC_ALL=C "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang.h 2>&1 >/dev/null +) || bindgen_libclang_code=$? +if [ -n "$bindgen_libclang_code" ]; then + echo >&2 "***" + echo >&2 "*** Running '$BINDGEN' to check the libclang version (used by the Rust" + echo >&2 "*** bindings generator) failed with code $bindgen_libclang_code. This may be caused by" + echo >&2 "*** a failure to locate libclang. See output and docs below for details:" + echo >&2 "***" + echo >&2 "$bindgen_libclang_output" + echo >&2 "***" + exit 1 +fi + +# `bindgen` returned successfully, thus use the output to check that the version +# of the `libclang` found by the Rust bindings generator is suitable. bindgen_libclang_version=$( \ - LC_ALL=C "$BINDGEN" $(dirname $0)/rust_is_available_bindgen_libclang.h 2>&1 >/dev/null \ - | sed -ne 's/.*clang version \([0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p' + echo "$bindgen_libclang_output" \ + | sed -nE 's:.*clang version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p' ) bindgen_libclang_min_version=$($min_tool_version llvm) bindgen_libclang_cversion=$(get_canonical_version $bindgen_libclang_version) bindgen_libclang_min_cversion=$(get_canonical_version $bindgen_libclang_min_version) if [ "$bindgen_libclang_cversion" -lt "$bindgen_libclang_min_cversion" ]; then - if [ "$1" = -v ]; then - echo >&2 "***" - echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') is too old." - echo >&2 "*** Your version: $bindgen_libclang_version" - echo >&2 "*** Minimum version: $bindgen_libclang_min_version" - echo >&2 "***" - fi + echo >&2 "***" + echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN') is too old." + echo >&2 "*** Your version: $bindgen_libclang_version" + echo >&2 "*** Minimum version: $bindgen_libclang_min_version" + echo >&2 "***" exit 1 fi @@ -123,21 +131,19 @@ # # In the future, we might be able to perform a full version check, see # https://github.com/rust-lang/rust-bindgen/issues/2138. -if [ "$1" = -v ]; then - cc_name=$($(dirname $0)/cc-version.sh "$CC" | cut -f1 -d' ') - if [ "$cc_name" = Clang ]; then - clang_version=$( \ - LC_ALL=C "$CC" --version 2>/dev/null \ - | sed -nE '1s:.*version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p' - ) - if [ "$clang_version" != "$bindgen_libclang_version" ]; then - echo >&2 "***" - echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN')" - echo >&2 "*** version does not match Clang's. This may be a problem." - echo >&2 "*** libclang version: $bindgen_libclang_version" - echo >&2 "*** Clang version: $clang_version" - echo >&2 "***" - fi +cc_name=$($(dirname $0)/cc-version.sh $CC | cut -f1 -d' ') +if [ "$cc_name" = Clang ]; then + clang_version=$( \ + LC_ALL=C $CC --version 2>/dev/null \ + | sed -nE '1s:.*version ([0-9]+\.[0-9]+\.[0-9]+).*:\1:p' + ) + if [ "$clang_version" != "$bindgen_libclang_version" ]; then + echo >&2 "***" + echo >&2 "*** libclang (used by the Rust bindings generator '$BINDGEN')" + echo >&2 "*** version does not match Clang's. This may be a problem." + echo >&2 "*** libclang version: $bindgen_libclang_version" + echo >&2 "*** Clang version: $clang_version" + echo >&2 "***" fi fi @@ -149,10 +155,8 @@ rustc_src_core="$rustc_src/core/src/lib.rs" if [ ! -e "$rustc_src_core" ]; then - if [ "$1" = -v ]; then - echo >&2 "***" - echo >&2 "*** Source code for the 'core' standard library could not be found" - echo >&2 "*** at '$rustc_src_core'." - echo >&2 "***" - fi + echo >&2 "***" + echo >&2 "*** Source code for the 'core' standard library could not be found" + echo >&2 "*** at '$rustc_src_core'." + echo >&2 "***" exit 1 fi diff -u linux-6.2.0/security/integrity/ima/Kconfig linux-6.2.0/security/integrity/ima/Kconfig --- linux-6.2.0/security/integrity/ima/Kconfig +++ linux-6.2.0/security/integrity/ima/Kconfig @@ -29,9 +29,11 @@ to learn more about IMA. If unsure, say N. +if IMA + config IMA_KEXEC bool "Enable carrying the IMA measurement list across a soft boot" - depends on IMA && TCG_TPM && HAVE_IMA_KEXEC + depends on TCG_TPM && HAVE_IMA_KEXEC default n help TPM PCRs are only reset on a hard reboot. In order to validate @@ -43,7 +45,6 @@ config IMA_MEASURE_PCR_IDX int - depends on IMA range 8 14 default 10 help @@ -53,7 +54,7 @@ config IMA_LSM_RULES bool - depends on IMA && AUDIT && (SECURITY_SELINUX || SECURITY_SMACK || SECURITY_APPARMOR) + depends on AUDIT && (SECURITY_SELINUX || SECURITY_SMACK || SECURITY_APPARMOR) default y help Disabling this option will disregard LSM based policy rules. @@ -61,7 +62,6 @@ choice prompt "Default template" default IMA_NG_TEMPLATE - depends on IMA help Select the default IMA measurement template. @@ -80,14 +80,12 @@ config IMA_DEFAULT_TEMPLATE string - depends on IMA default "ima-ng" if IMA_NG_TEMPLATE default "ima-sig" if IMA_SIG_TEMPLATE choice prompt "Default integrity hash algorithm" default IMA_DEFAULT_HASH_SHA1 - depends on IMA help Select the default hash algorithm used for the measurement list, integrity appraisal and audit log. The compiled default @@ -117,7 +115,6 @@ config IMA_DEFAULT_HASH string - depends on IMA default "sha1" if IMA_DEFAULT_HASH_SHA1 default "sha256" if IMA_DEFAULT_HASH_SHA256 default "sha512" if IMA_DEFAULT_HASH_SHA512 @@ -126,7 +123,6 @@ config IMA_WRITE_POLICY bool "Enable multiple writes to the IMA policy" - depends on IMA default n help IMA policy can now be updated multiple times. The new rules get @@ -137,7 +133,6 @@ config IMA_READ_POLICY bool "Enable reading back the current IMA policy" - depends on IMA default y if IMA_WRITE_POLICY default n if !IMA_WRITE_POLICY help @@ -147,7 +142,6 @@ config IMA_APPRAISE bool "Appraise integrity measurements" - depends on IMA default n help This option enables local measurement integrity appraisal. @@ -248,18 +242,6 @@ The modsig keyword can be used in the IMA policy to allow a hook to accept such signatures. -config IMA_TRUSTED_KEYRING - bool "Require all keys on the .ima keyring be signed (deprecated)" - depends on IMA_APPRAISE && SYSTEM_TRUSTED_KEYRING - depends on INTEGRITY_ASYMMETRIC_KEYS - select INTEGRITY_TRUSTED_KEYRING - default y - help - This option requires that all keys added to the .ima - keyring be signed by a key on the system trusted keyring. - - This option is deprecated in favor of INTEGRITY_TRUSTED_KEYRING - config IMA_KEYRINGS_PERMIT_SIGNED_BY_BUILTIN_OR_SECONDARY bool "Permit keys validly signed by a built-in or secondary CA cert (EXPERIMENTAL)" depends on SYSTEM_TRUSTED_KEYRING @@ -280,7 +262,7 @@ config IMA_BLACKLIST_KEYRING bool "Create IMA machine owner blacklist keyrings (EXPERIMENTAL)" depends on SYSTEM_TRUSTED_KEYRING - depends on IMA_TRUSTED_KEYRING + depends on INTEGRITY_TRUSTED_KEYRING default n help This option creates an IMA blacklist keyring, which contains all @@ -290,7 +272,7 @@ config IMA_LOAD_X509 bool "Load X509 certificate onto the '.ima' trusted keyring" - depends on IMA_TRUSTED_KEYRING + depends on INTEGRITY_TRUSTED_KEYRING default n help File signature verification is based on the public keys @@ -315,7 +297,6 @@ config IMA_MEASURE_ASYMMETRIC_KEYS bool - depends on IMA depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y default y @@ -337,4 +318,5 @@ - depends on IMA default n help This option disables htable to allow measurement of duplicate records. + +endif diff -u linux-6.2.0/security/security.c linux-6.2.0/security/security.c --- linux-6.2.0/security/security.c +++ linux-6.2.0/security/security.c @@ -1046,6 +1046,20 @@ call_void_hook(bprm_committed_creds, bprm); } +/** + * security_fs_context_submount() - Initialise fc->security + * @fc: new filesystem context + * @reference: dentry reference for submount/remount + * + * Fill out the ->security field for a new fs_context. + * + * Return: Returns 0 on success or negative error code on failure. + */ +int security_fs_context_submount(struct fs_context *fc, struct super_block *reference) +{ + return call_int_hook(fs_context_submount, 0, fc, reference); +} + int security_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) { return call_int_hook(fs_context_dup, 0, fc, src_fc); diff -u linux-6.2.0/security/selinux/hooks.c linux-6.2.0/security/selinux/hooks.c --- linux-6.2.0/security/selinux/hooks.c +++ linux-6.2.0/security/selinux/hooks.c @@ -2768,6 +2768,33 @@ FILESYSTEM__UNMOUNT, NULL); } +static int selinux_fs_context_submount(struct fs_context *fc, + struct super_block *reference) +{ + const struct superblock_security_struct *sbsec = selinux_superblock(reference); + struct selinux_mnt_opts *opts; + + /* + * Ensure that fc->security remains NULL when no options are set + * as expected by selinux_set_mnt_opts(). + */ + if (!(sbsec->flags & (FSCONTEXT_MNT|CONTEXT_MNT|DEFCONTEXT_MNT))) + return 0; + + opts = kzalloc(sizeof(*opts), GFP_KERNEL); + if (!opts) + return -ENOMEM; + + if (sbsec->flags & FSCONTEXT_MNT) + opts->fscontext_sid = sbsec->sid; + if (sbsec->flags & CONTEXT_MNT) + opts->context_sid = sbsec->mntpoint_sid; + if (sbsec->flags & DEFCONTEXT_MNT) + opts->defcontext_sid = sbsec->def_sid; + fc->security = opts; + return 0; +} + static int selinux_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc) { @@ -7308,6 +7335,7 @@ /* * PUT "CLONING" (ACCESSING + ALLOCATING) HOOKS HERE */ + LSM_HOOK_INIT(fs_context_submount, selinux_fs_context_submount), LSM_HOOK_INIT(fs_context_dup, selinux_fs_context_dup), LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param), LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts), diff -u linux-6.2.0/security/smack/smack.h linux-6.2.0/security/smack/smack.h --- linux-6.2.0/security/smack/smack.h +++ linux-6.2.0/security/smack/smack.h @@ -120,6 +120,7 @@ struct task_smack { struct smack_known *smk_task; /* label for access control */ struct smack_known *smk_forked; /* label when forked */ + struct smack_known *smk_transmuted;/* label when transmuted */ struct list_head smk_rules; /* per task access rules */ struct mutex smk_rules_lock; /* lock for the rules */ struct list_head smk_relabel; /* transit allowed labels */ diff -u linux-6.2.0/security/smack/smack_lsm.c linux-6.2.0/security/smack/smack_lsm.c --- linux-6.2.0/security/smack/smack_lsm.c +++ linux-6.2.0/security/smack/smack_lsm.c @@ -613,6 +613,56 @@ } /** + * smack_fs_context_submount - Initialise security data for a filesystem context + * @fc: The filesystem context. + * @reference: reference superblock + * + * Returns 0 on success or -ENOMEM on error. + */ +static int smack_fs_context_submount(struct fs_context *fc, + struct super_block *reference) +{ + struct superblock_smack *sbsp; + struct smack_mnt_opts *ctx; + struct inode_smack *isp; + + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return -ENOMEM; + fc->security = ctx; + + sbsp = smack_superblock(reference); + isp = smack_inode(reference->s_root->d_inode); + + if (sbsp->smk_default) { + ctx->fsdefault = kstrdup(sbsp->smk_default->smk_known, GFP_KERNEL); + if (!ctx->fsdefault) + return -ENOMEM; + } + + if (sbsp->smk_floor) { + ctx->fsfloor = kstrdup(sbsp->smk_floor->smk_known, GFP_KERNEL); + if (!ctx->fsfloor) + return -ENOMEM; + } + + if (sbsp->smk_hat) { + ctx->fshat = kstrdup(sbsp->smk_hat->smk_known, GFP_KERNEL); + if (!ctx->fshat) + return -ENOMEM; + } + + if (isp->smk_flags & SMK_INODE_TRANSMUTE) { + if (sbsp->smk_root) { + ctx->fstransmute = kstrdup(sbsp->smk_root->smk_known, GFP_KERNEL); + if (!ctx->fstransmute) + return -ENOMEM; + } + } + return 0; +} + +/** * smack_fs_context_dup - Duplicate the security data on fs_context duplication * @fc: The new filesystem context. * @src_fc: The source filesystem context being duplicated. @@ -950,8 +1000,9 @@ const struct qstr *qstr, const char **name, void **value, size_t *len) { + struct task_smack *tsp = smack_cred(current_cred()); struct inode_smack *issp = smack_inode(inode); - struct smack_known *skp = smk_of_current(); + struct smack_known *skp = smk_of_task(tsp); struct smack_known *isp = smk_of_inode(inode); struct smack_known *dsp = smk_of_inode(dir); int may; @@ -960,20 +1011,34 @@ *name = XATTR_SMACK_SUFFIX; if (value && len) { - rcu_read_lock(); - may = smk_access_entry(skp->smk_known, dsp->smk_known, - &skp->smk_rules); - rcu_read_unlock(); + /* + * If equal, transmuting already occurred in + * smack_dentry_create_files_as(). No need to check again. + */ + if (tsp->smk_task != tsp->smk_transmuted) { + rcu_read_lock(); + may = smk_access_entry(skp->smk_known, dsp->smk_known, + &skp->smk_rules); + rcu_read_unlock(); + } /* - * If the access rule allows transmutation and - * the directory requests transmutation then - * by all means transmute. + * In addition to having smk_task equal to smk_transmuted, + * if the access rule allows transmutation and the directory + * requests transmutation then by all means transmute. * Mark the inode as changed. */ - if (may > 0 && ((may & MAY_TRANSMUTE) != 0) && - smk_inode_transmutable(dir)) { - isp = dsp; + if ((tsp->smk_task == tsp->smk_transmuted) || + (may > 0 && ((may & MAY_TRANSMUTE) != 0) && + smk_inode_transmutable(dir))) { + /* + * The caller of smack_dentry_create_files_as() + * should have overridden the current cred, so the + * inode label was already set correctly in + * smack_inode_alloc_security(). + */ + if (tsp->smk_task != tsp->smk_transmuted) + isp = dsp; issp->smk_flags |= SMK_INODE_CHANGED; } @@ -1480,10 +1545,19 @@ struct super_block *sbp; struct inode *ip = (struct inode *)inode; struct smack_known *isp; + struct inode_smack *ispp; + size_t label_len; + char *label = NULL; - if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) + if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { isp = smk_of_inode(inode); - else { + } else if (strcmp(name, XATTR_SMACK_TRANSMUTE) == 0) { + ispp = smack_inode(inode); + if (ispp->smk_flags & SMK_INODE_TRANSMUTE) + label = TRANS_TRUE; + else + label = ""; + } else { /* * The rest of the Smack xattrs are only on sockets. */ @@ -1505,13 +1579,18 @@ return -EOPNOTSUPP; } + if (!label) + label = isp->smk_known; + + label_len = strlen(label); + if (alloc) { - *buffer = kstrdup(isp->smk_known, GFP_KERNEL); + *buffer = kstrdup(label, GFP_KERNEL); if (*buffer == NULL) return -ENOMEM; } - return strlen(isp->smk_known); + return label_len; } @@ -4764,8 +4843,10 @@ * providing access is transmuting use the containing * directory label instead of the process label. */ - if (may > 0 && (may & MAY_TRANSMUTE)) + if (may > 0 && (may & MAY_TRANSMUTE)) { ntsp->smk_task = isp->smk_inode; + ntsp->smk_transmuted = ntsp->smk_task; + } } return 0; } @@ -4864,6 +4945,7 @@ LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), LSM_HOOK_INIT(syslog, smack_syslog), + LSM_HOOK_INIT(fs_context_submount, smack_fs_context_submount), LSM_HOOK_INIT(fs_context_dup, smack_fs_context_dup), LSM_HOOK_INIT(fs_context_parse_param, smack_fs_context_parse_param), diff -u linux-6.2.0/security/smack/smackfs.c linux-6.2.0/security/smack/smackfs.c --- linux-6.2.0/security/smack/smackfs.c +++ linux-6.2.0/security/smack/smackfs.c @@ -896,7 +896,7 @@ } ret = sscanf(rule, "%d", &catlen); - if (ret != 1 || catlen > SMACK_CIPSO_MAXCATNUM) + if (ret != 1 || catlen < 0 || catlen > SMACK_CIPSO_MAXCATNUM) goto out; if (format == SMK_FIXED24_FMT && diff -u linux-6.2.0/sound/hda/intel-dsp-config.c linux-6.2.0/sound/hda/intel-dsp-config.c --- linux-6.2.0/sound/hda/intel-dsp-config.c +++ linux-6.2.0/sound/hda/intel-dsp-config.c @@ -481,6 +481,14 @@ }, #endif +/* Lunar Lake */ +#if IS_ENABLED(CONFIG_SND_SOC_SOF_LUNARLAKE) + /* Lunarlake-P */ + { + .flags = FLAG_SOF | FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE, + .device = PCI_DEVICE_ID_INTEL_HDA_LNL_P, + }, +#endif }; static const struct config_entry *snd_intel_dsp_find_config diff -u linux-6.2.0/sound/pci/ac97/ac97_codec.c linux-6.2.0/sound/pci/ac97/ac97_codec.c --- linux-6.2.0/sound/pci/ac97/ac97_codec.c +++ linux-6.2.0/sound/pci/ac97/ac97_codec.c @@ -2070,10 +2070,9 @@ .dev_disconnect = snd_ac97_dev_disconnect, }; - if (!rac97) - return -EINVAL; - if (snd_BUG_ON(!bus || !template)) + if (snd_BUG_ON(!bus || !template || !rac97)) return -EINVAL; + *rac97 = NULL; if (snd_BUG_ON(template->num >= 4)) return -EINVAL; if (bus->codec[template->num]) diff -u linux-6.2.0/sound/pci/hda/hda_intel.c linux-6.2.0/sound/pci/hda/hda_intel.c --- linux-6.2.0/sound/pci/hda/hda_intel.c +++ linux-6.2.0/sound/pci/hda/hda_intel.c @@ -2208,6 +2208,7 @@ SND_PCI_QUIRK(0x8086, 0x2068, "Intel NUC7i3BNB", 0), /* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */ SND_PCI_QUIRK(0x17aa, 0x2227, "Lenovo X1 Carbon 3rd Gen", 0), + SND_PCI_QUIRK(0x17aa, 0x316e, "Lenovo ThinkCentre M70q", 0), /* https://bugzilla.redhat.com/show_bug.cgi?id=1689623 */ SND_PCI_QUIRK(0x17aa, 0x367b, "Lenovo IdeaCentre B550", 0), /* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */ diff -u linux-6.2.0/sound/pci/hda/patch_realtek.c linux-6.2.0/sound/pci/hda/patch_realtek.c --- linux-6.2.0/sound/pci/hda/patch_realtek.c +++ linux-6.2.0/sound/pci/hda/patch_realtek.c @@ -9691,7 +9691,8 @@ SND_PCI_QUIRK(0x1043, 0x1d1f, "ASUS ROG Strix G17 2023 (G713PV)", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x1d42, "ASUS Zephyrus G14 2022", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), - SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS UX3402VA", ALC245_FIXUP_CS35L41_SPI_2), SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), @@ -11887,6 +11888,7 @@ SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN), SND_PCI_QUIRK(0x17aa, 0x3321, "Lenovo ThinkCentre M70 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN), SND_PCI_QUIRK(0x17aa, 0x331b, "Lenovo ThinkCentre M90 Gen4", ALC897_FIXUP_HEADSET_MIC_PIN), + SND_PCI_QUIRK(0x17aa, 0x3364, "Lenovo ThinkCentre M90 Gen5", ALC897_FIXUP_HEADSET_MIC_PIN), SND_PCI_QUIRK(0x17aa, 0x3742, "Lenovo TianYi510Pro-14IOB", ALC897_FIXUP_HEADSET_MIC_PIN2), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), diff -u linux-6.2.0/sound/soc/amd/yc/acp6x-mach.c linux-6.2.0/sound/soc/amd/yc/acp6x-mach.c --- linux-6.2.0/sound/soc/amd/yc/acp6x-mach.c +++ linux-6.2.0/sound/soc/amd/yc/acp6x-mach.c @@ -220,4 +220,25 @@ + DMI_MATCH(DMI_PRODUCT_NAME, "82TL"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "82QF"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), DMI_MATCH(DMI_PRODUCT_NAME, "82V2"), } }, { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "82UG"), + } + }, + { diff -u linux-6.2.0/sound/soc/codecs/Kconfig linux-6.2.0/sound/soc/codecs/Kconfig --- linux-6.2.0/sound/soc/codecs/Kconfig +++ linux-6.2.0/sound/soc/codecs/Kconfig @@ -1552,6 +1552,7 @@ config SND_SOC_STAC9766 tristate depends on SND_SOC_AC97_BUS + select REGMAP_AC97 config SND_SOC_STI_SAS tristate "codec Audio support for STI SAS codec" diff -u linux-6.2.0/sound/soc/codecs/es8316.c linux-6.2.0/sound/soc/codecs/es8316.c --- linux-6.2.0/sound/soc/codecs/es8316.c +++ linux-6.2.0/sound/soc/codecs/es8316.c @@ -153,7 +153,7 @@ "dmic data at high level", "dmic data at low level", }; -static const unsigned int es8316_dmic_values[] = { 0, 1, 2 }; +static const unsigned int es8316_dmic_values[] = { 0, 2, 3 }; static const struct soc_enum es8316_dmic_src_enum = SOC_VALUE_ENUM_SINGLE(ES8316_ADC_DMIC, 0, 3, ARRAY_SIZE(es8316_dmic_txt), diff -u linux-6.2.0/sound/soc/codecs/rt5640.c linux-6.2.0/sound/soc/codecs/rt5640.c --- linux-6.2.0/sound/soc/codecs/rt5640.c +++ linux-6.2.0/sound/soc/codecs/rt5640.c @@ -2400,13 +2400,11 @@ struct rt5640_priv *rt5640 = data; int delay = 0; - if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER) { - cancel_delayed_work_sync(&rt5640->jack_work); + if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER) delay = 100; - } if (rt5640->jack) - queue_delayed_work(system_long_wq, &rt5640->jack_work, delay); + mod_delayed_work(system_long_wq, &rt5640->jack_work, delay); return IRQ_HANDLED; } @@ -2562,10 +2560,9 @@ if (jack_data && jack_data->use_platform_clock) rt5640->use_platform_clock = jack_data->use_platform_clock; - ret = devm_request_threaded_irq(component->dev, rt5640->irq, - NULL, rt5640_irq, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - "rt5640", rt5640); + ret = request_irq(rt5640->irq, rt5640_irq, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + "rt5640", rt5640); if (ret) { dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret); rt5640_disable_jack_detect(component); @@ -2618,14 +2615,14 @@ rt5640->jack = jack; - ret = devm_request_threaded_irq(component->dev, rt5640->irq, - NULL, rt5640_irq, IRQF_TRIGGER_RISING | IRQF_ONESHOT, - "rt5640", rt5640); + ret = request_irq(rt5640->irq, rt5640_irq, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, "rt5640", rt5640); if (ret) { dev_warn(component->dev, "Failed to reguest IRQ %d: %d\n", rt5640->irq, ret); - rt5640->irq = -ENXIO; + rt5640->jack = NULL; return; } + rt5640->irq_requested = true; /* sync initial jack state */ queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); @@ -2794,7 +2791,7 @@ { struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component); - if (rt5640->irq) { + if (rt5640->jack) { /* disable jack interrupts during system suspend */ disable_irq(rt5640->irq); } @@ -2822,9 +2819,6 @@ regcache_cache_only(rt5640->regmap, false); regcache_sync(rt5640->regmap); - if (rt5640->irq) - enable_irq(rt5640->irq); - if (rt5640->jack) { if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER) { snd_soc_component_update_bits(component, @@ -2852,6 +2846,7 @@ } } + enable_irq(rt5640->irq); queue_delayed_work(system_long_wq, &rt5640->jack_work, 0); } diff -u linux-6.2.0/sound/soc/codecs/rt711-sdca-sdw.c linux-6.2.0/sound/soc/codecs/rt711-sdca-sdw.c --- linux-6.2.0/sound/soc/codecs/rt711-sdca-sdw.c +++ linux-6.2.0/sound/soc/codecs/rt711-sdca-sdw.c @@ -442,8 +442,16 @@ if (!rt711->first_hw_init) return 0; - if (!slave->unattach_request) + if (!slave->unattach_request) { + if (rt711->disable_irq == true) { + mutex_lock(&rt711->disable_irq_lock); + sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK1, SDW_SCP_SDCA_INTMASK_SDCA_0); + sdw_write_no_pm(slave, SDW_SCP_SDCA_INTMASK2, SDW_SCP_SDCA_INTMASK_SDCA_8); + rt711->disable_irq = false; + mutex_unlock(&rt711->disable_irq_lock); + } goto regmap_sync; + } time = wait_for_completion_timeout(&slave->initialization_complete, msecs_to_jiffies(RT711_PROBE_TIMEOUT)); diff -u linux-6.2.0/sound/soc/fsl/imx-audmix.c linux-6.2.0/sound/soc/fsl/imx-audmix.c --- linux-6.2.0/sound/soc/fsl/imx-audmix.c +++ linux-6.2.0/sound/soc/fsl/imx-audmix.c @@ -320,7 +320,7 @@ if (IS_ERR(priv->cpu_mclk)) { ret = PTR_ERR(priv->cpu_mclk); dev_err(&cpu_pdev->dev, "failed to get DAI mclk1: %d\n", ret); - return -EINVAL; + return ret; } priv->audmix_pdev = audmix_pdev; diff -u linux-6.2.0/sound/soc/intel/boards/sof_sdw.c linux-6.2.0/sound/soc/intel/boards/sof_sdw.c --- linux-6.2.0/sound/soc/intel/boards/sof_sdw.c +++ linux-6.2.0/sound/soc/intel/boards/sof_sdw.c @@ -489,7 +489,9 @@ DMI_MATCH(DMI_SYS_VENDOR, "Google"), DMI_MATCH(DMI_PRODUCT_NAME, "Rex"), }, - .driver_data = (void *)(SOF_SDW_PCH_DMIC), + .driver_data = (void *)(SOF_SDW_PCH_DMIC | + SOF_BT_OFFLOAD_SSP(1) | + SOF_SSP_BT_OFFLOAD_PRESENT), }, /* LunarLake devices */ { diff -u linux-6.2.0/sound/soc/sof/core.c linux-6.2.0/sound/soc/sof/core.c --- linux-6.2.0/sound/soc/sof/core.c +++ linux-6.2.0/sound/soc/sof/core.c @@ -461,10 +461,9 @@ snd_sof_ipc_free(sdev); snd_sof_free_debug(sdev); snd_sof_remove(sdev); + sof_ops_free(sdev); } - sof_ops_free(sdev); - /* release firmware */ snd_sof_fw_unload(sdev); diff -u linux-6.2.0/sound/soc/sof/topology.c linux-6.2.0/sound/soc/sof/topology.c --- linux-6.2.0/sound/soc/sof/topology.c +++ linux-6.2.0/sound/soc/sof/topology.c @@ -1131,16 +1131,17 @@ { struct snd_soc_card *card = scomp->card; struct snd_soc_pcm_runtime *rtd; + const char *sname = w->sname; struct snd_soc_dai *cpu_dai; int i; - if (!w->sname) + if (!sname) return; list_for_each_entry(rtd, &card->rtd_list, list) { /* does stream match DAI link ? */ if (!rtd->dai_link->stream_name || - strcmp(w->sname, rtd->dai_link->stream_name)) + strcmp(sname, rtd->dai_link->stream_name)) continue; switch (w->id) { diff -u linux-6.2.0/sound/usb/quirks.c linux-6.2.0/sound/usb/quirks.c --- linux-6.2.0/sound/usb/quirks.c +++ linux-6.2.0/sound/usb/quirks.c @@ -1874,8 +1874,10 @@ /* XMOS based USB DACs */ switch (chip->usb_id) { - case USB_ID(0x1511, 0x0037): /* AURALiC VEGA */ - case USB_ID(0x21ed, 0xd75a): /* Accuphase DAC-60 option card */ + case USB_ID(0x139f, 0x5504): /* Nagra DAC */ + case USB_ID(0x20b1, 0x3089): /* Mola-Mola DAC */ + case USB_ID(0x2522, 0x0007): /* LH Labs Geek Out 1V5 */ + case USB_ID(0x2522, 0x0009): /* LH Labs Geek Pulse X Inifinity 2V0 */ case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */ case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */ if (fp->altsetting == 2) @@ -1885,14 +1887,18 @@ case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */ case USB_ID(0x10cb, 0x0103): /* The Bit Opus #3; with fp->dsd_raw */ case USB_ID(0x16d0, 0x06b2): /* NuPrime DAC-10 */ - case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */ + case USB_ID(0x16d0, 0x06b4): /* NuPrime Audio HD-AVP/AVA */ case USB_ID(0x16d0, 0x0733): /* Furutech ADL Stratos */ + case USB_ID(0x16d0, 0x09d8): /* NuPrime IDA-8 */ case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */ + case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */ case USB_ID(0x1db5, 0x0003): /* Bryston BDA3 */ + case USB_ID(0x20a0, 0x4143): /* WaveIO USB Audio 2.0 */ case USB_ID(0x22e1, 0xca01): /* HDTA Serenade DSD */ case USB_ID(0x249c, 0x9326): /* M2Tech Young MkIII */ case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */ case USB_ID(0x2622, 0x0041): /* Audiolab M-DAC+ */ + case USB_ID(0x278b, 0x5100): /* Rotel RC-1590 */ case USB_ID(0x27f7, 0x3002): /* W4S DAC-2v2SE */ case USB_ID(0x29a2, 0x0086): /* Mutec MC3+ USB */ case USB_ID(0x6b42, 0x0042): /* MSB Technology */ @@ -1902,9 +1908,6 @@ /* Amanero Combo384 USB based DACs with native DSD support */ case USB_ID(0x16d0, 0x071a): /* Amanero - Combo384 */ - case USB_ID(0x2ab6, 0x0004): /* T+A DAC8DSD-V2.0, MP1000E-V2.0, MP2000R-V2.0, MP2500R-V2.0, MP3100HV-V2.0 */ - case USB_ID(0x2ab6, 0x0005): /* T+A USB HD Audio 1 */ - case USB_ID(0x2ab6, 0x0006): /* T+A USB HD Audio 2 */ if (fp->altsetting == 2) { switch (le16_to_cpu(chip->dev->descriptor.bcdDevice)) { case 0x199: @@ -2011,6 +2014,9 @@ QUIRK_FLAG_IGNORE_CTL_ERROR), DEVICE_FLG(0x041e, 0x4080, /* Creative Live Cam VF0610 */ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x045e, 0x083c, /* MS USB Link headset */ + QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY | + QUIRK_FLAG_DISABLE_AUTOSUSPEND), DEVICE_FLG(0x046d, 0x084c, /* Logitech ConferenceCam Connect */ QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY_1M), DEVICE_FLG(0x046d, 0x0991, /* Logitech QuickCam Pro */ @@ -2046,6 +2052,9 @@ QUIRK_FLAG_IFACE_DELAY), DEVICE_FLG(0x0644, 0x805f, /* TEAC Model 12 */ QUIRK_FLAG_FORCE_IFACE_RESET), + DEVICE_FLG(0x0644, 0x806b, /* TEAC UD-701 */ + QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | + QUIRK_FLAG_IFACE_DELAY), DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */ QUIRK_FLAG_IGNORE_CTL_ERROR), DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */ @@ -2084,6 +2093,8 @@ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), DEVICE_FLG(0x154e, 0x3006, /* Marantz SA-14S1 */ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), + DEVICE_FLG(0x154e, 0x300b, /* Marantz SA-KI RUBY / SA-12 */ + QUIRK_FLAG_DSD_RAW), DEVICE_FLG(0x154e, 0x500e, /* Denon DN-X1600 */ QUIRK_FLAG_IGNORE_CLOCK_SOURCE), DEVICE_FLG(0x1686, 0x00dd, /* Zoom R16/24 */ @@ -2128,6 +2139,10 @@ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x21b4, 0x0081, /* AudioQuest DragonFly */ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x21b4, 0x0230, /* Ayre QB-9 Twenty */ + QUIRK_FLAG_DSD_RAW), + DEVICE_FLG(0x21b4, 0x0232, /* Ayre QX-5 Twenty */ + QUIRK_FLAG_DSD_RAW), DEVICE_FLG(0x2522, 0x0007, /* LH Labs Geek Out HD Audio 1V5 */ QUIRK_FLAG_SET_IFACE_FIRST), DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */ @@ -2170,12 +2185,18 @@ QUIRK_FLAG_VALIDATE_RATES), VENDOR_FLG(0x1235, /* Focusrite Novation */ QUIRK_FLAG_VALIDATE_RATES), + VENDOR_FLG(0x1511, /* AURALiC */ + QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x152a, /* Thesycon devices */ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x18d1, /* iBasso devices */ + QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x1de7, /* Phoenix Audio */ QUIRK_FLAG_GET_SAMPLE_RATE), VENDOR_FLG(0x20b1, /* XMOS based devices */ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x21ed, /* Accuphase Laboratory */ + QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x22d9, /* Oppo */ QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x23ba, /* Playback Design */ @@ -2191,10 +2212,14 @@ QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x2ab6, /* T+A devices */ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x2d87, /* Cayin device */ + QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x3336, /* HEM devices */ QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x3353, /* Khadas devices */ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x35f4, /* MSB Technology */ + QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x3842, /* EVGA */ QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0xc502, /* HiBy devices */ diff -u linux-6.2.0/tools/include/uapi/linux/bpf.h linux-6.2.0/tools/include/uapi/linux/bpf.h --- linux-6.2.0/tools/include/uapi/linux/bpf.h +++ linux-6.2.0/tools/include/uapi/linux/bpf.h @@ -1845,7 +1845,9 @@ * performed again, if the helper is used in combination with * direct packet access. * Return - * 0 on success, or a negative error in case of failure. + * 0 on success, or a negative error in case of failure. Positive + * error indicates a potential drop or congestion in the target + * device. The particular positive error codes are not defined. * * u64 bpf_get_current_pid_tgid(void) * Description @@ -3121,6 +3123,11 @@ * **BPF_FIB_LOOKUP_OUTPUT** * Perform lookup from an egress perspective (default is * ingress). + * **BPF_FIB_LOOKUP_SKIP_NEIGH** + * Skip the neighbour table lookup. *params*->dmac + * and *params*->smac will not be set as output. A common + * use case is to call **bpf_redirect_neigh**\ () after + * doing **bpf_fib_lookup**\ (). * * *ctx* is either **struct xdp_md** for XDP programs or * **struct sk_buff** tc cls_act programs. @@ -6734,6 +6741,7 @@ enum { BPF_FIB_LOOKUP_DIRECT = (1U << 0), BPF_FIB_LOOKUP_OUTPUT = (1U << 1), + BPF_FIB_LOOKUP_SKIP_NEIGH = (1U << 2), }; enum { diff -u linux-6.2.0/tools/lib/bpf/libbpf.c linux-6.2.0/tools/lib/bpf/libbpf.c --- linux-6.2.0/tools/lib/bpf/libbpf.c +++ linux-6.2.0/tools/lib/bpf/libbpf.c @@ -6116,7 +6116,11 @@ if (main_prog == subprog) return 0; relos = libbpf_reallocarray(main_prog->reloc_desc, new_cnt, sizeof(*relos)); - if (!relos) + /* if new count is zero, reallocarray can return a valid NULL result; + * in this case the previous pointer will be freed, so we *have to* + * reassign old pointer to the new value (even if it's NULL) + */ + if (!relos && new_cnt) return -ENOMEM; if (subprog->nr_reloc) memcpy(relos + main_prog->nr_reloc, subprog->reloc_desc, @@ -8223,6 +8227,7 @@ bpf_object__elf_finish(obj); bpf_object_unload(obj); btf__free(obj->btf); + btf__free(obj->btf_vmlinux); btf_ext__free(obj->btf_ext); for (i = 0; i < obj->nr_maps; i++) @@ -8399,7 +8404,8 @@ return -EBUSY; insns = libbpf_reallocarray(prog->insns, new_insn_cnt, sizeof(*insns)); - if (!insns) { + /* NULL is a valid return from reallocarray if the new count is zero */ + if (!insns && new_insn_cnt) { pr_warn("prog '%s': failed to realloc prog code\n", prog->name); return -ENOMEM; } @@ -8694,7 +8700,11 @@ /* try to shrink the array, but it's ok if we couldn't */ sec_defs = libbpf_reallocarray(custom_sec_defs, custom_sec_def_cnt, sizeof(*sec_defs)); - if (sec_defs) + /* if new count is zero, reallocarray can return a valid NULL result; + * in this case the previous pointer will be freed, so we *have to* + * reassign old pointer to the new value (even if it's NULL) + */ + if (sec_defs || custom_sec_def_cnt == 0) custom_sec_defs = sec_defs; return 0; diff -u linux-6.2.0/tools/perf/util/Build linux-6.2.0/tools/perf/util/Build --- linux-6.2.0/tools/perf/util/Build +++ linux-6.2.0/tools/perf/util/Build @@ -284,6 +284,12 @@ else bison_flags += -w endif + +BISON_LT_381 := $(shell expr $(shell $(BISON) --version | grep bison | sed -e 's/.\+ \([0-9]\+\).\([0-9]\+\).\([0-9]\+\)/\1\2\3/g') \< 381) +ifeq ($(BISON_LT_381),1) + bison_flags += -DYYNOMEM=YYABORT +endif + CFLAGS_parse-events-bison.o += $(bison_flags) CFLAGS_pmu-bison.o += -DYYLTYPE_IS_TRIVIAL=0 $(bison_flags) CFLAGS_expr-bison.o += -DYYLTYPE_IS_TRIVIAL=0 $(bison_flags) diff -u linux-6.2.0/tools/testing/selftests/kselftest/runner.sh linux-6.2.0/tools/testing/selftests/kselftest/runner.sh --- linux-6.2.0/tools/testing/selftests/kselftest/runner.sh +++ linux-6.2.0/tools/testing/selftests/kselftest/runner.sh @@ -35,7 +35,8 @@ { # Make sure tests will time out if utility is available. if [ -x /usr/bin/timeout ] && [ $kselftest_timeout -gt 0 ] ; then - /usr/bin/timeout --foreground "$kselftest_timeout" $1 + /usr/bin/timeout --foreground "$kselftest_timeout" \ + /usr/bin/timeout "$kselftest_timeout" $1 else $1 fi diff -u linux-6.2.0/tools/testing/selftests/lib.mk linux-6.2.0/tools/testing/selftests/lib.mk --- linux-6.2.0/tools/testing/selftests/lib.mk +++ linux-6.2.0/tools/testing/selftests/lib.mk @@ -72,7 +72,7 @@ run_tests: all ifdef building_out_of_srctree @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \ - rsync -aLq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \ + rsync -aq --copy-unsafe-links $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \ fi @if [ "X$(TEST_PROGS)" != "X" ]; then \ $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) \ @@ -86,7 +86,7 @@ define INSTALL_SINGLE_RULE $(if $(INSTALL_LIST),@mkdir -p $(INSTALL_PATH)) - $(if $(INSTALL_LIST),rsync -aL $(INSTALL_LIST) $(INSTALL_PATH)/) + $(if $(INSTALL_LIST),rsync -a --copy-unsafe-links $(INSTALL_LIST) $(INSTALL_PATH)/) endef define INSTALL_RULE diff -u linux-6.2.0/tools/testing/selftests/net/tls.c linux-6.2.0/tools/testing/selftests/net/tls.c --- linux-6.2.0/tools/testing/selftests/net/tls.c +++ linux-6.2.0/tools/testing/selftests/net/tls.c @@ -493,11 +493,11 @@ msg.msg_iov = &vec; msg.msg_iovlen = 1; - EXPECT_EQ(sendmsg(self->cfd, &msg, 0), send_len); + EXPECT_EQ(sendmsg(self->fd, &msg, 0), send_len); } while (recvs++ < sends) { - EXPECT_NE(recv(self->fd, mem, send_len, 0), -1); + EXPECT_NE(recv(self->cfd, mem, send_len, 0), -1); } free(mem); @@ -526,9 +526,9 @@ msg.msg_iov = vec; msg.msg_iovlen = iov_len; - EXPECT_EQ(sendmsg(self->cfd, &msg, 0), total_len); + EXPECT_EQ(sendmsg(self->fd, &msg, 0), total_len); buf = malloc(total_len); - EXPECT_NE(recv(self->fd, buf, total_len, 0), -1); + EXPECT_NE(recv(self->cfd, buf, total_len, 0), -1); for (i = 0; i < iov_len; i++) { EXPECT_EQ(memcmp(test_strs[i], buf + len_cmp, strlen(test_strs[i])), diff -u linux-6.2.0/tools/testing/selftests/netfilter/Makefile linux-6.2.0/tools/testing/selftests/netfilter/Makefile --- linux-6.2.0/tools/testing/selftests/netfilter/Makefile +++ linux-6.2.0/tools/testing/selftests/netfilter/Makefile @@ -7,12 +7,12 @@ nft_queue.sh nft_meta.sh nf_nat_edemux.sh \ ipip-conntrack-mtu.sh conntrack_tcp_unreplied.sh \ - conntrack_vrf.sh nft_synproxy.sh rpath.sh + conntrack_vrf.sh nft_synproxy.sh rpath.sh nft_audit.sh HOSTPKG_CONFIG := pkg-config CFLAGS += $(shell $(HOSTPKG_CONFIG) --cflags libmnl 2>/dev/null) LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl) -TEST_GEN_FILES = nf-queue connect_close +TEST_GEN_FILES = nf-queue connect_close audit_logread include ../lib.mk diff -u linux-6.2.0/tools/testing/selftests/resctrl/cache.c linux-6.2.0/tools/testing/selftests/resctrl/cache.c --- linux-6.2.0/tools/testing/selftests/resctrl/cache.c +++ linux-6.2.0/tools/testing/selftests/resctrl/cache.c @@ -89,21 +89,19 @@ static int get_llc_perf(unsigned long *llc_perf_miss) { __u64 total_misses; + int ret; /* Stop counters after one span to get miss rate */ ioctl(fd_lm, PERF_EVENT_IOC_DISABLE, 0); - if (read(fd_lm, &rf_cqm, sizeof(struct read_format)) == -1) { + ret = read(fd_lm, &rf_cqm, sizeof(struct read_format)); + if (ret == -1) { perror("Could not get llc misses through perf"); - return -1; } total_misses = rf_cqm.values[0].value; - - close(fd_lm); - *llc_perf_miss = total_misses; return 0; @@ -258,19 +256,25 @@ memflush, operation, resctrl_val)) { fprintf(stderr, "Error-running fill buffer\n"); ret = -1; - break; + goto pe_close; } sleep(1); ret = measure_cache_vals(param, bm_pid); if (ret) - break; + goto pe_close; + + close(fd_lm); } else { break; } } return ret; + +pe_close: + close(fd_lm); + return ret; } /* diff -u linux-6.2.0/tools/testing/selftests/resctrl/fill_buf.c linux-6.2.0/tools/testing/selftests/resctrl/fill_buf.c --- linux-6.2.0/tools/testing/selftests/resctrl/fill_buf.c +++ linux-6.2.0/tools/testing/selftests/resctrl/fill_buf.c @@ -184,12 +184,13 @@ else ret = fill_cache_write(start_ptr, end_ptr, resctrl_val); + free(startptr); + if (ret) { printf("\n Error in fill cache read/write...\n"); return -1; } - free(startptr); return 0; } diff -u linux-6.2.0/tools/testing/selftests/resctrl/resctrl.h linux-6.2.0/tools/testing/selftests/resctrl/resctrl.h --- linux-6.2.0/tools/testing/selftests/resctrl/resctrl.h +++ linux-6.2.0/tools/testing/selftests/resctrl/resctrl.h @@ -43,6 +43,7 @@ do { \ perror(err_msg); \ kill(ppid, SIGKILL); \ + umount_resctrlfs(); \ exit(EXIT_FAILURE); \ } while (0) diff -u linux-6.2.0/update-dkms-versions linux-6.2.0/update-dkms-versions --- linux-6.2.0/update-dkms-versions +++ linux-6.2.0/update-dkms-versions @@ -104,15 +104,13 @@ (cd "$kv_repo" && git cat-file "$@") || exit 1 } -# Determine if this is merge format (main branch exists). -present=$(cat_file -t "$remote_name/main" 2>/dev/null) +present=$(cat_file -t "$remote_name/$remote_branch:devel/" 2>/dev/null) if [ "$present" ]; then - git_base="$remote_name/$remote_branch:$sru_cycle/" - git_base_devel="$remote_name/$remote_branch:tip/" + git_base_devel="$remote_name/$remote_branch:devel/" else - git_base="$remote_name/$sru_cycle:" - git_base_devel="$remote_name/master:" + git_base_devel="$remote_name/$remote_branch:tip/" fi +git_base="$remote_name/$remote_branch:$sru_cycle/" git_human="$remote_name/$sru_cycle" # Determine if we have this cycle. @@ -155,6 +153,7 @@ # mainline - backwards compatibility for versions_path_tail in \ "$our_series:$our_source:$our_type" \ + "$our_series:$our_mainline:$our_type" \ "$our_series:$our_type" \ "$our_mainline:$our_type" \ "$our_series" \ only in patch2: unchanged: --- linux-6.2.0.orig/Documentation/ABI/testing/sysfs-bus-fsi-devices-sbefifo +++ linux-6.2.0/Documentation/ABI/testing/sysfs-bus-fsi-devices-sbefifo @@ -5,6 +5,6 @@ Indicates whether or not this SBE device has experienced a timeout; i.e. the SBE did not respond within the time allotted by the driver. A value of 1 indicates that a timeout has - ocurred and no transfers have completed since the timeout. A - value of 0 indicates that no timeout has ocurred, or if one - has, more recent transfers have completed successful. + occurred and no transfers have completed since the timeout. A + value of 0 indicates that no timeout has occurred, or if one + has, more recent transfers have completed successfully. only in patch2: unchanged: --- linux-6.2.0.orig/Documentation/ABI/testing/sysfs-driver-chromeos-acpi +++ linux-6.2.0/Documentation/ABI/testing/sysfs-driver-chromeos-acpi @@ -134,4 +134,4 @@ Description: Returns the verified boot data block shared between the firmware verification step and the kernel verification step - (binary). + (hex dump). only in patch2: unchanged: --- linux-6.2.0.orig/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml +++ linux-6.2.0/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml @@ -16,8 +16,6 @@ reads required input clock frequencies from the devicetree and acts as clock provider for all clock consumers of PS clocks. -select: false - properties: compatible: const: xlnx,versal-clk only in patch2: unchanged: --- linux-6.2.0.orig/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml +++ linux-6.2.0/Documentation/devicetree/bindings/extcon/maxim,max77843.yaml @@ -23,6 +23,7 @@ connector: $ref: /schemas/connector/usb-connector.yaml# + unevaluatedProperties: false ports: $ref: /schemas/graph.yaml#/properties/ports only in patch2: unchanged: --- linux-6.2.0.orig/Documentation/mm/multigen_lru.rst +++ linux-6.2.0/Documentation/mm/multigen_lru.rst @@ -89,15 +89,15 @@ Generation numbers are truncated into ``order_base_2(MAX_NR_GENS+1)`` bits in order to fit into the gen counter in ``folio->flags``. Each -truncated generation number is an index to ``lrugen->lists[]``. The +truncated generation number is an index to ``lrugen->folios[]``. The sliding window technique is used to track at least ``MIN_NR_GENS`` and at most ``MAX_NR_GENS`` generations. The gen counter stores a value within ``[1, MAX_NR_GENS]`` while a page is on one of -``lrugen->lists[]``; otherwise it stores zero. +``lrugen->folios[]``; otherwise it stores zero. Each generation is divided into multiple tiers. A page accessed ``N`` times through file descriptors is in tier ``order_base_2(N)``. Unlike -generations, tiers do not have dedicated ``lrugen->lists[]``. In +generations, tiers do not have dedicated ``lrugen->folios[]``. In contrast to moving across generations, which requires the LRU lock, moving across tiers only involves atomic operations on ``folio->flags`` and therefore has a negligible cost. A feedback loop @@ -127,7 +127,7 @@ Eviction -------- The eviction consumes old generations. Given an ``lruvec``, it -increments ``min_seq`` when ``lrugen->lists[]`` indexed by +increments ``min_seq`` when ``lrugen->folios[]`` indexed by ``min_seq%MAX_NR_GENS`` becomes empty. To select a type and a tier to evict from, it first compares ``min_seq[]`` to select the older type. If both types are equally old, it selects the one whose first tier has only in patch2: unchanged: --- linux-6.2.0.orig/Documentation/scsi/scsi_mid_low_api.rst +++ linux-6.2.0/Documentation/scsi/scsi_mid_low_api.rst @@ -1190,11 +1190,11 @@ - pointer to scsi_device object that this command is associated with. resid - - an LLD should set this signed integer to the requested + - an LLD should set this unsigned integer to the requested transfer length (i.e. 'request_bufflen') less the number of bytes that are actually transferred. 'resid' is preset to 0 so an LLD can ignore it if it cannot detect - underruns (overruns should be rare). If possible an LLD + underruns (overruns should not be reported). An LLD should set 'resid' prior to invoking 'done'. The most interesting case is data transfers from a SCSI target device (e.g. READs) that underrun. only in patch2: unchanged: --- linux-6.2.0.orig/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst +++ linux-6.2.0/Documentation/userspace-api/media/v4l/ext-ctrls-codec-stateless.rst @@ -2923,6 +2923,13 @@ - ``poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` - PocLtCurr as described in section 8.3.2 "Decoding process for reference picture set": provides the index of the long term references in DPB array. + * - __u8 + - ``num_delta_pocs_of_ref_rps_idx`` + - When the short_term_ref_pic_set_sps_flag in the slice header is equal to 0, + it is the same as the derived value NumDeltaPocs[RefRpsIdx]. It can be used to parse + the RPS data in slice headers instead of skipping it with @short_term_ref_pic_set_size. + When the value of short_term_ref_pic_set_sps_flag in the slice header is + equal to 1, num_delta_pocs_of_ref_rps_idx shall be set to 0. * - struct :c:type:`v4l2_hevc_dpb_entry` - ``dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]`` - The decoded picture buffer, for meta-data about reference frames. only in patch2: unchanged: --- linux-6.2.0.orig/arch/arc/include/asm/atomic-llsc.h +++ linux-6.2.0/arch/arc/include/asm/atomic-llsc.h @@ -18,7 +18,7 @@ : [val] "=&r" (val) /* Early clobber to prevent reg reuse */ \ : [ctr] "r" (&v->counter), /* Not "m": llock only supports reg direct addr mode */ \ [i] "ir" (i) \ - : "cc"); \ + : "cc", "memory"); \ } \ #define ATOMIC_OP_RETURN(op, asm_op) \ @@ -34,7 +34,7 @@ : [val] "=&r" (val) \ : [ctr] "r" (&v->counter), \ [i] "ir" (i) \ - : "cc"); \ + : "cc", "memory"); \ \ return val; \ } @@ -56,7 +56,7 @@ [orig] "=&r" (orig) \ : [ctr] "r" (&v->counter), \ [i] "ir" (i) \ - : "cc"); \ + : "cc", "memory"); \ \ return orig; \ } only in patch2: unchanged: --- linux-6.2.0.orig/arch/arc/include/asm/atomic64-arcv2.h +++ linux-6.2.0/arch/arc/include/asm/atomic64-arcv2.h @@ -60,7 +60,7 @@ " bnz 1b \n" \ : "=&r"(val) \ : "r"(&v->counter), "ir"(a) \ - : "cc"); \ + : "cc", "memory"); \ } \ #define ATOMIC64_OP_RETURN(op, op1, op2) \ @@ -77,7 +77,7 @@ " bnz 1b \n" \ : [val] "=&r"(val) \ : "r"(&v->counter), "ir"(a) \ - : "cc"); /* memory clobber comes from smp_mb() */ \ + : "cc", "memory"); \ \ return val; \ } @@ -99,7 +99,7 @@ " bnz 1b \n" \ : "=&r"(orig), "=&r"(val) \ : "r"(&v->counter), "ir"(a) \ - : "cc"); /* memory clobber comes from smp_mb() */ \ + : "cc", "memory"); \ \ return orig; \ } only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/Makefile +++ linux-6.2.0/arch/arm/boot/dts/Makefile @@ -333,6 +333,7 @@ kirkwood-iconnect.dtb \ kirkwood-iomega_ix2_200.dtb \ kirkwood-is2.dtb \ + kirkwood-km_fixedeth.dtb \ kirkwood-km_kirkwood.dtb \ kirkwood-l-50.dtb \ kirkwood-laplug.dtb \ @@ -865,7 +866,10 @@ am3517-craneboard.dtb \ am3517-evm.dtb \ am3517_mt_ventoux.dtb \ + logicpd-torpedo-35xx-devkit.dtb \ logicpd-torpedo-37xx-devkit.dtb \ + logicpd-torpedo-37xx-devkit-28.dtb \ + logicpd-som-lv-35xx-devkit.dtb \ logicpd-som-lv-37xx-devkit.dtb \ omap3430-sdp.dtb \ omap3-beagle.dtb \ @@ -1537,6 +1541,8 @@ armada-388-helios4.dtb \ armada-388-rd.dtb dtb-$(CONFIG_MACH_ARMADA_39X) += \ + armada-390-db.dtb \ + armada-395-gp.dtb \ armada-398-db.dtb dtb-$(CONFIG_MACH_ARMADA_XP) += \ armada-xp-axpwifiap.dtb \ @@ -1566,6 +1572,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt2701-evb.dtb \ mt6580-evbp1.dtb \ + mt6582-prestigio-pmt5008-3g.dtb \ mt6589-aquaris5.dtb \ mt6589-fairphone-fp1.dtb \ mt6592-evb.dtb \ @@ -1620,6 +1627,7 @@ aspeed-bmc-intel-s2600wf.dtb \ aspeed-bmc-inspur-fp5280g2.dtb \ aspeed-bmc-inspur-nf5280m6.dtb \ + aspeed-bmc-inspur-on5263m5.dtb \ aspeed-bmc-lenovo-hr630.dtb \ aspeed-bmc-lenovo-hr855xg2.dtb \ aspeed-bmc-microsoft-olympus.dtb \ only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts +++ linux-6.2.0/arch/arm/boot/dts/bcm4708-linksys-ea6500-v2.dts @@ -19,7 +19,8 @@ memory@0 { device_type = "memory"; - reg = <0x00000000 0x08000000>; + reg = <0x00000000 0x08000000>, + <0x88000000 0x08000000>; }; gpio-keys { only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts +++ linux-6.2.0/arch/arm/boot/dts/bcm47189-luxul-xap-1440.dts @@ -46,3 +46,16 @@ }; }; }; + +&gmac0 { + phy-mode = "rgmii"; + phy-handle = <&bcm54210e>; + + mdio { + /delete-node/ switch@1e; + + bcm54210e: ethernet-phy@0 { + reg = <0>; + }; + }; +}; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts +++ linux-6.2.0/arch/arm/boot/dts/bcm47189-luxul-xap-810.dts @@ -83,3 +83,16 @@ }; }; }; + +&gmac0 { + phy-mode = "rgmii"; + phy-handle = <&bcm54210e>; + + mdio { + /delete-node/ switch@1e; + + bcm54210e: ethernet-phy@0 { + reg = <0>; + }; + }; +}; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/bcm47189-tenda-ac9.dts +++ linux-6.2.0/arch/arm/boot/dts/bcm47189-tenda-ac9.dts @@ -135,8 +135,8 @@ label = "lan4"; }; - port@5 { - reg = <5>; + port@8 { + reg = <8>; label = "cpu"; ethernet = <&gmac0>; }; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/bcm53573.dtsi +++ linux-6.2.0/arch/arm/boot/dts/bcm53573.dtsi @@ -127,6 +127,9 @@ pcie0: pcie@2000 { reg = <0x00002000 0x1000>; + + #address-cells = <3>; + #size-cells = <2>; }; usb2: usb2@4000 { @@ -156,8 +159,6 @@ }; ohci: usb@d000 { - #usb-cells = <0>; - compatible = "generic-ohci"; reg = <0xd000 0x1000>; interrupt-parent = <&gic>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/bcm947189acdbmr.dts +++ linux-6.2.0/arch/arm/boot/dts/bcm947189acdbmr.dts @@ -60,9 +60,9 @@ spi { compatible = "spi-gpio"; num-chipselects = <1>; - gpio-sck = <&chipcommon 21 0>; - gpio-miso = <&chipcommon 22 0>; - gpio-mosi = <&chipcommon 23 0>; + sck-gpios = <&chipcommon 21 0>; + miso-gpios = <&chipcommon 22 0>; + mosi-gpios = <&chipcommon 23 0>; cs-gpios = <&chipcommon 24 0>; #address-cells = <1>; #size-cells = <0>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/exynos4210-i9100.dts +++ linux-6.2.0/arch/arm/boot/dts/exynos4210-i9100.dts @@ -201,8 +201,8 @@ power-on-delay = <10>; reset-delay = <10>; - panel-width-mm = <90>; - panel-height-mm = <154>; + panel-width-mm = <56>; + panel-height-mm = <93>; display-timings { timing { only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/motorola-mapphone-common.dtsi +++ linux-6.2.0/arch/arm/boot/dts/motorola-mapphone-common.dtsi @@ -352,13 +352,13 @@ &omap4_pmx_core { /* hdmi_hpd.gpio_63 */ - hdmi_hpd_gpio: pinmux_hdmi_hpd_pins { + hdmi_hpd_gpio: hdmi-hpd-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x098, PIN_INPUT | MUX_MODE3) >; }; - hdq_pins: pinmux_hdq_pins { + hdq_pins: hdq-pins { pinctrl-single,pins = < /* 0x4a100120 hdq_sio.hdq_sio aa27 */ OMAP4_IOPAD(0x120, PIN_INPUT | MUX_MODE0) @@ -366,7 +366,7 @@ }; /* hdmi_cec.hdmi_cec, hdmi_scl.hdmi_scl, hdmi_sda.hdmi_sda */ - dss_hdmi_pins: pinmux_dss_hdmi_pins { + dss_hdmi_pins: dss-hdmi-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) OMAP4_IOPAD(0x09c, PIN_INPUT | MUX_MODE0) @@ -380,7 +380,7 @@ * devices. Off mode value should be tested if we have off mode working * later on. */ - mmc3_pins: pinmux_mmc3_pins { + mmc3_pins: mmc3-pins { pinctrl-single,pins = < /* 0x4a10008e gpmc_wait2.gpio_100 d23 */ OMAP4_IOPAD(0x08e, PIN_INPUT | MUX_MODE3) @@ -406,40 +406,40 @@ }; /* gpmc_ncs0.gpio_50 */ - poweroff_gpio: pinmux_poweroff_pins { + poweroff_gpio: poweroff-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x074, PIN_OUTPUT_PULLUP | MUX_MODE3) >; }; /* kpd_row0.gpio_178 */ - tmp105_irq: pinmux_tmp105_irq { + tmp105_irq: tmp105-irq-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x18e, PIN_INPUT_PULLUP | MUX_MODE3) >; }; - usb_gpio_mux_sel1: pinmux_usb_gpio_mux_sel1_pins { + usb_gpio_mux_sel1: usb-gpio-mux-sel1-pins { /* gpio_60 */ pinctrl-single,pins = < OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3) >; }; - touchscreen_pins: pinmux_touchscreen_pins { + touchscreen_pins: touchscreen-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x180, PIN_OUTPUT | MUX_MODE3) OMAP4_IOPAD(0x1a0, PIN_INPUT_PULLUP | MUX_MODE3) >; }; - als_proximity_pins: pinmux_als_proximity_pins { + als_proximity_pins: als-proximity-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x18c, PIN_INPUT_PULLUP | MUX_MODE3) >; }; - usb_mdm6600_pins: pinmux_usb_mdm6600_pins { + usb_mdm6600_pins: usb-mdm6600-pins { pinctrl-single,pins = < /* enable 0x4a1000d8 usbb1_ulpitll_dat7.gpio_95 ag16 */ OMAP4_IOPAD(0x0d8, PIN_INPUT | MUX_MODE3) @@ -476,7 +476,7 @@ >; }; - usb_ulpi_pins: pinmux_usb_ulpi_pins { + usb_ulpi_pins: usb-ulpi-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x196, MUX_MODE7) OMAP4_IOPAD(0x198, MUX_MODE7) @@ -496,7 +496,7 @@ }; /* usb0_otg_dp and usb0_otg_dm */ - usb_utmi_pins: pinmux_usb_utmi_pins { + usb_utmi_pins: usb-utmi-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x196, PIN_INPUT | MUX_MODE0) OMAP4_IOPAD(0x198, PIN_INPUT | MUX_MODE0) @@ -521,7 +521,7 @@ * when not used. If needed, we can add rts pin remux later based * on power measurements. */ - uart1_pins: pinmux_uart1_pins { + uart1_pins: uart1-pins { pinctrl-single,pins = < /* 0x4a10013c mcspi1_cs2.uart1_cts ag23 */ OMAP4_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE1) @@ -538,7 +538,7 @@ }; /* uart3_tx_irtx and uart3_rx_irrx */ - uart3_pins: pinmux_uart3_pins { + uart3_pins: uart3-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x196, MUX_MODE7) OMAP4_IOPAD(0x198, MUX_MODE7) @@ -557,7 +557,7 @@ >; }; - uart4_pins: pinmux_uart4_pins { + uart4_pins: uart4-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x15c, PIN_INPUT | MUX_MODE0) /* uart4_rx */ OMAP4_IOPAD(0x15e, PIN_OUTPUT | MUX_MODE0) /* uart4_tx */ @@ -566,7 +566,7 @@ >; }; - mcbsp2_pins: pinmux_mcbsp2_pins { + mcbsp2_pins: mcbsp2-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE0) /* abe_mcbsp2_clkx */ OMAP4_IOPAD(0x0f8, PIN_INPUT | MUX_MODE0) /* abe_mcbsp2_dr */ @@ -575,7 +575,7 @@ >; }; - mcbsp3_pins: pinmux_mcbsp3_pins { + mcbsp3_pins: mcbsp3-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x106, PIN_INPUT | MUX_MODE1) /* abe_mcbsp3_dr */ OMAP4_IOPAD(0x108, PIN_OUTPUT | MUX_MODE1) /* abe_mcbsp3_dx */ @@ -584,13 +584,13 @@ >; }; - vibrator_direction_pin: pinmux_vibrator_direction_pin { + vibrator_direction_pin: vibrator-direction-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x1ce, PIN_OUTPUT | MUX_MODE1) /* dmtimer8_pwm_evt (gpio_27) */ >; }; - vibrator_enable_pin: pinmux_vibrator_enable_pin { + vibrator_enable_pin: vibrator-enable-pins { pinctrl-single,pins = < OMAP4_IOPAD(0X1d0, PIN_OUTPUT | MUX_MODE1) /* dmtimer9_pwm_evt (gpio_28) */ >; @@ -598,7 +598,7 @@ }; &omap4_pmx_wkup { - usb_gpio_mux_sel2: pinmux_usb_gpio_mux_sel2_pins { + usb_gpio_mux_sel2: usb-gpio-mux-sel2-pins { /* gpio_wk0 */ pinctrl-single,pins = < OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3) @@ -614,12 +614,12 @@ /* Configure pwm clock source for timers 8 & 9 */ &timer8 { assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>; - assigned-clock-parents = <&sys_clkin_ck>; + assigned-clock-parents = <&sys_32k_ck>; }; &timer9 { assigned-clocks = <&l4_per_clkctrl OMAP4_TIMER9_CLKCTRL 24>; - assigned-clock-parents = <&sys_clkin_ck>; + assigned-clock-parents = <&sys_32k_ck>; }; /* only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap3-cpu-thermal.dtsi +++ linux-6.2.0/arch/arm/boot/dts/omap3-cpu-thermal.dtsi @@ -12,8 +12,7 @@ polling-delay = <1000>; /* milliseconds */ coefficients = <0 20000>; - /* sensor ID */ - thermal-sensors = <&bandgap 0>; + thermal-sensors = <&bandgap>; cpu_trips: trips { cpu_alert0: cpu_alert { only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4-cpu-thermal.dtsi +++ linux-6.2.0/arch/arm/boot/dts/omap4-cpu-thermal.dtsi @@ -12,7 +12,10 @@ polling-delay-passive = <250>; /* milliseconds */ polling-delay = <1000>; /* milliseconds */ - /* sensor ID */ + /* + * See 44xx files for single sensor addressing, omap5 and dra7 need + * also sensor ID for addressing. + */ thermal-sensors = <&bandgap 0>; cpu_trips: trips { only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4-duovero-parlor.dts +++ linux-6.2.0/arch/arm/boot/dts/omap4-duovero-parlor.dts @@ -62,33 +62,33 @@ &smsc_pins >; - led_pins: pinmux_led_pins { + led_pins: led-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x116, PIN_OUTPUT | MUX_MODE3) /* abe_dmic_din3.gpio_122 */ >; }; - button_pins: pinmux_button_pins { + button_pins: button-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x114, PIN_INPUT_PULLUP | MUX_MODE3) /* abe_dmic_din2.gpio_121 */ >; }; - i2c2_pins: pinmux_i2c2_pins { + i2c2_pins: i2c2-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */ OMAP4_IOPAD(0x128, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */ >; }; - i2c3_pins: pinmux_i2c3_pins { + i2c3_pins: i2c3-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ >; }; - smsc_pins: pinmux_smsc_pins { + smsc_pins: smsc-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x068, PIN_INPUT | MUX_MODE3) /* gpmc_a20.gpio_44: IRQ */ OMAP4_IOPAD(0x06a, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a21.gpio_45: nReset */ @@ -96,7 +96,7 @@ >; }; - dss_hdmi_pins: pinmux_dss_hdmi_pins { + dss_hdmi_pins: dss-hdmi-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x098, PIN_INPUT | MUX_MODE3) /* hdmi_hpd.gpio_63 */ OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4-duovero.dtsi +++ linux-6.2.0/arch/arm/boot/dts/omap4-duovero.dtsi @@ -73,14 +73,14 @@ &hsusbb1_pins >; - twl6040_pins: pinmux_twl6040_pins { + twl6040_pins: twl6040-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x166, PIN_OUTPUT | MUX_MODE3) /* usbb2_ulpitll_nxt.gpio_160 */ OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */ >; }; - mcbsp1_pins: pinmux_mcbsp1_pins { + mcbsp1_pins: mcbsp1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0fe, PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */ OMAP4_IOPAD(0x100, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dr.abe_mcbsp1_dr */ @@ -89,7 +89,7 @@ >; }; - hsusbb1_pins: pinmux_hsusbb1_pins { + hsusbb1_pins: hsusbb1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0c2, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */ OMAP4_IOPAD(0x0c4, PIN_OUTPUT | MUX_MODE4) /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */ @@ -106,34 +106,34 @@ >; }; - hsusb1phy_pins: pinmux_hsusb1phy_pins { + hsusb1phy_pins: hsusb1phy-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x08c, PIN_OUTPUT | MUX_MODE3) /* gpmc_wait1.gpio_62 */ >; }; - w2cbw0015_pins: pinmux_w2cbw0015_pins { + w2cbw0015_pins: w2cbw0015-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3) /* gpmc_a19.gpio_43 */ OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */ >; }; - i2c1_pins: pinmux_i2c1_pins { + i2c1_pins: i2c1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ >; }; - i2c4_pins: pinmux_i2c4_pins { + i2c4_pins: i2c4-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */ OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */ >; }; - mmc1_pins: pinmux_mmc1_pins { + mmc1_pins: mmc1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0e2, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */ OMAP4_IOPAD(0x0e4, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmcc1_cmd */ @@ -144,7 +144,7 @@ >; }; - mmc5_pins: pinmux_mmc5_pins { + mmc5_pins: mmc5-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk */ OMAP4_IOPAD(0x14a, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmcc5_cmd */ only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4-kc1.dts +++ linux-6.2.0/arch/arm/boot/dts/omap4-kc1.dts @@ -35,42 +35,42 @@ &omap4_pmx_core { pinctrl-names = "default"; - uart3_pins: pinmux_uart3_pins { + uart3_pins: uart3-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x144, PIN_INPUT | MUX_MODE0) /* uart3_rx_irrx */ OMAP4_IOPAD(0x146, PIN_OUTPUT | MUX_MODE0) /* uart3_tx_irtx */ >; }; - i2c1_pins: pinmux_i2c1_pins { + i2c1_pins: i2c1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ >; }; - i2c2_pins: pinmux_i2c2_pins { + i2c2_pins: i2c2-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */ OMAP4_IOPAD(0x128, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */ >; }; - i2c3_pins: pinmux_i2c3_pins { + i2c3_pins: i2c3-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ >; }; - i2c4_pins: pinmux_i2c4_pins { + i2c4_pins: i2c4-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */ OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */ >; }; - mmc2_pins: pinmux_mmc2_pins { + mmc2_pins: mmc2-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x040, PIN_INPUT_PULLUP | MUX_MODE1) /* sdmmc2_dat0 */ OMAP4_IOPAD(0x042, PIN_INPUT_PULLUP | MUX_MODE1) /* sdmmc2_dat1 */ @@ -85,7 +85,7 @@ >; }; - usb_otg_hs_pins: pinmux_usb_otg_hs_pins { + usb_otg_hs_pins: usb-otg-hs-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x194, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* usba0_otg_ce */ OMAP4_IOPAD(0x196, PIN_INPUT | MUX_MODE0) /* usba0_otg_dp */ only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4-mcpdm.dtsi +++ linux-6.2.0/arch/arm/boot/dts/omap4-mcpdm.dtsi @@ -7,7 +7,7 @@ */ &omap4_pmx_core { - mcpdm_pins: pinmux_mcpdm_pins { + mcpdm_pins: mcpdm-pins { pinctrl-single,pins = < /* 0x4a100106 abe_pdm_ul_data.abe_pdm_ul_data ag25 */ OMAP4_IOPAD(0x106, PIN_INPUT_PULLDOWN | MUX_MODE0) only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4-panda-common.dtsi +++ linux-6.2.0/arch/arm/boot/dts/omap4-panda-common.dtsi @@ -237,14 +237,14 @@ &hsusbb1_pins >; - twl6040_pins: pinmux_twl6040_pins { + twl6040_pins: twl6040-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x120, PIN_OUTPUT | MUX_MODE3) /* hdq_sio.gpio_127 */ OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */ >; }; - mcbsp1_pins: pinmux_mcbsp1_pins { + mcbsp1_pins: mcbsp1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0fe, PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */ OMAP4_IOPAD(0x100, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dr.abe_mcbsp1_dr */ @@ -253,7 +253,7 @@ >; }; - dss_dpi_pins: pinmux_dss_dpi_pins { + dss_dpi_pins: dss-dpi-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x162, PIN_OUTPUT | MUX_MODE5) /* dispc2_data23 */ OMAP4_IOPAD(0x164, PIN_OUTPUT | MUX_MODE5) /* dispc2_data22 */ @@ -288,13 +288,13 @@ >; }; - tfp410_pins: pinmux_tfp410_pins { + tfp410_pins: tfp410-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x184, PIN_OUTPUT | MUX_MODE3) /* gpio_0 */ >; }; - dss_hdmi_pins: pinmux_dss_hdmi_pins { + dss_hdmi_pins: dss-hdmi-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ @@ -302,7 +302,7 @@ >; }; - tpd12s015_pins: pinmux_tpd12s015_pins { + tpd12s015_pins: tpd12s015-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x062, PIN_OUTPUT | MUX_MODE3) /* gpmc_a17.gpio_41 */ OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3) /* gpmc_nbe1.gpio_60 */ @@ -310,7 +310,7 @@ >; }; - hsusbb1_pins: pinmux_hsusbb1_pins { + hsusbb1_pins: hsusbb1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0c2, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */ OMAP4_IOPAD(0x0c4, PIN_OUTPUT | MUX_MODE4) /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */ @@ -327,28 +327,28 @@ >; }; - i2c1_pins: pinmux_i2c1_pins { + i2c1_pins: i2c1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ >; }; - i2c2_pins: pinmux_i2c2_pins { + i2c2_pins: i2c2-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */ OMAP4_IOPAD(0x128, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */ >; }; - i2c3_pins: pinmux_i2c3_pins { + i2c3_pins: i2c3-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ >; }; - i2c4_pins: pinmux_i2c4_pins { + i2c4_pins: i2c4-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */ OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */ @@ -359,7 +359,7 @@ * wl12xx GPIO outputs for WLAN_EN, BT_EN, FM_EN, BT_WAKEUP * REVISIT: Are the pull-ups needed for GPIO 48 and 49? */ - wl12xx_gpio: pinmux_wl12xx_gpio { + wl12xx_gpio: wl12xx-gpio-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x066, PIN_OUTPUT | MUX_MODE3) /* gpmc_a19.gpio_43 */ OMAP4_IOPAD(0x06c, PIN_OUTPUT | MUX_MODE3) /* gpmc_a22.gpio_46 */ @@ -369,7 +369,7 @@ }; /* wl12xx GPIO inputs and SDIO pins */ - wl12xx_pins: pinmux_wl12xx_pins { + wl12xx_pins: wl12xx-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x078, PIN_INPUT | MUX_MODE3) /* gpmc_ncs2.gpio_52 */ OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */ @@ -382,7 +382,7 @@ >; }; - button_pins: pinmux_button_pins { + button_pins: button-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x114, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_121 */ >; @@ -390,7 +390,7 @@ }; &omap4_pmx_wkup { - led_wkgpio_pins: pinmux_leds_wkpins { + led_wkgpio_pins: leds-wkpins-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x05a, PIN_OUTPUT | MUX_MODE3) /* gpio_wk7 */ OMAP4_IOPAD(0x05c, PIN_OUTPUT | MUX_MODE3) /* gpio_wk8 */ only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4-panda-es.dts +++ linux-6.2.0/arch/arm/boot/dts/omap4-panda-es.dts @@ -38,26 +38,26 @@ }; &omap4_pmx_core { - led_gpio_pins: gpio_led_pmx { + led_gpio_pins: gpio-led-pmx-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0f6, PIN_OUTPUT | MUX_MODE3) /* gpio_110 */ >; }; - button_pins: pinmux_button_pins { + button_pins: button-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0fc, PIN_INPUT_PULLUP | MUX_MODE3) /* gpio_113 */ >; }; - bt_pins: pinmux_bt_pins { + bt_pins: bt-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x06c, PIN_OUTPUT | MUX_MODE3) /* gpmc_a22.gpio_46 - BTEN */ OMAP4_IOPAD(0x072, PIN_OUTPUT_PULLUP | MUX_MODE3) /* gpmc_a25.gpio_49 - BTWAKEUP */ >; }; - uart2_pins: pinmux_uart2_pins { + uart2_pins: uart2-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x118, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts - HCI */ OMAP4_IOPAD(0x11a, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4-sdp.dts +++ linux-6.2.0/arch/arm/boot/dts/omap4-sdp.dts @@ -214,7 +214,7 @@ &tpd12s015_pins >; - uart2_pins: pinmux_uart2_pins { + uart2_pins: uart2-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x118, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */ OMAP4_IOPAD(0x11a, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ @@ -223,7 +223,7 @@ >; }; - uart3_pins: pinmux_uart3_pins { + uart3_pins: uart3-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x140, PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */ OMAP4_IOPAD(0x142, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */ @@ -232,21 +232,21 @@ >; }; - uart4_pins: pinmux_uart4_pins { + uart4_pins: uart4-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x15c, PIN_INPUT | MUX_MODE0) /* uart4_rx.uart4_rx */ OMAP4_IOPAD(0x15e, PIN_OUTPUT | MUX_MODE0) /* uart4_tx.uart4_tx */ >; }; - twl6040_pins: pinmux_twl6040_pins { + twl6040_pins: twl6040-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x120, PIN_OUTPUT | MUX_MODE3) /* hdq_sio.gpio_127 */ OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */ >; }; - dmic_pins: pinmux_dmic_pins { + dmic_pins: dmic-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x110, PIN_OUTPUT | MUX_MODE0) /* abe_dmic_clk1.abe_dmic_clk1 */ OMAP4_IOPAD(0x112, PIN_INPUT | MUX_MODE0) /* abe_dmic_din1.abe_dmic_din1 */ @@ -255,7 +255,7 @@ >; }; - mcbsp1_pins: pinmux_mcbsp1_pins { + mcbsp1_pins: mcbsp1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0fe, PIN_INPUT | MUX_MODE0) /* abe_mcbsp1_clkx.abe_mcbsp1_clkx */ OMAP4_IOPAD(0x100, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp1_dr.abe_mcbsp1_dr */ @@ -264,7 +264,7 @@ >; }; - mcbsp2_pins: pinmux_mcbsp2_pins { + mcbsp2_pins: mcbsp2-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE0) /* abe_mcbsp2_clkx.abe_mcbsp2_clkx */ OMAP4_IOPAD(0x0f8, PIN_INPUT_PULLDOWN | MUX_MODE0) /* abe_mcbsp2_dr.abe_mcbsp2_dr */ @@ -273,7 +273,7 @@ >; }; - mcspi1_pins: pinmux_mcspi1_pins { + mcspi1_pins: mcspi1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x132, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */ OMAP4_IOPAD(0x134, PIN_INPUT | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */ @@ -282,7 +282,7 @@ >; }; - dss_hdmi_pins: pinmux_dss_hdmi_pins { + dss_hdmi_pins: dss-hdmi-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ @@ -290,7 +290,7 @@ >; }; - tpd12s015_pins: pinmux_tpd12s015_pins { + tpd12s015_pins: tpd12s015-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x062, PIN_OUTPUT | MUX_MODE3) /* gpmc_a17.gpio_41 */ OMAP4_IOPAD(0x088, PIN_OUTPUT | MUX_MODE3) /* gpmc_nbe1.gpio_60 */ @@ -298,28 +298,28 @@ >; }; - i2c1_pins: pinmux_i2c1_pins { + i2c1_pins: i2c1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ >; }; - i2c2_pins: pinmux_i2c2_pins { + i2c2_pins: i2c2-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x126, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_scl */ OMAP4_IOPAD(0x128, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c2_sda */ >; }; - i2c3_pins: pinmux_i2c3_pins { + i2c3_pins: i2c3-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ >; }; - i2c4_pins: pinmux_i2c4_pins { + i2c4_pins: i2c4-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */ OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */ @@ -327,14 +327,14 @@ }; /* wl12xx GPIO output for WLAN_EN */ - wl12xx_gpio: pinmux_wl12xx_gpio { + wl12xx_gpio: wl12xx-gpio-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x07c, PIN_OUTPUT | MUX_MODE3) /* gpmc_nwp.gpio_54 */ >; }; /* wl12xx GPIO inputs and SDIO pins */ - wl12xx_pins: pinmux_wl12xx_pins { + wl12xx_pins: wl12xx-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x07a, PIN_INPUT | MUX_MODE3) /* gpmc_ncs3.gpio_53 */ OMAP4_IOPAD(0x148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk.sdmmc5_clk */ @@ -347,13 +347,13 @@ }; /* gpio_48 for ENET_ENABLE */ - enet_enable_gpio: pinmux_enet_enable_gpio { + enet_enable_gpio: enet-enable-gpio-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x070, PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* gpmc_a24.gpio_48 */ >; }; - ks8851_pins: pinmux_ks8851_pins { + ks8851_pins: ks8851-pins { pinctrl-single,pins = < /* ENET_INT */ OMAP4_IOPAD(0x054, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_ad10.gpio_34 */ only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4-var-om44customboard.dtsi +++ linux-6.2.0/arch/arm/boot/dts/omap4-var-om44customboard.dtsi @@ -60,7 +60,7 @@ }; &omap4_pmx_core { - uart1_pins: pinmux_uart1_pins { + uart1_pins: uart1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x13c, PIN_INPUT_PULLUP | MUX_MODE1) /* mcspi1_cs2.uart1_cts */ OMAP4_IOPAD(0x13e, PIN_OUTPUT | MUX_MODE1) /* mcspi1_cs3.uart1_rts */ @@ -69,7 +69,7 @@ >; }; - mcspi1_pins: pinmux_mcspi1_pins { + mcspi1_pins: mcspi1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x132, PIN_INPUT | MUX_MODE0) /* mcspi1_clk.mcspi1_clk */ OMAP4_IOPAD(0x134, PIN_INPUT | MUX_MODE0) /* mcspi1_somi.mcspi1_somi */ @@ -78,13 +78,13 @@ >; }; - mcasp_pins: pinmux_mcsasp_pins { + mcasp_pins: mcsasp-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0f8, PIN_OUTPUT | MUX_MODE2) /* mcbsp2_dr.abe_mcasp_axr */ >; }; - dss_dpi_pins: pinmux_dss_dpi_pins { + dss_dpi_pins: dss-dpi-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x162, PIN_OUTPUT | MUX_MODE5) /* dispc2_data23 */ OMAP4_IOPAD(0x164, PIN_OUTPUT | MUX_MODE5) /* dispc2_data22 */ @@ -117,7 +117,7 @@ >; }; - dss_hdmi_pins: pinmux_dss_hdmi_pins { + dss_hdmi_pins: dss-hdmi-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x09a, PIN_INPUT | MUX_MODE0) /* hdmi_cec.hdmi_cec */ OMAP4_IOPAD(0x09c, PIN_INPUT_PULLUP | MUX_MODE0) /* hdmi_scl.hdmi_scl */ @@ -125,14 +125,14 @@ >; }; - i2c4_pins: pinmux_i2c4_pins { + i2c4_pins: i2c4-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x12e, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_scl */ OMAP4_IOPAD(0x130, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c4_sda */ >; }; - mmc5_pins: pinmux_mmc5_pins { + mmc5_pins: mmc5-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0f6, PIN_INPUT | MUX_MODE3) /* abe_mcbsp2_clkx.gpio_110 */ OMAP4_IOPAD(0x148, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc5_clk.sdmmc5_clk */ @@ -144,32 +144,32 @@ >; }; - gpio_led_pins: pinmux_gpio_led_pins { + gpio_led_pins: gpio-led-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x17e, PIN_OUTPUT | MUX_MODE3) /* kpd_col4.gpio_172 */ OMAP4_IOPAD(0x180, PIN_OUTPUT | MUX_MODE3) /* kpd_col5.gpio_173 */ >; }; - gpio_key_pins: pinmux_gpio_key_pins { + gpio_key_pins: gpio-key-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x1a2, PIN_INPUT | MUX_MODE3) /* sys_boot0.gpio_184 */ >; }; - ks8851_irq_pins: pinmux_ks8851_irq_pins { + ks8851_irq_pins: ks8851-irq-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x17c, PIN_INPUT_PULLUP | MUX_MODE3) /* kpd_col3.gpio_171 */ >; }; - hdmi_hpd_pins: pinmux_hdmi_hpd_pins { + hdmi_hpd_pins: hdmi-hpd-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x098, PIN_INPUT_PULLDOWN | MUX_MODE3) /* hdmi_hpd.gpio_63 */ >; }; - backlight_pins: pinmux_backlight_pins { + backlight_pins: backlight-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x116, PIN_OUTPUT | MUX_MODE3) /* abe_dmic_din3.gpio_122 */ >; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi +++ linux-6.2.0/arch/arm/boot/dts/omap4-var-som-om44-wlan.dtsi @@ -19,7 +19,7 @@ }; &omap4_pmx_core { - uart2_pins: pinmux_uart2_pins { + uart2_pins: uart2-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x118, PIN_INPUT_PULLUP | MUX_MODE0) /* uart2_cts.uart2_cts */ OMAP4_IOPAD(0x11a, PIN_OUTPUT | MUX_MODE0) /* uart2_rts.uart2_rts */ @@ -28,7 +28,7 @@ >; }; - wl12xx_ctrl_pins: pinmux_wl12xx_ctrl_pins { + wl12xx_ctrl_pins: wl12xx-ctrl-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x062, PIN_INPUT_PULLUP | MUX_MODE3) /* gpmc_a17.gpio_41 (WLAN_IRQ) */ OMAP4_IOPAD(0x064, PIN_OUTPUT | MUX_MODE3) /* gpmc_a18.gpio_42 (BT_EN) */ @@ -36,7 +36,7 @@ >; }; - mmc4_pins: pinmux_mmc4_pins { + mmc4_pins: mmc4-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x154, PIN_INPUT_PULLUP | MUX_MODE1) /* mcspi4_clk.sdmmc4_clk */ OMAP4_IOPAD(0x156, PIN_INPUT_PULLUP | MUX_MODE1) /* mcspi4_simo.sdmmc4_cmd */ only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4-var-som-om44.dtsi +++ linux-6.2.0/arch/arm/boot/dts/omap4-var-som-om44.dtsi @@ -65,21 +65,21 @@ &hsusbb1_pins >; - twl6040_pins: pinmux_twl6040_pins { + twl6040_pins: twl6040-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x19c, PIN_OUTPUT | MUX_MODE3) /* fref_clk2_out.gpio_182 */ OMAP4_IOPAD(0x1a0, PIN_INPUT | MUX_MODE0) /* sys_nirq2.sys_nirq2 */ >; }; - tsc2004_pins: pinmux_tsc2004_pins { + tsc2004_pins: tsc2004-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x090, PIN_INPUT | MUX_MODE3) /* gpmc_ncs4.gpio_101 (irq) */ OMAP4_IOPAD(0x092, PIN_OUTPUT | MUX_MODE3) /* gpmc_ncs5.gpio_102 (rst) */ >; }; - uart3_pins: pinmux_uart3_pins { + uart3_pins: uart3-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x140, PIN_INPUT_PULLUP | MUX_MODE0) /* uart3_cts_rctx.uart3_cts_rctx */ OMAP4_IOPAD(0x142, PIN_OUTPUT | MUX_MODE0) /* uart3_rts_sd.uart3_rts_sd */ @@ -88,7 +88,7 @@ >; }; - hsusbb1_pins: pinmux_hsusbb1_pins { + hsusbb1_pins: hsusbb1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0c2, PIN_INPUT_PULLDOWN | MUX_MODE4) /* usbb1_ulpitll_clk.usbb1_ulpiphy_clk */ OMAP4_IOPAD(0x0c4, PIN_OUTPUT | MUX_MODE4) /* usbb1_ulpitll_stp.usbb1_ulpiphy_stp */ @@ -105,27 +105,27 @@ >; }; - hsusbb1_phy_rst_pins: pinmux_hsusbb1_phy_rst_pins { + hsusbb1_phy_rst_pins: hsusbb1-phy-rst-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x18c, PIN_OUTPUT | MUX_MODE3) /* kpd_row2.gpio_177 */ >; }; - i2c1_pins: pinmux_i2c1_pins { + i2c1_pins: i2c1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x122, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_scl */ OMAP4_IOPAD(0x124, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c1_sda */ >; }; - i2c3_pins: pinmux_i2c3_pins { + i2c3_pins: i2c3-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x12a, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_scl */ OMAP4_IOPAD(0x12c, PIN_INPUT_PULLUP | MUX_MODE0) /* i2c3_sda */ >; }; - mmc1_pins: pinmux_mmc1_pins { + mmc1_pins: mmc1-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x0e2, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk.sdmmc1_clk */ OMAP4_IOPAD(0x0e4, PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_cmd.sdmmc1_cmd */ @@ -144,19 +144,19 @@ &lan7500_rst_pins >; - hsusbb1_phy_clk_pins: pinmux_hsusbb1_phy_clk_pins { + hsusbb1_phy_clk_pins: hsusbb1-phy-clk-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x058, PIN_OUTPUT | MUX_MODE0) /* fref_clk3_out */ >; }; - hsusbb1_hub_rst_pins: pinmux_hsusbb1_hub_rst_pins { + hsusbb1_hub_rst_pins: hsusbb1-hub-rst-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x042, PIN_OUTPUT | MUX_MODE3) /* gpio_wk1 */ >; }; - lan7500_rst_pins: pinmux_lan7500_rst_pins { + lan7500_rst_pins: lan7500-rst-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x040, PIN_OUTPUT | MUX_MODE3) /* gpio_wk0 */ >; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap443x.dtsi +++ linux-6.2.0/arch/arm/boot/dts/omap443x.dtsi @@ -69,6 +69,7 @@ }; &cpu_thermal { + thermal-sensors = <&bandgap>; coefficients = <0 20000>; }; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/omap4460.dtsi +++ linux-6.2.0/arch/arm/boot/dts/omap4460.dtsi @@ -79,6 +79,7 @@ }; &cpu_thermal { + thermal-sensors = <&bandgap>; coefficients = <348 (-9301)>; }; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/qcom-msm8974pro-sony-xperia-shinano-castor.dts +++ linux-6.2.0/arch/arm/boot/dts/qcom-msm8974pro-sony-xperia-shinano-castor.dts @@ -125,15 +125,15 @@ syna,startup-delay-ms = <10>; - rmi-f01@1 { + rmi4-f01@1 { reg = <0x1>; - syna,nosleep = <1>; + syna,nosleep-mode = <1>; }; - rmi-f11@11 { + rmi4-f11@11 { reg = <0x11>; - syna,f11-flip-x = <1>; syna,sensor-type = <1>; + touchscreen-inverted-x; }; }; }; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/qcom-sdx65-mtp.dts +++ linux-6.2.0/arch/arm/boot/dts/qcom-sdx65-mtp.dts @@ -7,7 +7,7 @@ #include "qcom-sdx65.dtsi" #include #include -#include +#include #include "qcom-pmx65.dtsi" / { only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/s3c6410-mini6410.dts +++ linux-6.2.0/arch/arm/boot/dts/s3c6410-mini6410.dts @@ -51,7 +51,7 @@ ethernet@18000000 { compatible = "davicom,dm9000"; - reg = <0x18000000 0x2 0x18000004 0x2>; + reg = <0x18000000 0x2>, <0x18000004 0x2>; interrupt-parent = <&gpn>; interrupts = <7 IRQ_TYPE_LEVEL_HIGH>; davicom,no-eeprom; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/s5pv210-smdkv210.dts +++ linux-6.2.0/arch/arm/boot/dts/s5pv210-smdkv210.dts @@ -41,7 +41,7 @@ ethernet@a8000000 { compatible = "davicom,dm9000"; - reg = <0xA8000000 0x2 0xA8000002 0x2>; + reg = <0xa8000000 0x2>, <0xa8000002 0x2>; interrupt-parent = <&gph1>; interrupts = <1 IRQ_TYPE_LEVEL_HIGH>; local-mac-address = [00 00 de ad be ef]; @@ -55,6 +55,14 @@ default-brightness-level = <6>; pinctrl-names = "default"; pinctrl-0 = <&pwm3_out>; + power-supply = <&dc5v_reg>; + }; + + dc5v_reg: regulator-0 { + compatible = "regulator-fixed"; + regulator-name = "DC5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; }; }; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi +++ linux-6.2.0/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi @@ -68,11 +68,6 @@ reg = <0x38000000 0x10000>; no-map; }; - - gpu_reserved: gpu@dc000000 { - reg = <0xdc000000 0x4000000>; - no-map; - }; }; led: gpio_leds { @@ -102,9 +97,11 @@ adc1: adc@0 { pinctrl-names = "default"; pinctrl-0 = <&adc1_in6_pins_a>; - st,min-sample-time-nsecs = <5000>; - st,adc-channels = <6>; status = "disabled"; + channel@6 { + reg = <6>; + st,min-sample-time-ns = <5000>; + }; }; adc2: adc@100 { @@ -183,10 +180,6 @@ }; }; -&gpu { - contiguous-area = <&gpu_reserved>; -}; - &hash1 { status = "okay"; }; @@ -375,8 +368,8 @@ &m4_rproc { memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, <&vdev0vring1>, <&vdev0buffer>; - mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; - mbox-names = "vq0", "vq1", "shutdown"; + mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>; + mbox-names = "vq0", "vq1", "shutdown", "detach"; interrupt-parent = <&exti>; interrupts = <68 1>; interrupt-names = "wdg"; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi +++ linux-6.2.0/arch/arm/boot/dts/stm32mp157c-odyssey-som.dtsi @@ -62,11 +62,6 @@ reg = <0x38000000 0x10000>; no-map; }; - - gpu_reserved: gpu@d4000000 { - reg = <0xd4000000 0x4000000>; - no-map; - }; }; led { @@ -80,11 +75,6 @@ }; }; -&gpu { - contiguous-area = <&gpu_reserved>; - status = "okay"; -}; - &i2c2 { pinctrl-names = "default"; pinctrl-0 = <&i2c2_pins_a>; @@ -240,8 +230,8 @@ &m4_rproc { memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, <&vdev0vring1>, <&vdev0buffer>; - mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; - mbox-names = "vq0", "vq1", "shutdown"; + mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>; + mbox-names = "vq0", "vq1", "shutdown", "detach"; interrupt-parent = <&exti>; interrupts = <68 1>; status = "okay"; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi +++ linux-6.2.0/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi @@ -80,17 +80,19 @@ vdda-supply = <&vdda>; vref-supply = <&vdda>; status = "okay"; +}; - adc1: adc@0 { - st,min-sample-time-nsecs = <5000>; - st,adc-channels = <0>; - status = "okay"; +&adc1 { + channel@0 { + reg = <0>; + st,min-sample-time-ns = <5000>; }; +}; - adc2: adc@100 { - st,adc-channels = <1>; - st,min-sample-time-nsecs = <5000>; - status = "okay"; +&adc2 { + channel@1 { + reg = <1>; + st,min-sample-time-ns = <5000>; }; }; @@ -414,8 +416,8 @@ &m4_rproc { memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>, <&vdev0vring1>, <&vdev0buffer>; - mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>; - mbox-names = "vq0", "vq1", "shutdown"; + mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>, <&ipcc 3>; + mbox-names = "vq0", "vq1", "shutdown", "detach"; interrupt-parent = <&exti>; interrupts = <68 1>; status = "okay"; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/boot/dts/twl6030_omap4.dtsi +++ linux-6.2.0/arch/arm/boot/dts/twl6030_omap4.dtsi @@ -19,7 +19,7 @@ }; &omap4_pmx_wkup { - twl6030_wkup_pins: pinmux_twl6030_wkup_pins { + twl6030_wkup_pins: twl6030-wkup-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x054, PIN_OUTPUT | MUX_MODE2) /* fref_clk0_out.sys_drm_msecure */ >; @@ -27,7 +27,7 @@ }; &omap4_pmx_core { - twl6030_pins: pinmux_twl6030_pins { + twl6030_pins: twl6030-pins { pinctrl-single,pins = < OMAP4_IOPAD(0x19e, WAKEUP_EN | PIN_INPUT_PULLUP | MUX_MODE0) /* sys_nirq1.sys_nirq1 */ >; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/include/asm/syscall.h +++ linux-6.2.0/arch/arm/include/asm/syscall.h @@ -25,6 +25,9 @@ if (IS_ENABLED(CONFIG_AEABI) && !IS_ENABLED(CONFIG_OABI_COMPAT)) return task_thread_info(task)->abi_syscall; + if (task_thread_info(task)->abi_syscall == -1) + return -1; + return task_thread_info(task)->abi_syscall & __NR_SYSCALL_MASK; } only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/kernel/entry-common.S +++ linux-6.2.0/arch/arm/kernel/entry-common.S @@ -103,6 +103,7 @@ cmp r0, #0 beq no_work_pending movlt scno, #(__NR_restart_syscall - __NR_SYSCALL_BASE) + str scno, [tsk, #TI_ABI_SYSCALL] @ make sure tracers see update ldmia sp, {r0 - r6} @ have to reload r0 - r6 b local_restart @ ... and off we go ENDPROC(ret_fast_syscall) only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/kernel/hw_breakpoint.c +++ linux-6.2.0/arch/arm/kernel/hw_breakpoint.c @@ -626,7 +626,7 @@ hw->address &= ~alignment_mask; hw->ctrl.len <<= offset; - if (is_default_overflow_handler(bp)) { + if (uses_default_overflow_handler(bp)) { /* * Mismatch breakpoints are required for single-stepping * breakpoints. @@ -798,7 +798,7 @@ * Otherwise, insert a temporary mismatch breakpoint so that * we can single-step over the watchpoint trigger. */ - if (!is_default_overflow_handler(wp)) + if (!uses_default_overflow_handler(wp)) continue; step: enable_single_step(wp, instruction_pointer(regs)); @@ -811,7 +811,7 @@ info->trigger = addr; pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); perf_bp_event(wp, regs); - if (is_default_overflow_handler(wp)) + if (uses_default_overflow_handler(wp)) enable_single_step(wp, instruction_pointer(regs)); } @@ -886,7 +886,7 @@ info->trigger = addr; pr_debug("breakpoint fired: address = 0x%x\n", addr); perf_bp_event(bp, regs); - if (is_default_overflow_handler(bp)) + if (uses_default_overflow_handler(bp)) enable_single_step(bp, addr); goto unlock; } only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/kernel/machine_kexec.c +++ linux-6.2.0/arch/arm/kernel/machine_kexec.c @@ -94,16 +94,28 @@ } } +static DEFINE_PER_CPU(call_single_data_t, cpu_stop_csd) = + CSD_INIT(machine_crash_nonpanic_core, NULL); + void crash_smp_send_stop(void) { static int cpus_stopped; unsigned long msecs; + call_single_data_t *csd; + int cpu, this_cpu = raw_smp_processor_id(); if (cpus_stopped) return; atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); - smp_call_function(machine_crash_nonpanic_core, NULL, false); + for_each_online_cpu(cpu) { + if (cpu == this_cpu) + continue; + + csd = &per_cpu(cpu_stop_csd, cpu); + smp_call_function_single_async(cpu, csd); + } + msecs = 1000; /* Wait at most a second for the other cpus to stop */ while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { mdelay(1); only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/kernel/ptrace.c +++ linux-6.2.0/arch/arm/kernel/ptrace.c @@ -783,8 +783,9 @@ break; case PTRACE_SET_SYSCALL: - task_thread_info(child)->abi_syscall = data & - __NR_SYSCALL_MASK; + if (data != -1) + data &= __NR_SYSCALL_MASK; + task_thread_info(child)->abi_syscall = data; ret = 0; break; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm/mach-omap2/powerdomain.c +++ linux-6.2.0/arch/arm/mach-omap2/powerdomain.c @@ -174,7 +174,7 @@ break; case PWRDM_STATE_PREV: prev = pwrdm_read_prev_pwrst(pwrdm); - if (pwrdm->state != prev) + if (prev >= 0 && pwrdm->state != prev) pwrdm->state_counter[prev]++; if (prev == PWRDM_POWER_RET) _update_logic_membank_counters(pwrdm); only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/freescale/Makefile +++ linux-6.2.0/arch/arm64/boot/dts/freescale/Makefile @@ -64,6 +64,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mm-nitrogen-r2.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-phg.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-phyboard-polis-rdk.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mm-prt8mm.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-tqma8mqml-mba8mx.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-var-som-symphony.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-venice-gw71xx-0x.dtb only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra186.dtsi @@ -191,7 +191,8 @@ clocks = <&bpmp TEGRA186_CLK_AHUB>; clock-names = "ahub"; assigned-clocks = <&bpmp TEGRA186_CLK_AHUB>; - assigned-clock-parents = <&bpmp TEGRA186_CLK_PLL_A_OUT0>; + assigned-clock-parents = <&bpmp TEGRA186_CLK_PLLP_OUT0>; + assigned-clock-rates = <81600000>; #address-cells = <1>; #size-cells = <1>; ranges = <0x02900800 0x02900800 0x11800>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts +++ linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra210-smaug.dts @@ -1312,6 +1312,7 @@ uartd: serial@70006300 { compatible = "nvidia,tegra30-hsuart"; + reset-names = "serial"; status = "okay"; bluetooth { only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra210.dtsi @@ -1438,7 +1438,8 @@ clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>; clock-names = "ahub"; assigned-clocks = <&tegra_car TEGRA210_CLK_D_AUDIO>; - assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_A_OUT0>; + assigned-clock-parents = <&tegra_car TEGRA210_CLK_PLL_P>; + assigned-clock-rates = <81600000>; #address-cells = <1>; #size-cells = <1>; ranges = <0x702d0000 0x702d0000 0x0000e400>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts +++ linux-6.2.0/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701-0000.dts @@ -2004,6 +2004,7 @@ serial@3100000 { compatible = "nvidia,tegra194-hsuart"; + reset-names = "serial"; status = "okay"; }; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts +++ linux-6.2.0/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts @@ -163,7 +163,7 @@ pinctrl-0 = <&light_int_default>; vdd-supply = <&pm8916_l17>; - vio-supply = <&pm8916_l6>; + vddio-supply = <&pm8916_l6>; }; gyroscope@68 { only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts +++ linux-6.2.0/arch/arm64/boot/dts/qcom/msm8996-xiaomi-gemini.dts @@ -82,7 +82,7 @@ #size-cells = <0>; interrupt-parent = <&tlmm>; interrupts = <125 IRQ_TYPE_LEVEL_LOW>; - vdda-supply = <&vreg_l6a_1p8>; + vio-supply = <&vreg_l6a_1p8>; vdd-supply = <&vdd_3v2_tp>; reset-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/qcom/pm6150l.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/pm6150l.dtsi @@ -115,8 +115,9 @@ pm6150l_wled: leds@d800 { compatible = "qcom,pm6150l-wled"; reg = <0xd800>, <0xd900>; - interrupts = <0x5 0xd8 0x1 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "ovp"; + interrupts = <0x5 0xd8 0x1 IRQ_TYPE_EDGE_RISING>, + <0x5 0xd8 0x2 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "ovp", "short"; label = "backlight"; status = "disabled"; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/qcom/pm660l.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/pm660l.dtsi @@ -74,8 +74,9 @@ pm660l_wled: leds@d800 { compatible = "qcom,pm660l-wled"; reg = <0xd800>, <0xd900>; - interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>; - interrupt-names = "ovp"; + interrupts = <0x3 0xd8 0x1 IRQ_TYPE_EDGE_RISING>, + <0x3 0xd8 0x2 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "ovp", "short"; label = "backlight"; status = "disabled"; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/qcom/pm8350.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/pm8350.dtsi @@ -8,7 +8,7 @@ / { thermal-zones { - pm8350_thermal: pm8350c-thermal { + pm8350_thermal: pm8350-thermal { polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&pm8350_temp_alarm>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/qcom/pm8350b.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/pm8350b.dtsi @@ -8,7 +8,7 @@ / { thermal-zones { - pm8350b_thermal: pm8350c-thermal { + pm8350b_thermal: pm8350b-thermal { polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&pm8350b_temp_alarm>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/qcom/pmr735b.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/pmr735b.dtsi @@ -8,7 +8,7 @@ / { thermal-zones { - pmr735a_thermal: pmr735a-thermal { + pmr735b_thermal: pmr735b-thermal { polling-delay-passive = <100>; polling-delay = <0>; thermal-sensors = <&pmr735b_temp_alarm>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts @@ -71,7 +71,7 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - gpio = <&pmc8280_1_gpios 1 GPIO_ACTIVE_HIGH>; + gpio = <&pmc8280_1_gpios 2 GPIO_ACTIVE_HIGH>; enable-active-high; pinctrl-names = "default"; @@ -465,7 +465,7 @@ }; misc_3p3_reg_en: misc-3p3-reg-en-state { - pins = "gpio1"; + pins = "gpio2"; function = "normal"; }; }; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi @@ -14,6 +14,15 @@ qcom,msm-id = <321 0x20001>; /* SDM845 v2.1 */ qcom,board-id = <8 0>; + aliases { + serial0 = &uart6; + serial1 = &uart9; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + gpio-keys { compatible = "gpio-keys"; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx203.dts @@ -14,3 +14,236 @@ }; /delete-node/ &vreg_l7f_1p8; + +&pm8009_gpios { + gpio-line-names = "NC", /* GPIO_1 */ + "CAM_PWR_LD_EN", + "WIDEC_PWR_EN", + "NC"; +}; + +&pm8150_gpios { + gpio-line-names = "VOL_DOWN_N", /* GPIO_1 */ + "OPTION_2", + "NC", + "PM_SLP_CLK_IN", + "OPTION_1", + "NC", + "NC", + "SP_ARI_PWR_ALARM", + "NC", + "NC"; /* GPIO_10 */ +}; + +&pm8150b_gpios { + gpio-line-names = "SNAPSHOT_N", /* GPIO_1 */ + "FOCUS_N", + "NC", + "NC", + "RF_LCD_ID_EN", + "NC", + "NC", + "LCD_ID", + "NC", + "WLC_EN_N", /* GPIO_10 */ + "NC", + "RF_ID"; +}; + +&pm8150l_gpios { + gpio-line-names = "NC", /* GPIO_1 */ + "PM3003A_EN", + "NC", + "NC", + "NC", + "AUX2_THERM", + "BB_HP_EN", + "FP_LDO_EN", + "PMX_RESET_N", + "AUX3_THERM", /* GPIO_10 */ + "DTV_PWR_EN", + "PM3003A_MODE"; +}; + +&tlmm { + gpio-line-names = "AP_CTI_IN", /* GPIO_0 */ + "MDM2AP_ERR_FATAL", + "AP_CTI_OUT", + "MDM2AP_STATUS", + "NFC_I2C_SDA", + "NFC_I2C_SCL", + "NFC_EN", + "NFC_CLK_REQ", + "NFC_ESE_PWR_REQ", + "DVDT_WRT_DET_AND", + "SPK_AMP_RESET_N", /* GPIO_10 */ + "SPK_AMP_INT_N", + "APPS_I2C_1_SDA", + "APPS_I2C_1_SCL", + "NC", + "TX_GTR_THRES_IN", + "HST_BT_UART_CTS", + "HST_BT_UART_RFR", + "HST_BT_UART_TX", + "HST_BT_UART_RX", + "HST_WLAN_EN", /* GPIO_20 */ + "HST_BT_EN", + "RGBC_IR_PWR_EN", + "FP_INT_N", + "NC", + "NC", + "NC", + "NC", + "NFC_ESE_SPI_MISO", + "NFC_ESE_SPI_MOSI", + "NFC_ESE_SPI_SCLK", /* GPIO_30 */ + "NFC_ESE_SPI_CS_N", + "WCD_RST_N", + "NC", + "SDM_DEBUG_UART_TX", + "SDM_DEBUG_UART_RX", + "TS_I2C_SDA", + "TS_I2C_SCL", + "TS_INT_N", + "FP_SPI_MISO", /* GPIO_40 */ + "FP_SPI_MOSI", + "FP_SPI_SCLK", + "FP_SPI_CS_N", + "APPS_I2C_0_SDA", + "APPS_I2C_0_SCL", + "DISP_ERR_FG", + "UIM2_DETECT_EN", + "NC", + "NC", + "NC", /* GPIO_50 */ + "NC", + "MDM_UART_CTS", + "MDM_UART_RFR", + "MDM_UART_TX", + "MDM_UART_RX", + "AP2MDM_STATUS", + "AP2MDM_ERR_FATAL", + "MDM_IPC_HS_UART_TX", + "MDM_IPC_HS_UART_RX", + "NC", /* GPIO_60 */ + "NC", + "NC", + "NC", + "NC", + "USB_CC_DIR", + "DISP_VSYNC", + "NC", + "NC", + "CAM_PWR_B_CS", + "NC", /* GPIO_70 */ + "CAM_PWR_A_CS", + "SBU_SW_SEL", + "SBU_SW_OE", + "FP_RESET_N", + "FP_RESET_N", + "DISP_RESET_N", + "DEBUG_GPIO0", + "TRAY_DET", + "CAM2_RST_N", + "PCIE0_RST_N", + "PCIE0_CLK_REQ_N", /* GPIO_80 */ + "PCIE0_WAKE_N", + "DVDT_ENABLE", + "DVDT_WRT_DET_OR", + "NC", + "PCIE2_RST_N", + "PCIE2_CLK_REQ_N", + "PCIE2_WAKE_N", + "MDM_VFR_IRQ0", + "MDM_VFR_IRQ1", + "SW_SERVICE", /* GPIO_90 */ + "CAM_SOF", + "CAM1_RST_N", + "CAM0_RST_N", + "CAM0_MCLK", + "CAM1_MCLK", + "CAM2_MCLK", + "CAM3_MCLK", + "CAM4_MCLK", + "TOF_RST_N", + "NC", /* GPIO_100 */ + "CCI0_I2C_SDA", + "CCI0_I2C_SCL", + "CCI1_I2C_SDA", + "CCI1_I2C_SCL_", + "CCI2_I2C_SDA", + "CCI2_I2C_SCL", + "CCI3_I2C_SDA", + "CCI3_I2C_SCL", + "CAM3_RST_N", + "NFC_DWL_REQ", /* GPIO_110 */ + "NFC_IRQ", + "XVS", + "NC", + "RF_ID_EXTENSION", + "SPK_AMP_I2C_SDA", + "SPK_AMP_I2C_SCL", + "NC", + "NC", + "WLC_I2C_SDA", + "WLC_I2C_SCL", /* GPIO_120 */ + "ACC_COVER_OPEN", + "ALS_PROX_INT_N", + "ACCEL_INT", + "WLAN_SW_CTRL", + "CAMSENSOR_I2C_SDA", + "CAMSENSOR_I2C_SCL", + "UDON_SWITCH_SEL", + "WDOG_DISABLE", + "BAROMETER_INT", + "NC", /* GPIO_130 */ + "NC", + "FORCED_USB_BOOT", + "NC", + "NC", + "WLC_INT_N", + "NC", + "NC", + "RGBC_IR_INT", + "NC", + "NC", /* GPIO_140 */ + "NC", + "BT_SLIMBUS_CLK", + "BT_SLIMBUS_DATA", + "HW_ID_0", + "HW_ID_1", + "WCD_SWR_TX_CLK", + "WCD_SWR_TX_DATA0", + "WCD_SWR_TX_DATA1", + "WCD_SWR_RX_CLK", + "WCD_SWR_RX_DATA0", /* GPIO_150 */ + "WCD_SWR_RX_DATA1", + "SDM_DMIC_CLK1", + "SDM_DMIC_DATA1", + "SDM_DMIC_CLK2", + "SDM_DMIC_DATA2", + "SPK_AMP_I2S_CLK", + "SPK_AMP_I2S_WS", + "SPK_AMP_I2S_ASP_DIN", + "SPK_AMP_I2S_ASP_DOUT", + "COMPASS_I2C_SDA", /* GPIO_160 */ + "COMPASS_I2C_SCL", + "NC", + "NC", + "SSC_SPI_1_MISO", + "SSC_SPI_1_MOSI", + "SSC_SPI_1_CLK", + "SSC_SPI_1_CS_N", + "NC", + "NC", + "SSC_SENSOR_I2C_SDA", /* GPIO_170 */ + "SSC_SENSOR_I2C_SCL", + "NC", + "NC", + "NC", + "NC", + "HST_BLE_SNS_UART6_TX", + "HST_BLE_SNS_UART6_RX", + "HST_WLAN_UART_TX", + "HST_WLAN_UART_RX"; +}; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts +++ linux-6.2.0/arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo-pdx206.dts @@ -20,6 +20,8 @@ }; &gpio_keys { + pinctrl-0 = <&focus_n &snapshot_n &vol_down_n &g_assist_n>; + g-assist-key { label = "Google Assistant Key"; linux,code = ; @@ -30,6 +32,247 @@ }; }; +&pm8009_gpios { + gpio-line-names = "NC", /* GPIO_1 */ + "NC", + "WIDEC_PWR_EN", + "NC"; +}; + +&pm8150_gpios { + gpio-line-names = "VOL_DOWN_N", /* GPIO_1 */ + "OPTION_2", + "NC", + "PM_SLP_CLK_IN", + "OPTION_1", + "G_ASSIST_N", + "NC", + "SP_ARI_PWR_ALARM", + "NC", + "NC"; /* GPIO_10 */ + + g_assist_n: g-assist-n-state { + pins = "gpio6"; + function = "normal"; + power-source = <1>; + bias-pull-up; + input-enable; + }; +}; + +&pm8150b_gpios { + gpio-line-names = "SNAPSHOT_N", /* GPIO_1 */ + "FOCUS_N", + "NC", + "NC", + "RF_LCD_ID_EN", + "NC", + "NC", + "LCD_ID", + "NC", + "NC", /* GPIO_10 */ + "NC", + "RF_ID"; +}; + +&pm8150l_gpios { + gpio-line-names = "NC", /* GPIO_1 */ + "PM3003A_EN", + "NC", + "NC", + "NC", + "AUX2_THERM", + "BB_HP_EN", + "FP_LDO_EN", + "PMX_RESET_N", + "NC", /* GPIO_10 */ + "NC", + "PM3003A_MODE"; +}; + +&tlmm { + gpio-line-names = "AP_CTI_IN", /* GPIO_0 */ + "MDM2AP_ERR_FATAL", + "AP_CTI_OUT", + "MDM2AP_STATUS", + "NFC_I2C_SDA", + "NFC_I2C_SCL", + "NFC_EN", + "NFC_CLK_REQ", + "NFC_ESE_PWR_REQ", + "DVDT_WRT_DET_AND", + "SPK_AMP_RESET_N", /* GPIO_10 */ + "SPK_AMP_INT_N", + "APPS_I2C_1_SDA", + "APPS_I2C_1_SCL", + "NC", + "TX_GTR_THRES_IN", + "HST_BT_UART_CTS", + "HST_BT_UART_RFR", + "HST_BT_UART_TX", + "HST_BT_UART_RX", + "HST_WLAN_EN", /* GPIO_20 */ + "HST_BT_EN", + "RGBC_IR_PWR_EN", + "FP_INT_N", + "NC", + "NC", + "NC", + "NC", + "NFC_ESE_SPI_MISO", + "NFC_ESE_SPI_MOSI", + "NFC_ESE_SPI_SCLK", /* GPIO_30 */ + "NFC_ESE_SPI_CS_N", + "WCD_RST_N", + "NC", + "SDM_DEBUG_UART_TX", + "SDM_DEBUG_UART_RX", + "TS_I2C_SDA", + "TS_I2C_SCL", + "TS_INT_N", + "FP_SPI_MISO", /* GPIO_40 */ + "FP_SPI_MOSI", + "FP_SPI_SCLK", + "FP_SPI_CS_N", + "APPS_I2C_0_SDA", + "APPS_I2C_0_SCL", + "DISP_ERR_FG", + "UIM2_DETECT_EN", + "NC", + "NC", + "NC", /* GPIO_50 */ + "NC", + "MDM_UART_CTS", + "MDM_UART_RFR", + "MDM_UART_TX", + "MDM_UART_RX", + "AP2MDM_STATUS", + "AP2MDM_ERR_FATAL", + "MDM_IPC_HS_UART_TX", + "MDM_IPC_HS_UART_RX", + "NC", /* GPIO_60 */ + "NC", + "NC", + "NC", + "NC", + "USB_CC_DIR", + "DISP_VSYNC", + "NC", + "NC", + "CAM_PWR_B_CS", + "NC", /* GPIO_70 */ + "FRONTC_PWR_EN", + "SBU_SW_SEL", + "SBU_SW_OE", + "FP_RESET_N", + "FP_RESET_N", + "DISP_RESET_N", + "DEBUG_GPIO0", + "TRAY_DET", + "CAM2_RST_N", + "PCIE0_RST_N", + "PCIE0_CLK_REQ_N", /* GPIO_80 */ + "PCIE0_WAKE_N", + "DVDT_ENABLE", + "DVDT_WRT_DET_OR", + "NC", + "PCIE2_RST_N", + "PCIE2_CLK_REQ_N", + "PCIE2_WAKE_N", + "MDM_VFR_IRQ0", + "MDM_VFR_IRQ1", + "SW_SERVICE", /* GPIO_90 */ + "CAM_SOF", + "CAM1_RST_N", + "CAM0_RST_N", + "CAM0_MCLK", + "CAM1_MCLK", + "CAM2_MCLK", + "CAM3_MCLK", + "NC", + "NC", + "NC", /* GPIO_100 */ + "CCI0_I2C_SDA", + "CCI0_I2C_SCL", + "CCI1_I2C_SDA", + "CCI1_I2C_SCL_", + "CCI2_I2C_SDA", + "CCI2_I2C_SCL", + "CCI3_I2C_SDA", + "CCI3_I2C_SCL", + "CAM3_RST_N", + "NFC_DWL_REQ", /* GPIO_110 */ + "NFC_IRQ", + "XVS", + "NC", + "RF_ID_EXTENSION", + "SPK_AMP_I2C_SDA", + "SPK_AMP_I2C_SCL", + "NC", + "NC", + "NC", + "NC", + "ACC_COVER_OPEN", + "ALS_PROX_INT_N", + "ACCEL_INT", + "WLAN_SW_CTRL", + "CAMSENSOR_I2C_SDA", + "CAMSENSOR_I2C_SCL", + "UDON_SWITCH_SEL", + "WDOG_DISABLE", + "BAROMETER_INT", + "NC", /* GPIO_130 */ + "NC", + "FORCED_USB_BOOT", + "NC", + "NC", + "NC", + "NC", + "NC", + "RGBC_IR_INT", + "NC", + "NC", /* GPIO_140 */ + "NC", + "BT_SLIMBUS_CLK", + "BT_SLIMBUS_DATA", + "HW_ID_0", + "HW_ID_1", + "WCD_SWR_TX_CLK", + "WCD_SWR_TX_DATA0", + "WCD_SWR_TX_DATA1", + "WCD_SWR_RX_CLK", + "WCD_SWR_RX_DATA0", /* GPIO_150 */ + "WCD_SWR_RX_DATA1", + "SDM_DMIC_CLK1", + "SDM_DMIC_DATA1", + "SDM_DMIC_CLK2", + "SDM_DMIC_DATA2", + "SPK_AMP_I2S_CLK", + "SPK_AMP_I2S_WS", + "SPK_AMP_I2S_ASP_DIN", + "SPK_AMP_I2S_ASP_DOUT", + "COMPASS_I2C_SDA", /* GPIO_160 */ + "COMPASS_I2C_SCL", + "NC", + "NC", + "SSC_SPI_1_MISO", + "SSC_SPI_1_MOSI", + "SSC_SPI_1_CLK", + "SSC_SPI_1_CS_N", + "NC", + "NC", + "SSC_SENSOR_I2C_SDA", /* GPIO_170 */ + "SSC_SENSOR_I2C_SCL", + "NC", + "NC", + "NC", + "NC", + "HST_BLE_SNS_UART6_TX", + "HST_BLE_SNS_UART6_RX", + "HST_WLAN_UART_TX", + "HST_WLAN_UART_RX"; +}; + &vreg_l2f_1p3 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi @@ -100,7 +100,7 @@ rxc-skew-psec = <2400>; txc-skew-psec = <2400>; rxdv-skew-psec = <0>; - txdv-skew-psec = <0>; + txen-skew-psec = <0>; rxd0-skew-psec = <0>; rxd1-skew-psec = <0>; rxd2-skew-psec = <0>; @@ -128,7 +128,7 @@ rxc-skew-psec = <2400>; txc-skew-psec = <2400>; rxdv-skew-psec = <0>; - txdv-skew-psec = <0>; + txen-skew-psec = <0>; rxd0-skew-psec = <0>; rxd1-skew-psec = <0>; rxd2-skew-psec = <0>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi @@ -77,7 +77,7 @@ rxc-skew-psec = <2400>; txc-skew-psec = <2400>; rxdv-skew-psec = <0>; - txdv-skew-psec = <0>; + txen-skew-psec = <0>; rxd0-skew-psec = <0>; rxd1-skew-psec = <0>; rxd2-skew-psec = <0>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/boot/dts/renesas/rzg2ul-smarc-som.dtsi +++ linux-6.2.0/arch/arm64/boot/dts/renesas/rzg2ul-smarc-som.dtsi @@ -80,7 +80,7 @@ rxc-skew-psec = <2400>; txc-skew-psec = <2400>; rxdv-skew-psec = <0>; - txdv-skew-psec = <0>; + txen-skew-psec = <0>; rxd0-skew-psec = <0>; rxd1-skew-psec = <0>; rxd2-skew-psec = <0>; @@ -107,7 +107,7 @@ rxc-skew-psec = <2400>; txc-skew-psec = <2400>; rxdv-skew-psec = <0>; - txdv-skew-psec = <0>; + txen-skew-psec = <0>; rxd0-skew-psec = <0>; rxd1-skew-psec = <0>; rxd2-skew-psec = <0>; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/configs/defconfig +++ linux-6.2.0/arch/arm64/configs/defconfig @@ -1058,7 +1058,6 @@ CONFIG_STAGING=y CONFIG_STAGING_MEDIA=y CONFIG_VIDEO_HANTRO=m -CONFIG_VIDEO_IMX_MEDIA=m CONFIG_VIDEO_MAX96712=m CONFIG_CHROME_PLATFORMS=y CONFIG_CROS_EC=y @@ -1074,7 +1073,6 @@ CONFIG_COMMON_CLK_PWM=y CONFIG_COMMON_CLK_RS9_PCIE=y CONFIG_COMMON_CLK_VC5=y -CONFIG_COMMON_CLK_NPCM8XX=y CONFIG_COMMON_CLK_BD718XX=m CONFIG_CLK_RASPBERRYPI=m CONFIG_CLK_IMX8MM=y only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/include/asm/cpufeature.h +++ linux-6.2.0/arch/arm64/include/asm/cpufeature.h @@ -670,7 +670,7 @@ isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1); return cpuid_feature_extract_unsigned_field(isar2, - ID_AA64ISAR2_EL1_BC_SHIFT); + ID_AA64ISAR2_EL1_CLRBHB_SHIFT); } const struct cpumask *system_32bit_el0_cpumask(void); @@ -864,7 +864,11 @@ if (!IS_ENABLED(CONFIG_ARM64_HW_AFDBM)) return false; - mmfr1 = read_cpuid(ID_AA64MMFR1_EL1); + /* + * Use cached version to avoid emulated msr operation on KVM + * guests. + */ + mmfr1 = read_sanitised_ftr_reg(SYS_ID_AA64MMFR1_EL1); return cpuid_feature_extract_unsigned_field(mmfr1, ID_AA64MMFR1_EL1_HAFDBS_SHIFT); } only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/include/asm/cputype.h +++ linux-6.2.0/arch/arm64/include/asm/cputype.h @@ -79,6 +79,7 @@ #define ARM_CPU_PART_CORTEX_A78AE 0xD42 #define ARM_CPU_PART_CORTEX_X1 0xD44 #define ARM_CPU_PART_CORTEX_A510 0xD46 +#define ARM_CPU_PART_CORTEX_A520 0xD80 #define ARM_CPU_PART_CORTEX_A710 0xD47 #define ARM_CPU_PART_CORTEX_A715 0xD4D #define ARM_CPU_PART_CORTEX_X2 0xD48 @@ -144,6 +145,7 @@ #define MIDR_CORTEX_A78AE MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78AE) #define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) +#define MIDR_CORTEX_A520 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A520) #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) #define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715) #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/include/asm/sdei.h +++ linux-6.2.0/arch/arm64/include/asm/sdei.h @@ -17,6 +17,9 @@ #include +DECLARE_PER_CPU(struct sdei_registered_event *, sdei_active_normal_event); +DECLARE_PER_CPU(struct sdei_registered_event *, sdei_active_critical_event); + extern unsigned long sdei_exit_mode; /* Software Delegated Exception entry point from firmware*/ @@ -29,6 +32,9 @@ unsigned long pc, unsigned long pstate); +/* Abort a running handler. Context is discarded. */ +void __sdei_handler_abort(void); + /* * The above entry point does the minimum to call C code. This function does * anything else, before calling the driver. only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/kernel/hw_breakpoint.c +++ linux-6.2.0/arch/arm64/kernel/hw_breakpoint.c @@ -654,7 +654,7 @@ perf_bp_event(bp, regs); /* Do we need to handle the stepping? */ - if (is_default_overflow_handler(bp)) + if (uses_default_overflow_handler(bp)) step = 1; unlock: rcu_read_unlock(); @@ -733,7 +733,7 @@ static int watchpoint_report(struct perf_event *wp, unsigned long addr, struct pt_regs *regs) { - int step = is_default_overflow_handler(wp); + int step = uses_default_overflow_handler(wp); struct arch_hw_breakpoint *info = counter_arch_bp(wp); info->trigger = addr; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/kernel/sdei.c +++ linux-6.2.0/arch/arm64/kernel/sdei.c @@ -47,6 +47,9 @@ DEFINE_PER_CPU(unsigned long *, sdei_shadow_call_stack_critical_ptr); #endif +DEFINE_PER_CPU(struct sdei_registered_event *, sdei_active_normal_event); +DEFINE_PER_CPU(struct sdei_registered_event *, sdei_active_critical_event); + static void _free_sdei_stack(unsigned long * __percpu *ptr, int cpu) { unsigned long *p; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/kernel/smp.c +++ linux-6.2.0/arch/arm64/kernel/smp.c @@ -1047,10 +1047,8 @@ * If this cpu is the only one alive at this point in time, online or * not, there are no stop messages to be sent around, so just back out. */ - if (num_other_online_cpus() == 0) { - sdei_mask_local_cpu(); - return; - } + if (num_other_online_cpus() == 0) + goto skip_ipi; cpumask_copy(&mask, cpu_online_mask); cpumask_clear_cpu(smp_processor_id(), &mask); @@ -1069,7 +1067,9 @@ pr_warn("SMP: failed to stop secondary CPUs %*pbl\n", cpumask_pr_args(&mask)); +skip_ipi: sdei_mask_local_cpu(); + sdei_handler_abort(); } bool smp_crash_stop_failed(void) only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/lib/csum.c +++ linux-6.2.0/arch/arm64/lib/csum.c @@ -24,7 +24,7 @@ const u64 *ptr; u64 data, sum64 = 0; - if (unlikely(len == 0)) + if (unlikely(len <= 0)) return 0; offset = (unsigned long)buff & 7; only in patch2: unchanged: --- linux-6.2.0.orig/arch/arm64/mm/hugetlbpage.c +++ linux-6.2.0/arch/arm64/mm/hugetlbpage.c @@ -236,7 +236,7 @@ unsigned long i, saddr = addr; for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) - pte_clear(mm, addr, ptep); + ptep_clear(mm, addr, ptep); flush_tlb_range(&vma, saddr, addr); } only in patch2: unchanged: --- linux-6.2.0.orig/arch/loongarch/include/asm/elf.h +++ linux-6.2.0/arch/loongarch/include/asm/elf.h @@ -111,6 +111,15 @@ #define R_LARCH_TLS_GD_HI20 98 #define R_LARCH_32_PCREL 99 #define R_LARCH_RELAX 100 +#define R_LARCH_DELETE 101 +#define R_LARCH_ALIGN 102 +#define R_LARCH_PCREL20_S2 103 +#define R_LARCH_CFA 104 +#define R_LARCH_ADD6 105 +#define R_LARCH_SUB6 106 +#define R_LARCH_ADD_ULEB128 107 +#define R_LARCH_SUB_ULEB128 108 +#define R_LARCH_64_PCREL 109 #ifndef ELF_ARCH only in patch2: unchanged: --- linux-6.2.0.orig/arch/loongarch/include/asm/pgtable-bits.h +++ linux-6.2.0/arch/loongarch/include/asm/pgtable-bits.h @@ -21,12 +21,14 @@ #define _PAGE_HGLOBAL_SHIFT 12 /* HGlobal is a PMD bit */ #define _PAGE_PFN_SHIFT 12 #define _PAGE_PFN_END_SHIFT 48 +#define _PAGE_PRESENT_INVALID_SHIFT 60 #define _PAGE_NO_READ_SHIFT 61 #define _PAGE_NO_EXEC_SHIFT 62 #define _PAGE_RPLV_SHIFT 63 /* Used by software */ #define _PAGE_PRESENT (_ULCAST_(1) << _PAGE_PRESENT_SHIFT) +#define _PAGE_PRESENT_INVALID (_ULCAST_(1) << _PAGE_PRESENT_INVALID_SHIFT) #define _PAGE_WRITE (_ULCAST_(1) << _PAGE_WRITE_SHIFT) #define _PAGE_ACCESSED (_ULCAST_(1) << _PAGE_ACCESSED_SHIFT) #define _PAGE_MODIFIED (_ULCAST_(1) << _PAGE_MODIFIED_SHIFT) only in patch2: unchanged: --- linux-6.2.0.orig/arch/loongarch/include/asm/pgtable.h +++ linux-6.2.0/arch/loongarch/include/asm/pgtable.h @@ -213,7 +213,7 @@ static inline int pmd_present(pmd_t pmd) { if (unlikely(pmd_val(pmd) & _PAGE_HUGE)) - return !!(pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE)); + return !!(pmd_val(pmd) & (_PAGE_PRESENT | _PAGE_PROTNONE | _PAGE_PRESENT_INVALID)); return pmd_val(pmd) != (unsigned long)invalid_pte_table; } @@ -528,6 +528,7 @@ static inline pmd_t pmd_mkinvalid(pmd_t pmd) { + pmd_val(pmd) |= _PAGE_PRESENT_INVALID; pmd_val(pmd) &= ~(_PAGE_PRESENT | _PAGE_VALID | _PAGE_DIRTY | _PAGE_PROTNONE); return pmd; @@ -562,6 +563,9 @@ } #endif /* CONFIG_NUMA_BALANCING */ +#define pmd_leaf(pmd) ((pmd_val(pmd) & _PAGE_HUGE) != 0) +#define pud_leaf(pud) ((pud_val(pud) & _PAGE_HUGE) != 0) + /* * We provide our own get_unmapped area to cope with the virtual aliasing * constraints placed on us by the cache architecture. only in patch2: unchanged: --- linux-6.2.0.orig/arch/loongarch/kernel/mem.c +++ linux-6.2.0/arch/loongarch/kernel/mem.c @@ -50,7 +50,6 @@ } memblock_set_current_limit(PFN_PHYS(max_low_pfn)); - memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0); /* Reserve the first 2MB */ memblock_reserve(PHYS_OFFSET, 0x200000); @@ -58,4 +57,7 @@ /* Reserve the kernel text/data/bss */ memblock_reserve(__pa_symbol(&_text), __pa_symbol(&_end) - __pa_symbol(&_text)); + + memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0); + memblock_set_node(0, PHYS_ADDR_MAX, &memblock.reserved, 0); } only in patch2: unchanged: --- linux-6.2.0.orig/arch/loongarch/kernel/module.c +++ linux-6.2.0/arch/loongarch/kernel/module.c @@ -382,7 +382,7 @@ /* The handlers for known reloc types */ static reloc_rela_handler reloc_rela_handlers[] = { - [R_LARCH_NONE ... R_LARCH_RELAX] = apply_r_larch_error, + [R_LARCH_NONE ... R_LARCH_64_PCREL] = apply_r_larch_error, [R_LARCH_NONE] = apply_r_larch_none, [R_LARCH_32] = apply_r_larch_32, only in patch2: unchanged: --- linux-6.2.0.orig/arch/loongarch/kernel/numa.c +++ linux-6.2.0/arch/loongarch/kernel/numa.c @@ -468,7 +468,7 @@ void __init mem_init(void) { - high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT); + high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); memblock_free_all(); setup_zero_pages(); /* This comes from node 0 */ } only in patch2: unchanged: --- linux-6.2.0.orig/arch/m68k/fpsp040/skeleton.S +++ linux-6.2.0/arch/m68k/fpsp040/skeleton.S @@ -499,13 +499,13 @@ dbf %d0,morein rts - .section .fixup,#alloc,#execinstr + .section .fixup,"ax" .even 1: jbsr fpsp040_die jbra .Lnotkern - .section __ex_table,#alloc + .section __ex_table,"a" .align 4 .long in_ea,1b only in patch2: unchanged: --- linux-6.2.0.orig/arch/m68k/ifpsp060/os.S +++ linux-6.2.0/arch/m68k/ifpsp060/os.S @@ -379,11 +379,11 @@ | Execption handling for movs access to illegal memory - .section .fixup,#alloc,#execinstr + .section .fixup,"ax" .even 1: moveq #-1,%d1 rts -.section __ex_table,#alloc +.section __ex_table,"a" .align 4 .long dmrbuae,1b .long dmrwuae,1b only in patch2: unchanged: --- linux-6.2.0.orig/arch/m68k/kernel/relocate_kernel.S +++ linux-6.2.0/arch/m68k/kernel/relocate_kernel.S @@ -26,7 +26,7 @@ lea %pc@(.Lcopy),%a4 2: addl #0x00000000,%a4 /* virt_to_phys() */ - .section ".m68k_fixup","aw" + .section .m68k_fixup,"aw" .long M68K_FIXUP_MEMOFFSET, 2b+2 .previous @@ -49,7 +49,7 @@ lea %pc@(.Lcont040),%a4 5: addl #0x00000000,%a4 /* virt_to_phys() */ - .section ".m68k_fixup","aw" + .section .m68k_fixup,"aw" .long M68K_FIXUP_MEMOFFSET, 5b+2 .previous only in patch2: unchanged: --- linux-6.2.0.orig/arch/parisc/include/asm/ldcw.h +++ linux-6.2.0/arch/parisc/include/asm/ldcw.h @@ -2,14 +2,28 @@ #ifndef __PARISC_LDCW_H #define __PARISC_LDCW_H -#ifndef CONFIG_PA20 /* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data, and GCC only guarantees 8-byte alignment for stack locals, we can't be assured of 16-byte alignment for atomic lock data even if we specify "__attribute ((aligned(16)))" in the type declaration. So, we use a struct containing an array of four ints for the atomic lock type and dynamically select the 16-byte aligned int from the array - for the semaphore. */ + for the semaphore. */ + +/* From: "Jim Hull" + I've attached a summary of the change, but basically, for PA 2.0, as + long as the ",CO" (coherent operation) completer is implemented, then the + 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead + they only require "natural" alignment (4-byte for ldcw, 8-byte for + ldcd). + + Although the cache control hint is accepted by all PA 2.0 processors, + it is only implemented on PA8800/PA8900 CPUs. Prior PA8X00 CPUs still + require 16-byte alignment. If the address is unaligned, the operation + of the instruction is undefined. The ldcw instruction does not generate + unaligned data reference traps so misaligned accesses are not detected. + This hid the problem for years. So, restore the 16-byte alignment dropped + by Kyle McMartin in "Remove __ldcw_align for PA-RISC 2.0 processors". */ #define __PA_LDCW_ALIGNMENT 16 #define __PA_LDCW_ALIGN_ORDER 4 @@ -19,22 +33,12 @@ & ~(__PA_LDCW_ALIGNMENT - 1); \ (volatile unsigned int *) __ret; \ }) -#define __LDCW "ldcw" -#else /*CONFIG_PA20*/ -/* From: "Jim Hull" - I've attached a summary of the change, but basically, for PA 2.0, as - long as the ",CO" (coherent operation) completer is specified, then the - 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead - they only require "natural" alignment (4-byte for ldcw, 8-byte for - ldcd). */ - -#define __PA_LDCW_ALIGNMENT 4 -#define __PA_LDCW_ALIGN_ORDER 2 -#define __ldcw_align(a) (&(a)->slock) +#ifdef CONFIG_PA20 #define __LDCW "ldcw,co" - -#endif /*!CONFIG_PA20*/ +#else +#define __LDCW "ldcw" +#endif /* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. We don't explicitly expose that "*a" may be written as reload only in patch2: unchanged: --- linux-6.2.0.orig/arch/parisc/include/asm/led.h +++ linux-6.2.0/arch/parisc/include/asm/led.h @@ -11,8 +11,8 @@ #define LED1 0x02 #define LED0 0x01 /* bottom (or furthest left) LED */ -#define LED_LAN_TX LED0 /* for LAN transmit activity */ -#define LED_LAN_RCV LED1 /* for LAN receive activity */ +#define LED_LAN_RCV LED0 /* for LAN receive activity */ +#define LED_LAN_TX LED1 /* for LAN transmit activity */ #define LED_DISK_IO LED2 /* for disk activity */ #define LED_HEARTBEAT LED3 /* heartbeat */ only in patch2: unchanged: --- linux-6.2.0.orig/arch/parisc/include/asm/ropes.h +++ linux-6.2.0/arch/parisc/include/asm/ropes.h @@ -86,6 +86,9 @@ struct ioc ioc[MAX_IOC]; }; +/* list of SBA's in system, see drivers/parisc/sba_iommu.c */ +extern struct sba_device *sba_list; + #define ASTRO_RUNWAY_PORT 0x582 #define IKE_MERCED_PORT 0x803 #define REO_MERCED_PORT 0x804 only in patch2: unchanged: --- linux-6.2.0.orig/arch/parisc/include/asm/spinlock_types.h +++ linux-6.2.0/arch/parisc/include/asm/spinlock_types.h @@ -3,13 +3,8 @@ #define __ASM_SPINLOCK_TYPES_H typedef struct { -#ifdef CONFIG_PA20 - volatile unsigned int slock; -# define __ARCH_SPIN_LOCK_UNLOCKED { 1 } -#else volatile unsigned int lock[4]; # define __ARCH_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } } -#endif } arch_spinlock_t; only in patch2: unchanged: --- linux-6.2.0.orig/arch/parisc/kernel/drivers.c +++ linux-6.2.0/arch/parisc/kernel/drivers.c @@ -924,9 +924,9 @@ pr_info("#define PARISC_MODEL \"%s\"\n\n", boot_cpu_data.pdc.sys_model_name); + #define p ((unsigned long *)&boot_cpu_data.pdc.model) pr_info("#define PARISC_PDC_MODEL 0x%lx, 0x%lx, 0x%lx, " "0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx\n\n", - #define p ((unsigned long *)&boot_cpu_data.pdc.model) p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8]); #undef p only in patch2: unchanged: --- linux-6.2.0.orig/arch/parisc/kernel/irq.c +++ linux-6.2.0/arch/parisc/kernel/irq.c @@ -368,7 +368,7 @@ volatile unsigned int lock[1]; }; -DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { +static DEFINE_PER_CPU(union irq_stack_union, irq_stack_union) = { .slock = { 1,1,1,1 }, }; #endif only in patch2: unchanged: --- linux-6.2.0.orig/arch/parisc/kernel/processor.c +++ linux-6.2.0/arch/parisc/kernel/processor.c @@ -377,10 +377,18 @@ show_cpuinfo (struct seq_file *m, void *v) { unsigned long cpu; + char cpu_name[60], *p; + + /* strip PA path from CPU name to not confuse lscpu */ + strlcpy(cpu_name, per_cpu(cpu_data, 0).dev->name, sizeof(cpu_name)); + p = strrchr(cpu_name, '['); + if (p) + *(--p) = 0; for_each_online_cpu(cpu) { - const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); #ifdef CONFIG_SMP + const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu); + if (0 == cpuinfo->hpa) continue; #endif @@ -425,8 +433,7 @@ seq_printf(m, "model\t\t: %s - %s\n", boot_cpu_data.pdc.sys_model_name, - cpuinfo->dev ? - cpuinfo->dev->name : "Unknown"); + cpu_name); seq_printf(m, "hversion\t: 0x%08x\n" "sversion\t: 0x%08x\n", only in patch2: unchanged: --- linux-6.2.0.orig/arch/parisc/kernel/smp.c +++ linux-6.2.0/arch/parisc/kernel/smp.c @@ -443,7 +443,9 @@ if (cpu_online(cpu)) return 0; - if (num_online_cpus() < setup_max_cpus && smp_boot_one_cpu(cpu, tidle)) + if (num_online_cpus() < nr_cpu_ids && + num_online_cpus() < setup_max_cpus && + smp_boot_one_cpu(cpu, tidle)) return -EIO; return cpu_online(cpu) ? 0 : -EIO; only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/include/asm/ftrace.h +++ linux-6.2.0/arch/powerpc/include/asm/ftrace.h @@ -12,7 +12,7 @@ /* Ignore unused weak functions which will have larger offsets */ #ifdef CONFIG_MPROFILE_KERNEL -#define FTRACE_MCOUNT_MAX_OFFSET 12 +#define FTRACE_MCOUNT_MAX_OFFSET 16 #elif defined(CONFIG_PPC32) #define FTRACE_MCOUNT_MAX_OFFSET 8 #endif only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/include/asm/lppaca.h +++ linux-6.2.0/arch/powerpc/include/asm/lppaca.h @@ -45,6 +45,7 @@ #include #include #include +#include /* * The lppaca is the "virtual processor area" registered with the hypervisor, @@ -127,13 +128,23 @@ */ #define LPPACA_OLD_SHARED_PROC 2 -static inline bool lppaca_shared_proc(struct lppaca *l) +#ifdef CONFIG_PPC_PSERIES +/* + * All CPUs should have the same shared proc value, so directly access the PACA + * to avoid false positives from DEBUG_PREEMPT. + */ +static inline bool lppaca_shared_proc(void) { + struct lppaca *l = local_paca->lppaca_ptr; + if (!firmware_has_feature(FW_FEATURE_SPLPAR)) return false; return !!(l->__old_status & LPPACA_OLD_SHARED_PROC); } +#define get_lppaca() (get_paca()->lppaca_ptr) +#endif + /* * SLB shadow buffer structure as defined in the PAPR. The save_area * contains adjacent ESID and VSID pairs for each shadowed SLB. The only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/include/asm/paravirt.h +++ linux-6.2.0/arch/powerpc/include/asm/paravirt.h @@ -6,6 +6,7 @@ #include #ifdef CONFIG_PPC64 #include +#include #include #endif only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/include/asm/plpar_wrappers.h +++ linux-6.2.0/arch/powerpc/include/asm/plpar_wrappers.h @@ -9,6 +9,7 @@ #include #include +#include #include static inline long poll_pending(void) only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/kernel/fadump.c +++ linux-6.2.0/arch/powerpc/kernel/fadump.c @@ -654,6 +654,7 @@ return ret; error_out: fw_dump.fadump_enabled = 0; + fw_dump.reserve_dump_area_size = 0; return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/kernel/hw_breakpoint.c +++ linux-6.2.0/arch/powerpc/kernel/hw_breakpoint.c @@ -505,11 +505,13 @@ struct arch_hw_breakpoint *info; int i; + preempt_disable(); + for (i = 0; i < nr_wp_slots(); i++) { if (unlikely(tsk->thread.last_hit_ubp[i])) goto reset; } - return; + goto out; reset: regs_set_return_msr(regs, regs->msr & ~MSR_SE); @@ -518,6 +520,9 @@ __set_breakpoint(i, info); tsk->thread.last_hit_ubp[i] = NULL; } + +out: + preempt_enable(); } static bool is_larx_stcx_instr(int type) @@ -632,6 +637,11 @@ } } +/* + * Handle a DABR or DAWR exception. + * + * Called in atomic context. + */ int hw_breakpoint_handler(struct die_args *args) { bool err = false; @@ -758,6 +768,8 @@ /* * Handle single-step exceptions following a DABR hit. + * + * Called in atomic context. */ static int single_step_dabr_instruction(struct die_args *args) { @@ -815,6 +827,8 @@ /* * Handle debug exception notifications. + * + * Called in atomic context. */ int hw_breakpoint_exceptions_notify( struct notifier_block *unused, unsigned long val, void *data) only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/kernel/hw_breakpoint_constraints.c +++ linux-6.2.0/arch/powerpc/kernel/hw_breakpoint_constraints.c @@ -131,8 +131,13 @@ int *type, int *size, unsigned long *ea) { struct instruction_op op; + int err; - if (__get_user_instr(*instr, (void __user *)regs->nip)) + pagefault_disable(); + err = __get_user_instr(*instr, (void __user *)regs->nip); + pagefault_enable(); + + if (err) return; analyse_instr(&op, regs, *instr); only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/kvm/book3s_hv_ras.c +++ linux-6.2.0/arch/powerpc/kvm/book3s_hv_ras.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/mm/book3s64/slb.c +++ linux-6.2.0/arch/powerpc/mm/book3s64/slb.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/perf/core-fsl-emb.c +++ linux-6.2.0/arch/powerpc/perf/core-fsl-emb.c @@ -645,7 +645,6 @@ struct cpu_hw_events *cpuhw = this_cpu_ptr(&cpu_hw_events); struct perf_event *event; unsigned long val; - int found = 0; for (i = 0; i < ppmu->n_counter; ++i) { event = cpuhw->event[i]; @@ -654,7 +653,6 @@ if ((int)val < 0) { if (event) { /* event has overflowed */ - found = 1; record_and_restart(event, val, regs); } else { /* @@ -672,11 +670,13 @@ isync(); } -void hw_perf_event_setup(int cpu) +static int fsl_emb_pmu_prepare_cpu(unsigned int cpu) { struct cpu_hw_events *cpuhw = &per_cpu(cpu_hw_events, cpu); memset(cpuhw, 0, sizeof(*cpuhw)); + + return 0; } int register_fsl_emb_pmu(struct fsl_emb_pmu *pmu) @@ -689,6 +689,8 @@ pmu->name); perf_pmu_register(&fsl_emb_pmu, "cpu", PERF_TYPE_RAW); + cpuhp_setup_state(CPUHP_PERF_POWER, "perf/powerpc:prepare", + fsl_emb_pmu_prepare_cpu, NULL); return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/perf/hv-24x7.c +++ linux-6.2.0/arch/powerpc/perf/hv-24x7.c @@ -1431,7 +1431,7 @@ } domain = event_get_domain(event); - if (domain >= HV_PERF_DOMAIN_MAX) { + if (domain == 0 || domain >= HV_PERF_DOMAIN_MAX) { pr_devel("invalid domain %d\n", domain); return -EINVAL; } only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/platforms/powermac/time.c +++ linux-6.2.0/arch/powerpc/platforms/powermac/time.c @@ -26,8 +26,8 @@ #include #include +#include #include -#include #include #include #include @@ -182,7 +182,7 @@ return 0; } of_node_put(vias); - via = ioremap(rsrc.start, resource_size(&rsrc)); + via = early_ioremap(rsrc.start, resource_size(&rsrc)); if (via == NULL) { printk(KERN_ERR "Failed to map VIA for timer calibration !\n"); return 0; @@ -207,7 +207,7 @@ ppc_tb_freq = (dstart - dend) * 100 / 6; - iounmap(via); + early_iounmap((void *)via, resource_size(&rsrc)); return 1; } only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/platforms/pseries/ibmebus.c +++ linux-6.2.0/arch/powerpc/platforms/pseries/ibmebus.c @@ -455,6 +455,7 @@ if (err) { printk(KERN_WARNING "%s: device_register returned %i\n", __func__, err); + put_device(&ibmebus_bus_device); bus_unregister(&ibmebus_bus_type); return err; only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/platforms/pseries/lpar.c +++ linux-6.2.0/arch/powerpc/platforms/pseries/lpar.c @@ -638,16 +638,8 @@ static int __init vcpudispatch_stats_procfs_init(void) { - /* - * Avoid smp_processor_id while preemptible. All CPUs should have - * the same value for lppaca_shared_proc. - */ - preempt_disable(); - if (!lppaca_shared_proc(get_lppaca())) { - preempt_enable(); + if (!lppaca_shared_proc()) return 0; - } - preempt_enable(); if (!proc_create("powerpc/vcpudispatch_stats", 0600, NULL, &vcpudispatch_stats_proc_ops)) only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/platforms/pseries/lparcfg.c +++ linux-6.2.0/arch/powerpc/platforms/pseries/lparcfg.c @@ -205,7 +205,7 @@ ppp_data.active_system_procs); /* pool related entries are appropriate for shared configs */ - if (lppaca_shared_proc(get_lppaca())) { + if (lppaca_shared_proc()) { unsigned long pool_idle_time, pool_procs; seq_printf(m, "pool=%d\n", ppp_data.pool_num); @@ -616,7 +616,7 @@ partition_potential_processors); seq_printf(m, "shared_processor_mode=%d\n", - lppaca_shared_proc(get_lppaca())); + lppaca_shared_proc()); #ifdef CONFIG_PPC_64S_HASH_MMU if (!radix_enabled()) only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/platforms/pseries/setup.c +++ linux-6.2.0/arch/powerpc/platforms/pseries/setup.c @@ -846,7 +846,7 @@ if (firmware_has_feature(FW_FEATURE_LPAR)) { vpa_init(boot_cpuid); - if (lppaca_shared_proc(get_lppaca())) { + if (lppaca_shared_proc()) { static_branch_enable(&shared_processor); pv_spinlocks_init(); #ifdef CONFIG_PARAVIRT_TIME_ACCOUNTING only in patch2: unchanged: --- linux-6.2.0.orig/arch/powerpc/sysdev/mpc5xxx_clocks.c +++ linux-6.2.0/arch/powerpc/sysdev/mpc5xxx_clocks.c @@ -25,8 +25,10 @@ fwnode_for_each_parent_node(fwnode, parent) { ret = fwnode_property_read_u32(parent, "bus-frequency", &bus_freq); - if (!ret) + if (!ret) { + fwnode_handle_put(parent); return bus_freq; + } } return 0; only in patch2: unchanged: --- linux-6.2.0.orig/arch/riscv/include/asm/errata_list.h +++ linux-6.2.0/arch/riscv/include/asm/errata_list.h @@ -102,7 +102,7 @@ * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | * 0000001 01001 rs1 000 00000 0001011 * dcache.cva rs1 (clean, virtual address) - * 0000001 00100 rs1 000 00000 0001011 + * 0000001 00101 rs1 000 00000 0001011 * * dcache.cipa rs1 (clean then invalidate, physical address) * | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 | @@ -115,7 +115,7 @@ * 0000000 11001 00000 000 00000 0001011 */ #define THEAD_inval_A0 ".long 0x0265000b" -#define THEAD_clean_A0 ".long 0x0245000b" +#define THEAD_clean_A0 ".long 0x0255000b" #define THEAD_flush_A0 ".long 0x0275000b" #define THEAD_SYNC_S ".long 0x0190000b" only in patch2: unchanged: --- linux-6.2.0.orig/arch/s390/crypto/paes_s390.c +++ linux-6.2.0/arch/s390/crypto/paes_s390.c @@ -35,7 +35,7 @@ * and padding is also possible, the limits need to be generous. */ #define PAES_MIN_KEYSIZE 16 -#define PAES_MAX_KEYSIZE 320 +#define PAES_MAX_KEYSIZE MAXEP11AESKEYBLOBSIZE static u8 *ctrblk; static DEFINE_MUTEX(ctrblk_lock); only in patch2: unchanged: --- linux-6.2.0.orig/arch/s390/include/uapi/asm/pkey.h +++ linux-6.2.0/arch/s390/include/uapi/asm/pkey.h @@ -26,7 +26,7 @@ #define MAXCLRKEYSIZE 32 /* a clear key value may be up to 32 bytes */ #define MAXAESCIPHERKEYSIZE 136 /* our aes cipher keys have always 136 bytes */ #define MINEP11AESKEYBLOBSIZE 256 /* min EP11 AES key blob size */ -#define MAXEP11AESKEYBLOBSIZE 320 /* max EP11 AES key blob size */ +#define MAXEP11AESKEYBLOBSIZE 336 /* max EP11 AES key blob size */ /* Minimum size of a key blob */ #define MINKEYBLOBSIZE SECKEYBLOBSIZE only in patch2: unchanged: --- linux-6.2.0.orig/arch/sh/boards/mach-ap325rxa/setup.c +++ linux-6.2.0/arch/sh/boards/mach-ap325rxa/setup.c @@ -530,7 +530,7 @@ device_initialize(&ap325rxa_ceu_device.dev); dma_declare_coherent_memory(&ap325rxa_ceu_device.dev, ceu_dma_membase, ceu_dma_membase, - ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(&ap325rxa_ceu_device); only in patch2: unchanged: --- linux-6.2.0.orig/arch/sh/boards/mach-ecovec24/setup.c +++ linux-6.2.0/arch/sh/boards/mach-ecovec24/setup.c @@ -1454,15 +1454,13 @@ device_initialize(&ecovec_ceu_devices[0]->dev); dma_declare_coherent_memory(&ecovec_ceu_devices[0]->dev, ceu0_dma_membase, ceu0_dma_membase, - ceu0_dma_membase + - CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(ecovec_ceu_devices[0]); device_initialize(&ecovec_ceu_devices[1]->dev); dma_declare_coherent_memory(&ecovec_ceu_devices[1]->dev, ceu1_dma_membase, ceu1_dma_membase, - ceu1_dma_membase + - CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(ecovec_ceu_devices[1]); gpiod_add_lookup_table(&cn12_power_gpiod_table); only in patch2: unchanged: --- linux-6.2.0.orig/arch/sh/boards/mach-kfr2r09/setup.c +++ linux-6.2.0/arch/sh/boards/mach-kfr2r09/setup.c @@ -603,7 +603,7 @@ device_initialize(&kfr2r09_ceu_device.dev); dma_declare_coherent_memory(&kfr2r09_ceu_device.dev, ceu_dma_membase, ceu_dma_membase, - ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(&kfr2r09_ceu_device); only in patch2: unchanged: --- linux-6.2.0.orig/arch/sh/boards/mach-migor/setup.c +++ linux-6.2.0/arch/sh/boards/mach-migor/setup.c @@ -604,7 +604,7 @@ device_initialize(&migor_ceu_device.dev); dma_declare_coherent_memory(&migor_ceu_device.dev, ceu_dma_membase, ceu_dma_membase, - ceu_dma_membase + CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(&migor_ceu_device); only in patch2: unchanged: --- linux-6.2.0.orig/arch/sh/boards/mach-se/7724/setup.c +++ linux-6.2.0/arch/sh/boards/mach-se/7724/setup.c @@ -940,15 +940,13 @@ device_initialize(&ms7724se_ceu_devices[0]->dev); dma_declare_coherent_memory(&ms7724se_ceu_devices[0]->dev, ceu0_dma_membase, ceu0_dma_membase, - ceu0_dma_membase + - CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(ms7724se_ceu_devices[0]); device_initialize(&ms7724se_ceu_devices[1]->dev); dma_declare_coherent_memory(&ms7724se_ceu_devices[1]->dev, ceu1_dma_membase, ceu1_dma_membase, - ceu1_dma_membase + - CEU_BUFFER_MEMORY_SIZE - 1); + CEU_BUFFER_MEMORY_SIZE); platform_device_add(ms7724se_ceu_devices[1]); return platform_add_devices(ms7724se_devices, only in patch2: unchanged: --- linux-6.2.0.orig/arch/sh/drivers/push-switch.c +++ linux-6.2.0/arch/sh/drivers/push-switch.c @@ -101,8 +101,8 @@ device_remove_file(&pdev->dev, &dev_attr_switch); platform_set_drvdata(pdev, NULL); - flush_work(&psw->work); timer_shutdown_sync(&psw->debounce); + flush_work(&psw->work); free_irq(irq, pdev); kfree(psw); only in patch2: unchanged: --- linux-6.2.0.orig/arch/um/configs/i386_defconfig +++ linux-6.2.0/arch/um/configs/i386_defconfig @@ -35,6 +35,7 @@ CONFIG_XTERM_CHAN=y CONFIG_CON_CHAN="pts" CONFIG_SSL_CHAN="pts" +CONFIG_SOUND=m CONFIG_UML_SOUND=m CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y only in patch2: unchanged: --- linux-6.2.0.orig/arch/um/configs/x86_64_defconfig +++ linux-6.2.0/arch/um/configs/x86_64_defconfig @@ -33,6 +33,7 @@ CONFIG_XTERM_CHAN=y CONFIG_CON_CHAN="pts" CONFIG_SSL_CHAN="pts" +CONFIG_SOUND=m CONFIG_UML_SOUND=m CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y only in patch2: unchanged: --- linux-6.2.0.orig/arch/um/drivers/Kconfig +++ linux-6.2.0/arch/um/drivers/Kconfig @@ -111,24 +111,14 @@ config UML_SOUND tristate "Sound support" + depends on SOUND + select SOUND_OSS_CORE help This option enables UML sound support. If enabled, it will pull in - soundcore and the UML hostaudio relay, which acts as a intermediary + the UML hostaudio relay, which acts as a intermediary between the host's dsp and mixer devices and the UML sound system. It is safe to say 'Y' here. -config SOUND - tristate - default UML_SOUND - -config SOUND_OSS_CORE - bool - default UML_SOUND - -config HOSTAUDIO - tristate - default UML_SOUND - endmenu menu "UML Network Devices" only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/boot/compressed/head_64.S +++ linux-6.2.0/arch/x86/boot/compressed/head_64.S @@ -459,11 +459,25 @@ /* Save the trampoline address in RCX */ movq %rax, %rcx + /* Set up 32-bit addressable stack */ + leaq TRAMPOLINE_32BIT_STACK_END(%rcx), %rsp + + /* + * Preserve live 64-bit registers on the stack: this is necessary + * because the architecture does not guarantee that GPRs will retain + * their full 64-bit values across a 32-bit mode switch. + */ + pushq %rbp + pushq %rbx + pushq %rsi + /* - * Load the address of trampoline_return() into RDI. - * It will be used by the trampoline to return to the main code. + * Push the 64-bit address of trampoline_return() onto the new stack. + * It will be used by the trampoline to return to the main code. Due to + * the 32-bit mode switch, it cannot be kept it in a register either. */ leaq trampoline_return(%rip), %rdi + pushq %rdi /* Switch to compatibility mode (CS.L = 0 CS.D = 1) via far return */ pushq $__KERNEL32_CS @@ -471,6 +485,11 @@ pushq %rax lretq trampoline_return: + /* Restore live 64-bit registers */ + popq %rsi + popq %rbx + popq %rbp + /* Restore the stack, the 32-bit trampoline uses its own stack */ leaq rva(boot_stack_end)(%rbx), %rsp @@ -582,7 +601,7 @@ /* * This is the 32-bit trampoline that will be copied over to low memory. * - * RDI contains the return address (might be above 4G). + * Return address is at the top of the stack (might be above 4G). * ECX contains the base address of the trampoline memory. * Non zero RDX means trampoline needs to enable 5-level paging. */ @@ -592,9 +611,6 @@ movl %eax, %ds movl %eax, %ss - /* Set up new stack */ - leal TRAMPOLINE_32BIT_STACK_END(%ecx), %esp - /* Disable paging */ movl %cr0, %eax btrl $X86_CR0_PG_BIT, %eax @@ -671,7 +687,7 @@ .code64 SYM_FUNC_START_LOCAL_NOALIGN(.Lpaging_enabled) /* Return from the trampoline */ - jmp *%rdi + retq SYM_FUNC_END(.Lpaging_enabled) /* only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/boot/compressed/ident_map_64.c +++ linux-6.2.0/arch/x86/boot/compressed/ident_map_64.c @@ -67,6 +67,14 @@ return NULL; } + /* Consumed more tables than expected? */ + if (pages->pgt_buf_offset == BOOT_PGT_SIZE_WARN) { + debug_putstr("pgt_buf running low in " __FILE__ "\n"); + debug_putstr("Need to raise BOOT_PGT_SIZE?\n"); + debug_putaddr(pages->pgt_buf_offset); + debug_putaddr(pages->pgt_buf_size); + } + entry = pages->pgt_buf + pages->pgt_buf_offset; pages->pgt_buf_offset += PAGE_SIZE; only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/include/asm/boot.h +++ linux-6.2.0/arch/x86/include/asm/boot.h @@ -40,23 +40,40 @@ #ifdef CONFIG_X86_64 # define BOOT_STACK_SIZE 0x4000 +/* + * Used by decompressor's startup_32() to allocate page tables for identity + * mapping of the 4G of RAM in 4-level paging mode: + * - 1 level4 table; + * - 1 level3 table; + * - 4 level2 table that maps everything with 2M pages; + * + * The additional level5 table needed for 5-level paging is allocated from + * trampoline_32bit memory. + */ # define BOOT_INIT_PGT_SIZE (6*4096) -# ifdef CONFIG_RANDOMIZE_BASE + /* - * Assuming all cross the 512GB boundary: - * 1 page for level4 - * (2+2)*4 pages for kernel, param, cmd_line, and randomized kernel - * 2 pages for first 2M (video RAM: CONFIG_X86_VERBOSE_BOOTUP). - * Total is 19 pages. + * Total number of page tables kernel_add_identity_map() can allocate, + * including page tables consumed by startup_32(). + * + * Worst-case scenario: + * - 5-level paging needs 1 level5 table; + * - KASLR needs to map kernel, boot_params, cmdline and randomized kernel, + * assuming all of them cross 256T boundary: + * + 4*2 level4 table; + * + 4*2 level3 table; + * + 4*2 level2 table; + * - X86_VERBOSE_BOOTUP needs to map the first 2M (video RAM): + * + 1 level4 table; + * + 1 level3 table; + * + 1 level2 table; + * Total: 28 tables + * + * Add 4 spare table in case decompressor touches anything beyond what is + * accounted above. Warn if it happens. */ -# ifdef CONFIG_X86_VERBOSE_BOOTUP -# define BOOT_PGT_SIZE (19*4096) -# else /* !CONFIG_X86_VERBOSE_BOOTUP */ -# define BOOT_PGT_SIZE (17*4096) -# endif -# else /* !CONFIG_RANDOMIZE_BASE */ -# define BOOT_PGT_SIZE BOOT_INIT_PGT_SIZE -# endif +# define BOOT_PGT_SIZE_WARN (28*4096) +# define BOOT_PGT_SIZE (32*4096) #else /* !CONFIG_X86_64 */ # define BOOT_STACK_SIZE 0x1000 only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/include/asm/kexec.h +++ linux-6.2.0/arch/x86/include/asm/kexec.h @@ -208,8 +208,6 @@ #endif #endif -typedef void crash_vmclear_fn(void); -extern crash_vmclear_fn __rcu *crash_vmclear_loaded_vmcss; extern void kdump_nmi_shootdown_cpus(void); #endif /* __ASSEMBLY__ */ only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/include/asm/pgtable_types.h +++ linux-6.2.0/arch/x86/include/asm/pgtable_types.h @@ -125,11 +125,12 @@ * instance, and is *not* included in this mask since * pte_modify() does modify it. */ -#define _PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ - _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY | \ - _PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC | \ - _PAGE_UFFD_WP) -#define _HPAGE_CHG_MASK (_PAGE_CHG_MASK | _PAGE_PSE) +#define _COMMON_PAGE_CHG_MASK (PTE_PFN_MASK | _PAGE_PCD | _PAGE_PWT | \ + _PAGE_SPECIAL | _PAGE_ACCESSED | _PAGE_DIRTY |\ + _PAGE_SOFT_DIRTY | _PAGE_DEVMAP | _PAGE_ENC | \ + _PAGE_UFFD_WP) +#define _PAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PAT) +#define _HPAGE_CHG_MASK (_COMMON_PAGE_CHG_MASK | _PAGE_PSE | _PAGE_PAT_LARGE) /* * The cache modes defined here are used to translate between pure SW usage only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/kernel/apm_32.c +++ linux-6.2.0/arch/x86/kernel/apm_32.c @@ -239,12 +239,6 @@ #endif /* - * The apm_bios device is one of the misc char devices. - * This is its minor number. - */ -#define APM_MINOR_DEV 134 - -/* * Various options can be changed at boot time as follows: * (We allow underscores for compatibility with the modules code) * apm=on/off enable/disable APM only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/kernel/callthunks.c +++ linux-6.2.0/arch/x86/kernel/callthunks.c @@ -272,7 +272,6 @@ pr_info("Setting up call depth tracking\n"); mutex_lock(&text_mutex); callthunks_setup(&cs, &builtin_coretext); - static_call_force_reinit(); thunks_initialized = true; mutex_unlock(&text_mutex); } only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/kernel/cpu/mce/internal.h +++ linux-6.2.0/arch/x86/kernel/cpu/mce/internal.h @@ -157,6 +157,9 @@ */ smca : 1, + /* Zen IFU quirk */ + zen_ifu_quirk : 1, + /* AMD-style error thresholding banks present. */ amd_threshold : 1, @@ -172,7 +175,7 @@ /* Skylake, Cascade Lake, Cooper Lake REP;MOVS* quirk */ skx_repmov_quirk : 1, - __reserved_0 : 56; + __reserved_0 : 55; }; extern struct mce_vendor_flags mce_flags; only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/kernel/cpu/sgx/encl.c +++ linux-6.2.0/arch/x86/kernel/cpu/sgx/encl.c @@ -235,6 +235,21 @@ return epc_page; } +/* + * Ensure the SECS page is not swapped out. Must be called with encl->lock + * to protect the enclave states including SECS and ensure the SECS page is + * not swapped out again while being used. + */ +static struct sgx_epc_page *sgx_encl_load_secs(struct sgx_encl *encl) +{ + struct sgx_epc_page *epc_page = encl->secs.epc_page; + + if (!epc_page) + epc_page = sgx_encl_eldu(&encl->secs, NULL); + + return epc_page; +} + static struct sgx_encl_page *__sgx_encl_load_page(struct sgx_encl *encl, struct sgx_encl_page *entry) { @@ -248,11 +263,9 @@ return entry; } - if (!(encl->secs.epc_page)) { - epc_page = sgx_encl_eldu(&encl->secs, NULL); - if (IS_ERR(epc_page)) - return ERR_CAST(epc_page); - } + epc_page = sgx_encl_load_secs(encl); + if (IS_ERR(epc_page)) + return ERR_CAST(epc_page); epc_page = sgx_encl_eldu(entry, encl->secs.epc_page); if (IS_ERR(epc_page)) @@ -339,6 +352,13 @@ mutex_lock(&encl->lock); + epc_page = sgx_encl_load_secs(encl); + if (IS_ERR(epc_page)) { + if (PTR_ERR(epc_page) == -EBUSY) + vmret = VM_FAULT_NOPAGE; + goto err_out_unlock; + } + epc_page = sgx_alloc_epc_page(encl_page, false); if (IS_ERR(epc_page)) { if (PTR_ERR(epc_page) == -EBUSY) only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/kernel/cpu/sgx/virt.c +++ linux-6.2.0/arch/x86/kernel/cpu/sgx/virt.c @@ -204,6 +204,7 @@ continue; xa_erase(&vepc->page_array, index); + cond_resched(); } /* @@ -222,6 +223,7 @@ list_add_tail(&epc_page->list, &secs_pages); xa_erase(&vepc->page_array, index); + cond_resched(); } /* @@ -243,6 +245,7 @@ if (sgx_vepc_free_page(epc_page)) list_add_tail(&epc_page->list, &secs_pages); + cond_resched(); } if (!list_empty(&secs_pages)) only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/kernel/kvm.c +++ linux-6.2.0/arch/x86/kernel/kvm.c @@ -966,10 +966,8 @@ * Ensure that _bss_decrypted section is marked as decrypted in the * shared pages list. */ - nr_pages = DIV_ROUND_UP(__end_bss_decrypted - __start_bss_decrypted, - PAGE_SIZE); early_set_mem_enc_dec_hypercall((unsigned long)__start_bss_decrypted, - nr_pages, 0); + __end_bss_decrypted - __start_bss_decrypted, 0); /* * If not booted using EFI, enable Live migration support. only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/kernel/sev-shared.c +++ linux-6.2.0/arch/x86/kernel/sev-shared.c @@ -253,7 +253,7 @@ return 0; } -static int sev_cpuid_hv(struct cpuid_leaf *leaf) +static int __sev_cpuid_hv_msr(struct cpuid_leaf *leaf) { int ret; @@ -276,6 +276,45 @@ return ret; } +static int __sev_cpuid_hv_ghcb(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) +{ + u32 cr4 = native_read_cr4(); + int ret; + + ghcb_set_rax(ghcb, leaf->fn); + ghcb_set_rcx(ghcb, leaf->subfn); + + if (cr4 & X86_CR4_OSXSAVE) + /* Safe to read xcr0 */ + ghcb_set_xcr0(ghcb, xgetbv(XCR_XFEATURE_ENABLED_MASK)); + else + /* xgetbv will cause #UD - use reset value for xcr0 */ + ghcb_set_xcr0(ghcb, 1); + + ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_CPUID, 0, 0); + if (ret != ES_OK) + return ret; + + if (!(ghcb_rax_is_valid(ghcb) && + ghcb_rbx_is_valid(ghcb) && + ghcb_rcx_is_valid(ghcb) && + ghcb_rdx_is_valid(ghcb))) + return ES_VMM_ERROR; + + leaf->eax = ghcb->save.rax; + leaf->ebx = ghcb->save.rbx; + leaf->ecx = ghcb->save.rcx; + leaf->edx = ghcb->save.rdx; + + return ES_OK; +} + +static int sev_cpuid_hv(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) +{ + return ghcb ? __sev_cpuid_hv_ghcb(ghcb, ctxt, leaf) + : __sev_cpuid_hv_msr(leaf); +} + /* * This may be called early while still running on the initial identity * mapping. Use RIP-relative addressing to obtain the correct address @@ -385,19 +424,20 @@ return false; } -static void snp_cpuid_hv(struct cpuid_leaf *leaf) +static void snp_cpuid_hv(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) { - if (sev_cpuid_hv(leaf)) + if (sev_cpuid_hv(ghcb, ctxt, leaf)) sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID_HV); } -static int snp_cpuid_postprocess(struct cpuid_leaf *leaf) +static int snp_cpuid_postprocess(struct ghcb *ghcb, struct es_em_ctxt *ctxt, + struct cpuid_leaf *leaf) { struct cpuid_leaf leaf_hv = *leaf; switch (leaf->fn) { case 0x1: - snp_cpuid_hv(&leaf_hv); + snp_cpuid_hv(ghcb, ctxt, &leaf_hv); /* initial APIC ID */ leaf->ebx = (leaf_hv.ebx & GENMASK(31, 24)) | (leaf->ebx & GENMASK(23, 0)); @@ -416,7 +456,7 @@ break; case 0xB: leaf_hv.subfn = 0; - snp_cpuid_hv(&leaf_hv); + snp_cpuid_hv(ghcb, ctxt, &leaf_hv); /* extended APIC ID */ leaf->edx = leaf_hv.edx; @@ -464,7 +504,7 @@ } break; case 0x8000001E: - snp_cpuid_hv(&leaf_hv); + snp_cpuid_hv(ghcb, ctxt, &leaf_hv); /* extended APIC ID */ leaf->eax = leaf_hv.eax; @@ -485,7 +525,7 @@ * Returns -EOPNOTSUPP if feature not enabled. Any other non-zero return value * should be treated as fatal by caller. */ -static int snp_cpuid(struct cpuid_leaf *leaf) +static int snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf) { const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table(); @@ -519,7 +559,7 @@ return 0; } - return snp_cpuid_postprocess(leaf); + return snp_cpuid_postprocess(ghcb, ctxt, leaf); } /* @@ -541,14 +581,14 @@ leaf.fn = fn; leaf.subfn = subfn; - ret = snp_cpuid(&leaf); + ret = snp_cpuid(NULL, NULL, &leaf); if (!ret) goto cpuid_done; if (ret != -EOPNOTSUPP) goto fail; - if (sev_cpuid_hv(&leaf)) + if (__sev_cpuid_hv_msr(&leaf)) goto fail; cpuid_done: @@ -589,6 +629,23 @@ sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ); } +static enum es_result vc_insn_string_check(struct es_em_ctxt *ctxt, + unsigned long address, + bool write) +{ + if (user_mode(ctxt->regs) && fault_in_kernel_space(address)) { + ctxt->fi.vector = X86_TRAP_PF; + ctxt->fi.error_code = X86_PF_USER; + ctxt->fi.cr2 = address; + if (write) + ctxt->fi.error_code |= X86_PF_WRITE; + + return ES_EXCEPTION; + } + + return ES_OK; +} + static enum es_result vc_insn_string_read(struct es_em_ctxt *ctxt, void *src, char *buf, unsigned int data_size, @@ -596,7 +653,12 @@ bool backwards) { int i, b = backwards ? -1 : 1; - enum es_result ret = ES_OK; + unsigned long address = (unsigned long)src; + enum es_result ret; + + ret = vc_insn_string_check(ctxt, address, false); + if (ret != ES_OK) + return ret; for (i = 0; i < count; i++) { void *s = src + (i * data_size * b); @@ -617,7 +679,12 @@ bool backwards) { int i, s = backwards ? -1 : 1; - enum es_result ret = ES_OK; + unsigned long address = (unsigned long)dst; + enum es_result ret; + + ret = vc_insn_string_check(ctxt, address, true); + if (ret != ES_OK) + return ret; for (i = 0; i < count; i++) { void *d = dst + (i * data_size * s); @@ -653,6 +720,9 @@ static enum es_result vc_ioio_exitinfo(struct es_em_ctxt *ctxt, u64 *exitinfo) { struct insn *insn = &ctxt->insn; + size_t size; + u64 port; + *exitinfo = 0; switch (insn->opcode.bytes[0]) { @@ -661,7 +731,7 @@ case 0x6d: *exitinfo |= IOIO_TYPE_INS; *exitinfo |= IOIO_SEG_ES; - *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; + port = ctxt->regs->dx & 0xffff; break; /* OUTS opcodes */ @@ -669,41 +739,43 @@ case 0x6f: *exitinfo |= IOIO_TYPE_OUTS; *exitinfo |= IOIO_SEG_DS; - *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; + port = ctxt->regs->dx & 0xffff; break; /* IN immediate opcodes */ case 0xe4: case 0xe5: *exitinfo |= IOIO_TYPE_IN; - *exitinfo |= (u8)insn->immediate.value << 16; + port = (u8)insn->immediate.value & 0xffff; break; /* OUT immediate opcodes */ case 0xe6: case 0xe7: *exitinfo |= IOIO_TYPE_OUT; - *exitinfo |= (u8)insn->immediate.value << 16; + port = (u8)insn->immediate.value & 0xffff; break; /* IN register opcodes */ case 0xec: case 0xed: *exitinfo |= IOIO_TYPE_IN; - *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; + port = ctxt->regs->dx & 0xffff; break; /* OUT register opcodes */ case 0xee: case 0xef: *exitinfo |= IOIO_TYPE_OUT; - *exitinfo |= (ctxt->regs->dx & 0xffff) << 16; + port = ctxt->regs->dx & 0xffff; break; default: return ES_DECODE_FAILED; } + *exitinfo |= port << 16; + switch (insn->opcode.bytes[0]) { case 0x6c: case 0x6e: @@ -713,12 +785,15 @@ case 0xee: /* Single byte opcodes */ *exitinfo |= IOIO_DATA_8; + size = 1; break; default: /* Length determined by instruction parsing */ *exitinfo |= (insn->opnd_bytes == 2) ? IOIO_DATA_16 : IOIO_DATA_32; + size = (insn->opnd_bytes == 2) ? 2 : 4; } + switch (insn->addr_bytes) { case 2: *exitinfo |= IOIO_ADDR_16; @@ -734,7 +809,7 @@ if (insn_has_rep_prefix(insn)) *exitinfo |= IOIO_REP; - return ES_OK; + return vc_ioio_check(ctxt, (u16)port, size); } static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt) @@ -845,14 +920,15 @@ return ret; } -static int vc_handle_cpuid_snp(struct pt_regs *regs) +static int vc_handle_cpuid_snp(struct ghcb *ghcb, struct es_em_ctxt *ctxt) { + struct pt_regs *regs = ctxt->regs; struct cpuid_leaf leaf; int ret; leaf.fn = regs->ax; leaf.subfn = regs->cx; - ret = snp_cpuid(&leaf); + ret = snp_cpuid(ghcb, ctxt, &leaf); if (!ret) { regs->ax = leaf.eax; regs->bx = leaf.ebx; @@ -871,7 +947,7 @@ enum es_result ret; int snp_cpuid_ret; - snp_cpuid_ret = vc_handle_cpuid_snp(regs); + snp_cpuid_ret = vc_handle_cpuid_snp(ghcb, ctxt); if (!snp_cpuid_ret) return ES_OK; if (snp_cpuid_ret != -EOPNOTSUPP) only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/kvm/svm/nested.c +++ linux-6.2.0/arch/x86/kvm/svm/nested.c @@ -672,10 +672,9 @@ vmcb02->control.tsc_offset = vcpu->arch.tsc_offset; - if (svm->tsc_ratio_msr != kvm_caps.default_tsc_scaling_ratio) { - WARN_ON(!svm->tsc_scaling_enabled); + if (svm->tsc_scaling_enabled && + svm->tsc_ratio_msr != kvm_caps.default_tsc_scaling_ratio) nested_svm_update_tsc_ratio_msr(vcpu); - } vmcb02->control.int_ctl = (svm->nested.ctl.int_ctl & int_ctl_vmcb12_bits) | @@ -1043,8 +1042,8 @@ vmcb_mark_dirty(vmcb01, VMCB_INTERCEPTS); } - if (svm->tsc_ratio_msr != kvm_caps.default_tsc_scaling_ratio) { - WARN_ON(!svm->tsc_scaling_enabled); + if (kvm_caps.has_tsc_control && + vcpu->arch.tsc_scaling_ratio != vcpu->arch.l1_tsc_scaling_ratio) { vcpu->arch.tsc_scaling_ratio = vcpu->arch.l1_tsc_scaling_ratio; __svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio); } only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/lib/memset_64.S +++ linux-6.2.0/arch/x86/lib/memset_64.S @@ -16,27 +16,22 @@ * rdx count (bytes) * * rax original destination + * + * The FSRS alternative should be done inline (avoiding the call and + * the disgusting return handling), but that would require some help + * from the compiler for better calling conventions. + * + * The 'rep stosb' itself is small enough to replace the call, but all + * the register moves blow up the code. And two of them are "needed" + * only for the return value that is the same as the source input, + * which the compiler could/should do much better anyway. */ SYM_FUNC_START(__memset) - /* - * Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended - * to use it when possible. If not available, use fast string instructions. - * - * Otherwise, use original memset function. - */ - ALTERNATIVE_2 "jmp memset_orig", "", X86_FEATURE_REP_GOOD, \ - "jmp memset_erms", X86_FEATURE_ERMS + ALTERNATIVE "jmp memset_orig", "", X86_FEATURE_FSRS movq %rdi,%r9 + movb %sil,%al movq %rdx,%rcx - andl $7,%edx - shrq $3,%rcx - /* expand byte value */ - movzbl %sil,%esi - movabs $0x0101010101010101,%rax - imulq %rsi,%rax - rep stosq - movl %edx,%ecx rep stosb movq %r9,%rax RET @@ -46,26 +41,6 @@ SYM_FUNC_ALIAS_WEAK(memset, __memset) EXPORT_SYMBOL(memset) -/* - * ISO C memset - set a memory block to a byte value. This function uses - * enhanced rep stosb to override the fast string function. - * The code is simpler and shorter than the fast string function as well. - * - * rdi destination - * rsi value (char) - * rdx count (bytes) - * - * rax original destination - */ -SYM_FUNC_START_LOCAL(memset_erms) - movq %rdi,%r9 - movb %sil,%al - movq %rdx,%rcx - rep stosb - movq %r9,%rax - RET -SYM_FUNC_END(memset_erms) - SYM_FUNC_START_LOCAL(memset_orig) movq %rdi,%r10 only in patch2: unchanged: --- linux-6.2.0.orig/arch/x86/lib/putuser.S +++ linux-6.2.0/arch/x86/lib/putuser.S @@ -56,7 +56,6 @@ EXPORT_SYMBOL(__put_user_1) SYM_FUNC_START(__put_user_nocheck_1) - ENDBR ASM_STAC 2: movb %al,(%_ASM_CX) xor %ecx,%ecx @@ -78,7 +77,6 @@ EXPORT_SYMBOL(__put_user_2) SYM_FUNC_START(__put_user_nocheck_2) - ENDBR ASM_STAC 4: movw %ax,(%_ASM_CX) xor %ecx,%ecx @@ -100,7 +98,6 @@ EXPORT_SYMBOL(__put_user_4) SYM_FUNC_START(__put_user_nocheck_4) - ENDBR ASM_STAC 6: movl %eax,(%_ASM_CX) xor %ecx,%ecx @@ -125,7 +122,6 @@ EXPORT_SYMBOL(__put_user_8) SYM_FUNC_START(__put_user_nocheck_8) - ENDBR ASM_STAC 9: mov %_ASM_AX,(%_ASM_CX) #ifdef CONFIG_X86_32 only in patch2: unchanged: --- linux-6.2.0.orig/arch/xtensa/boot/Makefile +++ linux-6.2.0/arch/xtensa/boot/Makefile @@ -9,8 +9,7 @@ # KBUILD_CFLAGS used when building rest of boot (takes effect recursively) -KBUILD_CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include -HOSTFLAGS += -Iarch/$(ARCH)/boot/include +KBUILD_CFLAGS += -fno-builtin subdir-y := lib targets += vmlinux.bin vmlinux.bin.gz only in patch2: unchanged: --- linux-6.2.0.orig/arch/xtensa/boot/lib/zmem.c +++ linux-6.2.0/arch/xtensa/boot/lib/zmem.c @@ -4,13 +4,14 @@ /* bits taken from ppc */ extern void *avail_ram, *end_avail; +void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp); -void exit (void) +static void exit(void) { for (;;); } -void *zalloc(unsigned size) +static void *zalloc(unsigned int size) { void *p = avail_ram; only in patch2: unchanged: --- linux-6.2.0.orig/arch/xtensa/include/asm/core.h +++ linux-6.2.0/arch/xtensa/include/asm/core.h @@ -6,6 +6,10 @@ #include +#ifndef XCHAL_HAVE_DIV32 +#define XCHAL_HAVE_DIV32 0 +#endif + #ifndef XCHAL_HAVE_EXCLUSIVE #define XCHAL_HAVE_EXCLUSIVE 0 #endif @@ -44,4 +48,13 @@ #define XTENSA_STACK_ALIGNMENT 16 #endif +#ifndef XCHAL_HW_MIN_VERSION +#if defined(XCHAL_HW_MIN_VERSION_MAJOR) && defined(XCHAL_HW_MIN_VERSION_MINOR) +#define XCHAL_HW_MIN_VERSION (XCHAL_HW_MIN_VERSION_MAJOR * 100 + \ + XCHAL_HW_MIN_VERSION_MINOR) +#else +#define XCHAL_HW_MIN_VERSION 0 +#endif +#endif + #endif only in patch2: unchanged: --- linux-6.2.0.orig/arch/xtensa/kernel/perf_event.c +++ linux-6.2.0/arch/xtensa/kernel/perf_event.c @@ -13,17 +13,26 @@ #include #include +#include #include #include +#define XTENSA_HWVERSION_RG_2015_0 260000 + +#if XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RG_2015_0 +#define XTENSA_PMU_ERI_BASE 0x00101000 +#else +#define XTENSA_PMU_ERI_BASE 0x00001000 +#endif + /* Global control/status for all perf counters */ -#define XTENSA_PMU_PMG 0x1000 +#define XTENSA_PMU_PMG XTENSA_PMU_ERI_BASE /* Perf counter values */ -#define XTENSA_PMU_PM(i) (0x1080 + (i) * 4) +#define XTENSA_PMU_PM(i) (XTENSA_PMU_ERI_BASE + 0x80 + (i) * 4) /* Perf counter control registers */ -#define XTENSA_PMU_PMCTRL(i) (0x1100 + (i) * 4) +#define XTENSA_PMU_PMCTRL(i) (XTENSA_PMU_ERI_BASE + 0x100 + (i) * 4) /* Perf counter status registers */ -#define XTENSA_PMU_PMSTAT(i) (0x1180 + (i) * 4) +#define XTENSA_PMU_PMSTAT(i) (XTENSA_PMU_ERI_BASE + 0x180 + (i) * 4) #define XTENSA_PMU_PMG_PMEN 0x1 only in patch2: unchanged: --- linux-6.2.0.orig/arch/xtensa/lib/umulsidi3.S +++ linux-6.2.0/arch/xtensa/lib/umulsidi3.S @@ -3,7 +3,9 @@ #include #include -#if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16 +#if XCHAL_HAVE_MUL16 || XCHAL_HAVE_MUL32 || XCHAL_HAVE_MAC16 +#define XCHAL_NO_MUL 0 +#else #define XCHAL_NO_MUL 1 #endif only in patch2: unchanged: --- linux-6.2.0.orig/block/blk-sysfs.c +++ linux-6.2.0/block/blk-sysfs.c @@ -531,21 +531,16 @@ static ssize_t queue_wc_store(struct request_queue *q, const char *page, size_t count) { - int set = -1; - - if (!strncmp(page, "write back", 10)) - set = 1; - else if (!strncmp(page, "write through", 13) || - !strncmp(page, "none", 4)) - set = 0; - - if (set == -1) - return -EINVAL; - - if (set) + if (!strncmp(page, "write back", 10)) { + if (!test_bit(QUEUE_FLAG_HW_WC, &q->queue_flags)) + return -EINVAL; blk_queue_flag_set(QUEUE_FLAG_WC, q); - else + } else if (!strncmp(page, "write through", 13) || + !strncmp(page, "none", 4)) { blk_queue_flag_clear(QUEUE_FLAG_WC, q); + } else { + return -EINVAL; + } return count; } only in patch2: unchanged: --- linux-6.2.0.orig/block/mq-deadline.c +++ linux-6.2.0/block/mq-deadline.c @@ -622,8 +622,9 @@ struct request_queue *q = hctx->queue; struct deadline_data *dd = q->elevator->elevator_data; struct blk_mq_tags *tags = hctx->sched_tags; + unsigned int shift = tags->bitmap_tags.sb.shift; - dd->async_depth = max(1UL, 3 * q->nr_requests / 4); + dd->async_depth = max(1U, 3 * (1U << shift) / 4); sbitmap_queue_min_shallow_depth(&tags->bitmap_tags, dd->async_depth); } only in patch2: unchanged: --- linux-6.2.0.orig/crypto/af_alg.c +++ linux-6.2.0/crypto/af_alg.c @@ -320,18 +320,21 @@ if (IS_ERR(ret)) { up_read(&key->sem); + key_put(key); return PTR_ERR(ret); } key_data = sock_kmalloc(&ask->sk, key_datalen, GFP_KERNEL); if (!key_data) { up_read(&key->sem); + key_put(key); return -ENOMEM; } memcpy(key_data, ret, key_datalen); up_read(&key->sem); + key_put(key); err = type->setkey(ask->private, key_data, key_datalen); only in patch2: unchanged: --- linux-6.2.0.orig/crypto/asymmetric_keys/x509_public_key.c +++ linux-6.2.0/crypto/asymmetric_keys/x509_public_key.c @@ -117,6 +117,11 @@ goto out; } + if (cert->unsupported_sig) { + ret = 0; + goto out; + } + ret = public_key_verify_signature(cert->pub, cert->sig); if (ret < 0) { if (ret == -ENOPKG) { only in patch2: unchanged: --- linux-6.2.0.orig/crypto/lrw.c +++ linux-6.2.0/crypto/lrw.c @@ -357,10 +357,10 @@ * cipher name. */ if (!strncmp(cipher_name, "ecb(", 4)) { - unsigned len; + int len; - len = strlcpy(ecb_name, cipher_name + 4, sizeof(ecb_name)); - if (len < 2 || len >= sizeof(ecb_name)) + len = strscpy(ecb_name, cipher_name + 4, sizeof(ecb_name)); + if (len < 2) goto err_free_inst; if (ecb_name[len - 1] != ')') only in patch2: unchanged: --- linux-6.2.0.orig/debian/scripts/misc/kconfig/run.py +++ linux-6.2.0/debian/scripts/misc/kconfig/run.py @@ -0,0 +1,365 @@ +# -*- mode: python -*- +# Manage Ubuntu kernel .config and annotations +# Copyright © 2022 Canonical Ltd. + +import sys +import os +import argparse +import json +from signal import signal, SIGPIPE, SIG_DFL + +try: + from argcomplete import autocomplete +except ModuleNotFoundError: + # Allow to run this program also when argcomplete is not available + def autocomplete(_unused): + pass + + +from kconfig.annotations import Annotation, KConfig # noqa: E402 Import not at top of file +from kconfig.utils import autodetect_annotations, arg_fail # noqa: E402 Import not at top of file +from kconfig.version import VERSION, ANNOTATIONS_FORMAT_VERSION # noqa: E402 Import not at top of file + + +SKIP_CONFIGS = ( + # CONFIG_VERSION_SIGNATURE is dynamically set during the build + "CONFIG_VERSION_SIGNATURE", + # Allow to use a different versions of toolchain tools + "CONFIG_GCC_VERSION", + "CONFIG_CC_VERSION_TEXT", + "CONFIG_AS_VERSION", + "CONFIG_LD_VERSION", + "CONFIG_LLD_VERSION", + "CONFIG_CLANG_VERSION", + "CONFIG_PAHOLE_VERSION", + "CONFIG_RUSTC_VERSION_TEXT", + "CONFIG_BINDGEN_VERSION_TEXT", +) + + +def make_parser(): + parser = argparse.ArgumentParser( + description="Manage Ubuntu kernel .config and annotations", + ) + parser.add_argument("--version", "-v", action="version", version=f"%(prog)s {VERSION}") + + parser.add_argument( + "--file", + "-f", + action="store", + help="Pass annotations or .config file to be parsed", + ) + parser.add_argument("--arch", "-a", action="store", help="Select architecture") + parser.add_argument("--flavour", "-l", action="store", help='Select flavour (default is "generic")') + parser.add_argument("--config", "-c", action="store", help="Select a specific config option") + parser.add_argument("--query", "-q", action="store_true", help="Query annotations") + parser.add_argument( + "--note", + "-n", + action="store", + help="Write a specific note to a config option in annotations", + ) + parser.add_argument( + "--autocomplete", + action="store_true", + help="Enable config bash autocomplete: `source <(annotations --autocomplete)`", + ) + parser.add_argument( + "--source", + "-t", + action="store_true", + help="Jump to a config definition in the kernel source code", + ) + parser.add_argument( + "--no-include", + action="store_true", + help="Do not process included annotations (stop at the main file)", + ) + + ga = parser.add_argument_group(title="Action").add_mutually_exclusive_group(required=False) + ga.add_argument( + "--write", + "-w", + action="store", + metavar="VALUE", + dest="value", + help="Set a specific config value in annotations (use 'null' to remove)", + ) + ga.add_argument( + "--export", + "-e", + action="store_true", + help="Convert annotations to .config format", + ) + ga.add_argument( + "--import", + "-i", + action="store", + metavar="FILE", + dest="import_file", + help="Import a full .config for a specific arch and flavour into annotations", + ) + ga.add_argument( + "--update", + "-u", + action="store", + metavar="FILE", + dest="update_file", + help="Import a partial .config into annotations (only resync configs specified in FILE)", + ) + ga.add_argument( + "--check", + "-k", + action="store", + metavar="FILE", + dest="check_file", + help="Validate kernel .config with annotations", + ) + return parser + + +_ARGPARSER = make_parser() + + +def export_result(data): + # Dump metadata / attributes first + out = '{\n "attributes": {\n' + for key, value in sorted(data["attributes"].items()): + out += f' "{key}": {json.dumps(value)},\n' + out = out.rstrip(",\n") + out += "\n }," + print(out) + + configs_with_note = {key: value for key, value in data["config"].items() if "note" in value} + configs_without_note = {key: value for key, value in data["config"].items() if "note" not in value} + + # Dump configs, sorted alphabetically, showing items with a note first + out = ' "config": {\n' + for key in sorted(configs_with_note) + sorted(configs_without_note): + policy = data["config"][key]["policy"] + if "note" in data["config"][key]: + note = data["config"][key]["note"] + out += f' "{key}": {{"policy": {json.dumps(policy)}, "note": {json.dumps(note)}}},\n' + else: + out += f' "{key}": {{"policy": {json.dumps(policy)}}},\n' + out = out.rstrip(",\n") + out += "\n }\n}" + print(out) + + +def print_result(config, data): + if data is not None and config is not None and config not in data: + data = {config: data} + print(json.dumps(data, sort_keys=True, indent=2)) + + +def do_query(args): + if args.arch is None and args.flavour is not None: + arg_fail(_ARGPARSER, "error: --flavour requires --arch") + a = Annotation(args.file, do_include=(not args.no_include)) + res = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour) + # If no arguments are specified dump the whole annotations structure + if args.config is None and args.arch is None and args.flavour is None: + res = { + "attributes": { + "arch": a.arch, + "flavour": a.flavour, + "flavour_dep": a.flavour_dep, + "include": a.include, + "_version": ANNOTATIONS_FORMAT_VERSION, + }, + "config": res, + } + export_result(res) + else: + print_result(args.config, res) + + +def do_autocomplete(args): + a = Annotation(args.file) + res = (c.removeprefix("CONFIG_") for c in a.search_config()) + res_str = " ".join(res) + print(f'complete -W "{res_str}" annotations') + + +def do_source(args): + if args.config is None: + arg_fail(_ARGPARSER, "error: --source requires --config") + if not os.path.exists("tags"): + print("tags not found in the current directory, try: `make tags`") + sys.exit(1) + os.system(f"vim -t {args.config}") + + +def do_note(args): + if args.config is None: + arg_fail(_ARGPARSER, "error: --note requires --config") + + # Set the note in annotations + a = Annotation(args.file) + a.set(args.config, note=args.note) + + # Save back to annotations + a.save(args.file) + + # Query and print back the value + a = Annotation(args.file) + res = a.search_config(config=args.config) + print_result(args.config, res) + + +def do_write(args): + if args.config is None: + arg_fail(_ARGPARSER, "error: --write requires --config") + + # Set the value in annotations ('null' means remove) + a = Annotation(args.file) + if args.value == "null": + a.remove(args.config, arch=args.arch, flavour=args.flavour) + else: + a.set( + args.config, + arch=args.arch, + flavour=args.flavour, + value=args.value, + note=args.note, + ) + + # Save back to annotations + a.save(args.file) + + # Query and print back the value + a = Annotation(args.file) + res = a.search_config(config=args.config) + print_result(args.config, res) + + +def do_export(args): + if args.arch is None: + arg_fail(_ARGPARSER, "error: --export requires --arch") + a = Annotation(args.file) + conf = a.search_config(config=args.config, arch=args.arch, flavour=args.flavour) + if conf: + print(a.to_config(conf)) + + +def do_import(args): + if args.arch is None: + arg_fail(_ARGPARSER, "error: --arch is required with --import") + if args.flavour is None: + arg_fail(_ARGPARSER, "error: --flavour is required with --import") + if args.config is not None: + arg_fail(_ARGPARSER, "error: --config cannot be used with --import (try --update)") + + # Merge with the current annotations + a = Annotation(args.file) + c = KConfig(args.import_file) + a.update(c, arch=args.arch, flavour=args.flavour) + + # Save back to annotations + a.save(args.file) + + +def do_update(args): + if args.arch is None: + arg_fail(_ARGPARSER, "error: --arch is required with --update") + + # Merge with the current annotations + a = Annotation(args.file) + c = KConfig(args.update_file) + if args.config is None: + configs = list(set(c.config.keys()) - set(SKIP_CONFIGS)) + if configs: + a.update(c, arch=args.arch, flavour=args.flavour, configs=configs) + + # Save back to annotations + a.save(args.file) + + +def do_check(args): + # Determine arch and flavour + if args.arch is None: + arg_fail(_ARGPARSER, "error: --arch is required with --check") + + print(f"check-config: loading annotations from {args.file}") + total = good = ret = 0 + + # Load annotations settings + a = Annotation(args.file) + a_configs = a.search_config(arch=args.arch, flavour=args.flavour).keys() + + # Parse target .config + c = KConfig(args.check_file) + c_configs = c.config.keys() + + # Validate .config against annotations + for conf in sorted(a_configs | c_configs): + if conf in SKIP_CONFIGS: + continue + entry = a.search_config(config=conf, arch=args.arch, flavour=args.flavour) + expected = entry[conf] if entry else "-" + value = c.config[conf] if conf in c.config else "-" + if value != expected: + policy = a.config[conf] if conf in a.config else "undefined" + if "policy" in policy: + policy = f"policy<{policy['policy']}>" + print(f"check-config: {conf} changed from {expected} to {value}: {policy})") + ret = 1 + else: + good += 1 + total += 1 + + num = total - good + if ret: + if os.path.exists(".git"): + print(f"check-config: {num} config options have been changed, review them with `git diff`") + else: + print(f"check-config: {num} config options have changed") + else: + print("check-config: all good") + sys.exit(ret) + + +def main(): + # Prevent broken pipe errors when showing output in pipe to other tools + # (less for example) + signal(SIGPIPE, SIG_DFL) + + # Main annotations program + autocomplete(_ARGPARSER) + args = _ARGPARSER.parse_args() + + if args.file is None: + args.file = autodetect_annotations() + if args.file is None: + arg_fail( + _ARGPARSER, + "error: could not determine DEBDIR, try using: --file/-f", + show_usage=False, + ) + + if args.config and not args.config.startswith("CONFIG_"): + args.config = "CONFIG_" + args.config + + if args.value: + do_write(args) + elif args.note: + do_note(args) + elif args.export: + do_export(args) + elif args.import_file: + do_import(args) + elif args.update_file: + do_update(args) + elif args.check_file: + do_check(args) + elif args.autocomplete: + do_autocomplete(args) + elif args.source: + do_source(args) + else: + do_query(args) + + +if __name__ == "__main__": + main() only in patch2: unchanged: --- linux-6.2.0.orig/debian/scripts/misc/kconfig/utils.py +++ linux-6.2.0/debian/scripts/misc/kconfig/utils.py @@ -0,0 +1,20 @@ +# -*- mode: python -*- +# Misc helpers for Kconfig and annotations +# Copyright © 2023 Canonical Ltd. + +import sys + + +def autodetect_annotations(): + try: + with open("debian/debian.env", "rt", encoding="utf-8") as fd: + return fd.read().rstrip().split("=")[1] + "/config/annotations" + except (FileNotFoundError, IndexError): + return None + + +def arg_fail(parser, message, show_usage=True): + print(message) + if show_usage: + parser.print_usage() + sys.exit(1) only in patch2: unchanged: --- linux-6.2.0.orig/debian/scripts/misc/kconfig/version.py +++ linux-6.2.0/debian/scripts/misc/kconfig/version.py @@ -0,0 +1,10 @@ +# -*- mode: python -*- +# version of annotations module +# Copyright © 2022 Canonical Ltd. + +VERSION = "0.1" + +ANNOTATIONS_FORMAT_VERSION = 5 + +if __name__ == "__main__": + print(VERSION) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/acpi/acpica/psopcode.c +++ linux-6.2.0/drivers/acpi/acpica/psopcode.c @@ -603,7 +603,7 @@ /* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY, AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R, - AML_FLAGS_EXEC_0A_0T_1R), + AML_FLAGS_EXEC_0A_0T_1R | AML_NO_OPERAND_RESOLVE), /* ACPI 5.0 opcodes */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/amba/bus.c +++ linux-6.2.0/drivers/amba/bus.c @@ -528,6 +528,7 @@ { struct amba_device *d = to_amba_device(dev); + of_node_put(d->dev.of_node); if (d->res.parent) release_resource(&d->res); mutex_destroy(&d->periphid_lock); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/ata/libahci.c +++ linux-6.2.0/drivers/ata/libahci.c @@ -1255,6 +1255,26 @@ return sprintf(buf, "%d\n", emp->blink_policy); } +static void ahci_port_clear_pending_irq(struct ata_port *ap) +{ + struct ahci_host_priv *hpriv = ap->host->private_data; + void __iomem *port_mmio = ahci_port_base(ap); + u32 tmp; + + /* clear SError */ + tmp = readl(port_mmio + PORT_SCR_ERR); + dev_dbg(ap->host->dev, "PORT_SCR_ERR 0x%x\n", tmp); + writel(tmp, port_mmio + PORT_SCR_ERR); + + /* clear port IRQ */ + tmp = readl(port_mmio + PORT_IRQ_STAT); + dev_dbg(ap->host->dev, "PORT_IRQ_STAT 0x%x\n", tmp); + if (tmp) + writel(tmp, port_mmio + PORT_IRQ_STAT); + + writel(1 << ap->port_no, hpriv->mmio + HOST_IRQ_STAT); +} + static void ahci_port_init(struct device *dev, struct ata_port *ap, int port_no, void __iomem *mmio, void __iomem *port_mmio) @@ -1269,18 +1289,7 @@ if (rc) dev_warn(dev, "%s (%d)\n", emsg, rc); - /* clear SError */ - tmp = readl(port_mmio + PORT_SCR_ERR); - dev_dbg(dev, "PORT_SCR_ERR 0x%x\n", tmp); - writel(tmp, port_mmio + PORT_SCR_ERR); - - /* clear port IRQ */ - tmp = readl(port_mmio + PORT_IRQ_STAT); - dev_dbg(dev, "PORT_IRQ_STAT 0x%x\n", tmp); - if (tmp) - writel(tmp, port_mmio + PORT_IRQ_STAT); - - writel(1 << port_no, mmio + HOST_IRQ_STAT); + ahci_port_clear_pending_irq(ap); /* mark esata ports */ tmp = readl(port_mmio + PORT_CMD); @@ -1601,6 +1610,8 @@ tf.status = ATA_BUSY; ata_tf_to_fis(&tf, 0, 0, d2h_fis); + ahci_port_clear_pending_irq(ap); + rc = sata_link_hardreset(link, timing, deadline, online, ahci_check_ready); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/ata/libata-sata.c +++ linux-6.2.0/drivers/ata/libata-sata.c @@ -394,10 +394,23 @@ case ATA_LPM_MED_POWER_WITH_DIPM: case ATA_LPM_MIN_POWER_WITH_PARTIAL: case ATA_LPM_MIN_POWER: - if (ata_link_nr_enabled(link) > 0) - /* no restrictions on LPM transitions */ + if (ata_link_nr_enabled(link) > 0) { + /* assume no restrictions on LPM transitions */ scontrol &= ~(0x7 << 8); - else { + + /* + * If the controller does not support partial, slumber, + * or devsleep, then disallow these transitions. + */ + if (link->ap->host->flags & ATA_HOST_NO_PART) + scontrol |= (0x1 << 8); + + if (link->ap->host->flags & ATA_HOST_NO_SSC) + scontrol |= (0x2 << 8); + + if (link->ap->host->flags & ATA_HOST_NO_DEVSLP) + scontrol |= (0x4 << 8); + } else { /* empty port, power off */ scontrol &= ~0xf; scontrol |= (0x1 << 2); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/ata/libata-transport.c +++ linux-6.2.0/drivers/ata/libata-transport.c @@ -266,6 +266,10 @@ put_device(dev); } +static const struct device_type ata_port_sas_type = { + .name = ATA_PORT_TYPE_NAME, +}; + /** ata_tport_add - initialize a transport ATA port structure * * @parent: parent device @@ -283,7 +287,10 @@ struct device *dev = &ap->tdev; device_initialize(dev); - dev->type = &ata_port_type; + if (ap->flags & ATA_FLAG_SAS_HOST) + dev->type = &ata_port_sas_type; + else + dev->type = &ata_port_type; dev->parent = parent; ata_host_get(ap->host); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/ata/libata.h +++ linux-6.2.0/drivers/ata/libata.h @@ -30,6 +30,8 @@ ATA_DNXFER_QUIET = (1 << 31), }; +#define ATA_PORT_TYPE_NAME "ata_port" + extern atomic_t ata_print_id; extern int atapi_passthru16; extern int libata_fua; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/ata/pata_arasan_cf.c +++ linux-6.2.0/drivers/ata/pata_arasan_cf.c @@ -529,7 +529,8 @@ /* dma_request_channel may sleep, so calling from process context */ acdev->dma_chan = dma_request_chan(acdev->host->dev, "data"); if (IS_ERR(acdev->dma_chan)) { - dev_err(acdev->host->dev, "Unable to get dma_chan\n"); + dev_err_probe(acdev->host->dev, PTR_ERR(acdev->dma_chan), + "Unable to get dma_chan\n"); acdev->dma_chan = NULL; goto chan_request_fail; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/ata/pata_falcon.c +++ linux-6.2.0/drivers/ata/pata_falcon.c @@ -123,8 +123,8 @@ struct resource *base_res, *ctl_res, *irq_res; struct ata_host *host; struct ata_port *ap; - void __iomem *base; - int irq = 0; + void __iomem *base, *ctl_base; + int irq = 0, io_offset = 1, reg_shift = 2; /* Falcon defaults */ dev_info(&pdev->dev, "Atari Falcon and Q40/Q60 PATA controller\n"); @@ -165,26 +165,34 @@ ap->pio_mask = ATA_PIO4; ap->flags |= ATA_FLAG_SLAVE_POSS | ATA_FLAG_NO_IORDY; - base = (void __iomem *)base_mem_res->start; /* N.B. this assumes data_addr will be used for word-sized I/O only */ - ap->ioaddr.data_addr = base + 0 + 0 * 4; - ap->ioaddr.error_addr = base + 1 + 1 * 4; - ap->ioaddr.feature_addr = base + 1 + 1 * 4; - ap->ioaddr.nsect_addr = base + 1 + 2 * 4; - ap->ioaddr.lbal_addr = base + 1 + 3 * 4; - ap->ioaddr.lbam_addr = base + 1 + 4 * 4; - ap->ioaddr.lbah_addr = base + 1 + 5 * 4; - ap->ioaddr.device_addr = base + 1 + 6 * 4; - ap->ioaddr.status_addr = base + 1 + 7 * 4; - ap->ioaddr.command_addr = base + 1 + 7 * 4; - - base = (void __iomem *)ctl_mem_res->start; - ap->ioaddr.altstatus_addr = base + 1; - ap->ioaddr.ctl_addr = base + 1; - - ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", - (unsigned long)base_mem_res->start, - (unsigned long)ctl_mem_res->start); + ap->ioaddr.data_addr = (void __iomem *)base_mem_res->start; + + if (base_res) { /* only Q40 has IO resources */ + io_offset = 0x10000; + reg_shift = 0; + base = (void __iomem *)base_res->start; + ctl_base = (void __iomem *)ctl_res->start; + } else { + base = (void __iomem *)base_mem_res->start; + ctl_base = (void __iomem *)ctl_mem_res->start; + } + + ap->ioaddr.error_addr = base + io_offset + (1 << reg_shift); + ap->ioaddr.feature_addr = base + io_offset + (1 << reg_shift); + ap->ioaddr.nsect_addr = base + io_offset + (2 << reg_shift); + ap->ioaddr.lbal_addr = base + io_offset + (3 << reg_shift); + ap->ioaddr.lbam_addr = base + io_offset + (4 << reg_shift); + ap->ioaddr.lbah_addr = base + io_offset + (5 << reg_shift); + ap->ioaddr.device_addr = base + io_offset + (6 << reg_shift); + ap->ioaddr.status_addr = base + io_offset + (7 << reg_shift); + ap->ioaddr.command_addr = base + io_offset + (7 << reg_shift); + + ap->ioaddr.altstatus_addr = ctl_base + io_offset; + ap->ioaddr.ctl_addr = ctl_base + io_offset; + + ata_port_desc(ap, "cmd %px ctl %px data %px", + base, ctl_base, ap->ioaddr.data_addr); irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (irq_res && irq_res->start > 0) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/ata/pata_ftide010.c +++ linux-6.2.0/drivers/ata/pata_ftide010.c @@ -567,6 +567,7 @@ }; module_platform_driver(pata_ftide010_driver); +MODULE_DESCRIPTION("low level driver for Faraday Technology FTIDE010"); MODULE_AUTHOR("Linus Walleij "); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/ata/sata_gemini.c +++ linux-6.2.0/drivers/ata/sata_gemini.c @@ -428,6 +428,7 @@ }; module_platform_driver(gemini_sata_driver); +MODULE_DESCRIPTION("low level driver for Cortina Systems Gemini SATA bridge"); MODULE_AUTHOR("Linus Walleij "); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:" DRV_NAME); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/ata/sata_mv.c +++ linux-6.2.0/drivers/ata/sata_mv.c @@ -1255,8 +1255,8 @@ for (b = 0; b < bytes; ) { for (w = 0, o = 0; b < bytes && w < 4; w++) { - o += snprintf(linebuf + o, sizeof(linebuf) - o, - "%08x ", readl(start + b)); + o += scnprintf(linebuf + o, sizeof(linebuf) - o, + "%08x ", readl(start + b)); b += sizeof(u32); } dev_dbg(dev, "%s: %p: %s\n", only in patch2: unchanged: --- linux-6.2.0.orig/drivers/base/regmap/regcache-rbtree.c +++ linux-6.2.0/drivers/base/regmap/regcache-rbtree.c @@ -277,7 +277,7 @@ blk = krealloc(rbnode->block, blklen * map->cache_word_size, - GFP_KERNEL); + map->alloc_flags); if (!blk) return -ENOMEM; @@ -286,7 +286,7 @@ if (BITS_TO_LONGS(blklen) > BITS_TO_LONGS(rbnode->blklen)) { present = krealloc(rbnode->cache_present, BITS_TO_LONGS(blklen) * sizeof(*present), - GFP_KERNEL); + map->alloc_flags); if (!present) return -ENOMEM; @@ -320,7 +320,7 @@ const struct regmap_range *range; int i; - rbnode = kzalloc(sizeof(*rbnode), GFP_KERNEL); + rbnode = kzalloc(sizeof(*rbnode), map->alloc_flags); if (!rbnode) return NULL; @@ -346,13 +346,13 @@ } rbnode->block = kmalloc_array(rbnode->blklen, map->cache_word_size, - GFP_KERNEL); + map->alloc_flags); if (!rbnode->block) goto err_free; rbnode->cache_present = kcalloc(BITS_TO_LONGS(rbnode->blklen), sizeof(*rbnode->cache_present), - GFP_KERNEL); + map->alloc_flags); if (!rbnode->cache_present) goto err_free_block; @@ -453,7 +453,8 @@ if (!rbnode) return -ENOMEM; regcache_rbtree_set_register(map, rbnode, - reg - rbnode->base_reg, value); + (reg - rbnode->base_reg) / map->reg_stride, + value); regcache_rbtree_insert(map, &rbtree_ctx->root, rbnode); rbtree_ctx->cached_rbnode = rbnode; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/base/test/test_async_driver_probe.c +++ linux-6.2.0/drivers/base/test/test_async_driver_probe.c @@ -84,7 +84,7 @@ pdev = platform_device_alloc(name, id); if (!pdev) - return NULL; + return ERR_PTR(-ENOMEM); if (nid != NUMA_NO_NODE) set_dev_node(&pdev->dev, nid); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/bluetooth/hci_nokia.c +++ linux-6.2.0/drivers/bluetooth/hci_nokia.c @@ -734,7 +734,11 @@ return err; } - clk_prepare_enable(sysclk); + err = clk_prepare_enable(sysclk); + if (err) { + dev_err(dev, "could not enable sysclk: %d", err); + return err; + } btdev->sysclk_speed = clk_get_rate(sysclk); clk_disable_unprepare(sysclk); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/bus/mhi/host/pm.c +++ linux-6.2.0/drivers/bus/mhi/host/pm.c @@ -470,6 +470,10 @@ /* Trigger MHI RESET so that the device will not access host memory */ if (!MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) { + /* Skip MHI RESET if in RDDM state */ + if (mhi_cntrl->rddm_image && mhi_get_exec_env(mhi_cntrl) == MHI_EE_RDDM) + goto skip_mhi_reset; + dev_dbg(dev, "Triggering MHI Reset in device\n"); mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); @@ -495,6 +499,7 @@ } } +skip_mhi_reset: dev_dbg(dev, "Waiting for all pending event ring processing to complete\n"); mhi_event = mhi_cntrl->mhi_event; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/char/hw_random/iproc-rng200.c +++ linux-6.2.0/drivers/char/hw_random/iproc-rng200.c @@ -182,6 +182,8 @@ return PTR_ERR(priv->base); } + dev_set_drvdata(dev, priv); + priv->rng.name = "iproc-rng200"; priv->rng.read = iproc_rng200_read; priv->rng.init = iproc_rng200_init; @@ -199,6 +201,28 @@ return 0; } +static int __maybe_unused iproc_rng200_suspend(struct device *dev) +{ + struct iproc_rng200_dev *priv = dev_get_drvdata(dev); + + iproc_rng200_cleanup(&priv->rng); + + return 0; +} + +static int __maybe_unused iproc_rng200_resume(struct device *dev) +{ + struct iproc_rng200_dev *priv = dev_get_drvdata(dev); + + iproc_rng200_init(&priv->rng); + + return 0; +} + +static const struct dev_pm_ops iproc_rng200_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(iproc_rng200_suspend, iproc_rng200_resume) +}; + static const struct of_device_id iproc_rng200_of_match[] = { { .compatible = "brcm,bcm2711-rng200", }, { .compatible = "brcm,bcm7211-rng200", }, @@ -212,6 +236,7 @@ .driver = { .name = "iproc-rng200", .of_match_table = iproc_rng200_of_match, + .pm = &iproc_rng200_pm_ops, }, .probe = iproc_rng200_probe, }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/char/hw_random/nomadik-rng.c +++ linux-6.2.0/drivers/char/hw_random/nomadik-rng.c @@ -13,8 +13,6 @@ #include #include -static struct clk *rng_clk; - static int nmk_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) { void __iomem *base = (void __iomem *)rng->priv; @@ -36,21 +34,20 @@ static int nmk_rng_probe(struct amba_device *dev, const struct amba_id *id) { + struct clk *rng_clk; void __iomem *base; int ret; - rng_clk = devm_clk_get(&dev->dev, NULL); + rng_clk = devm_clk_get_enabled(&dev->dev, NULL); if (IS_ERR(rng_clk)) { dev_err(&dev->dev, "could not get rng clock\n"); ret = PTR_ERR(rng_clk); return ret; } - clk_prepare_enable(rng_clk); - ret = amba_request_regions(dev, dev->dev.init_name); if (ret) - goto out_clk; + return ret; ret = -ENOMEM; base = devm_ioremap(&dev->dev, dev->res.start, resource_size(&dev->res)); @@ -64,15 +61,12 @@ out_release: amba_release_regions(dev); -out_clk: - clk_disable_unprepare(rng_clk); return ret; } static void nmk_rng_remove(struct amba_device *dev) { amba_release_regions(dev); - clk_disable_unprepare(rng_clk); } static const struct amba_id nmk_rng_ids[] = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/char/hw_random/pic32-rng.c +++ linux-6.2.0/drivers/char/hw_random/pic32-rng.c @@ -36,7 +36,6 @@ struct pic32_rng { void __iomem *base; struct hwrng rng; - struct clk *clk; }; /* @@ -70,6 +69,7 @@ static int pic32_rng_probe(struct platform_device *pdev) { struct pic32_rng *priv; + struct clk *clk; u32 v; int ret; @@ -81,13 +81,9 @@ if (IS_ERR(priv->base)) return PTR_ERR(priv->base); - priv->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(priv->clk)) - return PTR_ERR(priv->clk); - - ret = clk_prepare_enable(priv->clk); - if (ret) - return ret; + clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); /* enable TRNG in enhanced mode */ v = TRNGEN | TRNGMOD; @@ -98,15 +94,11 @@ ret = devm_hwrng_register(&pdev->dev, &priv->rng); if (ret) - goto err_register; + return ret; platform_set_drvdata(pdev, priv); return 0; - -err_register: - clk_disable_unprepare(priv->clk); - return ret; } static int pic32_rng_remove(struct platform_device *pdev) @@ -114,7 +106,6 @@ struct pic32_rng *rng = platform_get_drvdata(pdev); writel(0, rng->base + RNGCON); - clk_disable_unprepare(rng->clk); return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/char/ipmi/ipmi_si_intf.c +++ linux-6.2.0/drivers/char/ipmi/ipmi_si_intf.c @@ -2082,6 +2082,11 @@ new_smi->io.io_cleanup = NULL; } + if (rv && new_smi->si_sm) { + kfree(new_smi->si_sm); + new_smi->si_sm = NULL; + } + return rv; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/imx/clk-composite-8m.c +++ linux-6.2.0/drivers/clk/imx/clk-composite-8m.c @@ -97,7 +97,7 @@ int prediv_value; int div_value; int ret; - u32 val; + u32 orig, val; ret = imx8m_clk_composite_compute_dividers(rate, parent_rate, &prediv_value, &div_value); @@ -106,13 +106,15 @@ spin_lock_irqsave(divider->lock, flags); - val = readl(divider->reg); - val &= ~((clk_div_mask(divider->width) << divider->shift) | - (clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT)); + orig = readl(divider->reg); + val = orig & ~((clk_div_mask(divider->width) << divider->shift) | + (clk_div_mask(PCG_DIV_WIDTH) << PCG_DIV_SHIFT)); val |= (u32)(prediv_value - 1) << divider->shift; val |= (u32)(div_value - 1) << PCG_DIV_SHIFT; - writel(val, divider->reg); + + if (val != orig) + writel(val, divider->reg); spin_unlock_irqrestore(divider->lock, flags); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/imx/clk-pll14xx.c +++ linux-6.2.0/drivers/clk/imx/clk-pll14xx.c @@ -64,8 +64,6 @@ PLL_1443X_RATE(650000000U, 325, 3, 2, 0), PLL_1443X_RATE(594000000U, 198, 2, 2, 0), PLL_1443X_RATE(519750000U, 173, 2, 2, 16384), - PLL_1443X_RATE(393216000U, 262, 2, 3, 9437), - PLL_1443X_RATE(361267200U, 361, 3, 3, 17511), }; struct imx_pll14xx_clk imx_1443x_pll = { @@ -139,11 +137,10 @@ /* * Fractional PLL constrains: * - * a) 6MHz <= prate <= 25MHz - * b) 1 <= p <= 63 (1 <= p <= 4 prate = 24MHz) - * c) 64 <= m <= 1023 - * d) 0 <= s <= 6 - * e) -32768 <= k <= 32767 + * a) 1 <= p <= 63 + * b) 64 <= m <= 1023 + * c) 0 <= s <= 6 + * d) -32768 <= k <= 32767 * * fvco = (m * 65536 + k) * prate / (p * 65536) */ @@ -186,7 +183,7 @@ } /* Finally calculate best values */ - for (pdiv = 1; pdiv <= 7; pdiv++) { + for (pdiv = 1; pdiv <= 63; pdiv++) { for (sdiv = 0; sdiv <= 6; sdiv++) { /* calc mdiv = round(rate * pdiv * 2^sdiv) / prate) */ mdiv = DIV_ROUND_CLOSEST(rate * (pdiv << sdiv), prate); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/imx/clk-pllv4.c +++ linux-6.2.0/drivers/clk/imx/clk-pllv4.c @@ -44,11 +44,15 @@ u32 cfg_offset; u32 num_offset; u32 denom_offset; + bool use_mult_range; }; /* Valid PLL MULT Table */ static const int pllv4_mult_table[] = {33, 27, 22, 20, 17, 16}; +/* Valid PLL MULT range, (max, min) */ +static const int pllv4_mult_range[] = {54, 27}; + #define to_clk_pllv4(__hw) container_of(__hw, struct clk_pllv4, hw) #define LOCK_TIMEOUT_US USEC_PER_MSEC @@ -94,17 +98,30 @@ static long clk_pllv4_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *prate) { + struct clk_pllv4 *pll = to_clk_pllv4(hw); unsigned long parent_rate = *prate; unsigned long round_rate, i; u32 mfn, mfd = DEFAULT_MFD; bool found = false; u64 temp64; + u32 mult; - for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) { - round_rate = parent_rate * pllv4_mult_table[i]; - if (rate >= round_rate) { + if (pll->use_mult_range) { + temp64 = (u64)rate; + do_div(temp64, parent_rate); + mult = temp64; + if (mult >= pllv4_mult_range[1] && + mult <= pllv4_mult_range[0]) { + round_rate = parent_rate * mult; found = true; - break; + } + } else { + for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) { + round_rate = parent_rate * pllv4_mult_table[i]; + if (rate >= round_rate) { + found = true; + break; + } } } @@ -138,14 +155,20 @@ return round_rate + (u32)temp64; } -static bool clk_pllv4_is_valid_mult(unsigned int mult) +static bool clk_pllv4_is_valid_mult(struct clk_pllv4 *pll, unsigned int mult) { int i; /* check if mult is in valid MULT table */ - for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) { - if (pllv4_mult_table[i] == mult) + if (pll->use_mult_range) { + if (mult >= pllv4_mult_range[1] && + mult <= pllv4_mult_range[0]) return true; + } else { + for (i = 0; i < ARRAY_SIZE(pllv4_mult_table); i++) { + if (pllv4_mult_table[i] == mult) + return true; + } } return false; @@ -160,7 +183,7 @@ mult = rate / parent_rate; - if (!clk_pllv4_is_valid_mult(mult)) + if (!clk_pllv4_is_valid_mult(pll, mult)) return -EINVAL; if (parent_rate <= MAX_MFD) @@ -227,10 +250,13 @@ pll->base = base; - if (type == IMX_PLLV4_IMX8ULP) { + if (type == IMX_PLLV4_IMX8ULP || + type == IMX_PLLV4_IMX8ULP_1GHZ) { pll->cfg_offset = IMX8ULP_PLL_CFG_OFFSET; pll->num_offset = IMX8ULP_PLL_NUM_OFFSET; pll->denom_offset = IMX8ULP_PLL_DENOM_OFFSET; + if (type == IMX_PLLV4_IMX8ULP_1GHZ) + pll->use_mult_range = true; } else { pll->cfg_offset = PLL_CFG_OFFSET; pll->num_offset = PLL_NUM_OFFSET; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/imx/clk.h +++ linux-6.2.0/drivers/clk/imx/clk.h @@ -46,6 +46,7 @@ enum imx_pllv4_type { IMX_PLLV4_IMX7ULP, IMX_PLLV4_IMX8ULP, + IMX_PLLV4_IMX8ULP_1GHZ, }; enum imx_pfdv2_type { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/keystone/pll.c +++ linux-6.2.0/drivers/clk/keystone/pll.c @@ -209,7 +209,7 @@ } clk = clk_register_pll(NULL, node->name, parent_name, pll_data); - if (clk) { + if (!IS_ERR_OR_NULL(clk)) { of_clk_add_provider(node, of_clk_src_simple_get, clk); return; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/dispcc-sc8280xp.c +++ linux-6.2.0/drivers/clk/qcom/dispcc-sc8280xp.c @@ -3057,7 +3057,7 @@ .name = "disp0_mdss_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = HW_CTRL, + .flags = HW_CTRL | RETAIN_FF_ENABLE, }; static struct gdsc disp1_mdss_gdsc = { @@ -3069,7 +3069,7 @@ .name = "disp1_mdss_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = HW_CTRL, + .flags = HW_CTRL | RETAIN_FF_ENABLE, }; static struct gdsc disp0_mdss_int2_gdsc = { @@ -3081,7 +3081,7 @@ .name = "disp0_mdss_int2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = HW_CTRL, + .flags = HW_CTRL | RETAIN_FF_ENABLE, }; static struct gdsc disp1_mdss_int2_gdsc = { @@ -3093,7 +3093,7 @@ .name = "disp1_mdss_int2_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = HW_CTRL, + .flags = HW_CTRL | RETAIN_FF_ENABLE, }; static struct gdsc *disp0_cc_sc8280xp_gdscs[] = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/dispcc-sm8450.c +++ linux-6.2.0/drivers/clk/qcom/dispcc-sm8450.c @@ -1783,8 +1783,10 @@ return ret; regmap = qcom_cc_map(pdev, &disp_cc_sm8450_desc); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + goto err_put_rpm; + } clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config); clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config); @@ -1799,9 +1801,16 @@ regmap_update_bits(regmap, 0xe05c, BIT(0), BIT(0)); ret = qcom_cc_really_probe(pdev, &disp_cc_sm8450_desc, regmap); + if (ret) + goto err_put_rpm; pm_runtime_put(&pdev->dev); + return 0; + +err_put_rpm: + pm_runtime_put_sync(&pdev->dev); + return ret; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/gcc-mdm9615.c +++ linux-6.2.0/drivers/clk/qcom/gcc-mdm9615.c @@ -58,7 +58,7 @@ .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "pll0_vote", - .parent_names = (const char *[]){ "pll8" }, + .parent_names = (const char *[]){ "pll0" }, .num_parents = 1, .ops = &clk_pll_vote_ops, }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/gcc-sc7180.c +++ linux-6.2.0/drivers/clk/qcom/gcc-sc7180.c @@ -667,6 +667,7 @@ .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_5, .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .flags = CLK_OPS_PARENT_ENABLE, .ops = &clk_rcg2_floor_ops, }, }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/gcc-sc8280xp.c +++ linux-6.2.0/drivers/clk/qcom/gcc-sc8280xp.c @@ -6760,7 +6760,7 @@ .name = "pcie_0_tunnel_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = VOTABLE, + .flags = VOTABLE | RETAIN_FF_ENABLE, }; static struct gdsc pcie_1_tunnel_gdsc = { @@ -6771,7 +6771,7 @@ .name = "pcie_1_tunnel_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = VOTABLE, + .flags = VOTABLE | RETAIN_FF_ENABLE, }; /* @@ -6786,7 +6786,7 @@ .name = "pcie_2a_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = VOTABLE | ALWAYS_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, }; static struct gdsc pcie_2b_gdsc = { @@ -6797,7 +6797,7 @@ .name = "pcie_2b_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = VOTABLE | ALWAYS_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, }; static struct gdsc pcie_3a_gdsc = { @@ -6808,7 +6808,7 @@ .name = "pcie_3a_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = VOTABLE | ALWAYS_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, }; static struct gdsc pcie_3b_gdsc = { @@ -6819,7 +6819,7 @@ .name = "pcie_3b_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = VOTABLE | ALWAYS_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, }; static struct gdsc pcie_4_gdsc = { @@ -6830,7 +6830,7 @@ .name = "pcie_4_gdsc", }, .pwrsts = PWRSTS_OFF_ON, - .flags = VOTABLE | ALWAYS_ON, + .flags = VOTABLE | RETAIN_FF_ENABLE | ALWAYS_ON, }; static struct gdsc ufs_card_gdsc = { @@ -6839,6 +6839,7 @@ .name = "ufs_card_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE, }; static struct gdsc ufs_phy_gdsc = { @@ -6847,6 +6848,7 @@ .name = "ufs_phy_gdsc", }, .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE, }; static struct gdsc usb30_mp_gdsc = { @@ -6855,6 +6857,7 @@ .name = "usb30_mp_gdsc", }, .pwrsts = PWRSTS_RET_ON, + .flags = RETAIN_FF_ENABLE, }; static struct gdsc usb30_prim_gdsc = { @@ -6863,6 +6866,7 @@ .name = "usb30_prim_gdsc", }, .pwrsts = PWRSTS_RET_ON, + .flags = RETAIN_FF_ENABLE, }; static struct gdsc usb30_sec_gdsc = { @@ -6871,6 +6875,115 @@ .name = "usb30_sec_gdsc", }, .pwrsts = PWRSTS_RET_ON, + .flags = RETAIN_FF_ENABLE, +}; + +static struct gdsc emac_0_gdsc = { + .gdscr = 0xaa004, + .pd = { + .name = "emac_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE, +}; + +static struct gdsc emac_1_gdsc = { + .gdscr = 0xba004, + .pd = { + .name = "emac_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE, +}; + +static struct gdsc usb4_1_gdsc = { + .gdscr = 0xb8004, + .pd = { + .name = "usb4_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE, +}; + +static struct gdsc usb4_gdsc = { + .gdscr = 0x2a004, + .pd = { + .name = "usb4_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = RETAIN_FF_ENABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc = { + .gdscr = 0x7d050, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc = { + .gdscr = 0x7d058, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc = { + .gdscr = 0x7d054, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc = { + .gdscr = 0x7d06c, + .pd = { + .name = "hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_turing_mmu_tbu0_gdsc = { + .gdscr = 0x7d05c, + .pd = { + .name = "hlos1_vote_turing_mmu_tbu0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_turing_mmu_tbu1_gdsc = { + .gdscr = 0x7d060, + .pd = { + .name = "hlos1_vote_turing_mmu_tbu1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_turing_mmu_tbu2_gdsc = { + .gdscr = 0x7d0a0, + .pd = { + .name = "hlos1_vote_turing_mmu_tbu2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, +}; + +static struct gdsc hlos1_vote_turing_mmu_tbu3_gdsc = { + .gdscr = 0x7d0a4, + .pd = { + .name = "hlos1_vote_turing_mmu_tbu3_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = VOTABLE, }; static struct clk_regmap *gcc_sc8280xp_clocks[] = { @@ -7351,6 +7464,18 @@ [USB30_MP_GDSC] = &usb30_mp_gdsc, [USB30_PRIM_GDSC] = &usb30_prim_gdsc, [USB30_SEC_GDSC] = &usb30_sec_gdsc, + [EMAC_0_GDSC] = &emac_0_gdsc, + [EMAC_1_GDSC] = &emac_1_gdsc, + [USB4_1_GDSC] = &usb4_1_gdsc, + [USB4_GDSC] = &usb4_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf0_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_hf1_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_SF0_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_sf0_gdsc, + [HLOS1_VOTE_MMNOC_MMU_TBU_SF1_GDSC] = &hlos1_vote_mmnoc_mmu_tbu_sf1_gdsc, + [HLOS1_VOTE_TURING_MMU_TBU0_GDSC] = &hlos1_vote_turing_mmu_tbu0_gdsc, + [HLOS1_VOTE_TURING_MMU_TBU1_GDSC] = &hlos1_vote_turing_mmu_tbu1_gdsc, + [HLOS1_VOTE_TURING_MMU_TBU2_GDSC] = &hlos1_vote_turing_mmu_tbu2_gdsc, + [HLOS1_VOTE_TURING_MMU_TBU3_GDSC] = &hlos1_vote_turing_mmu_tbu3_gdsc, }; static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/gcc-sm6350.c +++ linux-6.2.0/drivers/clk/qcom/gcc-sm6350.c @@ -641,6 +641,7 @@ .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_8, .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_OPS_PARENT_ENABLE, .ops = &clk_rcg2_floor_ops, }, }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/gcc-sm8250.c +++ linux-6.2.0/drivers/clk/qcom/gcc-sm8250.c @@ -721,6 +721,7 @@ .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_4, .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_OPS_PARENT_ENABLE, .ops = &clk_rcg2_floor_ops, }, }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/gcc-sm8450.c +++ linux-6.2.0/drivers/clk/qcom/gcc-sm8450.c @@ -904,7 +904,7 @@ .parent_data = gcc_parent_data_7, .num_parents = ARRAY_SIZE(gcc_parent_data_7), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_ops, + .ops = &clk_rcg2_floor_ops, }, }; @@ -926,7 +926,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_floor_ops, }, }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/gpucc-sm6350.c +++ linux-6.2.0/drivers/clk/qcom/gpucc-sm6350.c @@ -25,6 +25,12 @@ #define CX_GMU_CBCR_WAKE_SHIFT 8 enum { + DT_BI_TCXO, + DT_GPLL0_OUT_MAIN, + DT_GPLL0_OUT_MAIN_DIV, +}; + +enum { P_BI_TCXO, P_GPLL0_OUT_MAIN, P_GPLL0_OUT_MAIN_DIV, @@ -61,6 +67,7 @@ .hw.init = &(struct clk_init_data){ .name = "gpu_cc_pll0", .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO, .fw_name = "bi_tcxo", }, .num_parents = 1, @@ -104,6 +111,7 @@ .hw.init = &(struct clk_init_data){ .name = "gpu_cc_pll1", .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO, .fw_name = "bi_tcxo", }, .num_parents = 1, @@ -121,11 +129,11 @@ }; static const struct clk_parent_data gpu_cc_parent_data_0[] = { - { .fw_name = "bi_tcxo" }, + { .index = DT_BI_TCXO, .fw_name = "bi_tcxo" }, { .hw = &gpu_cc_pll0.clkr.hw }, { .hw = &gpu_cc_pll1.clkr.hw }, - { .fw_name = "gcc_gpu_gpll0_clk" }, - { .fw_name = "gcc_gpu_gpll0_div_clk" }, + { .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk_src" }, + { .index = DT_GPLL0_OUT_MAIN_DIV, .fw_name = "gcc_gpu_gpll0_div_clk_src" }, }; static const struct parent_map gpu_cc_parent_map_1[] = { @@ -138,12 +146,12 @@ }; static const struct clk_parent_data gpu_cc_parent_data_1[] = { - { .fw_name = "bi_tcxo" }, + { .index = DT_BI_TCXO, .fw_name = "bi_tcxo" }, { .hw = &crc_div.hw }, { .hw = &gpu_cc_pll0.clkr.hw }, { .hw = &gpu_cc_pll1.clkr.hw }, { .hw = &gpu_cc_pll1.clkr.hw }, - { .fw_name = "gcc_gpu_gpll0_clk" }, + { .index = DT_GPLL0_OUT_MAIN, .fw_name = "gcc_gpu_gpll0_clk_src" }, }; static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/mss-sc7180.c +++ linux-6.2.0/drivers/clk/qcom/mss-sc7180.c @@ -87,11 +87,22 @@ return ret; } + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return ret; + ret = qcom_cc_probe(pdev, &mss_sc7180_desc); if (ret < 0) - return ret; + goto err_put_rpm; + + pm_runtime_put(&pdev->dev); return 0; + +err_put_rpm: + pm_runtime_put_sync(&pdev->dev); + + return ret; } static const struct dev_pm_ops mss_sc7180_pm_ops = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/q6sstop-qcs404.c +++ linux-6.2.0/drivers/clk/qcom/q6sstop-qcs404.c @@ -174,21 +174,32 @@ return ret; } + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return ret; + q6sstop_regmap_config.name = "q6sstop_tcsr"; desc = &tcsr_qcs404_desc; ret = qcom_cc_probe_by_index(pdev, 1, desc); if (ret) - return ret; + goto err_put_rpm; q6sstop_regmap_config.name = "q6sstop_cc"; desc = &q6sstop_qcs404_desc; ret = qcom_cc_probe_by_index(pdev, 0, desc); if (ret) - return ret; + goto err_put_rpm; + + pm_runtime_put(&pdev->dev); return 0; + +err_put_rpm: + pm_runtime_put_sync(&pdev->dev); + + return ret; } static const struct dev_pm_ops q6sstopcc_pm_ops = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/reset.c +++ linux-6.2.0/drivers/clk/qcom/reset.c @@ -16,7 +16,8 @@ struct qcom_reset_controller *rst = to_qcom_reset_controller(rcdev); rcdev->ops->assert(rcdev, id); - udelay(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */ + fsleep(rst->reset_map[id].udelay ?: 1); /* use 1 us as default */ + rcdev->ops->deassert(rcdev, id); return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/qcom/turingcc-qcs404.c +++ linux-6.2.0/drivers/clk/qcom/turingcc-qcs404.c @@ -125,11 +125,22 @@ return ret; } + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return ret; + ret = qcom_cc_probe(pdev, &turingcc_desc); if (ret < 0) - return ret; + goto err_put_rpm; + + pm_runtime_put(&pdev->dev); return 0; + +err_put_rpm: + pm_runtime_put_sync(&pdev->dev); + + return ret; } static const struct dev_pm_ops turingcc_pm_ops = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/rockchip/clk-rk3568.c +++ linux-6.2.0/drivers/clk/rockchip/clk-rk3568.c @@ -81,7 +81,7 @@ RK3036_PLL_RATE(108000000, 2, 45, 5, 1, 1, 0), RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0), RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0), - RK3036_PLL_RATE(78750000, 1, 96, 6, 4, 1, 0), + RK3036_PLL_RATE(78750000, 4, 315, 6, 4, 1, 0), RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0), { /* sentinel */ }, }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/sprd/ums512-clk.c +++ linux-6.2.0/drivers/clk/sprd/ums512-clk.c @@ -800,7 +800,7 @@ 0x250, 0, 3, UMS512_MUX_FLAG); static const struct clk_parent_data thm_parents[] = { - { .fw_name = "ext-32m" }, + { .fw_name = "ext-32k" }, { .hw = &clk_250k.hw }, }; static SPRD_MUX_CLK_DATA(thm0_clk, "thm0-clk", thm_parents, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/sunxi-ng/ccu_mmc_timing.c +++ linux-6.2.0/drivers/clk/sunxi-ng/ccu_mmc_timing.c @@ -43,7 +43,7 @@ EXPORT_SYMBOL_GPL(sunxi_ccu_set_mmc_timing_mode); /** - * sunxi_ccu_set_mmc_timing_mode: Get the current MMC clock timing mode + * sunxi_ccu_get_mmc_timing_mode: Get the current MMC clock timing mode * @clk: clock to query * * Returns 0 if the clock is in old timing mode, > 0 if it is in only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clk/tegra/clk-bpmp.c +++ linux-6.2.0/drivers/clk/tegra/clk-bpmp.c @@ -159,7 +159,7 @@ err = tegra_bpmp_clk_transfer(clk->bpmp, &msg); if (err < 0) - return err; + return 0; return response.rate; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/clocksource/arm_arch_timer.c +++ linux-6.2.0/drivers/clocksource/arm_arch_timer.c @@ -774,6 +774,13 @@ u64 cnt; ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); + + /* Timer must be disabled before programming CVAL */ + if (ctrl & ARCH_TIMER_CTRL_ENABLE) { + ctrl &= ~ARCH_TIMER_CTRL_ENABLE; + arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); + } + ctrl |= ARCH_TIMER_CTRL_ENABLE; ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/cpufreq/amd-pstate-ut.c +++ linux-6.2.0/drivers/cpufreq/amd-pstate-ut.c @@ -64,27 +64,9 @@ static bool get_shared_mem(void) { bool result = false; - char path[] = "/sys/module/amd_pstate/parameters/shared_mem"; - char buf[5] = {0}; - struct file *filp = NULL; - loff_t pos = 0; - ssize_t ret; - - if (!boot_cpu_has(X86_FEATURE_CPPC)) { - filp = filp_open(path, O_RDONLY, 0); - if (IS_ERR(filp)) - pr_err("%s unable to open %s file!\n", __func__, path); - else { - ret = kernel_read(filp, &buf, sizeof(buf), &pos); - if (ret < 0) - pr_err("%s read %s file fail ret=%ld!\n", - __func__, path, (long)ret); - filp_close(filp, NULL); - } - if ('Y' == *buf) - result = true; - } + if (!boot_cpu_has(X86_FEATURE_CPPC)) + result = true; return result; } @@ -158,7 +140,7 @@ if (ret) { amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cppc_get_perf_caps ret=%d error!\n", __func__, ret); - return; + goto skip_test; } nominal_perf = cppc_perf.nominal_perf; @@ -169,7 +151,7 @@ if (ret) { amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s read CPPC_CAP1 ret=%d error!\n", __func__, ret); - return; + goto skip_test; } nominal_perf = AMD_CPPC_NOMINAL_PERF(cap1); @@ -187,7 +169,7 @@ nominal_perf, cpudata->nominal_perf, lowest_nonlinear_perf, cpudata->lowest_nonlinear_perf, lowest_perf, cpudata->lowest_perf); - return; + goto skip_test; } if (!((highest_perf >= nominal_perf) && @@ -198,11 +180,15 @@ pr_err("%s cpu%d highest=%d >= nominal=%d > lowest_nonlinear=%d > lowest=%d > 0, the formula is incorrect!\n", __func__, cpu, highest_perf, nominal_perf, lowest_nonlinear_perf, lowest_perf); - return; + goto skip_test; } + cpufreq_cpu_put(policy); } amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; + return; +skip_test: + cpufreq_cpu_put(policy); } /* @@ -230,14 +216,14 @@ pr_err("%s cpu%d max=%d >= nominal=%d > lowest_nonlinear=%d > min=%d > 0, the formula is incorrect!\n", __func__, cpu, cpudata->max_freq, cpudata->nominal_freq, cpudata->lowest_nonlinear_freq, cpudata->min_freq); - return; + goto skip_test; } if (cpudata->min_freq != policy->min) { amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cpu%d cpudata_min_freq=%d policy_min=%d, they should be equal!\n", __func__, cpu, cpudata->min_freq, policy->min); - return; + goto skip_test; } if (cpudata->boost_supported) { @@ -249,16 +235,20 @@ pr_err("%s cpu%d policy_max=%d should be equal cpu_max=%d or cpu_nominal=%d !\n", __func__, cpu, policy->max, cpudata->max_freq, cpudata->nominal_freq); - return; + goto skip_test; } } else { amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_FAIL; pr_err("%s cpu%d must support boost!\n", __func__, cpu); - return; + goto skip_test; } + cpufreq_cpu_put(policy); } amd_pstate_ut_cases[index].result = AMD_PSTATE_UT_RESULT_PASS; + return; +skip_test: + cpufreq_cpu_put(policy); } static int __init amd_pstate_ut_init(void) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/cpufreq/brcmstb-avs-cpufreq.c +++ linux-6.2.0/drivers/cpufreq/brcmstb-avs-cpufreq.c @@ -434,7 +434,11 @@ if (ret) return ERR_PTR(ret); - table = devm_kcalloc(dev, AVS_PSTATE_MAX + 1, sizeof(*table), + /* + * We allocate space for the 5 different P-STATES AVS, + * plus extra space for a terminating element. + */ + table = devm_kcalloc(dev, AVS_PSTATE_MAX + 1 + 1, sizeof(*table), GFP_KERNEL); if (!table) return ERR_PTR(-ENOMEM); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/cpufreq/powernow-k8.c +++ linux-6.2.0/drivers/cpufreq/powernow-k8.c @@ -1101,7 +1101,8 @@ kfree(data->powernow_table); kfree(data); - for_each_cpu(cpu, pol->cpus) + /* pol->cpus will be empty here, use related_cpus instead. */ + for_each_cpu(cpu, pol->related_cpus) per_cpu(powernow_data, cpu) = NULL; return 0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/cpuidle/cpuidle-pseries.c +++ linux-6.2.0/drivers/cpuidle/cpuidle-pseries.c @@ -414,13 +414,7 @@ return -ENODEV; if (firmware_has_feature(FW_FEATURE_SPLPAR)) { - /* - * Use local_paca instead of get_lppaca() since - * preemption is not disabled, and it is not required in - * fact, since lppaca_ptr does not need to be the value - * associated to the current CPU, it can be from any CPU. - */ - if (lppaca_shared_proc(local_paca->lppaca_ptr)) { + if (lppaca_shared_proc()) { cpuidle_state_table = shared_states; max_idle_state = ARRAY_SIZE(shared_states); } else { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/crypto/caam/caampkc.c +++ linux-6.2.0/drivers/crypto/caam/caampkc.c @@ -223,7 +223,9 @@ if (len && *buff) break; - sg_miter_next(&miter); + if (!sg_miter_next(&miter)) + break; + buff = miter.addr; len = miter.length; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/crypto/qat/qat_common/adf_gen4_pm.h +++ linux-6.2.0/drivers/crypto/qat/qat_common/adf_gen4_pm.h @@ -35,7 +35,7 @@ #define ADF_GEN4_PM_MSG_PENDING BIT(0) #define ADF_GEN4_PM_MSG_PAYLOAD_BIT_MASK GENMASK(28, 1) -#define ADF_GEN4_PM_DEFAULT_IDLE_FILTER (0x0) +#define ADF_GEN4_PM_DEFAULT_IDLE_FILTER (0x6) #define ADF_GEN4_PM_MAX_IDLE_FILTER (0x7) int adf_gen4_enable_pm(struct adf_accel_dev *accel_dev); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/crypto/stm32/stm32-hash.c +++ linux-6.2.0/drivers/crypto/stm32/stm32-hash.c @@ -565,9 +565,9 @@ } for_each_sg(rctx->sg, tsg, rctx->nents, i) { + sg[0] = *tsg; len = sg->length; - sg[0] = *tsg; if (sg_is_last(sg)) { if (hdev->dma_mode == 1) { len = (ALIGN(sg->length, 16) - 16); @@ -1566,9 +1566,7 @@ if (!hdev) return -ENODEV; - ret = pm_runtime_resume_and_get(hdev->dev); - if (ret < 0) - return ret; + ret = pm_runtime_get_sync(hdev->dev); stm32_hash_unregister_algs(hdev); @@ -1584,7 +1582,8 @@ pm_runtime_disable(hdev->dev); pm_runtime_put_noidle(hdev->dev); - clk_disable_unprepare(hdev->clk); + if (ret >= 0) + clk_disable_unprepare(hdev->clk); return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/devfreq/devfreq.c +++ linux-6.2.0/drivers/devfreq/devfreq.c @@ -763,6 +763,7 @@ dev_pm_opp_put_opp_table(devfreq->opp_table); mutex_destroy(&devfreq->lock); + srcu_cleanup_notifier_head(&devfreq->transition_notifier_list); kfree(devfreq); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/dma/sh/rz-dmac.c +++ linux-6.2.0/drivers/dma/sh/rz-dmac.c @@ -9,6 +9,7 @@ * Copyright 2012 Javier Martin, Vista Silicon */ +#include #include #include #include @@ -145,8 +146,8 @@ #define CHCFG_REQD BIT(3) #define CHCFG_SEL(bits) ((bits) & 0x07) #define CHCFG_MEM_COPY (0x80400008) -#define CHCFG_FILL_DDS(a) (((a) << 16) & GENMASK(19, 16)) -#define CHCFG_FILL_SDS(a) (((a) << 12) & GENMASK(15, 12)) +#define CHCFG_FILL_DDS_MASK GENMASK(19, 16) +#define CHCFG_FILL_SDS_MASK GENMASK(15, 12) #define CHCFG_FILL_TM(a) (((a) & BIT(5)) << 22) #define CHCFG_FILL_AM(a) (((a) & GENMASK(4, 2)) << 6) #define CHCFG_FILL_LVL(a) (((a) & BIT(1)) << 5) @@ -609,13 +610,15 @@ if (val == CHCFG_DS_INVALID) return -EINVAL; - channel->chcfg |= CHCFG_FILL_DDS(val); + channel->chcfg &= ~CHCFG_FILL_DDS_MASK; + channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val); val = rz_dmac_ds_to_val_mapping(config->src_addr_width); if (val == CHCFG_DS_INVALID) return -EINVAL; - channel->chcfg |= CHCFG_FILL_SDS(val); + channel->chcfg &= ~CHCFG_FILL_SDS_MASK; + channel->chcfg |= FIELD_PREP(CHCFG_FILL_SDS_MASK, val); return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/dma/ste_dma40.c +++ linux-6.2.0/drivers/dma/ste_dma40.c @@ -3597,6 +3597,10 @@ spin_lock_init(&base->lcla_pool.lock); base->irq = platform_get_irq(pdev, 0); + if (base->irq < 0) { + ret = base->irq; + goto destroy_cache; + } ret = request_irq(base->irq, d40_handle_interrupt, 0, D40_NAME, base); if (ret) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/edac/igen6_edac.c +++ linux-6.2.0/drivers/edac/igen6_edac.c @@ -27,7 +27,7 @@ #include "edac_mc.h" #include "edac_module.h" -#define IGEN6_REVISION "v2.5" +#define IGEN6_REVISION "v2.5.1" #define EDAC_MOD_STR "igen6_edac" #define IGEN6_NMI_NAME "igen6_ibecc" @@ -1216,9 +1216,6 @@ INIT_WORK(&ecclog_work, ecclog_work_cb); init_irq_work(&ecclog_irq_work, ecclog_irq_work_cb); - /* Check if any pending errors before registering the NMI handler */ - ecclog_handler(); - rc = register_err_handler(); if (rc) goto fail3; @@ -1230,6 +1227,9 @@ goto fail4; } + /* Check if any pending errors before/during the registration of the error handler */ + ecclog_handler(); + igen6_debug_setup(); return 0; fail4: only in patch2: unchanged: --- linux-6.2.0.orig/drivers/extcon/Kconfig +++ linux-6.2.0/drivers/extcon/Kconfig @@ -62,6 +62,7 @@ tristate "Intel Cherrytrail Whiskey Cove PMIC extcon driver" depends on INTEL_SOC_PMIC_CHTWC depends on USB_SUPPORT + depends on POWER_SUPPLY select USB_ROLE_SWITCH help Say Y here to enable extcon support for charger detection / control only in patch2: unchanged: --- linux-6.2.0.orig/drivers/firewire/sbp2.c +++ linux-6.2.0/drivers/firewire/sbp2.c @@ -81,7 +81,8 @@ * * - power condition * Set the power condition field in the START STOP UNIT commands sent by - * sd_mod on suspend, resume, and shutdown (if manage_start_stop is on). + * sd_mod on suspend, resume, and shutdown (if manage_system_start_stop or + * manage_runtime_start_stop is on). * Some disks need this to spin down or to resume properly. * * - override internal blacklist @@ -1517,8 +1518,10 @@ sdev->use_10_for_rw = 1; - if (sbp2_param_exclusive_login) - sdev->manage_start_stop = 1; + if (sbp2_param_exclusive_login) { + sdev->manage_system_start_stop = true; + sdev->manage_runtime_start_stop = true; + } if (sdev->type == TYPE_ROM) sdev->use_10_for_ms = 1; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/firmware/arm_scmi/perf.c +++ linux-6.2.0/drivers/firmware/arm_scmi/perf.c @@ -139,7 +139,7 @@ struct scmi_perf_info { u32 version; - int num_domains; + u16 num_domains; enum scmi_power_scale power_scale; u64 stats_addr; u32 stats_size; @@ -356,11 +356,26 @@ return ret; } +static inline struct perf_dom_info * +scmi_perf_domain_lookup(const struct scmi_protocol_handle *ph, u32 domain) +{ + struct scmi_perf_info *pi = ph->get_priv(ph); + + if (domain >= pi->num_domains) + return ERR_PTR(-EINVAL); + + return pi->dom_info + domain; +} + static int scmi_perf_limits_set(const struct scmi_protocol_handle *ph, u32 domain, u32 max_perf, u32 min_perf) { struct scmi_perf_info *pi = ph->get_priv(ph); - struct perf_dom_info *dom = pi->dom_info + domain; + struct perf_dom_info *dom; + + dom = scmi_perf_domain_lookup(ph, domain); + if (IS_ERR(dom)) + return PTR_ERR(dom); if (PROTOCOL_REV_MAJOR(pi->version) >= 0x3 && !max_perf && !min_perf) return -EINVAL; @@ -408,8 +423,11 @@ static int scmi_perf_limits_get(const struct scmi_protocol_handle *ph, u32 domain, u32 *max_perf, u32 *min_perf) { - struct scmi_perf_info *pi = ph->get_priv(ph); - struct perf_dom_info *dom = pi->dom_info + domain; + struct perf_dom_info *dom; + + dom = scmi_perf_domain_lookup(ph, domain); + if (IS_ERR(dom)) + return PTR_ERR(dom); if (dom->fc_info && dom->fc_info[PERF_FC_LIMIT].get_addr) { struct scmi_fc_info *fci = &dom->fc_info[PERF_FC_LIMIT]; @@ -449,8 +467,11 @@ static int scmi_perf_level_set(const struct scmi_protocol_handle *ph, u32 domain, u32 level, bool poll) { - struct scmi_perf_info *pi = ph->get_priv(ph); - struct perf_dom_info *dom = pi->dom_info + domain; + struct perf_dom_info *dom; + + dom = scmi_perf_domain_lookup(ph, domain); + if (IS_ERR(dom)) + return PTR_ERR(dom); if (dom->fc_info && dom->fc_info[PERF_FC_LEVEL].set_addr) { struct scmi_fc_info *fci = &dom->fc_info[PERF_FC_LEVEL]; @@ -490,8 +511,11 @@ static int scmi_perf_level_get(const struct scmi_protocol_handle *ph, u32 domain, u32 *level, bool poll) { - struct scmi_perf_info *pi = ph->get_priv(ph); - struct perf_dom_info *dom = pi->dom_info + domain; + struct perf_dom_info *dom; + + dom = scmi_perf_domain_lookup(ph, domain); + if (IS_ERR(dom)) + return PTR_ERR(dom); if (dom->fc_info && dom->fc_info[PERF_FC_LEVEL].get_addr) { *level = ioread32(dom->fc_info[PERF_FC_LEVEL].get_addr); @@ -574,13 +598,14 @@ unsigned long freq; struct scmi_opp *opp; struct perf_dom_info *dom; - struct scmi_perf_info *pi = ph->get_priv(ph); domain = scmi_dev_domain_id(dev); if (domain < 0) - return domain; + return -EINVAL; - dom = pi->dom_info + domain; + dom = scmi_perf_domain_lookup(ph, domain); + if (IS_ERR(dom)) + return PTR_ERR(dom); for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) { freq = opp->perf * dom->mult_factor; @@ -603,14 +628,17 @@ scmi_dvfs_transition_latency_get(const struct scmi_protocol_handle *ph, struct device *dev) { + int domain; struct perf_dom_info *dom; - struct scmi_perf_info *pi = ph->get_priv(ph); - int domain = scmi_dev_domain_id(dev); + domain = scmi_dev_domain_id(dev); if (domain < 0) - return domain; + return -EINVAL; + + dom = scmi_perf_domain_lookup(ph, domain); + if (IS_ERR(dom)) + return PTR_ERR(dom); - dom = pi->dom_info + domain; /* uS to nS */ return dom->opp[dom->opp_count - 1].trans_latency_us * 1000; } @@ -618,8 +646,11 @@ static int scmi_dvfs_freq_set(const struct scmi_protocol_handle *ph, u32 domain, unsigned long freq, bool poll) { - struct scmi_perf_info *pi = ph->get_priv(ph); - struct perf_dom_info *dom = pi->dom_info + domain; + struct perf_dom_info *dom; + + dom = scmi_perf_domain_lookup(ph, domain); + if (IS_ERR(dom)) + return PTR_ERR(dom); return scmi_perf_level_set(ph, domain, freq / dom->mult_factor, poll); } @@ -630,11 +661,14 @@ int ret; u32 level; struct scmi_perf_info *pi = ph->get_priv(ph); - struct perf_dom_info *dom = pi->dom_info + domain; ret = scmi_perf_level_get(ph, domain, &level, poll); - if (!ret) + if (!ret) { + struct perf_dom_info *dom = pi->dom_info + domain; + + /* Note domain is validated implicitly by scmi_perf_level_get */ *freq = level * dom->mult_factor; + } return ret; } @@ -643,15 +677,14 @@ u32 domain, unsigned long *freq, unsigned long *power) { - struct scmi_perf_info *pi = ph->get_priv(ph); struct perf_dom_info *dom; unsigned long opp_freq; int idx, ret = -EINVAL; struct scmi_opp *opp; - dom = pi->dom_info + domain; - if (!dom) - return -EIO; + dom = scmi_perf_domain_lookup(ph, domain); + if (IS_ERR(dom)) + return PTR_ERR(dom); for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) { opp_freq = opp->perf * dom->mult_factor; @@ -670,10 +703,16 @@ static bool scmi_fast_switch_possible(const struct scmi_protocol_handle *ph, struct device *dev) { + int domain; struct perf_dom_info *dom; - struct scmi_perf_info *pi = ph->get_priv(ph); - dom = pi->dom_info + scmi_dev_domain_id(dev); + domain = scmi_dev_domain_id(dev); + if (domain < 0) + return false; + + dom = scmi_perf_domain_lookup(ph, domain); + if (IS_ERR(dom)) + return false; return dom->fc_info && dom->fc_info[PERF_FC_LEVEL].set_addr; } @@ -819,6 +858,8 @@ if (!pinfo) return -ENOMEM; + pinfo->version = version; + ret = scmi_perf_attributes_get(ph, pinfo); if (ret) return ret; @@ -838,8 +879,6 @@ scmi_perf_domain_init_fc(ph, domain, &dom->fc_info); } - pinfo->version = version; - return ph->set_priv(ph, pinfo); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/firmware/cirrus/cs_dsp.c +++ linux-6.2.0/drivers/firmware/cirrus/cs_dsp.c @@ -946,7 +946,8 @@ ctl->alg_region.alg == alg_region->alg && ctl->alg_region.type == alg_region->type) { if ((!subname && !ctl->subname) || - (subname && !strncmp(ctl->subname, subname, ctl->subname_len))) { + (subname && (ctl->subname_len == subname_len) && + !strncmp(ctl->subname, subname, ctl->subname_len))) { if (!ctl->enabled) ctl->enabled = 1; return 0; @@ -1827,15 +1828,15 @@ return PTR_ERR(adsp2_alg); for (i = 0; i < n_algs; i++) { - cs_dsp_info(dsp, - "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", - i, be32_to_cpu(adsp2_alg[i].alg.id), - (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, - (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, - be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, - be32_to_cpu(adsp2_alg[i].xm), - be32_to_cpu(adsp2_alg[i].ym), - be32_to_cpu(adsp2_alg[i].zm)); + cs_dsp_dbg(dsp, + "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", + i, be32_to_cpu(adsp2_alg[i].alg.id), + (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, + be32_to_cpu(adsp2_alg[i].xm), + be32_to_cpu(adsp2_alg[i].ym), + be32_to_cpu(adsp2_alg[i].zm)); alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, adsp2_alg[i].alg.id, @@ -1960,14 +1961,14 @@ return PTR_ERR(halo_alg); for (i = 0; i < n_algs; i++) { - cs_dsp_info(dsp, - "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", - i, be32_to_cpu(halo_alg[i].alg.id), - (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, - (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, - be32_to_cpu(halo_alg[i].alg.ver) & 0xff, - be32_to_cpu(halo_alg[i].xm_base), - be32_to_cpu(halo_alg[i].ym_base)); + cs_dsp_dbg(dsp, + "%d: ID %x v%d.%d.%d XM@%x YM@%x\n", + i, be32_to_cpu(halo_alg[i].alg.id), + (be32_to_cpu(halo_alg[i].alg.ver) & 0xff0000) >> 16, + (be32_to_cpu(halo_alg[i].alg.ver) & 0xff00) >> 8, + be32_to_cpu(halo_alg[i].alg.ver) & 0xff, + be32_to_cpu(halo_alg[i].xm_base), + be32_to_cpu(halo_alg[i].ym_base)); ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, halo_alg[i].alg.ver, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/firmware/efi/libstub/x86-stub.c +++ linux-6.2.0/drivers/firmware/efi/libstub/x86-stub.c @@ -61,7 +61,7 @@ rom->data.type = SETUP_PCI; rom->data.len = size - sizeof(struct setup_data); rom->data.next = 0; - rom->pcilen = pci->romsize; + rom->pcilen = romsize; *__rom = rom; status = efi_call_proto(pci, pci.read, EfiPciIoWidthUint16, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/firmware/imx/imx-dsp.c +++ linux-6.2.0/drivers/firmware/imx/imx-dsp.c @@ -115,6 +115,7 @@ dsp_chan->idx = i % 2; dsp_chan->ch = mbox_request_channel_byname(cl, chan_name); if (IS_ERR(dsp_chan->ch)) { + kfree(dsp_chan->name); ret = PTR_ERR(dsp_chan->ch); if (ret != -EPROBE_DEFER) dev_err(dev, "Failed to request mbox chan %s ret %d\n", only in patch2: unchanged: --- linux-6.2.0.orig/drivers/firmware/meson/meson_sm.c +++ linux-6.2.0/drivers/firmware/meson/meson_sm.c @@ -292,6 +292,8 @@ return -ENOMEM; chip = of_match_device(meson_sm_ids, dev)->data; + if (!chip) + return -EINVAL; if (chip->cmd_shmem_in_base) { fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/firmware/ti_sci.c +++ linux-6.2.0/drivers/firmware/ti_sci.c @@ -97,7 +97,6 @@ * @node: list head * @host_id: Host ID * @users: Number of users of this instance - * @is_suspending: Flag set to indicate in suspend path. */ struct ti_sci_info { struct device *dev; @@ -116,7 +115,6 @@ u8 host_id; /* protected by ti_sci_list_mutex */ int users; - bool is_suspending; }; #define cl_to_ti_sci_info(c) container_of(c, struct ti_sci_info, cl) @@ -418,14 +416,14 @@ ret = 0; - if (!info->is_suspending) { + if (system_state <= SYSTEM_RUNNING) { /* And we wait for the response. */ timeout = msecs_to_jiffies(info->desc->max_rx_timeout_ms); if (!wait_for_completion_timeout(&xfer->done, timeout)) ret = -ETIMEDOUT; } else { /* - * If we are suspending, we cannot use wait_for_completion_timeout + * If we are !running, we cannot use wait_for_completion_timeout * during noirq phase, so we must manually poll the completion. */ ret = read_poll_timeout_atomic(try_wait_for_completion, done_state, @@ -3281,35 +3279,6 @@ return NOTIFY_BAD; } -static void ti_sci_set_is_suspending(struct ti_sci_info *info, bool is_suspending) -{ - info->is_suspending = is_suspending; -} - -static int ti_sci_suspend(struct device *dev) -{ - struct ti_sci_info *info = dev_get_drvdata(dev); - /* - * We must switch operation to polled mode now as drivers and the genpd - * layer may make late TI SCI calls to change clock and device states - * from the noirq phase of suspend. - */ - ti_sci_set_is_suspending(info, true); - - return 0; -} - -static int ti_sci_resume(struct device *dev) -{ - struct ti_sci_info *info = dev_get_drvdata(dev); - - ti_sci_set_is_suspending(info, false); - - return 0; -} - -static DEFINE_SIMPLE_DEV_PM_OPS(ti_sci_pm_ops, ti_sci_suspend, ti_sci_resume); - /* Description for K2G */ static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = { .default_host_id = 2, @@ -3516,7 +3485,6 @@ .driver = { .name = "ti-sci", .of_match_table = of_match_ptr(ti_sci_of_match), - .pm = &ti_sci_pm_ops, }, }; module_platform_driver(ti_sci_driver); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/fsi/fsi-master-aspeed.c +++ linux-6.2.0/drivers/fsi/fsi-master-aspeed.c @@ -454,6 +454,8 @@ gpiod_set_value(aspeed->cfam_reset_gpio, 1); usleep_range(900, 1000); gpiod_set_value(aspeed->cfam_reset_gpio, 0); + usleep_range(900, 1000); + opb_writel(aspeed, ctrl_base + FSI_MRESP0, cpu_to_be32(FSI_MRESP_RST_ALL_MASTER)); mutex_unlock(&aspeed->lock); trace_fsi_master_aspeed_cfam_reset(false); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpio/gpio-aspeed.c +++ linux-6.2.0/drivers/gpio/gpio-aspeed.c @@ -964,7 +964,7 @@ else if (param == PIN_CONFIG_BIAS_DISABLE || param == PIN_CONFIG_BIAS_PULL_DOWN || param == PIN_CONFIG_DRIVE_STRENGTH) - return pinctrl_gpio_set_config(offset, config); + return pinctrl_gpio_set_config(chip->base + offset, config); else if (param == PIN_CONFIG_DRIVE_OPEN_DRAIN || param == PIN_CONFIG_DRIVE_OPEN_SOURCE) /* Return -ENOTSUPP to trigger emulation, as per datasheet */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpio/gpio-pmic-eic-sprd.c +++ linux-6.2.0/drivers/gpio/gpio-pmic-eic-sprd.c @@ -352,6 +352,7 @@ pmic_eic->chip.set_config = sprd_pmic_eic_set_config; pmic_eic->chip.set = sprd_pmic_eic_set; pmic_eic->chip.get = sprd_pmic_eic_get; + pmic_eic->chip.can_sleep = true; irq = &pmic_eic->chip.irq; gpio_irq_chip_set_chip(irq, &pmic_eic_irq_chip); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpio/gpio-pxa.c +++ linux-6.2.0/drivers/gpio/gpio-pxa.c @@ -243,6 +243,7 @@ switch (gpio_type) { case PXA3XX_GPIO: case MMP2_GPIO: + case MMP_GPIO: return false; default: only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpio/gpio-tb10x.c +++ linux-6.2.0/drivers/gpio/gpio-tb10x.c @@ -195,7 +195,7 @@ handle_edge_irq, IRQ_NOREQUEST, IRQ_NOPROBE, IRQ_GC_INIT_MASK_CACHE); if (ret) - return ret; + goto err_remove_domain; gc = tb10x_gpio->domain->gc->gc[0]; gc->reg_base = tb10x_gpio->base; @@ -209,6 +209,10 @@ } return 0; + +err_remove_domain: + irq_domain_remove(tb10x_gpio->domain); + return ret; } static int tb10x_gpio_remove(struct platform_device *pdev) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include #include #include @@ -528,11 +530,29 @@ return true; } +static int amdgpu_dirtyfb(struct drm_framebuffer *fb, struct drm_file *file, + unsigned int flags, unsigned int color, + struct drm_clip_rect *clips, unsigned int num_clips) +{ + + if (file) + return -ENOSYS; + + return drm_atomic_helper_dirtyfb(fb, file, flags, color, clips, + num_clips); +} + static const struct drm_framebuffer_funcs amdgpu_fb_funcs = { .destroy = drm_gem_fb_destroy, .create_handle = drm_gem_fb_create_handle, }; +static const struct drm_framebuffer_funcs amdgpu_fb_funcs_atomic = { + .destroy = drm_gem_fb_destroy, + .create_handle = drm_gem_fb_create_handle, + .dirty = amdgpu_dirtyfb +}; + uint32_t amdgpu_display_supported_domains(struct amdgpu_device *adev, uint64_t bo_flags) { @@ -1135,7 +1155,11 @@ if (ret) goto err; - ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); + if (drm_drv_uses_atomic_modeset(dev)) + ret = drm_framebuffer_init(dev, &rfb->base, + &amdgpu_fb_funcs_atomic); + else + ret = drm_framebuffer_init(dev, &rfb->base, &amdgpu_fb_funcs); if (ret) goto err; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ linux-6.2.0/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -555,6 +555,7 @@ crtc = (struct drm_crtc *)minfo->crtcs[i]; if (crtc && crtc->base.id == info->mode_crtc.id) { struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); + ui32 = amdgpu_crtc->crtc_id; found = 1; break; @@ -573,7 +574,7 @@ if (ret) return ret; - ret = copy_to_user(out, &ip, min((size_t)size, sizeof(ip))); + ret = copy_to_user(out, &ip, min_t(size_t, size, sizeof(ip))); return ret ? -EFAULT : 0; } case AMDGPU_INFO_HW_IP_COUNT: { @@ -719,17 +720,18 @@ ? -EFAULT : 0; } case AMDGPU_INFO_READ_MMR_REG: { - unsigned n, alloc_size; + unsigned int n, alloc_size; uint32_t *regs; - unsigned se_num = (info->read_mmr_reg.instance >> + unsigned int se_num = (info->read_mmr_reg.instance >> AMDGPU_INFO_MMR_SE_INDEX_SHIFT) & AMDGPU_INFO_MMR_SE_INDEX_MASK; - unsigned sh_num = (info->read_mmr_reg.instance >> + unsigned int sh_num = (info->read_mmr_reg.instance >> AMDGPU_INFO_MMR_SH_INDEX_SHIFT) & AMDGPU_INFO_MMR_SH_INDEX_MASK; /* set full masks if the userspace set all bits - * in the bitfields */ + * in the bitfields + */ if (se_num == AMDGPU_INFO_MMR_SE_INDEX_MASK) se_num = 0xffffffff; else if (se_num >= AMDGPU_GFX_MAX_SE) @@ -853,7 +855,7 @@ return ret; } case AMDGPU_INFO_VCE_CLOCK_TABLE: { - unsigned i; + unsigned int i; struct drm_amdgpu_info_vce_clock_table vce_clk_table = {}; struct amd_vce_state *vce_state; @@ -895,12 +897,17 @@ struct atom_context *atom_context; atom_context = adev->mode_info.atom_context; - memcpy(vbios_info.name, atom_context->name, sizeof(atom_context->name)); - memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, sizeof(atom_context->vbios_pn)); - vbios_info.version = atom_context->version; - memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str, - sizeof(atom_context->vbios_ver_str)); - memcpy(vbios_info.date, atom_context->date, sizeof(atom_context->date)); + if (atom_context) { + memcpy(vbios_info.name, atom_context->name, + sizeof(atom_context->name)); + memcpy(vbios_info.vbios_pn, atom_context->vbios_pn, + sizeof(atom_context->vbios_pn)); + vbios_info.version = atom_context->version; + memcpy(vbios_info.vbios_ver_str, atom_context->vbios_ver_str, + sizeof(atom_context->vbios_ver_str)); + memcpy(vbios_info.date, atom_context->date, + sizeof(atom_context->date)); + } return copy_to_user(out, &vbios_info, min((size_t)size, sizeof(vbios_info))) ? -EFAULT : 0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/amdgpu/cik.c +++ linux-6.2.0/drivers/gpu/drm/amd/amdgpu/cik.c @@ -1574,17 +1574,8 @@ u16 bridge_cfg2, gpu_cfg2; u32 max_lw, current_lw, tmp; - pcie_capability_read_word(root, PCI_EXP_LNKCTL, - &bridge_cfg); - pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL, - &gpu_cfg); - - tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; - pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16); - - tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; - pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL, - tmp16); + pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); + pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); tmp = RREG32_PCIE(ixPCIE_LC_STATUS1); max_lw = (tmp & PCIE_LC_STATUS1__LC_DETECTED_LINK_WIDTH_MASK) >> @@ -1637,21 +1628,14 @@ msleep(100); /* linkctl */ - pcie_capability_read_word(root, PCI_EXP_LNKCTL, - &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); - pcie_capability_write_word(root, PCI_EXP_LNKCTL, - tmp16); - - pcie_capability_read_word(adev->pdev, - PCI_EXP_LNKCTL, - &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); - pcie_capability_write_word(adev->pdev, - PCI_EXP_LNKCTL, - tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + bridge_cfg & + PCI_EXP_LNKCTL_HAWD); + pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + gpu_cfg & + PCI_EXP_LNKCTL_HAWD); /* linkctl2 */ pcie_capability_read_word(root, PCI_EXP_LNKCTL2, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c +++ linux-6.2.0/drivers/gpu/drm/amd/amdgpu/nbio_v4_3.c @@ -344,6 +344,9 @@ data &= ~RCC_DEV0_EPF2_STRAP2__STRAP_NO_SOFT_RESET_DEV0_F2_MASK; WREG32_SOC15(NBIO, 0, regRCC_DEV0_EPF2_STRAP2, data); } + if (amdgpu_sriov_vf(adev)) + adev->rmmio_remap.reg_offset = SOC15_REG_OFFSET(NBIO, 0, + regBIF_BX_DEV0_EPF0_VF0_HDP_MEM_COHERENCY_FLUSH_CNTL) << 2; } static u32 nbio_v4_3_get_rom_offset(struct amdgpu_device *adev) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ linux-6.2.0/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -147,14 +147,15 @@ int ret; int retry_loop; + /* Wait for bootloader to signify that it is ready having bit 31 of + * C2PMSG_35 set to 1. All other bits are expected to be cleared. + * If there is an error in processing command, bits[7:0] will be set. + * This is applicable for PSP v13.0.6 and newer. + */ for (retry_loop = 0; retry_loop < 10; retry_loop++) { - /* Wait for bootloader to signify that is - ready having bit 31 of C2PMSG_35 set to 1 */ - ret = psp_wait_for(psp, - SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), - 0x80000000, - 0x80000000, - false); + ret = psp_wait_for( + psp, SOC15_REG_OFFSET(MP0, 0, regMP0_SMN_C2PMSG_35), + 0x80000000, 0xffffffff, false); if (ret == 0) return 0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/amdgpu/si.c +++ linux-6.2.0/drivers/gpu/drm/amd/amdgpu/si.c @@ -2276,17 +2276,8 @@ u16 bridge_cfg2, gpu_cfg2; u32 max_lw, current_lw, tmp; - pcie_capability_read_word(root, PCI_EXP_LNKCTL, - &bridge_cfg); - pcie_capability_read_word(adev->pdev, PCI_EXP_LNKCTL, - &gpu_cfg); - - tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; - pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16); - - tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; - pcie_capability_write_word(adev->pdev, PCI_EXP_LNKCTL, - tmp16); + pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); + pcie_capability_set_word(adev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); tmp = RREG32_PCIE(PCIE_LC_STATUS1); max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; @@ -2331,21 +2322,14 @@ mdelay(100); - pcie_capability_read_word(root, PCI_EXP_LNKCTL, - &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); - pcie_capability_write_word(root, PCI_EXP_LNKCTL, - tmp16); - - pcie_capability_read_word(adev->pdev, - PCI_EXP_LNKCTL, - &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); - pcie_capability_write_word(adev->pdev, - PCI_EXP_LNKCTL, - tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + bridge_cfg & + PCI_EXP_LNKCTL_HAWD); + pcie_capability_clear_and_set_word(adev->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + gpu_cfg & + PCI_EXP_LNKCTL_HAWD); pcie_capability_read_word(root, PCI_EXP_LNKCTL2, &tmp16); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ linux-6.2.0/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -201,7 +201,7 @@ if (q->wptr_bo) { wptr_addr_off = (uint64_t)q->properties.write_ptr & (PAGE_SIZE - 1); - queue_input.wptr_mc_addr = ((uint64_t)q->wptr_bo->tbo.resource->start << PAGE_SHIFT) + wptr_addr_off; + queue_input.wptr_mc_addr = amdgpu_bo_gpu_offset(q->wptr_bo) + wptr_addr_off; } queue_input.is_kfd_process = 1; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -1269,6 +1269,13 @@ attributes.rotation_angle = 0; attributes.attribute_flags.value = 0; + /* Enable cursor degamma ROM on DCN3+ for implicit sRGB degamma in DRM + * legacy gamma setup. + */ + if (crtc_state->cm_is_degamma_srgb && + adev->dm.dc->caps.color.dpp.gamma_corr) + attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA = 1; + attributes.pitch = afb->base.pitches[0] / afb->base.format->cpp[0]; if (crtc_state->stream) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/display/dc/Makefile +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/Makefile @@ -82,3 +82,4 @@ AMD_DISPLAY_DMUB = $(addprefix $(AMDDALPATH)/dc/,$(DC_DMUB)) AMD_DISPLAY_EDID = $(addprefix $(AMDDALPATH)/dc/,$(DC_EDID)) AMD_DISPLAY_FILES += $(AMD_DISPLAY_DMUB) $(AMD_DISPLAY_EDID) + only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn315/dcn315_smu.c @@ -32,6 +32,7 @@ #define MAX_INSTANCE 6 #define MAX_SEGMENT 6 +#define SMU_REGISTER_WRITE_RETRY_COUNT 5 struct IP_BASE_INSTANCE { @@ -134,6 +135,8 @@ unsigned int msg_id, unsigned int param) { uint32_t result; + uint32_t i = 0; + uint32_t read_back_data; result = dcn315_smu_wait_for_response(clk_mgr, 10, 200000); @@ -150,10 +153,19 @@ /* Set the parameter register for the SMU message, unit is Mhz */ REG_WRITE(MP1_SMN_C2PMSG_37, param); - /* Trigger the message transaction by writing the message ID */ - generic_write_indirect_reg(CTX, - REG_NBIO(RSMU_INDEX), REG_NBIO(RSMU_DATA), - mmMP1_C2PMSG_3, msg_id); + for (i = 0; i < SMU_REGISTER_WRITE_RETRY_COUNT; i++) { + /* Trigger the message transaction by writing the message ID */ + generic_write_indirect_reg(CTX, + REG_NBIO(RSMU_INDEX), REG_NBIO(RSMU_DATA), + mmMP1_C2PMSG_3, msg_id); + read_back_data = generic_read_indirect_reg(CTX, + REG_NBIO(RSMU_INDEX), REG_NBIO(RSMU_DATA), + mmMP1_C2PMSG_3); + if (read_back_data == msg_id) + break; + udelay(2); + smu_print("SMU msg id write fail %x times. \n", i + 1); + } result = dcn315_smu_wait_for_response(clk_mgr, 10, 200000); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/display/dc/dc_hw_types.h +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dc_hw_types.h @@ -465,6 +465,7 @@ struct fixed31_32 v_scale_ratio; enum dc_rotation_angle rotation; bool mirror; + struct dc_stream_state *stream; }; /* IPP related types */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -963,7 +963,9 @@ return; } - if (link->panel_cntl) { + if (link->panel_cntl && !(link->dpcd_sink_ext_caps.bits.oled || + link->dpcd_sink_ext_caps.bits.hdr_aux_backlight_control == 1 || + link->dpcd_sink_ext_caps.bits.sdr_aux_backlight_control == 1)) { bool is_backlight_on = link->panel_cntl->funcs->is_panel_backlight_on(link->panel_cntl); if ((enable && is_backlight_on) || (!enable && !is_backlight_on)) { @@ -1774,10 +1776,13 @@ hws->funcs.edp_backlight_control(edp_link_with_sink, false); } /*resume from S3, no vbios posting, no need to power down again*/ + clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); + power_down_all_hw_blocks(dc); disable_vga_and_power_gate_all_controllers(dc); if (edp_link_with_sink && !keep_edp_vdd_on) dc->hwss.edp_power_control(edp_link_with_sink, false); + clk_mgr_optimize_pwr_state(dc, dc->clk_mgr); } bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_mpc.c @@ -212,8 +212,9 @@ /* check insert_above_mpcc exist in tree->opp_list */ struct mpcc *temp_mpcc = tree->opp_list; - while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc) - temp_mpcc = temp_mpcc->mpcc_bot; + if (temp_mpcc != insert_above_mpcc) + while (temp_mpcc && temp_mpcc->mpcc_bot != insert_above_mpcc) + temp_mpcc = temp_mpcc->mpcc_bot; if (temp_mpcc == NULL) return NULL; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hubp.c @@ -1075,8 +1075,16 @@ if (src_y_offset < 0) src_y_offset = 0; /* Save necessary cursor info x, y position. w, h is saved in attribute func. */ - hubp->cur_rect.x = src_x_offset + param->viewport.x; - hubp->cur_rect.y = src_y_offset + param->viewport.y; + if (param->stream->link->psr_settings.psr_version >= DC_PSR_VERSION_SU_1 && + param->rotation != ROTATION_ANGLE_0) { + hubp->cur_rect.x = 0; + hubp->cur_rect.y = 0; + hubp->cur_rect.w = param->stream->timing.h_addressable; + hubp->cur_rect.h = param->stream->timing.v_addressable; + } else { + hubp->cur_rect.x = src_x_offset + param->viewport.x; + hubp->cur_rect.y = src_y_offset + param->viewport.y; + } } void hubp2_clk_cntl(struct hubp *hubp, bool enable) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dcn301/dcn301_init.c @@ -75,6 +75,7 @@ .get_hw_state = dcn10_get_hw_state, .clear_status_bits = dcn10_clear_status_bits, .wait_for_mpcc_disconnect = dcn10_wait_for_mpcc_disconnect, + .edp_backlight_control = dce110_edp_backlight_control, .edp_power_control = dce110_edp_power_control, .edp_wait_for_hpd_ready = dce110_edp_wait_for_hpd_ready, .set_cursor_position = dcn10_set_cursor_position, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/dc/dml/dcn32/display_mode_vba_util_32.c @@ -3454,6 +3454,7 @@ double TimeForFetchingMetaPTE = 0; double TimeForFetchingRowInVBlank = 0; double LinesToRequestPrefetchPixelData = 0; + double LinesForPrefetchBandwidth = 0; unsigned int HostVMDynamicLevelsTrips; double trip_to_mem; double Tvm_trips; @@ -3883,11 +3884,15 @@ TimeForFetchingMetaPTE = Tvm_oto; TimeForFetchingRowInVBlank = Tr0_oto; *PrefetchBandwidth = prefetch_bw_oto; + /* 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; } *DestinationLinesToRequestVMInVBlank = dml_ceil(4.0 * TimeForFetchingMetaPTE / LineTime, 1.0) / 4.0; @@ -3895,7 +3900,7 @@ *DestinationLinesToRequestRowInVBlank = dml_ceil(4.0 * TimeForFetchingRowInVBlank / LineTime, 1.0) / 4.0; - LinesToRequestPrefetchPixelData = *DestinationLinesForPrefetch - + LinesToRequestPrefetchPixelData = LinesForPrefetchBandwidth - *DestinationLinesToRequestVMInVBlank - 2 * *DestinationLinesToRequestRowInVBlank; #ifdef __DML_VBA_DEBUG__ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ linux-6.2.0/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -338,7 +338,9 @@ * - Delta for CEIL: delta_from_mid_point_in_us_1 * - Delta for FLOOR: delta_from_mid_point_in_us_2 */ - if ((last_render_time_in_us / mid_point_frames_ceil) < in_out_vrr->min_duration_in_us) { + if (mid_point_frames_ceil && + (last_render_time_in_us / mid_point_frames_ceil) < + in_out_vrr->min_duration_in_us) { /* Check for out of range. * If using CEIL produces a value that is out of range, * then we are forced to use FLOOR. @@ -385,8 +387,9 @@ /* Either we've calculated the number of frames to insert, * or we need to insert min duration frames */ - if (last_render_time_in_us / frames_to_insert < - in_out_vrr->min_duration_in_us){ + if (frames_to_insert && + (last_render_time_in_us / frames_to_insert) < + in_out_vrr->min_duration_in_us){ frames_to_insert -= (frames_to_insert > 1) ? 1 : 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/armada/armada_overlay.c +++ linux-6.2.0/drivers/gpu/drm/armada/armada_overlay.c @@ -4,6 +4,8 @@ * Rewritten from the dovefb driver, and Armada510 manuals. */ +#include + #include #include #include @@ -445,8 +447,8 @@ drm_to_overlay_state(state)->colorkey_ug, drm_to_overlay_state(state)->colorkey_vb, 0); } else if (property == priv->colorkey_mode_prop) { - *val = (drm_to_overlay_state(state)->colorkey_mode & - CFG_CKMODE_MASK) >> ffs(CFG_CKMODE_MASK); + *val = FIELD_GET(CFG_CKMODE_MASK, + drm_to_overlay_state(state)->colorkey_mode); } else if (property == priv->brightness_prop) { *val = drm_to_overlay_state(state)->brightness + 256; } else if (property == priv->contrast_prop) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/ast/ast_post.c +++ linux-6.2.0/drivers/gpu/drm/ast/ast_post.c @@ -291,7 +291,7 @@ ; } while (ast_read32(ast, 0x10100) != 0xa8); } else {/* AST2100/1100 */ - if (ast->chip == AST2100 || ast->chip == 2200) + if (ast->chip == AST2100 || ast->chip == AST2200) dram_reg_info = ast2100_dram_table_data; else dram_reg_info = ast1100_dram_table_data; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ linux-6.2.0/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -786,8 +786,13 @@ else low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; - regmap_update_bits(adv7511->regmap, 0xfb, - 0x6, low_refresh_rate << 1); + if (adv7511->type == ADV7511) + regmap_update_bits(adv7511->regmap, 0xfb, + 0x6, low_refresh_rate << 1); + else + regmap_update_bits(adv7511->regmap, 0x4a, + 0xc, low_refresh_rate << 2); + regmap_update_bits(adv7511->regmap, 0x17, 0x60, (vsync_polarity << 6) | (hsync_polarity << 5)); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ linux-6.2.0/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -265,6 +265,7 @@ struct dw_mipi_dsi *master; /* dual-dsi master ptr */ struct dw_mipi_dsi *slave; /* dual-dsi slave ptr */ + struct drm_display_mode mode; const struct dw_mipi_dsi_plat_data *plat_data; }; @@ -332,6 +333,7 @@ if (IS_ERR(bridge)) return PTR_ERR(bridge); + bridge->pre_enable_prev_first = true; dsi->panel_bridge = bridge; drm_bridge_add(&dsi->bridge); @@ -859,15 +861,6 @@ */ dw_mipi_dsi_set_mode(dsi, 0); - /* - * TODO Only way found to call panel-bridge post_disable & - * panel unprepare before the dsi "final" disable... - * This needs to be fixed in the drm_bridge framework and the API - * needs to be updated to manage our own call chains... - */ - if (dsi->panel_bridge->funcs->post_disable) - dsi->panel_bridge->funcs->post_disable(dsi->panel_bridge); - if (phy_ops->power_off) phy_ops->power_off(dsi->plat_data->priv_data); @@ -942,15 +935,25 @@ phy_ops->power_on(dsi->plat_data->priv_data); } +static void dw_mipi_dsi_bridge_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) +{ + struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); + + /* Power up the dsi ctl into a command mode */ + dw_mipi_dsi_mode_set(dsi, &dsi->mode); + if (dsi->slave) + dw_mipi_dsi_mode_set(dsi->slave, &dsi->mode); +} + static void dw_mipi_dsi_bridge_mode_set(struct drm_bridge *bridge, const struct drm_display_mode *mode, const struct drm_display_mode *adjusted_mode) { struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); - dw_mipi_dsi_mode_set(dsi, adjusted_mode); - if (dsi->slave) - dw_mipi_dsi_mode_set(dsi->slave, adjusted_mode); + /* Store the display mode for later use in pre_enable callback */ + drm_mode_copy(&dsi->mode, adjusted_mode); } static void dw_mipi_dsi_bridge_atomic_enable(struct drm_bridge *bridge, @@ -1004,6 +1007,7 @@ .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_reset = drm_atomic_helper_bridge_reset, + .atomic_pre_enable = dw_mipi_dsi_bridge_atomic_pre_enable, .atomic_enable = dw_mipi_dsi_bridge_atomic_enable, .atomic_post_disable = dw_mipi_dsi_bridge_post_atomic_disable, .mode_set = dw_mipi_dsi_bridge_mode_set, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/bridge/tc358762.c +++ linux-6.2.0/drivers/gpu/drm/bridge/tc358762.c @@ -216,7 +216,7 @@ dsi->lanes = 1; dsi->format = MIPI_DSI_FMT_RGB888; dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | - MIPI_DSI_MODE_LPM; + MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_VIDEO_HSE; ret = tc358762_parse_dt(ctx); if (ret < 0) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/bridge/tc358764.c +++ linux-6.2.0/drivers/gpu/drm/bridge/tc358764.c @@ -176,7 +176,7 @@ if (ret >= 0) le32_to_cpus(val); - dev_dbg(ctx->dev, "read: %d, addr: %d\n", addr, *val); + dev_dbg(ctx->dev, "read: addr=0x%04x data=0x%08x\n", addr, *val); } static void tc358764_write(struct tc358764 *ctx, u16 addr, u32 val) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/etnaviv/etnaviv_dump.c +++ linux-6.2.0/drivers/gpu/drm/etnaviv/etnaviv_dump.c @@ -130,9 +130,9 @@ return; etnaviv_dump_core = false; - mutex_lock(&gpu->mmu_context->lock); + mutex_lock(&submit->mmu_context->lock); - mmu_size = etnaviv_iommu_dump_size(gpu->mmu_context); + mmu_size = etnaviv_iommu_dump_size(submit->mmu_context); /* We always dump registers, mmu, ring, hanging cmdbuf and end marker */ n_obj = 5; @@ -162,7 +162,7 @@ iter.start = __vmalloc(file_size, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); if (!iter.start) { - mutex_unlock(&gpu->mmu_context->lock); + mutex_unlock(&submit->mmu_context->lock); dev_warn(gpu->dev, "failed to allocate devcoredump file\n"); return; } @@ -174,18 +174,18 @@ memset(iter.hdr, 0, iter.data - iter.start); etnaviv_core_dump_registers(&iter, gpu); - etnaviv_core_dump_mmu(&iter, gpu->mmu_context, mmu_size); + etnaviv_core_dump_mmu(&iter, submit->mmu_context, mmu_size); etnaviv_core_dump_mem(&iter, ETDUMP_BUF_RING, gpu->buffer.vaddr, gpu->buffer.size, etnaviv_cmdbuf_get_va(&gpu->buffer, - &gpu->mmu_context->cmdbuf_mapping)); + &submit->mmu_context->cmdbuf_mapping)); etnaviv_core_dump_mem(&iter, ETDUMP_BUF_CMD, submit->cmdbuf.vaddr, submit->cmdbuf.size, etnaviv_cmdbuf_get_va(&submit->cmdbuf, - &gpu->mmu_context->cmdbuf_mapping)); + &submit->mmu_context->cmdbuf_mapping)); - mutex_unlock(&gpu->mmu_context->lock); + mutex_unlock(&submit->mmu_context->lock); /* Reserve space for the bomap */ if (n_bomap_pages) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ linux-6.2.0/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -39,13 +39,12 @@ if (exynos_crtc->ops->atomic_disable) exynos_crtc->ops->atomic_disable(exynos_crtc); + spin_lock_irq(&crtc->dev->event_lock); if (crtc->state->event && !crtc->state->active) { - spin_lock_irq(&crtc->dev->event_lock); drm_crtc_send_vblank_event(crtc, crtc->state->event); - spin_unlock_irq(&crtc->dev->event_lock); - crtc->state->event = NULL; } + spin_unlock_irq(&crtc->dev->event_lock); } static int exynos_crtc_atomic_check(struct drm_crtc *crtc, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/i915/gt/intel_engine_types.h +++ linux-6.2.0/drivers/gpu/drm/i915/gt/intel_engine_types.h @@ -56,6 +56,7 @@ typedef u32 intel_engine_mask_t; #define ALL_ENGINES ((intel_engine_mask_t)~0ul) +#define VIRTUAL_ENGINES BIT(BITS_PER_TYPE(intel_engine_mask_t) - 1) struct intel_hw_status_page { struct list_head timelines; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/i915/gt/intel_ggtt.c +++ linux-6.2.0/drivers/gpu/drm/i915/gt/intel_ggtt.c @@ -500,20 +500,31 @@ vm->clear_range(vm, vma_res->start, vma_res->vma_size); } +/* + * Reserve the top of the GuC address space for firmware images. Addresses + * beyond GUC_GGTT_TOP in the GuC address space are inaccessible by GuC, + * which makes for a suitable range to hold GuC/HuC firmware images if the + * size of the GGTT is 4G. However, on a 32-bit platform the size of the GGTT + * is limited to 2G, which is less than GUC_GGTT_TOP, but we reserve a chunk + * of the same size anyway, which is far more than needed, to keep the logic + * in uc_fw_ggtt_offset() simple. + */ +#define GUC_TOP_RESERVE_SIZE (SZ_4G - GUC_GGTT_TOP) + static int ggtt_reserve_guc_top(struct i915_ggtt *ggtt) { - u64 size; + u64 offset; int ret; if (!intel_uc_uses_guc(&ggtt->vm.gt->uc)) return 0; - GEM_BUG_ON(ggtt->vm.total <= GUC_GGTT_TOP); - size = ggtt->vm.total - GUC_GGTT_TOP; + GEM_BUG_ON(ggtt->vm.total <= GUC_TOP_RESERVE_SIZE); + offset = ggtt->vm.total - GUC_TOP_RESERVE_SIZE; - ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, size, - GUC_GGTT_TOP, I915_COLOR_UNEVICTABLE, - PIN_NOEVICT); + ret = i915_gem_gtt_reserve(&ggtt->vm, NULL, &ggtt->uc_fw, + GUC_TOP_RESERVE_SIZE, offset, + I915_COLOR_UNEVICTABLE, PIN_NOEVICT); if (ret) drm_dbg(&ggtt->vm.i915->drm, "Failed to reserve top of GGTT for GuC\n"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/i915/gvt/gtt.c +++ linux-6.2.0/drivers/gpu/drm/i915/gvt/gtt.c @@ -1174,6 +1174,7 @@ { const struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops; kvm_pfn_t pfn; + int ret; if (!HAS_PAGE_SIZES(vgpu->gvt->gt->i915, I915_GTT_PAGE_SIZE_2M)) return 0; @@ -1183,7 +1184,13 @@ pfn = gfn_to_pfn(vgpu->vfio_device.kvm, ops->get_pfn(entry)); if (is_error_noslot_pfn(pfn)) return -EINVAL; - return PageTransHuge(pfn_to_page(pfn)); + + if (!pfn_valid(pfn)) + return -EINVAL; + + ret = PageTransHuge(pfn_to_page(pfn)); + kvm_release_pfn_clean(pfn); + return ret; } static int split_2MB_gtt_entry(struct intel_vgpu *vgpu, @@ -2876,24 +2883,6 @@ } /** - * intel_vgpu_reset_gtt - reset the all GTT related status - * @vgpu: a vGPU - * - * This function is called from vfio core to reset reset all - * GTT related status, including GGTT, PPGTT, scratch page. - * - */ -void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu) -{ - /* Shadow pages are only created when there is no page - * table tracking data, so remove page tracking data after - * removing the shadow pages. - */ - intel_vgpu_destroy_all_ppgtt_mm(vgpu); - intel_vgpu_reset_ggtt(vgpu, true); -} - -/** * intel_gvt_restore_ggtt - restore all vGPU's ggtt entries * @gvt: intel gvt device * only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/i915/gvt/gtt.h +++ linux-6.2.0/drivers/gpu/drm/i915/gvt/gtt.h @@ -224,7 +224,6 @@ void intel_vgpu_invalidate_ppgtt(struct intel_vgpu *vgpu); int intel_gvt_init_gtt(struct intel_gvt *gvt); -void intel_vgpu_reset_gtt(struct intel_vgpu *vgpu); void intel_gvt_clean_gtt(struct intel_gvt *gvt); struct intel_vgpu_mm *intel_gvt_find_ppgtt_mm(struct intel_vgpu *vgpu, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/meson/meson_encoder_hdmi.c +++ linux-6.2.0/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -332,6 +332,8 @@ return; cec_notifier_set_phys_addr_from_edid(encoder_hdmi->cec_notifier, edid); + + kfree(edid); } else cec_notifier_phys_addr_invalidate(encoder_hdmi->cec_notifier); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +++ linux-6.2.0/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -521,6 +521,10 @@ gpu->perfcntrs = perfcntrs; gpu->num_perfcntrs = ARRAY_SIZE(perfcntrs); + ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); + if (ret) + goto fail; + if (adreno_is_a20x(adreno_gpu)) adreno_gpu->registers = a200_registers; else if (adreno_is_a225(adreno_gpu)) @@ -528,10 +532,6 @@ else adreno_gpu->registers = a220_registers; - ret = adreno_gpu_init(dev, pdev, adreno_gpu, &funcs, 1); - if (ret) - goto fail; - if (!gpu->aspace) { dev_err(dev->dev, "No memory protection without MMU\n"); if (!allow_vram_carveout) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ linux-6.2.0/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -460,7 +460,8 @@ wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt; wait_info.timeout_ms = KICKOFF_TIMEOUT_MS; - ret = dpu_encoder_helper_wait_for_irq(phys_enc, INTR_IDX_WB_DONE, + ret = dpu_encoder_helper_wait_for_irq(phys_enc, + phys_enc->irq[INTR_IDX_WB_DONE], dpu_encoder_phys_wb_done_irq, &wait_info); if (ret == -ETIMEDOUT) _dpu_encoder_phys_wb_handle_wbdone_timeout(phys_enc); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ linux-6.2.0/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -130,8 +130,7 @@ { struct mdp5_plane_state *pstate = to_mdp5_plane_state(state); - if (state->fb) - drm_framebuffer_put(state->fb); + __drm_atomic_helper_plane_destroy_state(state); kfree(pstate); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c +++ linux-6.2.0/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c @@ -192,5 +192,5 @@ new_blk->base_addr = base_addr; msm_disp_state_dump_regs(&new_blk->state, new_blk->size, base_addr); - list_add(&new_blk->node, &disp_state->blocks); + list_add_tail(&new_blk->node, &disp_state->blocks); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/mxsfb/mxsfb_kms.c +++ linux-6.2.0/drivers/gpu/drm/mxsfb/mxsfb_kms.c @@ -611,6 +611,14 @@ writel(ctrl, mxsfb->base + LCDC_AS_CTRL); } +static void mxsfb_plane_overlay_atomic_disable(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(plane->dev); + + writel(0, mxsfb->base + LCDC_AS_CTRL); +} + static bool mxsfb_format_mod_supported(struct drm_plane *plane, uint32_t format, uint64_t modifier) @@ -626,6 +634,7 @@ static const struct drm_plane_helper_funcs mxsfb_plane_overlay_helper_funcs = { .atomic_check = mxsfb_plane_atomic_check, .atomic_update = mxsfb_plane_overlay_atomic_update, + .atomic_disable = mxsfb_plane_overlay_atomic_disable, }; static const struct drm_plane_funcs mxsfb_plane_funcs = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/radeon/cik.c +++ linux-6.2.0/drivers/gpu/drm/radeon/cik.c @@ -9534,17 +9534,8 @@ u16 bridge_cfg2, gpu_cfg2; u32 max_lw, current_lw, tmp; - pcie_capability_read_word(root, PCI_EXP_LNKCTL, - &bridge_cfg); - pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL, - &gpu_cfg); - - tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; - pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16); - - tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; - pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL, - tmp16); + pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); + pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1); max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; @@ -9591,21 +9582,14 @@ msleep(100); /* linkctl */ - pcie_capability_read_word(root, PCI_EXP_LNKCTL, - &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); - pcie_capability_write_word(root, PCI_EXP_LNKCTL, - tmp16); - - pcie_capability_read_word(rdev->pdev, - PCI_EXP_LNKCTL, - &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); - pcie_capability_write_word(rdev->pdev, - PCI_EXP_LNKCTL, - tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + bridge_cfg & + PCI_EXP_LNKCTL_HAWD); + pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + gpu_cfg & + PCI_EXP_LNKCTL_HAWD); /* linkctl2 */ pcie_capability_read_word(root, PCI_EXP_LNKCTL2, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/radeon/si.c +++ linux-6.2.0/drivers/gpu/drm/radeon/si.c @@ -7131,17 +7131,8 @@ u16 bridge_cfg2, gpu_cfg2; u32 max_lw, current_lw, tmp; - pcie_capability_read_word(root, PCI_EXP_LNKCTL, - &bridge_cfg); - pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL, - &gpu_cfg); - - tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD; - pcie_capability_write_word(root, PCI_EXP_LNKCTL, tmp16); - - tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD; - pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL, - tmp16); + pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); + pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); tmp = RREG32_PCIE(PCIE_LC_STATUS1); max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; @@ -7188,22 +7179,14 @@ msleep(100); /* linkctl */ - pcie_capability_read_word(root, PCI_EXP_LNKCTL, - &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD); - pcie_capability_write_word(root, - PCI_EXP_LNKCTL, - tmp16); - - pcie_capability_read_word(rdev->pdev, - PCI_EXP_LNKCTL, - &tmp16); - tmp16 &= ~PCI_EXP_LNKCTL_HAWD; - tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD); - pcie_capability_write_word(rdev->pdev, - PCI_EXP_LNKCTL, - tmp16); + pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + bridge_cfg & + PCI_EXP_LNKCTL_HAWD); + pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_HAWD, + gpu_cfg & + PCI_EXP_LNKCTL_HAWD); /* linkctl2 */ pcie_capability_read_word(root, PCI_EXP_LNKCTL2, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/tegra/dpaux.c +++ linux-6.2.0/drivers/gpu/drm/tegra/dpaux.c @@ -468,7 +468,7 @@ dpaux->irq = platform_get_irq(pdev, 0); if (dpaux->irq < 0) - return -ENXIO; + return dpaux->irq; if (!pdev->dev.pm_domain) { dpaux->rst = devm_reset_control_get(&pdev->dev, "dpaux"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/tests/drm_mm_test.c +++ linux-6.2.0/drivers/gpu/drm/tests/drm_mm_test.c @@ -939,7 +939,7 @@ KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max - 1)); KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, 0, max / 2)); KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, - max / 2, max / 2)); + max / 2, max)); KUNIT_ASSERT_FALSE(test, __drm_test_mm_insert_range(test, count, size, max / 4 + 1, 3 * max / 4 - 1)); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/tiny/gm12u320.c +++ linux-6.2.0/drivers/gpu/drm/tiny/gm12u320.c @@ -69,10 +69,10 @@ #define READ_STATUS_SIZE 13 #define MISC_VALUE_SIZE 4 -#define CMD_TIMEOUT msecs_to_jiffies(200) -#define DATA_TIMEOUT msecs_to_jiffies(1000) -#define IDLE_TIMEOUT msecs_to_jiffies(2000) -#define FIRST_FRAME_TIMEOUT msecs_to_jiffies(2000) +#define CMD_TIMEOUT 200 +#define DATA_TIMEOUT 1000 +#define IDLE_TIMEOUT 2000 +#define FIRST_FRAME_TIMEOUT 2000 #define MISC_REQ_GET_SET_ECO_A 0xff #define MISC_REQ_GET_SET_ECO_B 0x35 @@ -388,7 +388,7 @@ * switches back to showing its logo. */ queue_delayed_work(system_long_wq, &gm12u320->fb_update.work, - IDLE_TIMEOUT); + msecs_to_jiffies(IDLE_TIMEOUT)); return; err: only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/tiny/repaper.c +++ linux-6.2.0/drivers/gpu/drm/tiny/repaper.c @@ -533,7 +533,7 @@ DRM_DEBUG("Flushing [FB:%d] st=%ums\n", fb->base.id, epd->factored_stage_time); - buf = kmalloc_array(fb->width, fb->height, GFP_KERNEL); + buf = kmalloc(fb->width * fb->height / 8, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto out_exit; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/virtio/virtgpu_ioctl.c +++ linux-6.2.0/drivers/gpu/drm/virtio/virtgpu_ioctl.c @@ -43,13 +43,9 @@ struct virtio_gpu_fence *fence, uint32_t ring_idx) { - struct virtio_gpu_fpriv *vfpriv = file->driver_priv; struct virtio_gpu_fence_event *e = NULL; int ret; - if (!(vfpriv->ring_idx_mask & BIT_ULL(ring_idx))) - return 0; - e = kzalloc(sizeof(*e), GFP_KERNEL); if (!e) return -ENOMEM; @@ -121,6 +117,7 @@ struct virtio_gpu_device *vgdev = dev->dev_private; struct virtio_gpu_fpriv *vfpriv = file->driver_priv; struct virtio_gpu_fence *out_fence; + bool drm_fence_event; int ret; uint32_t *bo_handles = NULL; void __user *user_bo_handles = NULL; @@ -216,15 +213,24 @@ goto out_memdup; } - out_fence = virtio_gpu_fence_alloc(vgdev, fence_ctx, ring_idx); - if(!out_fence) { - ret = -ENOMEM; - goto out_unresv; - } + if ((exbuf->flags & VIRTGPU_EXECBUF_RING_IDX) && + (vfpriv->ring_idx_mask & BIT_ULL(ring_idx))) + drm_fence_event = true; + else + drm_fence_event = false; + + if ((exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_OUT) || + exbuf->num_bo_handles || + drm_fence_event) + out_fence = virtio_gpu_fence_alloc(vgdev, fence_ctx, ring_idx); + else + out_fence = NULL; - ret = virtio_gpu_fence_event_create(dev, file, out_fence, ring_idx); - if (ret) - goto out_unresv; + if (drm_fence_event) { + ret = virtio_gpu_fence_event_create(dev, file, out_fence, ring_idx); + if (ret) + goto out_unresv; + } if (out_fence_fd >= 0) { sync_file = sync_file_create(&out_fence->f); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/gpu/drm/xlnx/zynqmp_dpsub.c +++ linux-6.2.0/drivers/gpu/drm/xlnx/zynqmp_dpsub.c @@ -227,7 +227,9 @@ dpsub->dev = &pdev->dev; platform_set_drvdata(pdev, dpsub); - dma_set_mask(dpsub->dev, DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT)); + ret = dma_set_mask(dpsub->dev, DMA_BIT_MASK(ZYNQMP_DISP_MAX_DMA_BIT)); + if (ret) + return ret; /* Try the reserved memory. Proceed if there's none. */ of_reserved_mem_device_init(&pdev->dev); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/hid/hid-logitech-dj.c +++ linux-6.2.0/drivers/hid/hid-logitech-dj.c @@ -1285,6 +1285,9 @@ * 50 msec should gives enough time to the receiver to be ready. */ msleep(50); + + if (retval) + return retval; } /* @@ -1306,7 +1309,7 @@ buf[5] = 0x09; buf[6] = 0x00; - hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf, + retval = hid_hw_raw_request(hdev, REPORT_ID_HIDPP_SHORT, buf, HIDPP_REPORT_SHORT_LENGTH, HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/hid/hid-sony.c +++ linux-6.2.0/drivers/hid/hid-sony.c @@ -3076,6 +3076,8 @@ return ret; err: + usb_free_urb(sc->ghl_urb); + hid_hw_stop(hdev); return ret; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/hwmon/nzxt-smart2.c +++ linux-6.2.0/drivers/hwmon/nzxt-smart2.c @@ -791,6 +791,8 @@ { HID_USB_DEVICE(0x1e71, 0x2009) }, /* NZXT RGB & Fan Controller */ { HID_USB_DEVICE(0x1e71, 0x200e) }, /* NZXT RGB & Fan Controller */ { HID_USB_DEVICE(0x1e71, 0x2010) }, /* NZXT RGB & Fan Controller */ + { HID_USB_DEVICE(0x1e71, 0x2011) }, /* NZXT RGB & Fan Controller (6 RGB) */ + { HID_USB_DEVICE(0x1e71, 0x2019) }, /* NZXT RGB & Fan Controller (6 RGB) */ {}, }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/hwspinlock/qcom_hwspinlock.c +++ linux-6.2.0/drivers/hwspinlock/qcom_hwspinlock.c @@ -69,9 +69,18 @@ .unlock = qcom_hwspinlock_unlock, }; +static const struct regmap_config sfpb_mutex_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x100, + .fast_io = true, +}; + static const struct qcom_hwspinlock_of_data of_sfpb_mutex = { .offset = 0x4, .stride = 0x4, + .regmap_config = &sfpb_mutex_config, }; static const struct regmap_config tcsr_msm8226_mutex_config = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/hwtracing/coresight/coresight-tmc-etf.c +++ linux-6.2.0/drivers/hwtracing/coresight/coresight-tmc-etf.c @@ -428,7 +428,7 @@ return -EINVAL; /* wrap head around to the amount of space we have */ - head = handle->head & ((buf->nr_pages << PAGE_SHIFT) - 1); + head = handle->head & (((unsigned long)buf->nr_pages << PAGE_SHIFT) - 1); /* find the page to write to */ buf->cur = head / PAGE_SIZE; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/hwtracing/coresight/coresight-tmc.h +++ linux-6.2.0/drivers/hwtracing/coresight/coresight-tmc.h @@ -325,7 +325,7 @@ static inline unsigned long tmc_sg_table_buf_size(struct tmc_sg_table *sg_table) { - return sg_table->data_pages.nr_pages << PAGE_SHIFT; + return (unsigned long)sg_table->data_pages.nr_pages << PAGE_SHIFT; } struct coresight_device *tmc_etr_get_catu_device(struct tmc_drvdata *drvdata); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/hwtracing/coresight/coresight-trbe.c +++ linux-6.2.0/drivers/hwtracing/coresight/coresight-trbe.c @@ -1223,6 +1223,16 @@ enable_percpu_irq(drvdata->irq, IRQ_TYPE_NONE); } +static void arm_trbe_disable_cpu(void *info) +{ + struct trbe_drvdata *drvdata = info; + struct trbe_cpudata *cpudata = this_cpu_ptr(drvdata->cpudata); + + disable_percpu_irq(drvdata->irq); + trbe_reset_local(cpudata); +} + + static void arm_trbe_register_coresight_cpu(struct trbe_drvdata *drvdata, int cpu) { struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu); @@ -1324,18 +1334,12 @@ cpumask_clear_cpu(cpu, &drvdata->supported_cpus); } -static void arm_trbe_remove_coresight_cpu(void *info) +static void arm_trbe_remove_coresight_cpu(struct trbe_drvdata *drvdata, int cpu) { - int cpu = smp_processor_id(); - struct trbe_drvdata *drvdata = info; - struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu); struct coresight_device *trbe_csdev = coresight_get_percpu_sink(cpu); - disable_percpu_irq(drvdata->irq); - trbe_reset_local(cpudata); if (trbe_csdev) { coresight_unregister(trbe_csdev); - cpudata->drvdata = NULL; coresight_set_percpu_sink(cpu, NULL); } } @@ -1364,8 +1368,10 @@ { int cpu; - for_each_cpu(cpu, &drvdata->supported_cpus) - smp_call_function_single(cpu, arm_trbe_remove_coresight_cpu, drvdata, 1); + for_each_cpu(cpu, &drvdata->supported_cpus) { + smp_call_function_single(cpu, arm_trbe_disable_cpu, drvdata, 1); + arm_trbe_remove_coresight_cpu(drvdata, cpu); + } free_percpu(drvdata->cpudata); return 0; } @@ -1404,12 +1410,8 @@ { struct trbe_drvdata *drvdata = hlist_entry_safe(node, struct trbe_drvdata, hotplug_node); - if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) { - struct trbe_cpudata *cpudata = per_cpu_ptr(drvdata->cpudata, cpu); - - disable_percpu_irq(drvdata->irq); - trbe_reset_local(cpudata); - } + if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) + arm_trbe_disable_cpu(drvdata); return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/i2c/busses/i2c-aspeed.c +++ linux-6.2.0/drivers/i2c/busses/i2c-aspeed.c @@ -698,13 +698,16 @@ if (time_left == 0) { /* - * If timed out and bus is still busy in a multi master - * environment, attempt recovery at here. + * In a multi-master setup, if a timeout occurs, attempt + * recovery. But if the bus is idle, we still need to reset the + * i2c controller to clear the remaining interrupts. */ if (bus->multi_master && (readl(bus->base + ASPEED_I2C_CMD_REG) & ASPEED_I2CD_BUS_BUSY_STS)) aspeed_i2c_recover_bus(bus); + else + aspeed_i2c_reset(bus); /* * If timed out and the state is still pending, drop the pending only in patch2: unchanged: --- linux-6.2.0.orig/drivers/i2c/busses/i2c-i801.c +++ linux-6.2.0/drivers/i2c/busses/i2c-i801.c @@ -1754,6 +1754,7 @@ "SMBus I801 adapter at %04lx", priv->smba); err = i2c_add_adapter(&priv->adapter); if (err) { + platform_device_unregister(priv->tco_pdev); i801_acpi_remove(priv); return err; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/i2c/busses/i2c-npcm7xx.c +++ linux-6.2.0/drivers/i2c/busses/i2c-npcm7xx.c @@ -695,6 +695,7 @@ { struct i2c_msg *msgs; int msgs_num; + bool do_complete = false; msgs = bus->msgs; msgs_num = bus->msgs_num; @@ -723,23 +724,17 @@ msgs[1].flags & I2C_M_RD) msgs[1].len = info; } - if (completion_done(&bus->cmd_complete) == false) - complete(&bus->cmd_complete); - break; - + do_complete = true; + break; case I2C_NACK_IND: /* MASTER transmit got a NACK before tx all bytes */ bus->cmd_err = -ENXIO; - if (bus->master_or_slave == I2C_MASTER) - complete(&bus->cmd_complete); - + do_complete = true; break; case I2C_BUS_ERR_IND: /* Bus error */ bus->cmd_err = -EAGAIN; - if (bus->master_or_slave == I2C_MASTER) - complete(&bus->cmd_complete); - + do_complete = true; break; case I2C_WAKE_UP_IND: /* I2C wake up */ @@ -753,6 +748,8 @@ if (bus->slave) bus->master_or_slave = I2C_SLAVE; #endif + if (do_complete) + complete(&bus->cmd_complete); } static u8 npcm_i2c_fifo_usage(struct npcm_i2c *bus) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/i2c/i2c-core-of.c +++ linux-6.2.0/drivers/i2c/i2c-core-of.c @@ -244,6 +244,11 @@ return NOTIFY_OK; } + /* + * Clear the flag before adding the device so that fw_devlink + * doesn't skip adding consumers to this device. + */ + rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE; client = of_i2c_register_device(adap, rd->dn); if (IS_ERR(client)) { dev_err(&adap->dev, "failed to create client for '%pOF'\n", only in patch2: unchanged: --- linux-6.2.0.orig/drivers/i2c/muxes/i2c-demux-pinctrl.c +++ linux-6.2.0/drivers/i2c/muxes/i2c-demux-pinctrl.c @@ -243,6 +243,10 @@ props[i].name = devm_kstrdup(&pdev->dev, "status", GFP_KERNEL); props[i].value = devm_kstrdup(&pdev->dev, "ok", GFP_KERNEL); + if (!props[i].name || !props[i].value) { + err = -ENOMEM; + goto err_rollback; + } props[i].length = 3; of_changeset_init(&priv->chan[i].chgset); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/i2c/muxes/i2c-mux-gpio.c +++ linux-6.2.0/drivers/i2c/muxes/i2c-mux-gpio.c @@ -105,8 +105,10 @@ } else if (is_acpi_node(child)) { rc = acpi_get_local_address(ACPI_HANDLE_FWNODE(child), values + i); - if (rc) + if (rc) { + fwnode_handle_put(child); return dev_err_probe(dev, rc, "Cannot get address\n"); + } } i++; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/idle/intel_idle.c +++ linux-6.2.0/drivers/idle/intel_idle.c @@ -1430,6 +1430,7 @@ X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, &idle_cpu_adl_l), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_N, &idle_cpu_adl_n), X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X, &idle_cpu_spr), + X86_MATCH_INTEL_FAM6_MODEL(EMERALDRAPIDS_X, &idle_cpu_spr), X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNL, &idle_cpu_knl), X86_MATCH_INTEL_FAM6_MODEL(XEON_PHI_KNM, &idle_cpu_knl), X86_MATCH_INTEL_FAM6_MODEL(ATOM_GOLDMONT, &idle_cpu_bxt), @@ -1862,6 +1863,7 @@ skx_idle_state_table_update(); break; case INTEL_FAM6_SAPPHIRERAPIDS_X: + case INTEL_FAM6_EMERALDRAPIDS_X: spr_idle_state_table_update(); break; case INTEL_FAM6_ALDERLAKE: only in patch2: unchanged: --- linux-6.2.0.orig/drivers/iio/accel/adxl313_i2c.c +++ linux-6.2.0/drivers/iio/accel/adxl313_i2c.c @@ -40,8 +40,8 @@ static const struct i2c_device_id adxl313_i2c_id[] = { { .name = "adxl312", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] }, - { .name = "adxl313", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] }, - { .name = "adxl314", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL312] }, + { .name = "adxl313", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL313] }, + { .name = "adxl314", .driver_data = (kernel_ulong_t)&adxl31x_chip_info[ADXL314] }, { } }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/infiniband/core/cma_configfs.c +++ linux-6.2.0/drivers/infiniband/core/cma_configfs.c @@ -217,7 +217,7 @@ return -ENOMEM; for (i = 0; i < ports_num; i++) { - char port_str[10]; + char port_str[11]; ports[i].port_num = i + 1; snprintf(port_str, sizeof(port_str), "%u", i + 1); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/infiniband/core/nldev.c +++ linux-6.2.0/drivers/infiniband/core/nldev.c @@ -2529,6 +2529,7 @@ }, [RDMA_NLDEV_CMD_SYS_SET] = { .doit = nldev_set_sys_set_doit, + .flags = RDMA_NL_ADMIN_PERM, }, [RDMA_NLDEV_CMD_STAT_SET] = { .doit = nldev_stat_set_doit, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/infiniband/core/uverbs_std_types_counters.c +++ linux-6.2.0/drivers/infiniband/core/uverbs_std_types_counters.c @@ -107,6 +107,8 @@ return ret; uattr = uverbs_attr_get(attrs, UVERBS_ATTR_READ_COUNTERS_BUFF); + if (IS_ERR(uattr)) + return PTR_ERR(uattr); read_attr.ncounters = uattr->ptr_attr.len / sizeof(u64); read_attr.counters_buff = uverbs_zalloc( attrs, array_size(read_attr.ncounters, sizeof(u64))); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/infiniband/hw/hns/hns_roce_device.h +++ linux-6.2.0/drivers/infiniband/hw/hns/hns_roce_device.h @@ -97,6 +97,7 @@ #define HNS_ROCE_CQ_BANK_NUM 4 #define CQ_BANKID_SHIFT 2 +#define CQ_BANKID_MASK GENMASK(1, 0) enum { SERV_TYPE_RC, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/infiniband/hw/hns/hns_roce_qp.c +++ linux-6.2.0/drivers/infiniband/hw/hns/hns_roce_qp.c @@ -170,14 +170,29 @@ } } -static u8 get_least_load_bankid_for_qp(struct hns_roce_bank *bank) +static u8 get_affinity_cq_bank(u8 qp_bank) { - u32 least_load = bank[0].inuse; + return (qp_bank >> 1) & CQ_BANKID_MASK; +} + +static u8 get_least_load_bankid_for_qp(struct ib_qp_init_attr *init_attr, + struct hns_roce_bank *bank) +{ +#define INVALID_LOAD_QPNUM 0xFFFFFFFF + struct ib_cq *scq = init_attr->send_cq; + u32 least_load = INVALID_LOAD_QPNUM; + unsigned long cqn = 0; u8 bankid = 0; u32 bankcnt; u8 i; - for (i = 1; i < HNS_ROCE_QP_BANK_NUM; i++) { + if (scq) + cqn = to_hr_cq(scq)->cqn; + + for (i = 0; i < HNS_ROCE_QP_BANK_NUM; i++) { + if (scq && (get_affinity_cq_bank(i) != (cqn & CQ_BANKID_MASK))) + continue; + bankcnt = bank[i].inuse; if (bankcnt < least_load) { least_load = bankcnt; @@ -209,7 +224,8 @@ return 0; } -static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp) +static int alloc_qpn(struct hns_roce_dev *hr_dev, struct hns_roce_qp *hr_qp, + struct ib_qp_init_attr *init_attr) { struct hns_roce_qp_table *qp_table = &hr_dev->qp_table; unsigned long num = 0; @@ -220,7 +236,7 @@ num = 1; } else { mutex_lock(&qp_table->bank_mutex); - bankid = get_least_load_bankid_for_qp(qp_table->bank); + bankid = get_least_load_bankid_for_qp(init_attr, qp_table->bank); ret = alloc_qpn_with_bankid(&qp_table->bank[bankid], bankid, &num); @@ -1146,7 +1162,7 @@ goto err_buf; } - ret = alloc_qpn(hr_dev, hr_qp); + ret = alloc_qpn(hr_dev, hr_qp, init_attr); if (ret) { ibdev_err(ibdev, "failed to alloc QPN, ret = %d.\n", ret); goto err_qpn; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/infiniband/hw/mlx4/sysfs.c +++ linux-6.2.0/drivers/infiniband/hw/mlx4/sysfs.c @@ -223,7 +223,7 @@ static int add_port_entries(struct mlx4_ib_dev *device, int port_num) { int i; - char buff[11]; + char buff[12]; struct mlx4_ib_iov_port *port = NULL; int ret = 0 ; struct ib_port_attr attr; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/infiniband/sw/siw/siw.h +++ linux-6.2.0/drivers/infiniband/sw/siw/siw.h @@ -74,6 +74,7 @@ u32 vendor_part_id; int numa_node; + char raw_gid[ETH_ALEN]; /* physical port state (only one port per device) */ enum ib_port_state state; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/infiniband/sw/siw/siw_cm.c +++ linux-6.2.0/drivers/infiniband/sw/siw/siw_cm.c @@ -973,6 +973,7 @@ siw_cep_put(cep); new_cep->listen_cep = NULL; if (rv) { + siw_cancel_mpatimer(new_cep); siw_cep_set_free(new_cep); goto error; } @@ -1097,9 +1098,12 @@ /* * Socket close before MPA request received. */ - siw_dbg_cep(cep, "no mpareq: drop listener\n"); - siw_cep_put(cep->listen_cep); - cep->listen_cep = NULL; + if (cep->listen_cep) { + siw_dbg_cep(cep, + "no mpareq: drop listener\n"); + siw_cep_put(cep->listen_cep); + cep->listen_cep = NULL; + } } } release_cep = 1; @@ -1222,7 +1226,11 @@ if (!cep) goto out; - siw_dbg_cep(cep, "state: %d\n", cep->state); + siw_dbg_cep(cep, "cep state: %d, socket state %d\n", + cep->state, sk->sk_state); + + if (sk->sk_state != TCP_ESTABLISHED) + goto out; switch (cep->state) { case SIW_EPSTATE_RDMA_MODE: @@ -1496,7 +1504,6 @@ cep->cm_id = NULL; id->rem_ref(id); - siw_cep_put(cep); qp->cep = NULL; siw_cep_put(cep); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/infiniband/sw/siw/siw_verbs.c +++ linux-6.2.0/drivers/infiniband/sw/siw/siw_verbs.c @@ -157,7 +157,7 @@ attr->vendor_part_id = sdev->vendor_part_id; addrconf_addr_eui48((u8 *)&attr->sys_image_guid, - sdev->netdev->dev_addr); + sdev->raw_gid); return 0; } @@ -218,7 +218,7 @@ /* subnet_prefix == interface_id == 0; */ memset(gid, 0, sizeof(*gid)); - memcpy(&gid->raw[0], sdev->netdev->dev_addr, 6); + memcpy(gid->raw, sdev->raw_gid, ETH_ALEN); return 0; } @@ -1494,7 +1494,7 @@ if (pbl->max_buf < num_sle) { siw_dbg_mem(mem, "too many SGE's: %d > %d\n", - mem->pbl->max_buf, num_sle); + num_sle, pbl->max_buf); return -ENOMEM; } for_each_sg(sl, slp, num_sle, i) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/infiniband/ulp/srp/ib_srp.c +++ linux-6.2.0/drivers/infiniband/ulp/srp/ib_srp.c @@ -1984,12 +1984,8 @@ if (unlikely(rsp->flags & SRP_RSP_FLAG_DIUNDER)) scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); - else if (unlikely(rsp->flags & SRP_RSP_FLAG_DIOVER)) - scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_in_res_cnt)); else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOUNDER)) scsi_set_resid(scmnd, be32_to_cpu(rsp->data_out_res_cnt)); - else if (unlikely(rsp->flags & SRP_RSP_FLAG_DOOVER)) - scsi_set_resid(scmnd, -be32_to_cpu(rsp->data_out_res_cnt)); srp_free_req(ch, req, scmnd, be32_to_cpu(rsp->req_lim_delta)); @@ -2793,7 +2789,6 @@ u32 tag; u16 ch_idx; struct srp_rdma_ch *ch; - int ret; shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); @@ -2807,19 +2802,14 @@ shost_printk(KERN_ERR, target->scsi_host, "Sending SRP abort for tag %#x\n", tag); if (srp_send_tsk_mgmt(ch, tag, scmnd->device->lun, - SRP_TSK_ABORT_TASK, NULL) == 0) - ret = SUCCESS; - else if (target->rport->state == SRP_RPORT_LOST) - ret = FAST_IO_FAIL; - else - ret = FAILED; - if (ret == SUCCESS) { + SRP_TSK_ABORT_TASK, NULL) == 0) { srp_free_req(ch, req, scmnd, 0); - scmnd->result = DID_ABORT << 16; - scsi_done(scmnd); + return SUCCESS; } + if (target->rport->state == SRP_RPORT_LOST) + return FAST_IO_FAIL; - return ret; + return FAILED; } static int srp_reset_device(struct scsi_cmnd *scmnd) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/input/keyboard/tca6416-keypad.c +++ linux-6.2.0/drivers/input/keyboard/tca6416-keypad.c @@ -148,7 +148,7 @@ if (chip->use_polling) schedule_delayed_work(&chip->dwork, msecs_to_jiffies(100)); else - enable_irq(chip->irqnum); + enable_irq(chip->client->irq); return 0; } @@ -160,7 +160,7 @@ if (chip->use_polling) cancel_delayed_work_sync(&chip->dwork); else - disable_irq(chip->irqnum); + disable_irq(chip->client->irq); } static int tca6416_setup_registers(struct tca6416_keypad_chip *chip) @@ -266,12 +266,7 @@ goto fail1; if (!chip->use_polling) { - if (pdata->irq_is_gpio) - chip->irqnum = gpio_to_irq(client->irq); - else - chip->irqnum = client->irq; - - error = request_threaded_irq(chip->irqnum, NULL, + error = request_threaded_irq(client->irq, NULL, tca6416_keys_isr, IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_NO_AUTOEN, @@ -279,7 +274,7 @@ if (error) { dev_dbg(&client->dev, "Unable to claim irq %d; error %d\n", - chip->irqnum, error); + client->irq, error); goto fail1; } } @@ -297,10 +292,8 @@ return 0; fail2: - if (!chip->use_polling) { - free_irq(chip->irqnum, chip); - enable_irq(chip->irqnum); - } + if (!chip->use_polling) + free_irq(client->irq, chip); fail1: input_free_device(input); kfree(chip); @@ -311,10 +304,8 @@ { struct tca6416_keypad_chip *chip = i2c_get_clientdata(client); - if (!chip->use_polling) { - free_irq(chip->irqnum, chip); - enable_irq(chip->irqnum); - } + if (!chip->use_polling) + free_irq(client->irq, chip); input_unregister_device(chip->input); kfree(chip); @@ -323,10 +314,9 @@ static int tca6416_keypad_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); - struct tca6416_keypad_chip *chip = i2c_get_clientdata(client); if (device_may_wakeup(dev)) - enable_irq_wake(chip->irqnum); + enable_irq_wake(client->irq); return 0; } @@ -334,10 +324,9 @@ static int tca6416_keypad_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); - struct tca6416_keypad_chip *chip = i2c_get_clientdata(client); if (device_may_wakeup(dev)) - disable_irq_wake(chip->irqnum); + disable_irq_wake(client->irq); return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/input/misc/iqs7222.c +++ linux-6.2.0/drivers/input/misc/iqs7222.c @@ -1381,9 +1381,6 @@ if (error) return error; - sys_setup &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK; - sys_setup &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK; - for (i = 0; i < IQS7222_NUM_RETRIES; i++) { /* * Trigger ATI from streaming and normal-power modes so that @@ -1561,8 +1558,11 @@ return error; } - if (dir == READ) + if (dir == READ) { + iqs7222->sys_setup[0] &= ~IQS7222_SYS_SETUP_INTF_MODE_MASK; + iqs7222->sys_setup[0] &= ~IQS7222_SYS_SETUP_PWR_MODE_MASK; return 0; + } return iqs7222_ati_trigger(iqs7222); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c +++ linux-6.2.0/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c @@ -186,6 +186,15 @@ } } +/* + * Cloned from the MAX_TLBI_OPS in arch/arm64/include/asm/tlbflush.h, this + * is used as a threshold to replace per-page TLBI commands to issue in the + * command queue with an address-space TLBI command, when SMMU w/o a range + * invalidation feature handles too many per-page TLBI commands, which will + * otherwise result in a soft lockup. + */ +#define CMDQ_MAX_TLBI_OPS (1 << (PAGE_SHIFT - 3)) + static void arm_smmu_mm_invalidate_range(struct mmu_notifier *mn, struct mm_struct *mm, unsigned long start, unsigned long end) @@ -200,10 +209,22 @@ * range. So do a simple translation here by calculating size correctly. */ size = end - start; + if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_RANGE_INV)) { + if (size >= CMDQ_MAX_TLBI_OPS * PAGE_SIZE) + size = 0; + } + + if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM)) { + if (!size) + arm_smmu_tlb_inv_asid(smmu_domain->smmu, + smmu_mn->cd->asid); + else + arm_smmu_tlb_inv_range_asid(start, size, + smmu_mn->cd->asid, + PAGE_SIZE, false, + smmu_domain); + } - if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_BTM)) - arm_smmu_tlb_inv_range_asid(start, size, smmu_mn->cd->asid, - PAGE_SIZE, false, smmu_domain); arm_smmu_atc_inv_domain(smmu_domain, mm->pasid, start, size); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ linux-6.2.0/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -273,6 +273,13 @@ ctx->secure_init = true; } + /* Disable context bank before programming */ + iommu_writel(ctx, ARM_SMMU_CB_SCTLR, 0); + + /* Clear context bank fault address fault status registers */ + iommu_writel(ctx, ARM_SMMU_CB_FAR, 0); + iommu_writel(ctx, ARM_SMMU_CB_FSR, ARM_SMMU_FSR_FAULT); + /* TTBRs */ iommu_writeq(ctx, ARM_SMMU_CB_TTBR0, pgtbl_cfg.arm_lpae_s1_cfg.ttbr | only in patch2: unchanged: --- linux-6.2.0.orig/drivers/iommu/intel/iommu.h +++ linux-6.2.0/drivers/iommu/intel/iommu.h @@ -588,7 +588,7 @@ struct iopf_queue *iopf_queue; unsigned char iopfq_name[16]; struct q_inval *qi; /* Queued invalidation info */ - u32 *iommu_state; /* Store iommu states between suspend and resume.*/ + u32 iommu_state[MAX_SR_DMAR_REGS]; /* Store iommu states between suspend and resume.*/ #ifdef CONFIG_IRQ_REMAP struct ir_table *ir_table; /* Interrupt remapping info */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/iommu/sprd-iommu.c +++ linux-6.2.0/drivers/iommu/sprd-iommu.c @@ -147,6 +147,7 @@ dom->domain.geometry.aperture_start = 0; dom->domain.geometry.aperture_end = SZ_256M - 1; + dom->domain.geometry.force_aperture = true; return &dom->domain; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/leds/led-class-multicolor.c +++ linux-6.2.0/drivers/leds/led-class-multicolor.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -19,9 +20,10 @@ int i; for (i = 0; i < mcled_cdev->num_colors; i++) - mcled_cdev->subled_info[i].brightness = brightness * - mcled_cdev->subled_info[i].intensity / - led_cdev->max_brightness; + mcled_cdev->subled_info[i].brightness = + DIV_ROUND_CLOSEST(brightness * + mcled_cdev->subled_info[i].intensity, + led_cdev->max_brightness); return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/leds/led-core.c +++ linux-6.2.0/drivers/leds/led-core.c @@ -419,10 +419,6 @@ struct fwnode_handle *fwnode = init_data->fwnode; const char *devicename = init_data->devicename; - /* We want to label LEDs that can produce full range of colors - * as RGB, not multicolor */ - BUG_ON(props.color == LED_COLOR_ID_MULTI); - if (!led_classdev_name) return -EINVAL; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/leds/leds-pwm.c +++ linux-6.2.0/drivers/leds/leds-pwm.c @@ -146,7 +146,7 @@ led.name = to_of_node(fwnode)->name; if (!led.name) { - ret = EINVAL; + ret = -EINVAL; goto err_child_out; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/leds/trigger/ledtrig-tty.c +++ linux-6.2.0/drivers/leds/trigger/ledtrig-tty.c @@ -7,6 +7,8 @@ #include #include +#define LEDTRIG_TTY_INTERVAL 50 + struct ledtrig_tty_data { struct led_classdev *led_cdev; struct delayed_work dwork; @@ -122,17 +124,19 @@ if (icount.rx != trigger_data->rx || icount.tx != trigger_data->tx) { - led_set_brightness_sync(trigger_data->led_cdev, LED_ON); + unsigned long interval = LEDTRIG_TTY_INTERVAL; + + led_blink_set_oneshot(trigger_data->led_cdev, &interval, + &interval, 0); trigger_data->rx = icount.rx; trigger_data->tx = icount.tx; - } else { - led_set_brightness_sync(trigger_data->led_cdev, LED_OFF); } out: mutex_unlock(&trigger_data->mutex); - schedule_delayed_work(&trigger_data->dwork, msecs_to_jiffies(100)); + schedule_delayed_work(&trigger_data->dwork, + msecs_to_jiffies(LEDTRIG_TTY_INTERVAL * 2)); } static struct attribute *ledtrig_tty_attrs[] = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/mailbox/qcom-ipcc.c +++ linux-6.2.0/drivers/mailbox/qcom-ipcc.c @@ -227,10 +227,8 @@ ret = of_parse_phandle_with_args(client_dn, "mboxes", "#mbox-cells", j, &curr_ph); of_node_put(curr_ph.np); - if (!ret && curr_ph.np == controller_dn) { + if (!ret && curr_ph.np == controller_dn) ipcc->num_chans++; - break; - } } } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/md/dm-zoned-target.c +++ linux-6.2.0/drivers/md/dm-zoned-target.c @@ -748,17 +748,16 @@ /* * Cleanup zoned device information. */ -static void dmz_put_zoned_device(struct dm_target *ti) +static void dmz_put_zoned_devices(struct dm_target *ti) { struct dmz_target *dmz = ti->private; int i; - for (i = 0; i < dmz->nr_ddevs; i++) { - if (dmz->ddev[i]) { + for (i = 0; i < dmz->nr_ddevs; i++) + if (dmz->ddev[i]) dm_put_device(ti, dmz->ddev[i]); - dmz->ddev[i] = NULL; - } - } + + kfree(dmz->ddev); } static int dmz_fixup_devices(struct dm_target *ti) @@ -948,7 +947,7 @@ err_meta: dmz_dtr_metadata(dmz->metadata); err_dev: - dmz_put_zoned_device(ti); + dmz_put_zoned_devices(ti); err: kfree(dmz->dev); kfree(dmz); @@ -978,7 +977,7 @@ bioset_exit(&dmz->bio_set); - dmz_put_zoned_device(ti); + dmz_put_zoned_devices(ti); mutex_destroy(&dmz->chunk_lock); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/md/md-linear.c +++ linux-6.2.0/drivers/md/md-linear.c @@ -223,7 +223,8 @@ bio_sector < start_sector)) goto out_of_bounds; - if (unlikely(is_mddev_broken(tmp_dev->rdev, "linear"))) { + if (unlikely(is_rdev_broken(tmp_dev->rdev))) { + md_error(mddev, tmp_dev->rdev); bio_io_error(bio); return true; } @@ -270,6 +271,16 @@ seq_printf(seq, " %dk rounding", mddev->chunk_sectors / 2); } +static void linear_error(struct mddev *mddev, struct md_rdev *rdev) +{ + if (!test_and_set_bit(MD_BROKEN, &mddev->flags)) { + char *md_name = mdname(mddev); + + pr_crit("md/linear%s: Disk failure on %pg detected, failing array.\n", + md_name, rdev->bdev); + } +} + static void linear_quiesce(struct mddev *mddev, int state) { } @@ -286,6 +297,7 @@ .hot_add_disk = linear_add, .size = linear_size, .quiesce = linear_quiesce, + .error_handler = linear_error, }; static int __init linear_init (void) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/md/md.h +++ linux-6.2.0/drivers/md/md.h @@ -315,7 +315,7 @@ unsigned long sb_flags; int suspended; - atomic_t active_io; + struct percpu_ref active_io; int ro; int sysfs_active; /* set when sysfs deletes * are happening, so run/ @@ -789,15 +789,9 @@ struct md_rdev *md_find_rdev_nr_rcu(struct mddev *mddev, int nr); struct md_rdev *md_find_rdev_rcu(struct mddev *mddev, dev_t dev); -static inline bool is_mddev_broken(struct md_rdev *rdev, const char *md_type) +static inline bool is_rdev_broken(struct md_rdev *rdev) { - if (!disk_live(rdev->bdev->bd_disk)) { - if (!test_and_set_bit(MD_BROKEN, &rdev->mddev->flags)) - pr_warn("md: %s: %s array has a missing/failed member\n", - mdname(rdev->mddev), md_type); - return true; - } - return false; + return !disk_live(rdev->bdev->bd_disk); } static inline void rdev_dec_pending(struct md_rdev *rdev, struct mddev *mddev) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/md/raid5-cache.c +++ linux-6.2.0/drivers/md/raid5-cache.c @@ -1260,14 +1260,13 @@ if (bio->bi_status) md_error(log->rdev->mddev, log->rdev); + bio_uninit(bio); spin_lock_irqsave(&log->io_list_lock, flags); list_for_each_entry(io, &log->flushing_ios, log_sibling) r5l_io_run_stripes(io); list_splice_tail_init(&log->flushing_ios, &log->finished_ios); spin_unlock_irqrestore(&log->io_list_lock, flags); - - bio_uninit(bio); } /* @@ -3164,12 +3163,15 @@ { struct r5l_log *log = conf->log; - /* Ensure disable_writeback_work wakes up and exits */ - wake_up(&conf->mddev->sb_wait); - flush_work(&log->disable_writeback_work); md_unregister_thread(&log->reclaim_thread); + /* + * 'reconfig_mutex' is held by caller, set 'confg->log' to NULL to + * ensure disable_writeback_work wakes up and exits. + */ conf->log = NULL; + wake_up(&conf->mddev->sb_wait); + flush_work(&log->disable_writeback_work); mempool_exit(&log->meta_pool); bioset_exit(&log->bs); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/cec/usb/pulse8/pulse8-cec.c +++ linux-6.2.0/drivers/media/cec/usb/pulse8/pulse8-cec.c @@ -809,8 +809,11 @@ mutex_lock(&pulse8->lock); cmd = MSGCODE_PING; - pulse8_send_and_wait(pulse8, &cmd, 1, - MSGCODE_COMMAND_ACCEPTED, 0); + if (pulse8_send_and_wait(pulse8, &cmd, 1, + MSGCODE_COMMAND_ACCEPTED, 0)) { + dev_warn(pulse8->dev, "failed to ping EEPROM\n"); + goto unlock; + } if (pulse8->vers < 2) goto unlock; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/common/videobuf2/frame_vector.c +++ linux-6.2.0/drivers/media/common/videobuf2/frame_vector.c @@ -31,6 +31,10 @@ * different type underlying the specified range of virtual addresses. * When the function isn't able to map a single page, it returns error. * + * Note that get_vaddr_frames() cannot follow VM_IO mappings. It used + * to be able to do that, but that could (racily) return non-refcounted + * pfns. + * * This function takes care of grabbing mmap_lock as necessary. */ int get_vaddr_frames(unsigned long start, unsigned int nr_frames, bool write, @@ -59,8 +63,6 @@ if (likely(ret > 0)) return ret; - /* This used to (racily) return non-refcounted pfns. Let people know */ - WARN_ONCE(1, "get_vaddr_frames() cannot follow VM_IO mapping"); vec->nr_frames = 0; return ret ? ret : -EFAULT; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/ascot2e.c +++ linux-6.2.0/drivers/media/dvb-frontends/ascot2e.c @@ -533,7 +533,7 @@ priv->i2c_address, priv->i2c); return fe; } -EXPORT_SYMBOL(ascot2e_attach); +EXPORT_SYMBOL_GPL(ascot2e_attach); MODULE_DESCRIPTION("Sony ASCOT2E terr/cab tuner driver"); MODULE_AUTHOR("info@netup.ru"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/atbm8830.c +++ linux-6.2.0/drivers/media/dvb-frontends/atbm8830.c @@ -489,7 +489,7 @@ return NULL; } -EXPORT_SYMBOL(atbm8830_attach); +EXPORT_SYMBOL_GPL(atbm8830_attach); MODULE_DESCRIPTION("AltoBeam ATBM8830/8831 GB20600 demodulator driver"); MODULE_AUTHOR("David T. L. Wong "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/au8522_dig.c +++ linux-6.2.0/drivers/media/dvb-frontends/au8522_dig.c @@ -879,7 +879,7 @@ au8522_release_state(state); return NULL; } -EXPORT_SYMBOL(au8522_attach); +EXPORT_SYMBOL_GPL(au8522_attach); static const struct dvb_frontend_ops au8522_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/bcm3510.c +++ linux-6.2.0/drivers/media/dvb-frontends/bcm3510.c @@ -835,7 +835,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(bcm3510_attach); +EXPORT_SYMBOL_GPL(bcm3510_attach); static const struct dvb_frontend_ops bcm3510_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/cx22700.c +++ linux-6.2.0/drivers/media/dvb-frontends/cx22700.c @@ -432,4 +432,4 @@ MODULE_AUTHOR("Holger Waechtler"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(cx22700_attach); +EXPORT_SYMBOL_GPL(cx22700_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/cx22702.c +++ linux-6.2.0/drivers/media/dvb-frontends/cx22702.c @@ -604,7 +604,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(cx22702_attach); +EXPORT_SYMBOL_GPL(cx22702_attach); static const struct dvb_frontend_ops cx22702_ops = { .delsys = { SYS_DVBT }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/cx24110.c +++ linux-6.2.0/drivers/media/dvb-frontends/cx24110.c @@ -653,4 +653,4 @@ MODULE_AUTHOR("Peter Hettkamp"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(cx24110_attach); +EXPORT_SYMBOL_GPL(cx24110_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/cx24113.c +++ linux-6.2.0/drivers/media/dvb-frontends/cx24113.c @@ -590,7 +590,7 @@ return NULL; } -EXPORT_SYMBOL(cx24113_attach); +EXPORT_SYMBOL_GPL(cx24113_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/cx24116.c +++ linux-6.2.0/drivers/media/dvb-frontends/cx24116.c @@ -1133,7 +1133,7 @@ state->frontend.demodulator_priv = state; return &state->frontend; } -EXPORT_SYMBOL(cx24116_attach); +EXPORT_SYMBOL_GPL(cx24116_attach); /* * Initialise or wake up device only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/cx24120.c +++ linux-6.2.0/drivers/media/dvb-frontends/cx24120.c @@ -305,7 +305,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(cx24120_attach); +EXPORT_SYMBOL_GPL(cx24120_attach); static int cx24120_test_rom(struct cx24120_state *state) { @@ -973,7 +973,9 @@ cmd.arg[8] = (clock_ratios_table[idx].rate >> 8) & 0xff; cmd.arg[9] = (clock_ratios_table[idx].rate >> 0) & 0xff; - cx24120_message_send(state, &cmd); + ret = cx24120_message_send(state, &cmd); + if (ret != 0) + return; /* Calculate ber window rates for stat work */ cx24120_calculate_ber_window(state, clock_ratios_table[idx].rate); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/cx24123.c +++ linux-6.2.0/drivers/media/dvb-frontends/cx24123.c @@ -1096,7 +1096,7 @@ return NULL; } -EXPORT_SYMBOL(cx24123_attach); +EXPORT_SYMBOL_GPL(cx24123_attach); static const struct dvb_frontend_ops cx24123_ops = { .delsys = { SYS_DVBS }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/cxd2820r_core.c +++ linux-6.2.0/drivers/media/dvb-frontends/cxd2820r_core.c @@ -536,7 +536,7 @@ return pdata.get_dvb_frontend(client); } -EXPORT_SYMBOL(cxd2820r_attach); +EXPORT_SYMBOL_GPL(cxd2820r_attach); static struct dvb_frontend *cxd2820r_get_dvb_frontend(struct i2c_client *client) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/cxd2841er.c +++ linux-6.2.0/drivers/media/dvb-frontends/cxd2841er.c @@ -3930,14 +3930,14 @@ { return cxd2841er_attach(cfg, i2c, SYS_DVBS); } -EXPORT_SYMBOL(cxd2841er_attach_s); +EXPORT_SYMBOL_GPL(cxd2841er_attach_s); struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg, struct i2c_adapter *i2c) { return cxd2841er_attach(cfg, i2c, 0); } -EXPORT_SYMBOL(cxd2841er_attach_t_c); +EXPORT_SYMBOL_GPL(cxd2841er_attach_t_c); static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = { .delsys = { SYS_DVBS, SYS_DVBS2 }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c +++ linux-6.2.0/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c @@ -1950,7 +1950,7 @@ return fe; } -EXPORT_SYMBOL(cxd2880_attach); +EXPORT_SYMBOL_GPL(cxd2880_attach); MODULE_DESCRIPTION("Sony CXD2880 DVB-T2/T tuner + demod driver"); MODULE_AUTHOR("Sony Semiconductor Solutions Corporation"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/dib0070.c +++ linux-6.2.0/drivers/media/dvb-frontends/dib0070.c @@ -762,7 +762,7 @@ fe->tuner_priv = NULL; return NULL; } -EXPORT_SYMBOL(dib0070_attach); +EXPORT_SYMBOL_GPL(dib0070_attach); MODULE_AUTHOR("Patrick Boettcher "); MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/dib0090.c +++ linux-6.2.0/drivers/media/dvb-frontends/dib0090.c @@ -2634,7 +2634,7 @@ return NULL; } -EXPORT_SYMBOL(dib0090_register); +EXPORT_SYMBOL_GPL(dib0090_register); struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) { @@ -2660,7 +2660,7 @@ fe->tuner_priv = NULL; return NULL; } -EXPORT_SYMBOL(dib0090_fw_register); +EXPORT_SYMBOL_GPL(dib0090_fw_register); MODULE_AUTHOR("Patrick Boettcher "); MODULE_AUTHOR("Olivier Grenie "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/dib3000mb.c +++ linux-6.2.0/drivers/media/dvb-frontends/dib3000mb.c @@ -815,4 +815,4 @@ MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(dib3000mb_attach); +EXPORT_SYMBOL_GPL(dib3000mb_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/dib3000mc.c +++ linux-6.2.0/drivers/media/dvb-frontends/dib3000mc.c @@ -935,7 +935,7 @@ kfree(st); return NULL; } -EXPORT_SYMBOL(dib3000mc_attach); +EXPORT_SYMBOL_GPL(dib3000mc_attach); static const struct dvb_frontend_ops dib3000mc_ops = { .delsys = { SYS_DVBT }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/dib7000m.c +++ linux-6.2.0/drivers/media/dvb-frontends/dib7000m.c @@ -1434,7 +1434,7 @@ kfree(st); return NULL; } -EXPORT_SYMBOL(dib7000m_attach); +EXPORT_SYMBOL_GPL(dib7000m_attach); static const struct dvb_frontend_ops dib7000m_ops = { .delsys = { SYS_DVBT }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/dib7000p.c +++ linux-6.2.0/drivers/media/dvb-frontends/dib7000p.c @@ -497,7 +497,7 @@ prediv = reg_1856 & 0x3f; loopdiv = (reg_1856 >> 6) & 0x3f; - if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) { + if (loopdiv && bw && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) { dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)\n", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio); reg_1856 &= 0xf000; reg_1857 = dib7000p_read_word(state, 1857); @@ -2822,7 +2822,7 @@ return ops; } -EXPORT_SYMBOL(dib7000p_attach); +EXPORT_SYMBOL_GPL(dib7000p_attach); static const struct dvb_frontend_ops dib7000p_ops = { .delsys = { SYS_DVBT }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/dib8000.c +++ linux-6.2.0/drivers/media/dvb-frontends/dib8000.c @@ -4527,7 +4527,7 @@ return ops; } -EXPORT_SYMBOL(dib8000_attach); +EXPORT_SYMBOL_GPL(dib8000_attach); MODULE_AUTHOR("Olivier Grenie "); MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/dib9000.c +++ linux-6.2.0/drivers/media/dvb-frontends/dib9000.c @@ -2546,7 +2546,7 @@ kfree(st); return NULL; } -EXPORT_SYMBOL(dib9000_attach); +EXPORT_SYMBOL_GPL(dib9000_attach); static const struct dvb_frontend_ops dib9000_ops = { .delsys = { SYS_DVBT }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ linux-6.2.0/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -12369,7 +12369,7 @@ return NULL; } -EXPORT_SYMBOL(drx39xxj_attach); +EXPORT_SYMBOL_GPL(drx39xxj_attach); static const struct dvb_frontend_ops drx39xxj_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/drxd_hard.c +++ linux-6.2.0/drivers/media/dvb-frontends/drxd_hard.c @@ -2939,7 +2939,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(drxd_attach); +EXPORT_SYMBOL_GPL(drxd_attach); MODULE_DESCRIPTION("DRXD driver"); MODULE_AUTHOR("Micronas"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/drxk_hard.c +++ linux-6.2.0/drivers/media/dvb-frontends/drxk_hard.c @@ -6833,7 +6833,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(drxk_attach); +EXPORT_SYMBOL_GPL(drxk_attach); MODULE_DESCRIPTION("DRX-K driver"); MODULE_AUTHOR("Ralph Metzler"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/ds3000.c +++ linux-6.2.0/drivers/media/dvb-frontends/ds3000.c @@ -859,7 +859,7 @@ ds3000_set_voltage(&state->frontend, SEC_VOLTAGE_OFF); return &state->frontend; } -EXPORT_SYMBOL(ds3000_attach); +EXPORT_SYMBOL_GPL(ds3000_attach); static int ds3000_set_carrier_offset(struct dvb_frontend *fe, s32 carrier_offset_khz) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/dvb-pll.c +++ linux-6.2.0/drivers/media/dvb-frontends/dvb-pll.c @@ -866,7 +866,7 @@ return NULL; } -EXPORT_SYMBOL(dvb_pll_attach); +EXPORT_SYMBOL_GPL(dvb_pll_attach); static int only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/ec100.c +++ linux-6.2.0/drivers/media/dvb-frontends/ec100.c @@ -299,7 +299,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(ec100_attach); +EXPORT_SYMBOL_GPL(ec100_attach); static const struct dvb_frontend_ops ec100_ops = { .delsys = { SYS_DVBT }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/helene.c +++ linux-6.2.0/drivers/media/dvb-frontends/helene.c @@ -1025,7 +1025,7 @@ priv->i2c_address, priv->i2c); return fe; } -EXPORT_SYMBOL(helene_attach_s); +EXPORT_SYMBOL_GPL(helene_attach_s); struct dvb_frontend *helene_attach(struct dvb_frontend *fe, const struct helene_config *config, @@ -1061,7 +1061,7 @@ priv->i2c_address, priv->i2c); return fe; } -EXPORT_SYMBOL(helene_attach); +EXPORT_SYMBOL_GPL(helene_attach); static int helene_probe(struct i2c_client *client) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/horus3a.c +++ linux-6.2.0/drivers/media/dvb-frontends/horus3a.c @@ -395,7 +395,7 @@ priv->i2c_address, priv->i2c); return fe; } -EXPORT_SYMBOL(horus3a_attach); +EXPORT_SYMBOL_GPL(horus3a_attach); MODULE_DESCRIPTION("Sony HORUS3A satellite tuner driver"); MODULE_AUTHOR("Sergey Kozlov "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/isl6405.c +++ linux-6.2.0/drivers/media/dvb-frontends/isl6405.c @@ -141,7 +141,7 @@ return fe; } -EXPORT_SYMBOL(isl6405_attach); +EXPORT_SYMBOL_GPL(isl6405_attach); MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6405"); MODULE_AUTHOR("Hartmut Hackmann & Oliver Endriss"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/isl6421.c +++ linux-6.2.0/drivers/media/dvb-frontends/isl6421.c @@ -213,7 +213,7 @@ return fe; } -EXPORT_SYMBOL(isl6421_attach); +EXPORT_SYMBOL_GPL(isl6421_attach); MODULE_DESCRIPTION("Driver for lnb supply and control ic isl6421"); MODULE_AUTHOR("Andrew de Quincey & Oliver Endriss"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/isl6423.c +++ linux-6.2.0/drivers/media/dvb-frontends/isl6423.c @@ -289,7 +289,7 @@ fe->sec_priv = NULL; return NULL; } -EXPORT_SYMBOL(isl6423_attach); +EXPORT_SYMBOL_GPL(isl6423_attach); MODULE_DESCRIPTION("ISL6423 SEC"); MODULE_AUTHOR("Manu Abraham"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/itd1000.c +++ linux-6.2.0/drivers/media/dvb-frontends/itd1000.c @@ -389,7 +389,7 @@ return fe; } -EXPORT_SYMBOL(itd1000_attach); +EXPORT_SYMBOL_GPL(itd1000_attach); MODULE_AUTHOR("Patrick Boettcher "); MODULE_DESCRIPTION("Integrant ITD1000 driver"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/ix2505v.c +++ linux-6.2.0/drivers/media/dvb-frontends/ix2505v.c @@ -302,7 +302,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(ix2505v_attach); +EXPORT_SYMBOL_GPL(ix2505v_attach); module_param_named(debug, ix2505v_debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/l64781.c +++ linux-6.2.0/drivers/media/dvb-frontends/l64781.c @@ -593,4 +593,4 @@ MODULE_AUTHOR("Holger Waechtler, Marko Kohtala"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(l64781_attach); +EXPORT_SYMBOL_GPL(l64781_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/lg2160.c +++ linux-6.2.0/drivers/media/dvb-frontends/lg2160.c @@ -1426,7 +1426,7 @@ return &state->frontend; } -EXPORT_SYMBOL(lg2160_attach); +EXPORT_SYMBOL_GPL(lg2160_attach); MODULE_DESCRIPTION("LG Electronics LG216x ATSC/MH Demodulator Driver"); MODULE_AUTHOR("Michael Krufky "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/lgdt3305.c +++ linux-6.2.0/drivers/media/dvb-frontends/lgdt3305.c @@ -1148,7 +1148,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(lgdt3305_attach); +EXPORT_SYMBOL_GPL(lgdt3305_attach); static const struct dvb_frontend_ops lgdt3304_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/lgdt3306a.c +++ linux-6.2.0/drivers/media/dvb-frontends/lgdt3306a.c @@ -1859,7 +1859,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(lgdt3306a_attach); +EXPORT_SYMBOL_GPL(lgdt3306a_attach); #ifdef DBG_DUMP only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/lgdt330x.c +++ linux-6.2.0/drivers/media/dvb-frontends/lgdt330x.c @@ -927,7 +927,7 @@ return lgdt330x_get_dvb_frontend(client); } -EXPORT_SYMBOL(lgdt330x_attach); +EXPORT_SYMBOL_GPL(lgdt330x_attach); static const struct dvb_frontend_ops lgdt3302_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/lgs8gxx.c +++ linux-6.2.0/drivers/media/dvb-frontends/lgs8gxx.c @@ -1043,7 +1043,7 @@ return NULL; } -EXPORT_SYMBOL(lgs8gxx_attach); +EXPORT_SYMBOL_GPL(lgs8gxx_attach); MODULE_DESCRIPTION("Legend Silicon LGS8913/LGS8GXX DMB-TH demodulator driver"); MODULE_AUTHOR("David T. L. Wong "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/lnbh25.c +++ linux-6.2.0/drivers/media/dvb-frontends/lnbh25.c @@ -173,7 +173,7 @@ __func__, priv->i2c_address); return fe; } -EXPORT_SYMBOL(lnbh25_attach); +EXPORT_SYMBOL_GPL(lnbh25_attach); MODULE_DESCRIPTION("ST LNBH25 driver"); MODULE_AUTHOR("info@netup.ru"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/lnbp21.c +++ linux-6.2.0/drivers/media/dvb-frontends/lnbp21.c @@ -155,7 +155,7 @@ return lnbx2x_attach(fe, i2c, override_set, override_clear, i2c_addr, LNBH24_TTX); } -EXPORT_SYMBOL(lnbh24_attach); +EXPORT_SYMBOL_GPL(lnbh24_attach); struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, @@ -164,7 +164,7 @@ return lnbx2x_attach(fe, i2c, override_set, override_clear, 0x08, LNBP21_ISEL); } -EXPORT_SYMBOL(lnbp21_attach); +EXPORT_SYMBOL_GPL(lnbp21_attach); MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24"); MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/lnbp22.c +++ linux-6.2.0/drivers/media/dvb-frontends/lnbp22.c @@ -125,7 +125,7 @@ return fe; } -EXPORT_SYMBOL(lnbp22_attach); +EXPORT_SYMBOL_GPL(lnbp22_attach); MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp22"); MODULE_AUTHOR("Dominik Kuhlen"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/m88ds3103.c +++ linux-6.2.0/drivers/media/dvb-frontends/m88ds3103.c @@ -1695,7 +1695,7 @@ *tuner_i2c_adapter = pdata.get_i2c_adapter(client); return pdata.get_dvb_frontend(client); } -EXPORT_SYMBOL(m88ds3103_attach); +EXPORT_SYMBOL_GPL(m88ds3103_attach); static const struct dvb_frontend_ops m88ds3103_ops = { .delsys = {SYS_DVBS, SYS_DVBS2}, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/m88rs2000.c +++ linux-6.2.0/drivers/media/dvb-frontends/m88rs2000.c @@ -808,7 +808,7 @@ return NULL; } -EXPORT_SYMBOL(m88rs2000_attach); +EXPORT_SYMBOL_GPL(m88rs2000_attach); MODULE_DESCRIPTION("M88RS2000 DVB-S Demodulator driver"); MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/mb86a16.c +++ linux-6.2.0/drivers/media/dvb-frontends/mb86a16.c @@ -1848,6 +1848,6 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(mb86a16_attach); +EXPORT_SYMBOL_GPL(mb86a16_attach); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Manu Abraham"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/mb86a20s.c +++ linux-6.2.0/drivers/media/dvb-frontends/mb86a20s.c @@ -2081,7 +2081,7 @@ dev_info(&i2c->dev, "Detected a Fujitsu mb86a20s frontend\n"); return &state->frontend; } -EXPORT_SYMBOL(mb86a20s_attach); +EXPORT_SYMBOL_GPL(mb86a20s_attach); static const struct dvb_frontend_ops mb86a20s_ops = { .delsys = { SYS_ISDBT }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/mt312.c +++ linux-6.2.0/drivers/media/dvb-frontends/mt312.c @@ -827,7 +827,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(mt312_attach); +EXPORT_SYMBOL_GPL(mt312_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/mt352.c +++ linux-6.2.0/drivers/media/dvb-frontends/mt352.c @@ -593,4 +593,4 @@ MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(mt352_attach); +EXPORT_SYMBOL_GPL(mt352_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/nxt200x.c +++ linux-6.2.0/drivers/media/dvb-frontends/nxt200x.c @@ -1216,5 +1216,5 @@ MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(nxt200x_attach); +EXPORT_SYMBOL_GPL(nxt200x_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/nxt6000.c +++ linux-6.2.0/drivers/media/dvb-frontends/nxt6000.c @@ -621,4 +621,4 @@ MODULE_AUTHOR("Florian Schirmer"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(nxt6000_attach); +EXPORT_SYMBOL_GPL(nxt6000_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/or51132.c +++ linux-6.2.0/drivers/media/dvb-frontends/or51132.c @@ -605,4 +605,4 @@ MODULE_AUTHOR("Trent Piepho"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(or51132_attach); +EXPORT_SYMBOL_GPL(or51132_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/or51211.c +++ linux-6.2.0/drivers/media/dvb-frontends/or51211.c @@ -551,5 +551,5 @@ MODULE_AUTHOR("Kirk Lapray"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(or51211_attach); +EXPORT_SYMBOL_GPL(or51211_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/s5h1409.c +++ linux-6.2.0/drivers/media/dvb-frontends/s5h1409.c @@ -981,7 +981,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(s5h1409_attach); +EXPORT_SYMBOL_GPL(s5h1409_attach); static const struct dvb_frontend_ops s5h1409_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/s5h1411.c +++ linux-6.2.0/drivers/media/dvb-frontends/s5h1411.c @@ -900,7 +900,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(s5h1411_attach); +EXPORT_SYMBOL_GPL(s5h1411_attach); static const struct dvb_frontend_ops s5h1411_ops = { .delsys = { SYS_ATSC, SYS_DVBC_ANNEX_B }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/s5h1420.c +++ linux-6.2.0/drivers/media/dvb-frontends/s5h1420.c @@ -918,7 +918,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(s5h1420_attach); +EXPORT_SYMBOL_GPL(s5h1420_attach); static const struct dvb_frontend_ops s5h1420_ops = { .delsys = { SYS_DVBS }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/s5h1432.c +++ linux-6.2.0/drivers/media/dvb-frontends/s5h1432.c @@ -355,7 +355,7 @@ return &state->frontend; } -EXPORT_SYMBOL(s5h1432_attach); +EXPORT_SYMBOL_GPL(s5h1432_attach); static const struct dvb_frontend_ops s5h1432_ops = { .delsys = { SYS_DVBT }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/s921.c +++ linux-6.2.0/drivers/media/dvb-frontends/s921.c @@ -495,7 +495,7 @@ return &state->frontend; } -EXPORT_SYMBOL(s921_attach); +EXPORT_SYMBOL_GPL(s921_attach); static const struct dvb_frontend_ops s921_ops = { .delsys = { SYS_ISDBT }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/si21xx.c +++ linux-6.2.0/drivers/media/dvb-frontends/si21xx.c @@ -937,7 +937,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(si21xx_attach); +EXPORT_SYMBOL_GPL(si21xx_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/sp887x.c +++ linux-6.2.0/drivers/media/dvb-frontends/sp887x.c @@ -624,4 +624,4 @@ MODULE_DESCRIPTION("Spase sp887x DVB-T demodulator driver"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(sp887x_attach); +EXPORT_SYMBOL_GPL(sp887x_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/stb0899_drv.c +++ linux-6.2.0/drivers/media/dvb-frontends/stb0899_drv.c @@ -1638,7 +1638,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stb0899_attach); +EXPORT_SYMBOL_GPL(stb0899_attach); MODULE_PARM_DESC(verbose, "Set Verbosity level"); MODULE_AUTHOR("Manu Abraham"); MODULE_DESCRIPTION("STB0899 Multi-Std frontend"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/stb6000.c +++ linux-6.2.0/drivers/media/dvb-frontends/stb6000.c @@ -232,7 +232,7 @@ return fe; } -EXPORT_SYMBOL(stb6000_attach); +EXPORT_SYMBOL_GPL(stb6000_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/stb6100.c +++ linux-6.2.0/drivers/media/dvb-frontends/stb6100.c @@ -557,7 +557,7 @@ kfree(state); } -EXPORT_SYMBOL(stb6100_attach); +EXPORT_SYMBOL_GPL(stb6100_attach); MODULE_PARM_DESC(verbose, "Set Verbosity level"); MODULE_AUTHOR("Manu Abraham"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/stv0288.c +++ linux-6.2.0/drivers/media/dvb-frontends/stv0288.c @@ -590,7 +590,7 @@ return NULL; } -EXPORT_SYMBOL(stv0288_attach); +EXPORT_SYMBOL_GPL(stv0288_attach); module_param(debug_legacy_dish_switch, int, 0444); MODULE_PARM_DESC(debug_legacy_dish_switch, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/stv0297.c +++ linux-6.2.0/drivers/media/dvb-frontends/stv0297.c @@ -710,4 +710,4 @@ MODULE_AUTHOR("Dennis Noermann and Andrew de Quincey"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(stv0297_attach); +EXPORT_SYMBOL_GPL(stv0297_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/stv0299.c +++ linux-6.2.0/drivers/media/dvb-frontends/stv0299.c @@ -752,4 +752,4 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, Andreas Oberritter, Andrew de Quincey, Kenneth Aafly"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(stv0299_attach); +EXPORT_SYMBOL_GPL(stv0299_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/stv0367.c +++ linux-6.2.0/drivers/media/dvb-frontends/stv0367.c @@ -1750,7 +1750,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stv0367ter_attach); +EXPORT_SYMBOL_GPL(stv0367ter_attach); static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable) { @@ -2919,7 +2919,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stv0367cab_attach); +EXPORT_SYMBOL_GPL(stv0367cab_attach); /* * Functions for operation on Digital Devices hardware @@ -3340,7 +3340,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stv0367ddb_attach); +EXPORT_SYMBOL_GPL(stv0367ddb_attach); MODULE_PARM_DESC(debug, "Set debug"); MODULE_PARM_DESC(i2c_debug, "Set i2c debug"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/stv0900_core.c +++ linux-6.2.0/drivers/media/dvb-frontends/stv0900_core.c @@ -1957,7 +1957,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stv0900_attach); +EXPORT_SYMBOL_GPL(stv0900_attach); MODULE_PARM_DESC(debug, "Set debug"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/stv090x.c +++ linux-6.2.0/drivers/media/dvb-frontends/stv090x.c @@ -5071,7 +5071,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(stv090x_attach); +EXPORT_SYMBOL_GPL(stv090x_attach); static const struct i2c_device_id stv090x_id_table[] = { {"stv090x", 0}, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/stv6110.c +++ linux-6.2.0/drivers/media/dvb-frontends/stv6110.c @@ -427,7 +427,7 @@ return fe; } -EXPORT_SYMBOL(stv6110_attach); +EXPORT_SYMBOL_GPL(stv6110_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/stv6110x.c +++ linux-6.2.0/drivers/media/dvb-frontends/stv6110x.c @@ -467,7 +467,7 @@ dev_info(&stv6110x->i2c->dev, "Attaching STV6110x\n"); return stv6110x->devctl; } -EXPORT_SYMBOL(stv6110x_attach); +EXPORT_SYMBOL_GPL(stv6110x_attach); static const struct i2c_device_id stv6110x_id_table[] = { {"stv6110x", 0}, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/tda10021.c +++ linux-6.2.0/drivers/media/dvb-frontends/tda10021.c @@ -523,4 +523,4 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Markus Schulz"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(tda10021_attach); +EXPORT_SYMBOL_GPL(tda10021_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/tda10023.c +++ linux-6.2.0/drivers/media/dvb-frontends/tda10023.c @@ -594,4 +594,4 @@ MODULE_AUTHOR("Georg Acher, Hartmut Birr"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(tda10023_attach); +EXPORT_SYMBOL_GPL(tda10023_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/tda10048.c +++ linux-6.2.0/drivers/media/dvb-frontends/tda10048.c @@ -1138,7 +1138,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(tda10048_attach); +EXPORT_SYMBOL_GPL(tda10048_attach); static const struct dvb_frontend_ops tda10048_ops = { .delsys = { SYS_DVBT }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/tda1004x.c +++ linux-6.2.0/drivers/media/dvb-frontends/tda1004x.c @@ -1378,5 +1378,5 @@ MODULE_AUTHOR("Andrew de Quincey & Robert Schlabbach"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(tda10045_attach); -EXPORT_SYMBOL(tda10046_attach); +EXPORT_SYMBOL_GPL(tda10045_attach); +EXPORT_SYMBOL_GPL(tda10046_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/tda10086.c +++ linux-6.2.0/drivers/media/dvb-frontends/tda10086.c @@ -764,4 +764,4 @@ MODULE_AUTHOR("Andrew de Quincey"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(tda10086_attach); +EXPORT_SYMBOL_GPL(tda10086_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/tda665x.c +++ linux-6.2.0/drivers/media/dvb-frontends/tda665x.c @@ -227,7 +227,7 @@ return fe; } -EXPORT_SYMBOL(tda665x_attach); +EXPORT_SYMBOL_GPL(tda665x_attach); MODULE_DESCRIPTION("TDA665x driver"); MODULE_AUTHOR("Manu Abraham"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/tda8083.c +++ linux-6.2.0/drivers/media/dvb-frontends/tda8083.c @@ -481,4 +481,4 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(tda8083_attach); +EXPORT_SYMBOL_GPL(tda8083_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/tda8261.c +++ linux-6.2.0/drivers/media/dvb-frontends/tda8261.c @@ -188,7 +188,7 @@ return NULL; } -EXPORT_SYMBOL(tda8261_attach); +EXPORT_SYMBOL_GPL(tda8261_attach); MODULE_AUTHOR("Manu Abraham"); MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/tda826x.c +++ linux-6.2.0/drivers/media/dvb-frontends/tda826x.c @@ -164,7 +164,7 @@ return fe; } -EXPORT_SYMBOL(tda826x_attach); +EXPORT_SYMBOL_GPL(tda826x_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/ts2020.c +++ linux-6.2.0/drivers/media/dvb-frontends/ts2020.c @@ -525,7 +525,7 @@ return fe; } -EXPORT_SYMBOL(ts2020_attach); +EXPORT_SYMBOL_GPL(ts2020_attach); /* * We implement own regmap locking due to legacy DVB attach which uses frontend only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/tua6100.c +++ linux-6.2.0/drivers/media/dvb-frontends/tua6100.c @@ -186,7 +186,7 @@ fe->tuner_priv = priv; return fe; } -EXPORT_SYMBOL(tua6100_attach); +EXPORT_SYMBOL_GPL(tua6100_attach); MODULE_DESCRIPTION("DVB tua6100 driver"); MODULE_AUTHOR("Andrew de Quincey"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/ves1820.c +++ linux-6.2.0/drivers/media/dvb-frontends/ves1820.c @@ -434,4 +434,4 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(ves1820_attach); +EXPORT_SYMBOL_GPL(ves1820_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/ves1x93.c +++ linux-6.2.0/drivers/media/dvb-frontends/ves1x93.c @@ -540,4 +540,4 @@ MODULE_AUTHOR("Ralph Metzler"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(ves1x93_attach); +EXPORT_SYMBOL_GPL(ves1x93_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/zl10036.c +++ linux-6.2.0/drivers/media/dvb-frontends/zl10036.c @@ -496,7 +496,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(zl10036_attach); +EXPORT_SYMBOL_GPL(zl10036_attach); module_param_named(debug, zl10036_debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/zl10039.c +++ linux-6.2.0/drivers/media/dvb-frontends/zl10039.c @@ -295,7 +295,7 @@ kfree(state); return NULL; } -EXPORT_SYMBOL(zl10039_attach); +EXPORT_SYMBOL_GPL(zl10039_attach); module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/dvb-frontends/zl10353.c +++ linux-6.2.0/drivers/media/dvb-frontends/zl10353.c @@ -665,4 +665,4 @@ MODULE_AUTHOR("Chris Pascoe"); MODULE_LICENSE("GPL"); -EXPORT_SYMBOL(zl10353_attach); +EXPORT_SYMBOL_GPL(zl10353_attach); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/i2c/ad5820.c +++ linux-6.2.0/drivers/media/i2c/ad5820.c @@ -349,7 +349,6 @@ static const struct i2c_device_id ad5820_id_table[] = { { "ad5820", 0 }, { "ad5821", 0 }, - { "ad5823", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, ad5820_id_table); @@ -357,7 +356,6 @@ static const struct of_device_id ad5820_of_table[] = { { .compatible = "adi,ad5820" }, { .compatible = "adi,ad5821" }, - { .compatible = "adi,ad5823" }, { } }; MODULE_DEVICE_TABLE(of, ad5820_of_table); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/i2c/ccs/ccs-data.c +++ linux-6.2.0/drivers/media/i2c/ccs/ccs-data.c @@ -464,8 +464,7 @@ rule_payload = __rule_type + 1; rule_plen2 = rule_plen - sizeof(*__rule_type); - switch (*__rule_type) { - case CCS_DATA_BLOCK_RULE_ID_IF: { + if (*__rule_type == CCS_DATA_BLOCK_RULE_ID_IF) { const struct __ccs_data_block_rule_if *__if_rules = rule_payload; const size_t __num_if_rules = @@ -514,49 +513,61 @@ rules->if_rules = if_rule; rules->num_if_rules = __num_if_rules; } - break; - } - case CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS: - rval = ccs_data_parse_reg_rules(bin, &rules->read_only_regs, - &rules->num_read_only_regs, - rule_payload, - rule_payload + rule_plen2, - dev); - if (rval) - return rval; - break; - case CCS_DATA_BLOCK_RULE_ID_FFD: - rval = ccs_data_parse_ffd(bin, &rules->frame_format, - rule_payload, - rule_payload + rule_plen2, - dev); - if (rval) - return rval; - break; - case CCS_DATA_BLOCK_RULE_ID_MSR: - rval = ccs_data_parse_reg_rules(bin, - &rules->manufacturer_regs, - &rules->num_manufacturer_regs, - rule_payload, - rule_payload + rule_plen2, - dev); - if (rval) - return rval; - break; - case CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT: - rval = ccs_data_parse_pdaf_readout(bin, - &rules->pdaf_readout, - rule_payload, - rule_payload + rule_plen2, - dev); - if (rval) - return rval; - break; - default: - dev_dbg(dev, - "Don't know how to handle rule type %u!\n", - *__rule_type); - return -EINVAL; + } else { + /* Check there was an if rule before any other rules */ + if (bin->base && !rules) + return -EINVAL; + + switch (*__rule_type) { + case CCS_DATA_BLOCK_RULE_ID_READ_ONLY_REGS: + rval = ccs_data_parse_reg_rules(bin, + rules ? + &rules->read_only_regs : NULL, + rules ? + &rules->num_read_only_regs : NULL, + rule_payload, + rule_payload + rule_plen2, + dev); + if (rval) + return rval; + break; + case CCS_DATA_BLOCK_RULE_ID_FFD: + rval = ccs_data_parse_ffd(bin, rules ? + &rules->frame_format : NULL, + rule_payload, + rule_payload + rule_plen2, + dev); + if (rval) + return rval; + break; + case CCS_DATA_BLOCK_RULE_ID_MSR: + rval = ccs_data_parse_reg_rules(bin, + rules ? + &rules->manufacturer_regs : NULL, + rules ? + &rules->num_manufacturer_regs : NULL, + rule_payload, + rule_payload + rule_plen2, + dev); + if (rval) + return rval; + break; + case CCS_DATA_BLOCK_RULE_ID_PDAF_READOUT: + rval = ccs_data_parse_pdaf_readout(bin, + rules ? + &rules->pdaf_readout : NULL, + rule_payload, + rule_payload + rule_plen2, + dev); + if (rval) + return rval; + break; + default: + dev_dbg(dev, + "Don't know how to handle rule type %u!\n", + *__rule_type); + return -EINVAL; + } } __next_rule = __next_rule + rule_hlen + rule_plen; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/i2c/ov2680.c +++ linux-6.2.0/drivers/media/i2c/ov2680.c @@ -54,6 +54,9 @@ #define OV2680_WIDTH_MAX 1600 #define OV2680_HEIGHT_MAX 1200 +#define OV2680_DEFAULT_WIDTH 800 +#define OV2680_DEFAULT_HEIGHT 600 + enum ov2680_mode_id { OV2680_MODE_QUXGA_800_600, OV2680_MODE_720P_1280_720, @@ -85,15 +88,8 @@ struct ov2680_ctrls { struct v4l2_ctrl_handler handler; - struct { - struct v4l2_ctrl *auto_exp; - struct v4l2_ctrl *exposure; - }; - struct { - struct v4l2_ctrl *auto_gain; - struct v4l2_ctrl *gain; - }; - + struct v4l2_ctrl *exposure; + struct v4l2_ctrl *gain; struct v4l2_ctrl *hflip; struct v4l2_ctrl *vflip; struct v4l2_ctrl *test_pattern; @@ -143,6 +139,7 @@ {0x380e, 0x02}, {0x380f, 0x84}, {0x3811, 0x04}, {0x3813, 0x04}, {0x3814, 0x31}, {0x3815, 0x31}, {0x3820, 0xc0}, {0x4008, 0x00}, {0x4009, 0x03}, {0x4837, 0x1e}, {0x3501, 0x4e}, {0x3502, 0xe0}, + {0x3503, 0x03}, }; static const struct reg_value ov2680_setting_30fps_720P_1280_720[] = { @@ -321,70 +318,62 @@ usleep_range(5000, 10000); } -static int ov2680_bayer_order(struct ov2680_dev *sensor) +static void ov2680_set_bayer_order(struct ov2680_dev *sensor, + struct v4l2_mbus_framefmt *fmt) { - u32 format1; - u32 format2; - u32 hv_flip; - int ret; - - ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT1, &format1); - if (ret < 0) - return ret; - - ret = ov2680_read_reg(sensor, OV2680_REG_FORMAT2, &format2); - if (ret < 0) - return ret; + int hv_flip = 0; - hv_flip = (format2 & BIT(2) << 1) | (format1 & BIT(2)); + if (sensor->ctrls.vflip && sensor->ctrls.vflip->val) + hv_flip += 1; - sensor->fmt.code = ov2680_hv_flip_bayer_order[hv_flip]; + if (sensor->ctrls.hflip && sensor->ctrls.hflip->val) + hv_flip += 2; - return 0; + fmt->code = ov2680_hv_flip_bayer_order[hv_flip]; } -static int ov2680_vflip_enable(struct ov2680_dev *sensor) +static void ov2680_fill_format(struct ov2680_dev *sensor, + struct v4l2_mbus_framefmt *fmt, + unsigned int width, unsigned int height) { - int ret; - - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(2)); - if (ret < 0) - return ret; - - return ov2680_bayer_order(sensor); + memset(fmt, 0, sizeof(*fmt)); + fmt->width = width; + fmt->height = height; + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_SRGB; + ov2680_set_bayer_order(sensor, fmt); } -static int ov2680_vflip_disable(struct ov2680_dev *sensor) +static int ov2680_set_vflip(struct ov2680_dev *sensor, s32 val) { int ret; - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, BIT(2), BIT(0)); - if (ret < 0) - return ret; - - return ov2680_bayer_order(sensor); -} - -static int ov2680_hflip_enable(struct ov2680_dev *sensor) -{ - int ret; + if (sensor->is_streaming) + return -EBUSY; - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(2)); + ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT1, + BIT(2), val ? BIT(2) : 0); if (ret < 0) return ret; - return ov2680_bayer_order(sensor); + ov2680_set_bayer_order(sensor, &sensor->fmt); + return 0; } -static int ov2680_hflip_disable(struct ov2680_dev *sensor) +static int ov2680_set_hflip(struct ov2680_dev *sensor, s32 val) { int ret; - ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, BIT(2), BIT(0)); + if (sensor->is_streaming) + return -EBUSY; + + ret = ov2680_mod_reg(sensor, OV2680_REG_FORMAT2, + BIT(2), val ? BIT(2) : 0); if (ret < 0) return ret; - return ov2680_bayer_order(sensor); + ov2680_set_bayer_order(sensor, &sensor->fmt); + return 0; } static int ov2680_test_pattern_set(struct ov2680_dev *sensor, int value) @@ -405,69 +394,15 @@ return 0; } -static int ov2680_gain_set(struct ov2680_dev *sensor, bool auto_gain) -{ - struct ov2680_ctrls *ctrls = &sensor->ctrls; - u32 gain; - int ret; - - ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(1), - auto_gain ? 0 : BIT(1)); - if (ret < 0) - return ret; - - if (auto_gain || !ctrls->gain->is_new) - return 0; - - gain = ctrls->gain->val; - - ret = ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); - - return 0; -} - -static int ov2680_gain_get(struct ov2680_dev *sensor) -{ - u32 gain; - int ret; - - ret = ov2680_read_reg16(sensor, OV2680_REG_GAIN_PK, &gain); - if (ret) - return ret; - - return gain; -} - -static int ov2680_exposure_set(struct ov2680_dev *sensor, bool auto_exp) +static int ov2680_gain_set(struct ov2680_dev *sensor, u32 gain) { - struct ov2680_ctrls *ctrls = &sensor->ctrls; - u32 exp; - int ret; - - ret = ov2680_mod_reg(sensor, OV2680_REG_R_MANUAL, BIT(0), - auto_exp ? 0 : BIT(0)); - if (ret < 0) - return ret; - - if (auto_exp || !ctrls->exposure->is_new) - return 0; - - exp = (u32)ctrls->exposure->val; - exp <<= 4; - - return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, exp); + return ov2680_write_reg16(sensor, OV2680_REG_GAIN_PK, gain); } -static int ov2680_exposure_get(struct ov2680_dev *sensor) +static int ov2680_exposure_set(struct ov2680_dev *sensor, u32 exp) { - int ret; - u32 exp; - - ret = ov2680_read_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, &exp); - if (ret) - return ret; - - return exp >> 4; + return ov2680_write_reg24(sensor, OV2680_REG_EXPOSURE_PK_HIGH, + exp << 4); } static int ov2680_stream_enable(struct ov2680_dev *sensor) @@ -482,33 +417,17 @@ static int ov2680_mode_set(struct ov2680_dev *sensor) { - struct ov2680_ctrls *ctrls = &sensor->ctrls; int ret; - ret = ov2680_gain_set(sensor, false); - if (ret < 0) - return ret; - - ret = ov2680_exposure_set(sensor, false); + ret = ov2680_load_regs(sensor, sensor->current_mode); if (ret < 0) return ret; - ret = ov2680_load_regs(sensor, sensor->current_mode); + /* Restore value of all ctrls */ + ret = __v4l2_ctrl_handler_setup(&sensor->ctrls.handler); if (ret < 0) return ret; - if (ctrls->auto_gain->val) { - ret = ov2680_gain_set(sensor, true); - if (ret < 0) - return ret; - } - - if (ctrls->auto_exp->val == V4L2_EXPOSURE_AUTO) { - ret = ov2680_exposure_set(sensor, true); - if (ret < 0) - return ret; - } - sensor->mode_pending_changes = false; return 0; @@ -556,7 +475,7 @@ ret = ov2680_write_reg(sensor, OV2680_REG_SOFT_RESET, 0x01); if (ret != 0) { dev_err(dev, "sensor soft reset failed\n"); - return ret; + goto err_disable_regulators; } usleep_range(1000, 2000); } else { @@ -566,7 +485,7 @@ ret = clk_prepare_enable(sensor->xvclk); if (ret < 0) - return ret; + goto err_disable_regulators; sensor->is_enabled = true; @@ -576,6 +495,10 @@ ov2680_stream_disable(sensor); return 0; + +err_disable_regulators: + regulator_bulk_disable(OV2680_NUM_SUPPLIES, sensor->supplies); + return ret; } static int ov2680_s_power(struct v4l2_subdev *sd, int on) @@ -590,15 +513,10 @@ else ret = ov2680_power_off(sensor); - mutex_unlock(&sensor->lock); - - if (on && ret == 0) { - ret = v4l2_ctrl_handler_setup(&sensor->ctrls.handler); - if (ret < 0) - return ret; - + if (on && ret == 0) ret = ov2680_mode_restore(sensor); - } + + mutex_unlock(&sensor->lock); return ret; } @@ -664,7 +582,6 @@ { struct ov2680_dev *sensor = to_ov2680_dev(sd); struct v4l2_mbus_framefmt *fmt = NULL; - int ret = 0; if (format->pad != 0) return -EINVAL; @@ -672,22 +589,17 @@ mutex_lock(&sensor->lock); if (format->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API fmt = v4l2_subdev_get_try_format(&sensor->sd, sd_state, format->pad); -#else - ret = -EINVAL; -#endif } else { fmt = &sensor->fmt; } - if (fmt) - format->format = *fmt; + format->format = *fmt; mutex_unlock(&sensor->lock); - return ret; + return 0; } static int ov2680_set_fmt(struct v4l2_subdev *sd, @@ -695,43 +607,35 @@ struct v4l2_subdev_format *format) { struct ov2680_dev *sensor = to_ov2680_dev(sd); - struct v4l2_mbus_framefmt *fmt = &format->format; -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API struct v4l2_mbus_framefmt *try_fmt; -#endif const struct ov2680_mode_info *mode; int ret = 0; if (format->pad != 0) return -EINVAL; - mutex_lock(&sensor->lock); - - if (sensor->is_streaming) { - ret = -EBUSY; - goto unlock; - } - mode = v4l2_find_nearest_size(ov2680_mode_data, - ARRAY_SIZE(ov2680_mode_data), width, - height, fmt->width, fmt->height); - if (!mode) { - ret = -EINVAL; - goto unlock; - } + ARRAY_SIZE(ov2680_mode_data), + width, height, + format->format.width, + format->format.height); + if (!mode) + return -EINVAL; + + ov2680_fill_format(sensor, &format->format, mode->width, mode->height); if (format->which == V4L2_SUBDEV_FORMAT_TRY) { -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API try_fmt = v4l2_subdev_get_try_format(sd, sd_state, 0); - format->format = *try_fmt; -#endif - goto unlock; + *try_fmt = format->format; + return 0; } - fmt->width = mode->width; - fmt->height = mode->height; - fmt->code = sensor->fmt.code; - fmt->colorspace = sensor->fmt.colorspace; + mutex_lock(&sensor->lock); + + if (sensor->is_streaming) { + ret = -EBUSY; + goto unlock; + } sensor->current_mode = mode; sensor->fmt = format->format; @@ -746,16 +650,11 @@ static int ov2680_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state) { - struct v4l2_subdev_format fmt = { - .which = sd_state ? V4L2_SUBDEV_FORMAT_TRY - : V4L2_SUBDEV_FORMAT_ACTIVE, - .format = { - .width = 800, - .height = 600, - } - }; + struct ov2680_dev *sensor = to_ov2680_dev(sd); - return ov2680_set_fmt(sd, sd_state, &fmt); + ov2680_fill_format(sensor, &sd_state->pads[0].try_fmt, + OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT); + return 0; } static int ov2680_enum_frame_size(struct v4l2_subdev *sd, @@ -794,66 +693,23 @@ return 0; } -static int ov2680_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct v4l2_subdev *sd = ctrl_to_sd(ctrl); - struct ov2680_dev *sensor = to_ov2680_dev(sd); - struct ov2680_ctrls *ctrls = &sensor->ctrls; - int val; - - if (!sensor->is_enabled) - return 0; - - switch (ctrl->id) { - case V4L2_CID_GAIN: - val = ov2680_gain_get(sensor); - if (val < 0) - return val; - ctrls->gain->val = val; - break; - case V4L2_CID_EXPOSURE: - val = ov2680_exposure_get(sensor); - if (val < 0) - return val; - ctrls->exposure->val = val; - break; - } - - return 0; -} - static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl) { struct v4l2_subdev *sd = ctrl_to_sd(ctrl); struct ov2680_dev *sensor = to_ov2680_dev(sd); - struct ov2680_ctrls *ctrls = &sensor->ctrls; if (!sensor->is_enabled) return 0; switch (ctrl->id) { - case V4L2_CID_AUTOGAIN: - return ov2680_gain_set(sensor, !!ctrl->val); case V4L2_CID_GAIN: - return ov2680_gain_set(sensor, !!ctrls->auto_gain->val); - case V4L2_CID_EXPOSURE_AUTO: - return ov2680_exposure_set(sensor, !!ctrl->val); + return ov2680_gain_set(sensor, ctrl->val); case V4L2_CID_EXPOSURE: - return ov2680_exposure_set(sensor, !!ctrls->auto_exp->val); + return ov2680_exposure_set(sensor, ctrl->val); case V4L2_CID_VFLIP: - if (sensor->is_streaming) - return -EBUSY; - if (ctrl->val) - return ov2680_vflip_enable(sensor); - else - return ov2680_vflip_disable(sensor); + return ov2680_set_vflip(sensor, ctrl->val); case V4L2_CID_HFLIP: - if (sensor->is_streaming) - return -EBUSY; - if (ctrl->val) - return ov2680_hflip_enable(sensor); - else - return ov2680_hflip_disable(sensor); + return ov2680_set_hflip(sensor, ctrl->val); case V4L2_CID_TEST_PATTERN: return ov2680_test_pattern_set(sensor, ctrl->val); default: @@ -864,7 +720,6 @@ } static const struct v4l2_ctrl_ops ov2680_ctrl_ops = { - .g_volatile_ctrl = ov2680_g_volatile_ctrl, .s_ctrl = ov2680_s_ctrl, }; @@ -898,11 +753,8 @@ const struct ov2680_mode_info *init_mode; /* set initial mode */ - sensor->fmt.code = MEDIA_BUS_FMT_SBGGR10_1X10; - sensor->fmt.width = 800; - sensor->fmt.height = 600; - sensor->fmt.field = V4L2_FIELD_NONE; - sensor->fmt.colorspace = V4L2_COLORSPACE_SRGB; + ov2680_fill_format(sensor, &sensor->fmt, + OV2680_DEFAULT_WIDTH, OV2680_DEFAULT_HEIGHT); sensor->frame_interval.denominator = OV2680_FRAME_RATE; sensor->frame_interval.numerator = 1; @@ -926,9 +778,7 @@ v4l2_i2c_subdev_init(&sensor->sd, sensor->i2c_client, &ov2680_subdev_ops); -#ifdef CONFIG_VIDEO_V4L2_SUBDEV_API sensor->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; -#endif sensor->pad.flags = MEDIA_PAD_FL_SOURCE; sensor->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; @@ -936,7 +786,7 @@ if (ret < 0) return ret; - v4l2_ctrl_handler_init(hdl, 7); + v4l2_ctrl_handler_init(hdl, 5); hdl->lock = &sensor->lock; @@ -948,16 +798,9 @@ ARRAY_SIZE(test_pattern_menu) - 1, 0, 0, test_pattern_menu); - ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops, - V4L2_CID_EXPOSURE_AUTO, - V4L2_EXPOSURE_MANUAL, 0, - V4L2_EXPOSURE_AUTO); - ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE, 0, 32767, 1, 0); - ctrls->auto_gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTOGAIN, - 0, 1, 1, 1); ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 2047, 1, 0); if (hdl->error) { @@ -965,14 +808,9 @@ goto cleanup_entity; } - ctrls->gain->flags |= V4L2_CTRL_FLAG_VOLATILE; - ctrls->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; - v4l2_ctrl_auto_cluster(2, &ctrls->auto_gain, 0, true); - v4l2_ctrl_auto_cluster(2, &ctrls->auto_exp, 1, true); - sensor->sd.ctrl_handler = hdl; ret = v4l2_async_register_subdev(&sensor->sd); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/i2c/rdacm21.c +++ linux-6.2.0/drivers/media/i2c/rdacm21.c @@ -351,7 +351,7 @@ static int ov10640_check_id(struct rdacm21_device *dev) { unsigned int i; - u8 val; + u8 val = 0; /* Read OV10640 ID to test communications. */ for (i = 0; i < OV10640_PID_TIMEOUT; ++i) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/i2c/tvp5150.c +++ linux-6.2.0/drivers/media/i2c/tvp5150.c @@ -2068,6 +2068,10 @@ tvpc->ent.name = devm_kasprintf(dev, GFP_KERNEL, "%s %s", v4l2c->name, v4l2c->label ? v4l2c->label : ""); + if (!tvpc->ent.name) { + ret = -ENOMEM; + goto err_free; + } } ep_np = of_graph_get_endpoint_by_regs(np, TVP5150_PAD_VID_OUT, 0); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/pci/bt8xx/dst.c +++ linux-6.2.0/drivers/media/pci/bt8xx/dst.c @@ -1722,7 +1722,7 @@ return state; /* Manu (DST is a card not a frontend) */ } -EXPORT_SYMBOL(dst_attach); +EXPORT_SYMBOL_GPL(dst_attach); static const struct dvb_frontend_ops dst_dvbt_ops = { .delsys = { SYS_DVBT }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/pci/bt8xx/dst_ca.c +++ linux-6.2.0/drivers/media/pci/bt8xx/dst_ca.c @@ -668,7 +668,7 @@ return NULL; } -EXPORT_SYMBOL(dst_ca_attach); +EXPORT_SYMBOL_GPL(dst_ca_attach); MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver"); MODULE_AUTHOR("Manu Abraham"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/pci/cx23885/cx23885-dvb.c +++ linux-6.2.0/drivers/media/pci/cx23885/cx23885-dvb.c @@ -2459,16 +2459,10 @@ request_module("%s", info.type); client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); if (!i2c_client_has_driver(client_tuner)) { - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } if (!try_module_get(client_tuner->dev.driver->owner)) { i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } port->i2c_client_tuner = client_tuner; @@ -2505,16 +2499,10 @@ request_module("%s", info.type); client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); if (!i2c_client_has_driver(client_tuner)) { - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } if (!try_module_get(client_tuner->dev.driver->owner)) { i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } port->i2c_client_tuner = client_tuner; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c +++ linux-6.2.0/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c @@ -112,7 +112,7 @@ state->frontend.demodulator_priv = state; return &state->frontend; } -EXPORT_SYMBOL(ddbridge_dummy_fe_qam_attach); +EXPORT_SYMBOL_GPL(ddbridge_dummy_fe_qam_attach); static const struct dvb_frontend_ops ddbridge_dummy_fe_qam_ops = { .delsys = { SYS_DVBC_ANNEX_A }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/pci/intel/ipu3/cio2-bridge.c +++ linux-6.2.0/drivers/media/pci/intel/ipu3/cio2-bridge.c @@ -280,6 +280,11 @@ } sensor = &bridge->sensors[bridge->n_sensors]; + /* + * Borrow our adev ref to the sensor for now, on success + * acpi_dev_get(adev) is done further below. + */ + sensor->adev = adev; strscpy(sensor->name, cfg->hid, sizeof(sensor->name)); ret = cio2_bridge_read_acpi_buffer(adev, "SSDB", only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/platform/amphion/vpu.h +++ linux-6.2.0/drivers/media/platform/amphion/vpu.h @@ -355,6 +355,9 @@ int vpu_core_driver_init(void); void vpu_core_driver_exit(void); +const char *vpu_id_name(u32 id); +const char *vpu_codec_state_name(enum vpu_codec_state state); + extern bool debug; #define vpu_trace(dev, fmt, arg...) \ do { \ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/platform/amphion/vpu_cmds.c +++ linux-6.2.0/drivers/media/platform/amphion/vpu_cmds.c @@ -98,7 +98,7 @@ cmd->id = id; ret = vpu_iface_pack_cmd(inst->core, cmd->pkt, inst->id, id, data); if (ret) { - dev_err(inst->dev, "iface pack cmd(%d) fail\n", id); + dev_err(inst->dev, "iface pack cmd %s fail\n", vpu_id_name(id)); vfree(cmd->pkt); vfree(cmd); return NULL; @@ -125,14 +125,14 @@ { int ret; - dev_dbg(inst->dev, "[%d]send cmd(0x%x)\n", inst->id, cmd->id); + dev_dbg(inst->dev, "[%d]send cmd %s\n", inst->id, vpu_id_name(cmd->id)); vpu_iface_pre_send_cmd(inst); ret = vpu_cmd_send(inst->core, cmd->pkt); if (!ret) { vpu_iface_post_send_cmd(inst); vpu_inst_record_flow(inst, cmd->id); } else { - dev_err(inst->dev, "[%d] iface send cmd(0x%x) fail\n", inst->id, cmd->id); + dev_err(inst->dev, "[%d] iface send cmd %s fail\n", inst->id, vpu_id_name(cmd->id)); } return ret; @@ -149,7 +149,8 @@ list_for_each_entry_safe(cmd, tmp, &inst->cmd_q, list) { list_del_init(&cmd->list); if (vpu_session_process_cmd(inst, cmd)) - dev_err(inst->dev, "[%d] process cmd(%d) fail\n", inst->id, cmd->id); + dev_err(inst->dev, "[%d] process cmd %s fail\n", + inst->id, vpu_id_name(cmd->id)); if (cmd->request) { inst->pending = (void *)cmd; break; @@ -305,7 +306,8 @@ dev_dbg(core->dev, "try to wake up\n"); mutex_lock(&core->cmd_lock); - vpu_cmd_send(core, &pkt); + if (vpu_cmd_send(core, &pkt)) + dev_err(core->dev, "fail to keep active\n"); mutex_unlock(&core->cmd_lock); } @@ -313,7 +315,7 @@ { unsigned long key; int sync = false; - int ret = -EINVAL; + int ret; if (inst->id < 0) return -EINVAL; @@ -339,7 +341,7 @@ exit: if (ret) - dev_err(inst->dev, "[%d] send cmd(0x%x) fail\n", inst->id, id); + dev_err(inst->dev, "[%d] send cmd %s fail\n", inst->id, vpu_id_name(id)); return ret; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/platform/amphion/vpu_dbg.c +++ linux-6.2.0/drivers/media/platform/amphion/vpu_dbg.c @@ -50,6 +50,13 @@ [VPU_BUF_STATE_ERROR] = "error", }; +static inline const char *to_vpu_stat_name(int state) +{ + if (state <= VPU_BUF_STATE_ERROR) + return vpu_stat_name[state]; + return "unknown"; +} + static int vpu_dbg_instance(struct seq_file *s, void *data) { struct vpu_inst *inst = s->private; @@ -67,7 +74,7 @@ num = scnprintf(str, sizeof(str), "tgig = %d,pid = %d\n", inst->tgid, inst->pid); if (seq_write(s, str, num)) return 0; - num = scnprintf(str, sizeof(str), "state = %d\n", inst->state); + num = scnprintf(str, sizeof(str), "state = %s\n", vpu_codec_state_name(inst->state)); if (seq_write(s, str, num)) return 0; num = scnprintf(str, sizeof(str), @@ -141,7 +148,7 @@ num = scnprintf(str, sizeof(str), "output [%2d] state = %10s, %8s\n", i, vb2_stat_name[vb->state], - vpu_stat_name[vpu_get_buffer_state(vbuf)]); + to_vpu_stat_name(vpu_get_buffer_state(vbuf))); if (seq_write(s, str, num)) return 0; } @@ -156,7 +163,7 @@ num = scnprintf(str, sizeof(str), "capture[%2d] state = %10s, %8s\n", i, vb2_stat_name[vb->state], - vpu_stat_name[vpu_get_buffer_state(vbuf)]); + to_vpu_stat_name(vpu_get_buffer_state(vbuf))); if (seq_write(s, str, num)) return 0; } @@ -188,9 +195,9 @@ if (!inst->flows[idx]) continue; - num = scnprintf(str, sizeof(str), "\t[%s]0x%x\n", + num = scnprintf(str, sizeof(str), "\t[%s] %s\n", inst->flows[idx] >= VPU_MSG_ID_NOOP ? "M" : "C", - inst->flows[idx]); + vpu_id_name(inst->flows[idx])); if (seq_write(s, str, num)) { mutex_unlock(&inst->core->cmd_lock); return 0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/platform/amphion/vpu_helpers.c +++ linux-6.2.0/drivers/media/platform/amphion/vpu_helpers.c @@ -11,6 +11,7 @@ #include #include #include "vpu.h" +#include "vpu_defs.h" #include "vpu_core.h" #include "vpu_rpc.h" #include "vpu_helpers.h" @@ -447,3 +448,63 @@ return -EINVAL; } + +const char *vpu_id_name(u32 id) +{ + switch (id) { + case VPU_CMD_ID_NOOP: return "noop"; + case VPU_CMD_ID_CONFIGURE_CODEC: return "configure codec"; + case VPU_CMD_ID_START: return "start"; + case VPU_CMD_ID_STOP: return "stop"; + case VPU_CMD_ID_ABORT: return "abort"; + case VPU_CMD_ID_RST_BUF: return "reset buf"; + case VPU_CMD_ID_SNAPSHOT: return "snapshot"; + case VPU_CMD_ID_FIRM_RESET: return "reset firmware"; + case VPU_CMD_ID_UPDATE_PARAMETER: return "update parameter"; + case VPU_CMD_ID_FRAME_ENCODE: return "encode frame"; + case VPU_CMD_ID_SKIP: return "skip"; + case VPU_CMD_ID_FS_ALLOC: return "alloc fb"; + case VPU_CMD_ID_FS_RELEASE: return "release fb"; + case VPU_CMD_ID_TIMESTAMP: return "timestamp"; + case VPU_CMD_ID_DEBUG: return "debug"; + case VPU_MSG_ID_RESET_DONE: return "reset done"; + case VPU_MSG_ID_START_DONE: return "start done"; + case VPU_MSG_ID_STOP_DONE: return "stop done"; + case VPU_MSG_ID_ABORT_DONE: return "abort done"; + case VPU_MSG_ID_BUF_RST: return "buf reset done"; + case VPU_MSG_ID_MEM_REQUEST: return "mem request"; + case VPU_MSG_ID_PARAM_UPD_DONE: return "param upd done"; + case VPU_MSG_ID_FRAME_INPUT_DONE: return "frame input done"; + case VPU_MSG_ID_ENC_DONE: return "encode done"; + case VPU_MSG_ID_DEC_DONE: return "frame display"; + case VPU_MSG_ID_FRAME_REQ: return "fb request"; + case VPU_MSG_ID_FRAME_RELEASE: return "fb release"; + case VPU_MSG_ID_SEQ_HDR_FOUND: return "seq hdr found"; + case VPU_MSG_ID_RES_CHANGE: return "resolution change"; + case VPU_MSG_ID_PIC_HDR_FOUND: return "pic hdr found"; + case VPU_MSG_ID_PIC_DECODED: return "picture decoded"; + case VPU_MSG_ID_PIC_EOS: return "eos"; + case VPU_MSG_ID_FIFO_LOW: return "fifo low"; + case VPU_MSG_ID_BS_ERROR: return "bs error"; + case VPU_MSG_ID_UNSUPPORTED: return "unsupported"; + case VPU_MSG_ID_FIRMWARE_XCPT: return "exception"; + case VPU_MSG_ID_PIC_SKIPPED: return "skipped"; + } + return ""; +} + +const char *vpu_codec_state_name(enum vpu_codec_state state) +{ + switch (state) { + case VPU_CODEC_STATE_DEINIT: return "initialization"; + case VPU_CODEC_STATE_CONFIGURED: return "configured"; + case VPU_CODEC_STATE_START: return "start"; + case VPU_CODEC_STATE_STARTED: return "started"; + case VPU_CODEC_STATE_ACTIVE: return "active"; + case VPU_CODEC_STATE_SEEK: return "seek"; + case VPU_CODEC_STATE_STOP: return "stop"; + case VPU_CODEC_STATE_DRAIN: return "drain"; + case VPU_CODEC_STATE_DYAMIC_RESOLUTION_CHANGE: return "resolution change"; + } + return ""; +} only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/platform/amphion/vpu_mbox.c +++ linux-6.2.0/drivers/media/platform/amphion/vpu_mbox.c @@ -46,11 +46,10 @@ cl->rx_callback = vpu_mbox_rx_callback; ch = mbox_request_channel_byname(cl, mbox->name); - if (IS_ERR(ch)) { - dev_err(dev, "Failed to request mbox chan %s, ret : %ld\n", - mbox->name, PTR_ERR(ch)); - return PTR_ERR(ch); - } + if (IS_ERR(ch)) + return dev_err_probe(dev, PTR_ERR(ch), + "Failed to request mbox chan %s\n", + mbox->name); mbox->ch = ch; return 0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/platform/amphion/vpu_msgs.c +++ linux-6.2.0/drivers/media/platform/amphion/vpu_msgs.c @@ -32,7 +32,7 @@ static void vpu_session_handle_mem_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt) { - struct vpu_pkt_mem_req_data req_data; + struct vpu_pkt_mem_req_data req_data = { 0 }; vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&req_data); vpu_trace(inst->dev, "[%d] %d:%d %d:%d %d:%d\n", @@ -80,7 +80,7 @@ static void vpu_session_handle_enc_frame_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) { - struct vpu_enc_pic_info info; + struct vpu_enc_pic_info info = { 0 }; vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info); dev_dbg(inst->dev, "[%d] frame id = %d, wptr = 0x%x, size = %d\n", @@ -90,7 +90,7 @@ static void vpu_session_handle_frame_request(struct vpu_inst *inst, struct vpu_rpc_event *pkt) { - struct vpu_fs_info fs; + struct vpu_fs_info fs = { 0 }; vpu_iface_unpack_msg_data(inst->core, pkt, &fs); call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_REQ, &fs); @@ -107,7 +107,7 @@ info.type = inst->out_format.type; call_void_vop(inst, buf_done, &info); } else if (inst->core->type == VPU_CORE_TYPE_DEC) { - struct vpu_fs_info fs; + struct vpu_fs_info fs = { 0 }; vpu_iface_unpack_msg_data(inst->core, pkt, &fs); call_void_vop(inst, event_notify, VPU_MSG_ID_FRAME_RELEASE, &fs); @@ -122,7 +122,7 @@ static void vpu_session_handle_pic_decoded(struct vpu_inst *inst, struct vpu_rpc_event *pkt) { - struct vpu_dec_pic_info info; + struct vpu_dec_pic_info info = { 0 }; vpu_iface_unpack_msg_data(inst->core, pkt, (void *)&info); call_void_vop(inst, get_one_frame, &info); @@ -130,7 +130,7 @@ static void vpu_session_handle_pic_done(struct vpu_inst *inst, struct vpu_rpc_event *pkt) { - struct vpu_dec_pic_info info; + struct vpu_dec_pic_info info = { 0 }; struct vpu_frame_info frame; memset(&frame, 0, sizeof(frame)); @@ -210,7 +210,7 @@ return -EINVAL; msg_id = ret; - dev_dbg(inst->dev, "[%d] receive event(0x%x)\n", inst->id, msg_id); + dev_dbg(inst->dev, "[%d] receive event(%s)\n", inst->id, vpu_id_name(msg_id)); for (i = 0; i < ARRAY_SIZE(handlers); i++) { if (handlers[i].id == msg_id) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/platform/marvell/Kconfig +++ linux-6.2.0/drivers/media/platform/marvell/Kconfig @@ -7,7 +7,7 @@ depends on V4L_PLATFORM_DRIVERS depends on PCI && I2C && VIDEO_DEV depends on COMMON_CLK - select VIDEO_OV7670 + select VIDEO_OV7670 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR select VIDEOBUF2_VMALLOC select VIDEOBUF2_DMA_CONTIG select VIDEOBUF2_DMA_SG @@ -22,7 +22,7 @@ depends on I2C && VIDEO_DEV depends on ARCH_MMP || COMPILE_TEST depends on COMMON_CLK - select VIDEO_OV7670 + select VIDEO_OV7670 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR select I2C_GPIO select VIDEOBUF2_VMALLOC select VIDEOBUF2_DMA_CONTIG only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c +++ linux-6.2.0/drivers/media/platform/mediatek/mdp3/mtk-mdp3-comp.c @@ -775,11 +775,13 @@ ret = cmdq_dev_get_client_reg(&comp_pdev->dev, &cmdq_reg, index); if (ret != 0) { dev_err(&comp_pdev->dev, "cmdq_dev_get_subsys fail!\n"); + put_device(&comp_pdev->dev); return -EINVAL; } comp->subsys_id = cmdq_reg.subsys; dev_dbg(&comp_pdev->dev, "subsys id=%d\n", cmdq_reg.subsys); + put_device(&comp_pdev->dev); return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c +++ linux-6.2.0/drivers/media/platform/mediatek/vcodec/vdec/vdec_vp9_if.c @@ -226,10 +226,11 @@ if (fb->base_y.va == addr) { list_move_tail(&node->list, &inst->available_fb_node_list); - break; + return fb; } } - return fb; + + return NULL; } static void vp9_add_to_fb_free_list(struct vdec_vp9_inst *inst, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/platform/qcom/venus/hfi_venus.c +++ linux-6.2.0/drivers/media/platform/qcom/venus/hfi_venus.c @@ -131,7 +131,6 @@ static bool venus_pkt_debug; int venus_fw_debug = HFI_DEBUG_MSG_ERROR | HFI_DEBUG_MSG_FATAL; -static bool venus_sys_idle_indicator; static bool venus_fw_low_power_mode = true; static int venus_hw_rsp_timeout = 1000; static bool venus_fw_coverage; @@ -454,7 +453,6 @@ void __iomem *wrapper_base = hdev->core->wrapper_base; int ret = 0; - writel(BIT(VIDC_CTRL_INIT_CTRL_SHIFT), cpu_cs_base + VIDC_CTRL_INIT); if (IS_V6(hdev->core)) { mask_val = readl(wrapper_base + WRAPPER_INTR_MASK); mask_val &= ~(WRAPPER_INTR_MASK_A2HWD_BASK_V6 | @@ -465,6 +463,7 @@ writel(mask_val, wrapper_base + WRAPPER_INTR_MASK); writel(1, cpu_cs_base + CPU_CS_SCIACMDARG3); + writel(BIT(VIDC_CTRL_INIT_CTRL_SHIFT), cpu_cs_base + VIDC_CTRL_INIT); while (!ctrl_status && count < max_tries) { ctrl_status = readl(cpu_cs_base + CPU_CS_SCIACMDARG0); if ((ctrl_status & CPU_CS_SCIACMDARG0_ERROR_STATUS_MASK) == 4) { @@ -947,17 +946,12 @@ if (ret) dev_warn(dev, "setting fw debug msg ON failed (%d)\n", ret); - /* - * Idle indicator is disabled by default on some 4xx firmware versions, - * enable it explicitly in order to make suspend functional by checking - * WFI (wait-for-interrupt) bit. - */ - if (IS_V4(hdev->core) || IS_V6(hdev->core)) - venus_sys_idle_indicator = true; - - ret = venus_sys_set_idle_message(hdev, venus_sys_idle_indicator); - if (ret) - dev_warn(dev, "setting idle response ON failed (%d)\n", ret); + /* HFI_PROPERTY_SYS_IDLE_INDICATOR is not supported beyond 8916 (HFI V1) */ + if (IS_V1(hdev->core)) { + ret = venus_sys_set_idle_message(hdev, false); + if (ret) + dev_warn(dev, "setting idle response ON failed (%d)\n", ret); + } ret = venus_sys_set_power_control(hdev, venus_fw_low_power_mode); if (ret) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/platform/via/Kconfig +++ linux-6.2.0/drivers/media/platform/via/Kconfig @@ -7,7 +7,7 @@ depends on V4L_PLATFORM_DRIVERS depends on FB_VIA && VIDEO_DEV select VIDEOBUF2_DMA_SG - select VIDEO_OV7670 + select VIDEO_OV7670 if VIDEO_CAMERA_SENSOR help Driver support for the integrated camera controller in VIA Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/fc0011.c +++ linux-6.2.0/drivers/media/tuners/fc0011.c @@ -499,7 +499,7 @@ return fe; } -EXPORT_SYMBOL(fc0011_attach); +EXPORT_SYMBOL_GPL(fc0011_attach); MODULE_DESCRIPTION("Fitipower FC0011 silicon tuner driver"); MODULE_AUTHOR("Michael Buesch "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/fc0012.c +++ linux-6.2.0/drivers/media/tuners/fc0012.c @@ -495,7 +495,7 @@ return fe; } -EXPORT_SYMBOL(fc0012_attach); +EXPORT_SYMBOL_GPL(fc0012_attach); MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver"); MODULE_AUTHOR("Hans-Frieder Vogt "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/fc0013.c +++ linux-6.2.0/drivers/media/tuners/fc0013.c @@ -608,7 +608,7 @@ return fe; } -EXPORT_SYMBOL(fc0013_attach); +EXPORT_SYMBOL_GPL(fc0013_attach); MODULE_DESCRIPTION("Fitipower FC0013 silicon tuner driver"); MODULE_AUTHOR("Hans-Frieder Vogt "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/max2165.c +++ linux-6.2.0/drivers/media/tuners/max2165.c @@ -410,7 +410,7 @@ return fe; } -EXPORT_SYMBOL(max2165_attach); +EXPORT_SYMBOL_GPL(max2165_attach); MODULE_AUTHOR("David T. L. Wong "); MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/mc44s803.c +++ linux-6.2.0/drivers/media/tuners/mc44s803.c @@ -356,7 +356,7 @@ kfree(priv); return NULL; } -EXPORT_SYMBOL(mc44s803_attach); +EXPORT_SYMBOL_GPL(mc44s803_attach); MODULE_AUTHOR("Jochen Friedrich"); MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/mt2060.c +++ linux-6.2.0/drivers/media/tuners/mt2060.c @@ -440,7 +440,7 @@ return fe; } -EXPORT_SYMBOL(mt2060_attach); +EXPORT_SYMBOL_GPL(mt2060_attach); static int mt2060_probe(struct i2c_client *client) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/mt2131.c +++ linux-6.2.0/drivers/media/tuners/mt2131.c @@ -274,7 +274,7 @@ fe->tuner_priv = priv; return fe; } -EXPORT_SYMBOL(mt2131_attach); +EXPORT_SYMBOL_GPL(mt2131_attach); MODULE_AUTHOR("Steven Toth"); MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/mt2266.c +++ linux-6.2.0/drivers/media/tuners/mt2266.c @@ -336,7 +336,7 @@ mt2266_calibrate(priv); return fe; } -EXPORT_SYMBOL(mt2266_attach); +EXPORT_SYMBOL_GPL(mt2266_attach); MODULE_AUTHOR("Olivier DANET"); MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/mxl5005s.c +++ linux-6.2.0/drivers/media/tuners/mxl5005s.c @@ -4116,7 +4116,7 @@ fe->tuner_priv = state; return fe; } -EXPORT_SYMBOL(mxl5005s_attach); +EXPORT_SYMBOL_GPL(mxl5005s_attach); MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver"); MODULE_AUTHOR("Steven Toth"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/qt1010.c +++ linux-6.2.0/drivers/media/tuners/qt1010.c @@ -345,11 +345,12 @@ else valptr = &tmpval; - BUG_ON(i >= ARRAY_SIZE(i2c_data) - 1); - - err = qt1010_init_meas1(priv, i2c_data[i+1].reg, - i2c_data[i].reg, - i2c_data[i].val, valptr); + if (i >= ARRAY_SIZE(i2c_data) - 1) + err = -EIO; + else + err = qt1010_init_meas1(priv, i2c_data[i + 1].reg, + i2c_data[i].reg, + i2c_data[i].val, valptr); i++; break; } @@ -440,7 +441,7 @@ fe->tuner_priv = priv; return fe; } -EXPORT_SYMBOL(qt1010_attach); +EXPORT_SYMBOL_GPL(qt1010_attach); MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver"); MODULE_AUTHOR("Antti Palosaari "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/tda18218.c +++ linux-6.2.0/drivers/media/tuners/tda18218.c @@ -336,7 +336,7 @@ return fe; } -EXPORT_SYMBOL(tda18218_attach); +EXPORT_SYMBOL_GPL(tda18218_attach); MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver"); MODULE_AUTHOR("Antti Palosaari "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/xc2028.c +++ linux-6.2.0/drivers/media/tuners/xc2028.c @@ -1512,7 +1512,7 @@ return NULL; } -EXPORT_SYMBOL(xc2028_attach); +EXPORT_SYMBOL_GPL(xc2028_attach); MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver"); MODULE_AUTHOR("Michel Ludwig "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/xc4000.c +++ linux-6.2.0/drivers/media/tuners/xc4000.c @@ -1742,7 +1742,7 @@ xc4000_release(fe); return NULL; } -EXPORT_SYMBOL(xc4000_attach); +EXPORT_SYMBOL_GPL(xc4000_attach); MODULE_AUTHOR("Steven Toth, Davide Ferri"); MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/tuners/xc5000.c +++ linux-6.2.0/drivers/media/tuners/xc5000.c @@ -1460,7 +1460,7 @@ xc5000_release(fe); return NULL; } -EXPORT_SYMBOL(xc5000_attach); +EXPORT_SYMBOL_GPL(xc5000_attach); MODULE_AUTHOR("Steven Toth"); MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/usb/dvb-usb-v2/af9035.c +++ linux-6.2.0/drivers/media/usb/dvb-usb-v2/af9035.c @@ -270,6 +270,7 @@ struct dvb_usb_device *d = i2c_get_adapdata(adap); struct state *state = d_to_priv(d); int ret; + u32 reg; if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; @@ -322,8 +323,10 @@ ret = -EOPNOTSUPP; } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || (msg[0].addr == state->af9033_i2c_addr[1])) { + if (msg[0].len < 3 || msg[1].len < 1) + return -EOPNOTSUPP; /* demod access via firmware interface */ - u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | + reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | msg[0].buf[2]; if (msg[0].addr == state->af9033_i2c_addr[1]) @@ -381,17 +384,16 @@ ret = -EOPNOTSUPP; } else if ((msg[0].addr == state->af9033_i2c_addr[0]) || (msg[0].addr == state->af9033_i2c_addr[1])) { + if (msg[0].len < 3) + return -EOPNOTSUPP; /* demod access via firmware interface */ - u32 reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | + reg = msg[0].buf[0] << 16 | msg[0].buf[1] << 8 | msg[0].buf[2]; if (msg[0].addr == state->af9033_i2c_addr[1]) reg |= 0x100000; - ret = (msg[0].len >= 3) ? af9035_wr_regs(d, reg, - &msg[0].buf[3], - msg[0].len - 3) - : -EOPNOTSUPP; + ret = af9035_wr_regs(d, reg, &msg[0].buf[3], msg[0].len - 3); } else { /* I2C write */ u8 buf[MAX_XFER_SIZE]; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/usb/dvb-usb-v2/anysee.c +++ linux-6.2.0/drivers/media/usb/dvb-usb-v2/anysee.c @@ -202,7 +202,7 @@ while (i < num) { if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { - if (msg[i].len > 2 || msg[i+1].len > 60) { + if (msg[i].len != 2 || msg[i + 1].len > 60) { ret = -EOPNOTSUPP; break; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/usb/dvb-usb-v2/gl861.c +++ linux-6.2.0/drivers/media/usb/dvb-usb-v2/gl861.c @@ -120,7 +120,7 @@ } else if (num == 2 && !(msg[0].flags & I2C_M_RD) && (msg[1].flags & I2C_M_RD)) { /* I2C write + read */ - if (msg[0].len > 1 || msg[1].len > sizeof(ctx->buf)) { + if (msg[0].len != 1 || msg[1].len > sizeof(ctx->buf)) { ret = -EOPNOTSUPP; goto err; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/usb/dvb-usb/af9005.c +++ linux-6.2.0/drivers/media/usb/dvb-usb/af9005.c @@ -422,6 +422,10 @@ if (ret == 0) ret = 2; } else { + if (msg[0].len < 2) { + ret = -EOPNOTSUPP; + goto unlock; + } /* write one or more registers */ reg = msg[0].buf[0]; addr = msg[0].addr; @@ -431,6 +435,7 @@ ret = 1; } +unlock: mutex_unlock(&d->i2c_mutex); return ret; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/usb/dvb-usb/m920x.c +++ linux-6.2.0/drivers/media/usb/dvb-usb/m920x.c @@ -277,7 +277,6 @@ char *read = kmalloc(1, GFP_KERNEL); if (!read) { ret = -ENOMEM; - kfree(read); goto unlock; } @@ -288,8 +287,10 @@ if ((ret = m920x_read(d->udev, M9206_I2C, 0x0, 0x20 | stop, - read, 1)) != 0) + read, 1)) != 0) { + kfree(read); goto unlock; + } msg[i].buf[j] = read[0]; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/usb/em28xx/Kconfig +++ linux-6.2.0/drivers/media/usb/em28xx/Kconfig @@ -12,8 +12,8 @@ select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_MSP3400 if MEDIA_SUBDRV_AUTOSELECT - select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT - select VIDEO_OV2640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT + select VIDEO_MT9V011 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR + select VIDEO_OV2640 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR help This is a video4linux driver for Empia 28xx based TV cards. only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/usb/go7007/Kconfig +++ linux-6.2.0/drivers/media/usb/go7007/Kconfig @@ -12,8 +12,8 @@ select VIDEO_TW2804 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TW9903 if MEDIA_SUBDRV_AUTOSELECT select VIDEO_TW9906 if MEDIA_SUBDRV_AUTOSELECT - select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT && MEDIA_CAMERA_SUPPORT select VIDEO_UDA1342 if MEDIA_SUBDRV_AUTOSELECT + select VIDEO_OV7640 if MEDIA_SUBDRV_AUTOSELECT && VIDEO_CAMERA_SENSOR help This is a video4linux driver for the WIS GO7007 MPEG encoder chip. only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/usb/go7007/go7007-i2c.c +++ linux-6.2.0/drivers/media/usb/go7007/go7007-i2c.c @@ -165,8 +165,6 @@ } else if (msgs[i].len == 3) { if (msgs[i].flags & I2C_M_RD) return -EIO; - if (msgs[i].len != 3) - return -EIO; if (go7007_i2c_xfer(go, msgs[i].addr, 0, (msgs[i].buf[0] << 8) | msgs[i].buf[1], 0x01, &msgs[i].buf[2]) < 0) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/media/v4l2-core/v4l2-fwnode.c +++ linux-6.2.0/drivers/media/v4l2-core/v4l2-fwnode.c @@ -566,19 +566,29 @@ link->local_id = fwep.id; link->local_port = fwep.port; link->local_node = fwnode_graph_get_port_parent(fwnode); + if (!link->local_node) + return -ENOLINK; fwnode = fwnode_graph_get_remote_endpoint(fwnode); - if (!fwnode) { - fwnode_handle_put(fwnode); - return -ENOLINK; - } + if (!fwnode) + goto err_put_local_node; fwnode_graph_parse_endpoint(fwnode, &fwep); link->remote_id = fwep.id; link->remote_port = fwep.port; link->remote_node = fwnode_graph_get_port_parent(fwnode); + if (!link->remote_node) + goto err_put_remote_endpoint; return 0; + +err_put_remote_endpoint: + fwnode_handle_put(fwnode); + +err_put_local_node: + fwnode_handle_put(link->local_node); + + return -ENOLINK; } EXPORT_SYMBOL_GPL(v4l2_fwnode_parse_link); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/misc/Kconfig +++ linux-6.2.0/drivers/misc/Kconfig @@ -496,6 +496,7 @@ config OPEN_DICE tristate "Open Profile for DICE driver" depends on OF_RESERVED_MEM + depends on HAS_IOMEM help This driver exposes a DICE reserved memory region to userspace via a character device. The memory region contains Compound Device only in patch2: unchanged: --- linux-6.2.0.orig/drivers/mmc/host/renesas_sdhi_core.c +++ linux-6.2.0/drivers/mmc/host/renesas_sdhi_core.c @@ -1006,6 +1006,8 @@ host->sdcard_irq_setbit_mask = TMIO_STAT_ALWAYS_SET_27; host->sdcard_irq_mask_all = TMIO_MASK_ALL_RCAR2; host->reset = renesas_sdhi_reset; + } else { + host->sdcard_irq_mask_all = TMIO_MASK_ALL; } /* Orginally registers were 16 bit apart, could be 32 or 64 nowadays */ @@ -1100,9 +1102,7 @@ host->ops.hs400_complete = renesas_sdhi_hs400_complete; } - ret = tmio_mmc_host_probe(host); - if (ret < 0) - goto edisclk; + sd_ctrl_write32_as_16_and_16(host, CTL_IRQ_MASK, host->sdcard_irq_mask_all); num_irqs = platform_irq_count(pdev); if (num_irqs < 0) { @@ -1129,6 +1129,10 @@ goto eirq; } + ret = tmio_mmc_host_probe(host); + if (ret < 0) + goto edisclk; + dev_info(&pdev->dev, "%s base at %pa, max clock rate %u MHz\n", mmc_hostname(host->mmc), &res->start, host->mmc->f_max / 1000000); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ linux-6.2.0/drivers/mtd/nand/raw/brcmnand/brcmnand.c @@ -272,6 +272,7 @@ const unsigned int *page_sizes; unsigned int page_size_shift; unsigned int max_oob; + u32 ecc_level_shift; u32 features; /* for low-power standby/resume only */ @@ -596,6 +597,34 @@ INTFC_CTLR_READY = BIT(31), }; +/*********************************************************************** + * NAND ACC CONTROL bitfield + * + * Some bits have remained constant throughout hardware revision, while + * others have shifted around. + ***********************************************************************/ + +/* Constant for all versions (where supported) */ +enum { + /* See BRCMNAND_HAS_CACHE_MODE */ + ACC_CONTROL_CACHE_MODE = BIT(22), + + /* See BRCMNAND_HAS_PREFETCH */ + ACC_CONTROL_PREFETCH = BIT(23), + + ACC_CONTROL_PAGE_HIT = BIT(24), + ACC_CONTROL_WR_PREEMPT = BIT(25), + ACC_CONTROL_PARTIAL_PAGE = BIT(26), + ACC_CONTROL_RD_ERASED = BIT(27), + ACC_CONTROL_FAST_PGM_RDIN = BIT(28), + ACC_CONTROL_WR_ECC = BIT(30), + ACC_CONTROL_RD_ECC = BIT(31), +}; + +#define ACC_CONTROL_ECC_SHIFT 16 +/* Only for v7.2 */ +#define ACC_CONTROL_ECC_EXT_SHIFT 13 + static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl) { #if IS_ENABLED(CONFIG_MTD_NAND_BRCMNAND_BCMA) @@ -737,6 +766,12 @@ else if (of_property_read_bool(ctrl->dev->of_node, "brcm,nand-has-wp")) ctrl->features |= BRCMNAND_HAS_WP; + /* v7.2 has different ecc level shift in the acc register */ + if (ctrl->nand_version == 0x0702) + ctrl->ecc_level_shift = ACC_CONTROL_ECC_EXT_SHIFT; + else + ctrl->ecc_level_shift = ACC_CONTROL_ECC_SHIFT; + return 0; } @@ -931,30 +966,6 @@ return 0; } -/*********************************************************************** - * NAND ACC CONTROL bitfield - * - * Some bits have remained constant throughout hardware revision, while - * others have shifted around. - ***********************************************************************/ - -/* Constant for all versions (where supported) */ -enum { - /* See BRCMNAND_HAS_CACHE_MODE */ - ACC_CONTROL_CACHE_MODE = BIT(22), - - /* See BRCMNAND_HAS_PREFETCH */ - ACC_CONTROL_PREFETCH = BIT(23), - - ACC_CONTROL_PAGE_HIT = BIT(24), - ACC_CONTROL_WR_PREEMPT = BIT(25), - ACC_CONTROL_PARTIAL_PAGE = BIT(26), - ACC_CONTROL_RD_ERASED = BIT(27), - ACC_CONTROL_FAST_PGM_RDIN = BIT(28), - ACC_CONTROL_WR_ECC = BIT(30), - ACC_CONTROL_RD_ECC = BIT(31), -}; - static inline u32 brcmnand_spare_area_mask(struct brcmnand_controller *ctrl) { if (ctrl->nand_version == 0x0702) @@ -967,18 +978,15 @@ return GENMASK(4, 0); } -#define NAND_ACC_CONTROL_ECC_SHIFT 16 -#define NAND_ACC_CONTROL_ECC_EXT_SHIFT 13 - static inline u32 brcmnand_ecc_level_mask(struct brcmnand_controller *ctrl) { u32 mask = (ctrl->nand_version >= 0x0600) ? 0x1f : 0x0f; - mask <<= NAND_ACC_CONTROL_ECC_SHIFT; + mask <<= ACC_CONTROL_ECC_SHIFT; /* v7.2 includes additional ECC levels */ - if (ctrl->nand_version >= 0x0702) - mask |= 0x7 << NAND_ACC_CONTROL_ECC_EXT_SHIFT; + if (ctrl->nand_version == 0x0702) + mask |= 0x7 << ACC_CONTROL_ECC_EXT_SHIFT; return mask; } @@ -992,8 +1000,8 @@ if (en) { acc_control |= ecc_flags; /* enable RD/WR ECC */ - acc_control |= host->hwcfg.ecc_level - << NAND_ACC_CONTROL_ECC_SHIFT; + acc_control &= ~brcmnand_ecc_level_mask(ctrl); + acc_control |= host->hwcfg.ecc_level << ctrl->ecc_level_shift; } else { acc_control &= ~ecc_flags; /* disable RD/WR ECC */ acc_control &= ~brcmnand_ecc_level_mask(ctrl); @@ -1072,6 +1080,14 @@ cpu_relax(); } while (time_after(limit, jiffies)); + /* + * do a final check after time out in case the CPU was busy and the driver + * did not get enough time to perform the polling to avoid false alarms + */ + val = brcmnand_read_reg(ctrl, BRCMNAND_INTFC_STATUS); + if ((val & mask) == expected_val) + return 0; + dev_warn(ctrl->dev, "timeout on status poll (expected %x got %x)\n", expected_val, val & mask); @@ -1461,19 +1477,33 @@ const u8 *oob, int sas, int sector_1k) { int tbytes = sas << sector_1k; - int j; + int j, k = 0; + u32 last = 0xffffffff; + u8 *plast = (u8 *)&last; /* Adjust OOB values for 1K sector size */ if (sector_1k && (i & 0x01)) tbytes = max(0, tbytes - (int)ctrl->max_oob); tbytes = min_t(int, tbytes, ctrl->max_oob); - for (j = 0; j < tbytes; j += 4) + /* + * tbytes may not be multiple of words. Make sure we don't read out of + * the boundary and stop at last word. + */ + for (j = 0; (j + 3) < tbytes; j += 4) oob_reg_write(ctrl, j, (oob[j + 0] << 24) | (oob[j + 1] << 16) | (oob[j + 2] << 8) | (oob[j + 3] << 0)); + + /* handle the remaing bytes */ + while (j < tbytes) + plast[k++] = oob[j++]; + + if (tbytes & 0x3) + oob_reg_write(ctrl, (tbytes & ~0x3), (__force u32)cpu_to_be32(last)); + return tbytes; } @@ -1592,7 +1622,17 @@ dev_dbg(ctrl->dev, "send native cmd %d addr 0x%llx\n", cmd, cmd_addr); - BUG_ON(ctrl->cmd_pending != 0); + /* + * If we came here through _panic_write and there is a pending + * command, try to wait for it. If it times out, rather than + * hitting BUG_ON, just return so we don't crash while crashing. + */ + if (oops_in_progress) { + if (ctrl->cmd_pending && + bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0)) + return; + } else + BUG_ON(ctrl->cmd_pending != 0); ctrl->cmd_pending = cmd; ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0); @@ -2561,7 +2601,7 @@ tmp &= ~brcmnand_ecc_level_mask(ctrl); tmp &= ~brcmnand_spare_area_mask(ctrl); if (ctrl->nand_version >= 0x0302) { - tmp |= cfg->ecc_level << NAND_ACC_CONTROL_ECC_SHIFT; + tmp |= cfg->ecc_level << ctrl->ecc_level_shift; tmp |= cfg->spare_area_size; } nand_writereg(ctrl, acc_control_offs, tmp); @@ -2612,6 +2652,8 @@ struct nand_chip *chip = &host->chip; const struct nand_ecc_props *requirements = nanddev_get_ecc_requirements(&chip->base); + struct nand_memory_organization *memorg = + nanddev_get_memorg(&chip->base); struct brcmnand_controller *ctrl = host->ctrl; struct brcmnand_cfg *cfg = &host->hwcfg; char msg[128]; @@ -2633,10 +2675,11 @@ if (cfg->spare_area_size > ctrl->max_oob) cfg->spare_area_size = ctrl->max_oob; /* - * Set oobsize to be consistent with controller's spare_area_size, as - * the rest is inaccessible. + * Set mtd and memorg oobsize to be consistent with controller's + * spare_area_size, as the rest is inaccessible. */ mtd->oobsize = cfg->spare_area_size * (mtd->writesize >> FC_SHIFT); + memorg->oobsize = mtd->oobsize; cfg->device_size = mtd->size; cfg->block_size = mtd->erasesize; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/mtd/nand/raw/fsmc_nand.c +++ linux-6.2.0/drivers/mtd/nand/raw/fsmc_nand.c @@ -1202,9 +1202,14 @@ static int fsmc_nand_resume(struct device *dev) { struct fsmc_nand_data *host = dev_get_drvdata(dev); + int ret; if (host) { - clk_prepare_enable(host->clk); + ret = clk_prepare_enable(host->clk); + if (ret) { + dev_err(dev, "failed to enable clk\n"); + return ret; + } if (host->dev_timings) fsmc_nand_setup(host, host->dev_timings); nand_reset(&host->nand, 0); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/mtd/spi-nor/winbond.c +++ linux-6.2.0/drivers/mtd/spi-nor/winbond.c @@ -120,8 +120,9 @@ NO_SFDP_FLAGS(SECT_4K) }, { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16) NO_SFDP_FLAGS(SECT_4K) }, - { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256) - NO_SFDP_FLAGS(SECT_4K) }, + { "w25q128", INFO(0xef4018, 0, 0, 0) + PARSE_SFDP + FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) .fixups = &w25q256_fixups }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/arcnet/arcnet.c +++ linux-6.2.0/drivers/net/arcnet/arcnet.c @@ -468,7 +468,7 @@ ret = sock_queue_err_skb(sk, ackskb); if (ret) - kfree_skb(ackskb); + dev_kfree_skb_irq(ackskb); local_irq_enable(); }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/can/Kconfig +++ linux-6.2.0/drivers/net/can/Kconfig @@ -174,10 +174,10 @@ config CAN_SUN4I tristate "Allwinner A10 CAN controller" - depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST + depends on MACH_SUN4I || MACH_SUN7I || RISCV || COMPILE_TEST help Say Y here if you want to use CAN controller found on Allwinner - A10/A20 SoCs. + A10/A20/D1 SoCs. To compile this driver as a module, choose M here: the module will be called sun4i_can. only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/can/m_can/tcan4x5x-regmap.c +++ linux-6.2.0/drivers/net/can/m_can/tcan4x5x-regmap.c @@ -95,7 +95,6 @@ regmap_reg_range(0x000c, 0x0010), /* Device configuration registers and Interrupt Flags*/ regmap_reg_range(0x0800, 0x080c), - regmap_reg_range(0x0814, 0x0814), regmap_reg_range(0x0820, 0x0820), regmap_reg_range(0x0830, 0x0830), /* M_CAN */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/can/sun4i_can.c +++ linux-6.2.0/drivers/net/can/sun4i_can.c @@ -91,6 +91,8 @@ #define SUN4I_REG_BUF12_ADDR 0x0070 /* CAN Tx/Rx Buffer 12 */ #define SUN4I_REG_ACPC_ADDR 0x0040 /* CAN Acceptance Code 0 */ #define SUN4I_REG_ACPM_ADDR 0x0044 /* CAN Acceptance Mask 0 */ +#define SUN4I_REG_ACPC_ADDR_D1 0x0028 /* CAN Acceptance Code 0 on the D1 */ +#define SUN4I_REG_ACPM_ADDR_D1 0x002C /* CAN Acceptance Mask 0 on the D1 */ #define SUN4I_REG_RBUF_RBACK_START_ADDR 0x0180 /* CAN transmit buffer start */ #define SUN4I_REG_RBUF_RBACK_END_ADDR 0x01b0 /* CAN transmit buffer end */ @@ -205,9 +207,11 @@ * struct sun4ican_quirks - Differences between SoC variants. * * @has_reset: SoC needs reset deasserted. + * @acp_offset: Offset of ACPC and ACPM registers */ struct sun4ican_quirks { bool has_reset; + int acp_offset; }; struct sun4ican_priv { @@ -216,6 +220,7 @@ struct clk *clk; struct reset_control *reset; spinlock_t cmdreg_lock; /* lock for concurrent cmd register writes */ + int acp_offset; }; static const struct can_bittiming_const sun4ican_bittiming_const = { @@ -338,8 +343,8 @@ } /* set filters - we accept all */ - writel(0x00000000, priv->base + SUN4I_REG_ACPC_ADDR); - writel(0xFFFFFFFF, priv->base + SUN4I_REG_ACPM_ADDR); + writel(0x00000000, priv->base + SUN4I_REG_ACPC_ADDR + priv->acp_offset); + writel(0xFFFFFFFF, priv->base + SUN4I_REG_ACPM_ADDR + priv->acp_offset); /* clear error counters and error code capture */ writel(0, priv->base + SUN4I_REG_ERRC_ADDR); @@ -768,10 +773,17 @@ static const struct sun4ican_quirks sun4ican_quirks_a10 = { .has_reset = false, + .acp_offset = 0, }; static const struct sun4ican_quirks sun4ican_quirks_r40 = { .has_reset = true, + .acp_offset = 0, +}; + +static const struct sun4ican_quirks sun4ican_quirks_d1 = { + .has_reset = true, + .acp_offset = (SUN4I_REG_ACPC_ADDR_D1 - SUN4I_REG_ACPC_ADDR), }; static const struct of_device_id sun4ican_of_match[] = { @@ -785,6 +797,9 @@ .compatible = "allwinner,sun8i-r40-can", .data = &sun4ican_quirks_r40 }, { + .compatible = "allwinner,sun20i-d1-can", + .data = &sun4ican_quirks_d1 + }, { /* sentinel */ }, }; @@ -872,6 +887,7 @@ priv->base = addr; priv->clk = clk; priv->reset = reset; + priv->acp_offset = quirks->acp_offset; spin_lock_init(&priv->cmdreg_lock); platform_set_drvdata(pdev, dev); @@ -909,4 +925,4 @@ MODULE_AUTHOR("Peter Chen "); MODULE_AUTHOR("Gerhard Bertelsmann "); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20)"); +MODULE_DESCRIPTION("CAN driver for Allwinner SoCs (A10/A20/D1)"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/dsa/mv88e6xxx/global1.c +++ linux-6.2.0/drivers/net/dsa/mv88e6xxx/global1.c @@ -75,37 +75,6 @@ return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1); } -void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip) -{ - const unsigned long timeout = jiffies + 1 * HZ; - u16 val; - int err; - - /* Wait up to 1 second for the switch to finish reading the - * EEPROM. - */ - while (time_before(jiffies, timeout)) { - err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val); - if (err) { - dev_err(chip->dev, "Error reading status"); - return; - } - - /* If the switch is still resetting, it may not - * respond on the bus, and so MDIO read returns - * 0xffff. Differentiate between that, and waiting for - * the EEPROM to be done by bit 0 being set. - */ - if (val != 0xffff && - val & BIT(MV88E6XXX_G1_STS_IRQ_EEPROM_DONE)) - return; - - usleep_range(1000, 2000); - } - - dev_err(chip->dev, "Timeout waiting for EEPROM done"); -} - /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1 * Offset 0x02: Switch MAC Address Register Bytes 2 & 3 * Offset 0x03: Switch MAC Address Register Bytes 4 & 5 only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/dsa/mv88e6xxx/global1.h +++ linux-6.2.0/drivers/net/dsa/mv88e6xxx/global1.h @@ -281,7 +281,6 @@ int mv88e6185_g1_reset(struct mv88e6xxx_chip *chip); int mv88e6352_g1_reset(struct mv88e6xxx_chip *chip); int mv88e6250_g1_reset(struct mv88e6xxx_chip *chip); -void mv88e6xxx_g1_wait_eeprom_done(struct mv88e6xxx_chip *chip); int mv88e6185_g1_ppu_enable(struct mv88e6xxx_chip *chip); int mv88e6185_g1_ppu_disable(struct mv88e6xxx_chip *chip); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/dsa/sja1105/sja1105_dynamic_config.c +++ linux-6.2.0/drivers/net/dsa/sja1105/sja1105_dynamic_config.c @@ -1175,18 +1175,15 @@ static int sja1105_dynamic_config_poll_valid(struct sja1105_private *priv, - struct sja1105_dyn_cmd *cmd, - const struct sja1105_dynamic_table_ops *ops) + const struct sja1105_dynamic_table_ops *ops, + void *entry, bool check_valident, + bool check_errors) { u8 packed_buf[SJA1105_MAX_DYN_CMD_SIZE] = {}; + struct sja1105_dyn_cmd cmd = {}; int rc; - /* We don't _need_ to read the full entry, just the command area which - * is a fixed SJA1105_SIZE_DYN_CMD. But our cmd_packing() API expects a - * buffer that contains the full entry too. Additionally, our API - * doesn't really know how many bytes into the buffer does the command - * area really begin. So just read back the whole entry. - */ + /* Read back the whole entry + command structure. */ rc = sja1105_xfer_buf(priv, SPI_READ, ops->addr, packed_buf, ops->packed_size); if (rc) @@ -1195,11 +1192,25 @@ /* Unpack the command structure, and return it to the caller in case it * needs to perform further checks on it (VALIDENT). */ - memset(cmd, 0, sizeof(*cmd)); - ops->cmd_packing(packed_buf, cmd, UNPACK); + ops->cmd_packing(packed_buf, &cmd, UNPACK); /* Hardware hasn't cleared VALID => still working on it */ - return cmd->valid ? -EAGAIN : 0; + if (cmd.valid) + return -EAGAIN; + + if (check_valident && !cmd.valident && !(ops->access & OP_VALID_ANYWAY)) + return -ENOENT; + + if (check_errors && cmd.errors) + return -EINVAL; + + /* Don't dereference possibly NULL pointer - maybe caller + * only wanted to see whether the entry existed or not. + */ + if (entry) + ops->entry_packing(packed_buf, entry, UNPACK); + + return 0; } /* Poll the dynamic config entry's control area until the hardware has @@ -1208,16 +1219,19 @@ */ static int sja1105_dynamic_config_wait_complete(struct sja1105_private *priv, - struct sja1105_dyn_cmd *cmd, - const struct sja1105_dynamic_table_ops *ops) + const struct sja1105_dynamic_table_ops *ops, + void *entry, bool check_valident, + bool check_errors) { - int rc; + int err, rc; - return read_poll_timeout(sja1105_dynamic_config_poll_valid, - rc, rc != -EAGAIN, - SJA1105_DYNAMIC_CONFIG_SLEEP_US, - SJA1105_DYNAMIC_CONFIG_TIMEOUT_US, - false, priv, cmd, ops); + err = read_poll_timeout(sja1105_dynamic_config_poll_valid, + rc, rc != -EAGAIN, + SJA1105_DYNAMIC_CONFIG_SLEEP_US, + SJA1105_DYNAMIC_CONFIG_TIMEOUT_US, + false, priv, ops, entry, check_valident, + check_errors); + return err < 0 ? err : rc; } /* Provides read access to the settings through the dynamic interface @@ -1286,25 +1300,14 @@ mutex_lock(&priv->dynamic_config_lock); rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, ops->packed_size); - if (rc < 0) { - mutex_unlock(&priv->dynamic_config_lock); - return rc; - } - - rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops); - mutex_unlock(&priv->dynamic_config_lock); if (rc < 0) - return rc; + goto out; - if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY)) - return -ENOENT; + rc = sja1105_dynamic_config_wait_complete(priv, ops, entry, true, false); +out: + mutex_unlock(&priv->dynamic_config_lock); - /* Don't dereference possibly NULL pointer - maybe caller - * only wanted to see whether the entry existed or not. - */ - if (entry) - ops->entry_packing(packed_buf, entry, UNPACK); - return 0; + return rc; } int sja1105_dynamic_config_write(struct sja1105_private *priv, @@ -1356,22 +1359,14 @@ mutex_lock(&priv->dynamic_config_lock); rc = sja1105_xfer_buf(priv, SPI_WRITE, ops->addr, packed_buf, ops->packed_size); - if (rc < 0) { - mutex_unlock(&priv->dynamic_config_lock); - return rc; - } - - rc = sja1105_dynamic_config_wait_complete(priv, &cmd, ops); - mutex_unlock(&priv->dynamic_config_lock); if (rc < 0) - return rc; + goto out; - cmd = (struct sja1105_dyn_cmd) {0}; - ops->cmd_packing(packed_buf, &cmd, UNPACK); - if (cmd.errors) - return -EINVAL; + rc = sja1105_dynamic_config_wait_complete(priv, ops, NULL, false, true); +out: + mutex_unlock(&priv->dynamic_config_lock); - return 0; + return rc; } static u8 sja1105_crc8_add(u8 crc, u8 byte, u8 poly) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/dsa/sja1105/sja1105_spi.c +++ linux-6.2.0/drivers/net/dsa/sja1105/sja1105_spi.c @@ -781,6 +781,7 @@ .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, + .fixed_cbs_mapping = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, @@ -831,6 +832,7 @@ .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, + .fixed_cbs_mapping = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, @@ -881,6 +883,7 @@ .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, + .fixed_cbs_mapping = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, @@ -931,6 +934,7 @@ .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, + .fixed_cbs_mapping = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/adi/adin1110.c +++ linux-6.2.0/drivers/net/ethernet/adi/adin1110.c @@ -740,7 +740,7 @@ u32 port_rules = 0; u8 mask[ETH_ALEN]; - memset(mask, 0xFF, ETH_ALEN); + eth_broadcast_addr(mask); if (accept_broadcast && port_priv->state == BR_STATE_FORWARDING) port_rules = adin1110_port_rules(port_priv, true, true); @@ -761,7 +761,7 @@ return -EADDRNOTAVAIL; eth_hw_addr_set(netdev, dev_addr); - memset(mask, 0xFF, ETH_ALEN); + eth_broadcast_addr(mask); mac_slot = (!port_priv->nr) ? ADIN_MAC_P1_ADDR_SLOT : ADIN_MAC_P2_ADDR_SLOT; port_rules = adin1110_port_rules(port_priv, true, false); @@ -1272,7 +1272,7 @@ goto out; /* Allow only BPDUs to be passed to the CPU */ - memset(mask, 0xFF, ETH_ALEN); + eth_broadcast_addr(mask); port_rules = adin1110_port_rules(port_priv, true, false); ret = adin1110_write_mac_address(port_priv, mac_slot, mac, mask, port_rules); @@ -1386,8 +1386,8 @@ return -ENOMEM; other_port = priv->ports[!port_priv->nr]; - port_rules = adin1110_port_rules(port_priv, false, true); - memset(mask, 0xFF, ETH_ALEN); + port_rules = adin1110_port_rules(other_port, false, true); + eth_broadcast_addr(mask); return adin1110_write_mac_address(other_port, mac_nr, (u8 *)fdb->addr, mask, port_rules); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c +++ linux-6.2.0/drivers/net/ethernet/amazon/ena/ena_netdev.c @@ -1778,6 +1778,9 @@ return work_done; error: + if (xdp_flags & ENA_XDP_REDIRECT) + xdp_do_flush(); + adapter = netdev_priv(rx_ring->netdev); if (rc == -ENOSPC) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/atheros/alx/ethtool.c +++ linux-6.2.0/drivers/net/ethernet/atheros/alx/ethtool.c @@ -292,9 +292,8 @@ spin_lock(&alx->stats_lock); alx_update_hw_stats(hw); - BUILD_BUG_ON(sizeof(hw->stats) - offsetof(struct alx_hw_stats, rx_ok) < - ALX_NUM_STATS * sizeof(u64)); - memcpy(data, &hw->stats.rx_ok, ALX_NUM_STATS * sizeof(u64)); + BUILD_BUG_ON(sizeof(hw->stats) != ALX_NUM_STATS * sizeof(u64)); + memcpy(data, &hw->stats, sizeof(hw->stats)); spin_unlock(&alx->stats_lock); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ linux-6.2.0/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -2104,8 +2104,11 @@ real_len = (((unsigned char *)ip_hdr(skb) - skb->data) + ntohs(ip_hdr(skb)->tot_len)); - if (real_len < skb->len) - pskb_trim(skb, real_len); + if (real_len < skb->len) { + err = pskb_trim(skb, real_len); + if (err) + return err; + } hdr_len = skb_tcp_all_headers(skb); if (unlikely(skb->len == hdr_len)) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ linux-6.2.0/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -14313,11 +14313,16 @@ bp->fw_seq = SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK; - if (netif_running(dev)) - bnx2x_nic_load(bp, LOAD_NORMAL); + if (netif_running(dev)) { + if (bnx2x_nic_load(bp, LOAD_NORMAL)) { + netdev_err(bp->dev, "Error during driver initialization, try unloading/reloading the driver\n"); + goto done; + } + } netif_device_attach(dev); +done: rtnl_unlock(); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/cadence/macb.h +++ linux-6.2.0/drivers/net/ethernet/cadence/macb.h @@ -95,6 +95,8 @@ #define GEM_SA4B 0x00A0 /* Specific4 Bottom */ #define GEM_SA4T 0x00A4 /* Specific4 Top */ #define GEM_WOL 0x00b8 /* Wake on LAN */ +#define GEM_RXPTPUNI 0x00D4 /* PTP RX Unicast address */ +#define GEM_TXPTPUNI 0x00D8 /* PTP TX Unicast address */ #define GEM_EFTSH 0x00e8 /* PTP Event Frame Transmitted Seconds Register 47:32 */ #define GEM_EFRSH 0x00ec /* PTP Event Frame Received Seconds Register 47:32 */ #define GEM_PEFTSH 0x00f0 /* PTP Peer Event Frame Transmitted Seconds Register 47:32 */ @@ -245,6 +247,8 @@ #define MACB_TZQ_OFFSET 12 /* Transmit zero quantum pause frame */ #define MACB_TZQ_SIZE 1 #define MACB_SRTSM_OFFSET 15 /* Store Receive Timestamp to Memory */ +#define MACB_PTPUNI_OFFSET 20 /* PTP Unicast packet enable */ +#define MACB_PTPUNI_SIZE 1 #define MACB_OSSMODE_OFFSET 24 /* Enable One Step Synchro Mode */ #define MACB_OSSMODE_SIZE 1 #define MACB_MIIONRGMII_OFFSET 28 /* MII Usage on RGMII Interface */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/engleder/tsnep_main.c +++ linux-6.2.0/drivers/net/ethernet/engleder/tsnep_main.c @@ -69,8 +69,11 @@ /* handle TX/RX queue 0 interrupt */ if ((active & adapter->queue[0].irq_mask) != 0) { - tsnep_disable_irq(adapter, adapter->queue[0].irq_mask); - napi_schedule(&adapter->queue[0].napi); + if (napi_schedule_prep(&adapter->queue[0].napi)) { + tsnep_disable_irq(adapter, adapter->queue[0].irq_mask); + /* schedule after masking to avoid races */ + __napi_schedule(&adapter->queue[0].napi); + } } return IRQ_HANDLED; @@ -81,8 +84,11 @@ struct tsnep_queue *queue = arg; /* handle TX/RX queue interrupt */ - tsnep_disable_irq(queue->adapter, queue->irq_mask); - napi_schedule(&queue->napi); + if (napi_schedule_prep(&queue->napi)) { + tsnep_disable_irq(queue->adapter, queue->irq_mask); + /* schedule after masking to avoid races */ + __napi_schedule(&queue->napi); + } return IRQ_HANDLED; } @@ -1010,6 +1016,10 @@ if (queue->tx) complete = tsnep_tx_poll(queue->tx, budget); + /* handle case where we are called by netpoll with a budget of 0 */ + if (unlikely(budget <= 0)) + return budget; + if (queue->rx) { done = tsnep_rx_poll(queue->rx, napi, budget); if (done >= budget) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/google/gve/gve_rx_dqo.c +++ linux-6.2.0/drivers/net/ethernet/google/gve/gve_rx_dqo.c @@ -492,7 +492,10 @@ if (!skb) return -1; - skb_shinfo(rx->ctx.skb_tail)->frag_list = skb; + if (rx->ctx.skb_tail == rx->ctx.skb_head) + skb_shinfo(rx->ctx.skb_head)->frag_list = skb; + else + rx->ctx.skb_tail->next = skb; rx->ctx.skb_tail = skb; num_frags = 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -774,7 +774,9 @@ hns3_get_ksettings(h, cmd); break; case HNAE3_MEDIA_TYPE_FIBER: - if (module_type == HNAE3_MODULE_TYPE_CR) + if (module_type == HNAE3_MODULE_TYPE_UNKNOWN) + cmd->base.port = PORT_OTHER; + else if (module_type == HNAE3_MODULE_TYPE_CR) cmd->base.port = PORT_DA; else cmd->base.port = PORT_FIBRE; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +++ linux-6.2.0/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h @@ -916,8 +916,6 @@ #define HCLGE_FLAG_MAIN BIT(0) #define HCLGE_FLAG_DCB_CAPABLE BIT(1) -#define HCLGE_FLAG_DCB_ENABLE BIT(2) -#define HCLGE_FLAG_MQPRIO_ENABLE BIT(3) u32 flag; u32 pkt_buf_size; /* Total pf buf size for tx/rx */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/huawei/hinic/hinic_port.c +++ linux-6.2.0/drivers/net/ethernet/huawei/hinic/hinic_port.c @@ -456,9 +456,6 @@ u16 out_size = sizeof(vlan_filter); int err; - if (!hwdev) - return -EINVAL; - vlan_filter.func_idx = HINIC_HWIF_FUNC_IDX(hwif); vlan_filter.enable = en; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +++ linux-6.2.0/drivers/net/ethernet/intel/ice/ice_ptp_hw.c @@ -131,6 +131,8 @@ case READ_TIME: cmd_val |= GLTSYN_CMD_READ_TIME; break; + case ICE_PTP_NOP: + break; } wr32(hw, GLTSYN_CMD, cmd_val); @@ -1226,18 +1228,18 @@ } /** - * ice_ptp_one_port_cmd - Prepare a single PHY port for a timer command + * ice_ptp_write_port_cmd_e822 - Prepare a single PHY port for a timer command * @hw: pointer to HW struct * @port: Port to which cmd has to be sent * @cmd: Command to be sent to the port * * Prepare the requested port for an upcoming timer sync command. * - * Note there is no equivalent of this operation on E810, as that device - * always handles all external PHYs internally. + * Do not use this function directly. If you want to configure exactly one + * port, use ice_ptp_one_port_cmd() instead. */ static int -ice_ptp_one_port_cmd(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd) +ice_ptp_write_port_cmd_e822(struct ice_hw *hw, u8 port, enum ice_ptp_tmr_cmd cmd) { u32 cmd_val, val; u8 tmr_idx; @@ -1261,6 +1263,8 @@ case ADJ_TIME_AT_TIME: cmd_val |= PHY_CMD_ADJ_TIME_AT_TIME; break; + case ICE_PTP_NOP: + break; } /* Tx case */ @@ -1307,6 +1311,39 @@ } /** + * ice_ptp_one_port_cmd - Prepare one port for a timer command + * @hw: pointer to the HW struct + * @configured_port: the port to configure with configured_cmd + * @configured_cmd: timer command to prepare on the configured_port + * + * Prepare the configured_port for the configured_cmd, and prepare all other + * ports for ICE_PTP_NOP. This causes the configured_port to execute the + * desired command while all other ports perform no operation. + */ +static int +ice_ptp_one_port_cmd(struct ice_hw *hw, u8 configured_port, + enum ice_ptp_tmr_cmd configured_cmd) +{ + u8 port; + + for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) { + enum ice_ptp_tmr_cmd cmd; + int err; + + if (port == configured_port) + cmd = configured_cmd; + else + cmd = ICE_PTP_NOP; + + err = ice_ptp_write_port_cmd_e822(hw, port, cmd); + if (err) + return err; + } + + return 0; +} + +/** * ice_ptp_port_cmd_e822 - Prepare all ports for a timer command * @hw: pointer to the HW struct * @cmd: timer command to prepare @@ -1322,7 +1359,7 @@ for (port = 0; port < ICE_NUM_EXTERNAL_PORTS; port++) { int err; - err = ice_ptp_one_port_cmd(hw, port, cmd); + err = ice_ptp_write_port_cmd_e822(hw, port, cmd); if (err) return err; } @@ -2252,6 +2289,9 @@ if (err) goto err_unlock; + /* Do not perform any action on the main timer */ + ice_ptp_src_cmd(hw, ICE_PTP_NOP); + /* Issue the sync to activate the time adjustment */ ice_ptp_exec_tmr_cmd(hw); @@ -2372,6 +2412,9 @@ if (err) return err; + /* Do not perform any action on the main timer */ + ice_ptp_src_cmd(hw, ICE_PTP_NOP); + ice_ptp_exec_tmr_cmd(hw); err = ice_read_phy_reg_e822(hw, port, P_REG_PS, &val); @@ -2847,6 +2890,8 @@ case ADJ_TIME_AT_TIME: cmd_val = GLTSYN_CMD_ADJ_INIT_TIME; break; + case ICE_PTP_NOP: + return 0; } /* Read, modify, write */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +++ linux-6.2.0/drivers/net/ethernet/intel/ice/ice_ptp_hw.h @@ -9,7 +9,8 @@ INIT_INCVAL, ADJ_TIME, ADJ_TIME_AT_TIME, - READ_TIME + READ_TIME, + ICE_PTP_NOP, }; enum ice_ptp_serdes { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/intel/ice/ice_virtchnl.c +++ linux-6.2.0/drivers/net/ethernet/intel/ice/ice_virtchnl.c @@ -2615,12 +2615,14 @@ goto err; } - /* Read flexiflag registers to determine whether the - * corresponding RXDID is configured and supported or not. - * Since Legacy 16byte descriptor format is not supported, - * start from Legacy 32byte descriptor. + /* RXDIDs supported by DDP package can be read from the register + * to get the supported RXDID bitmap. But the legacy 32byte RXDID + * is not listed in DDP package, add it in the bitmap manually. + * Legacy 16byte descriptor is not supported. */ - for (i = ICE_RXDID_LEGACY_1; i < ICE_FLEX_DESC_RXDID_MAX_NUM; i++) { + rxdid->supported_rxdids |= BIT(ICE_RXDID_LEGACY_1); + + for (i = ICE_RXDID_FLEX_NIC; i < ICE_FLEX_DESC_RXDID_MAX_NUM; i++) { regval = rd32(hw, GLFLXP_RXDID_FLAGS(i, 0)); if ((regval >> GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_S) & GLFLXP_RXDID_FLAGS_FLEXIFLAG_4N_M) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/intel/igb/igb.h +++ linux-6.2.0/drivers/net/ethernet/intel/igb/igb.h @@ -34,11 +34,11 @@ /* TX/RX descriptor defines */ #define IGB_DEFAULT_TXD 256 #define IGB_DEFAULT_TX_WORK 128 -#define IGB_MIN_TXD 80 +#define IGB_MIN_TXD 64 #define IGB_MAX_TXD 4096 #define IGB_DEFAULT_RXD 256 -#define IGB_MIN_RXD 80 +#define IGB_MIN_RXD 64 #define IGB_MAX_RXD 4096 #define IGB_DEFAULT_ITR 3 /* dynamic */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/intel/igbvf/igbvf.h +++ linux-6.2.0/drivers/net/ethernet/intel/igbvf/igbvf.h @@ -39,11 +39,11 @@ /* Tx/Rx descriptor defines */ #define IGBVF_DEFAULT_TXD 256 #define IGBVF_MAX_TXD 4096 -#define IGBVF_MIN_TXD 80 +#define IGBVF_MIN_TXD 64 #define IGBVF_DEFAULT_RXD 256 #define IGBVF_MAX_RXD 4096 -#define IGBVF_MIN_RXD 80 +#define IGBVF_MIN_RXD 64 #define IGBVF_MIN_ITR_USECS 10 /* 100000 irq/sec */ #define IGBVF_MAX_ITR_USECS 10000 /* 100 irq/sec */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ linux-6.2.0/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c @@ -979,6 +979,7 @@ u32 tsync_tx_ctl = IXGBE_TSYNCTXCTL_ENABLED; u32 tsync_rx_ctl = IXGBE_TSYNCRXCTL_ENABLED; u32 tsync_rx_mtrl = PTP_EV_PORT << 16; + u32 aflags = adapter->flags; bool is_l2 = false; u32 regval; @@ -996,20 +997,20 @@ case HWTSTAMP_FILTER_NONE: tsync_rx_ctl = 0; tsync_rx_mtrl = 0; - adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | - IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + aflags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); break; case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; tsync_rx_mtrl |= IXGBE_RXMTRL_V1_SYNC_MSG; - adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | - IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); break; case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_L4_V1; tsync_rx_mtrl |= IXGBE_RXMTRL_V1_DELAY_REQ_MSG; - adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | - IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); break; case HWTSTAMP_FILTER_PTP_V2_EVENT: case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: @@ -1023,8 +1024,8 @@ tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_EVENT_V2; is_l2 = true; config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; - adapter->flags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | - IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); + aflags |= (IXGBE_FLAG_RX_HWTSTAMP_ENABLED | + IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); break; case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: case HWTSTAMP_FILTER_NTP_ALL: @@ -1035,7 +1036,7 @@ if (hw->mac.type >= ixgbe_mac_X550) { tsync_rx_ctl |= IXGBE_TSYNCRXCTL_TYPE_ALL; config->rx_filter = HWTSTAMP_FILTER_ALL; - adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; + aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; break; } fallthrough; @@ -1046,8 +1047,6 @@ * Delay_Req messages and hardware does not support * timestamping all packets => return error */ - adapter->flags &= ~(IXGBE_FLAG_RX_HWTSTAMP_ENABLED | - IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER); config->rx_filter = HWTSTAMP_FILTER_NONE; return -ERANGE; } @@ -1079,8 +1078,8 @@ IXGBE_TSYNCRXCTL_TYPE_ALL | IXGBE_TSYNCRXCTL_TSIP_UT_EN; config->rx_filter = HWTSTAMP_FILTER_ALL; - adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; - adapter->flags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; + aflags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; + aflags &= ~IXGBE_FLAG_RX_HWTSTAMP_IN_REGISTER; is_l2 = true; break; default: @@ -1113,6 +1112,9 @@ IXGBE_WRITE_FLUSH(hw); + /* configure adapter flags only when HW is actually configured */ + adapter->flags = aflags; + /* clear TX/RX time stamp registers, just to be sure */ ixgbe_ptp_clear_tx_timestamp(adapter); IXGBE_READ_REG(hw, IXGBE_RXSTMPH); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ linux-6.2.0/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -5578,6 +5578,11 @@ break; case ETHTOOL_GRXCLSRLALL: for (i = 0; i < MVPP2_N_RFS_ENTRIES_PER_FLOW; i++) { + if (loc == info->rule_cnt) { + ret = -EMSGSIZE; + break; + } + if (port->rfs_rules[i]) rules[loc++] = i; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c +++ linux-6.2.0/drivers/net/ethernet/marvell/octeon_ep/octep_tx.c @@ -69,12 +69,12 @@ compl_sg++; dma_unmap_single(iq->dev, tx_buffer->sglist[0].dma_ptr[0], - tx_buffer->sglist[0].len[0], DMA_TO_DEVICE); + tx_buffer->sglist[0].len[3], DMA_TO_DEVICE); i = 1; /* entry 0 is main skb, unmapped above */ while (frags--) { dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3], - tx_buffer->sglist[i >> 2].len[i & 3], DMA_TO_DEVICE); + tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE); i++; } @@ -131,13 +131,13 @@ dma_unmap_single(iq->dev, tx_buffer->sglist[0].dma_ptr[0], - tx_buffer->sglist[0].len[0], + tx_buffer->sglist[0].len[3], DMA_TO_DEVICE); i = 1; /* entry 0 is main skb, unmapped above */ while (frags--) { dma_unmap_page(iq->dev, tx_buffer->sglist[i >> 2].dma_ptr[i & 3], - tx_buffer->sglist[i >> 2].len[i & 3], DMA_TO_DEVICE); + tx_buffer->sglist[i >> 2].len[3 - (i & 3)], DMA_TO_DEVICE); i++; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h +++ linux-6.2.0/drivers/net/ethernet/marvell/octeon_ep/octep_tx.h @@ -17,7 +17,21 @@ #define TX_BUFTYPE_NET_SG 2 #define NUM_TX_BUFTYPES 3 -/* Hardware format for Scatter/Gather list */ +/* Hardware format for Scatter/Gather list + * + * 63 48|47 32|31 16|15 0 + * ----------------------------------------- + * | Len 0 | Len 1 | Len 2 | Len 3 | + * ----------------------------------------- + * | Ptr 0 | + * ----------------------------------------- + * | Ptr 1 | + * ----------------------------------------- + * | Ptr 2 | + * ----------------------------------------- + * | Ptr 3 | + * ----------------------------------------- + */ struct octep_tx_sglist_desc { u16 len[4]; dma_addr_t dma_ptr[4]; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +++ linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c @@ -716,7 +716,8 @@ int otx2_txsch_alloc(struct otx2_nic *pfvf) { struct nix_txsch_alloc_req *req; - int lvl; + struct nix_txsch_alloc_rsp *rsp; + int lvl, schq, rc; /* Get memory to put this msg */ req = otx2_mbox_alloc_msg_nix_txsch_alloc(&pfvf->mbox); @@ -726,33 +727,69 @@ /* Request one schq per level */ for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) req->schq[lvl] = 1; + rc = otx2_sync_mbox_msg(&pfvf->mbox); + if (rc) + return rc; - return otx2_sync_mbox_msg(&pfvf->mbox); + rsp = (struct nix_txsch_alloc_rsp *) + otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr); + if (IS_ERR(rsp)) + return PTR_ERR(rsp); + + /* Setup transmit scheduler list */ + for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) + for (schq = 0; schq < rsp->schq[lvl]; schq++) + pfvf->hw.txschq_list[lvl][schq] = + rsp->schq_list[lvl][schq]; + + pfvf->hw.txschq_link_cfg_lvl = rsp->link_cfg_lvl; + + return 0; } -int otx2_txschq_stop(struct otx2_nic *pfvf) +void otx2_txschq_free_one(struct otx2_nic *pfvf, u16 lvl, u16 schq) { struct nix_txsch_free_req *free_req; - int lvl, schq, err; + int err; mutex_lock(&pfvf->mbox.lock); - /* Free the transmit schedulers */ + free_req = otx2_mbox_alloc_msg_nix_txsch_free(&pfvf->mbox); if (!free_req) { mutex_unlock(&pfvf->mbox.lock); - return -ENOMEM; + netdev_err(pfvf->netdev, + "Failed alloc txschq free req\n"); + return; } - free_req->flags = TXSCHQ_FREE_ALL; + free_req->schq_lvl = lvl; + free_req->schq = schq; + err = otx2_sync_mbox_msg(&pfvf->mbox); + if (err) { + netdev_err(pfvf->netdev, + "Failed stop txschq %d at level %d\n", schq, lvl); + } + mutex_unlock(&pfvf->mbox.lock); +} +EXPORT_SYMBOL(otx2_txschq_free_one); + +void otx2_txschq_stop(struct otx2_nic *pfvf) +{ + int lvl, schq; + + /* free non QOS TLx nodes */ + for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) + otx2_txschq_free_one(pfvf, lvl, + pfvf->hw.txschq_list[lvl][0]); /* Clear the txschq list */ for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) { for (schq = 0; schq < MAX_TXSCHQ_PER_FUNC; schq++) pfvf->hw.txschq_list[lvl][schq] = 0; } - return err; + } void otx2_sqb_flush(struct otx2_nic *pfvf) @@ -1629,21 +1666,6 @@ pfvf->hw.cgx_fec_uncorr_blks += rsp->fec_uncorr_blks; } -void mbox_handler_nix_txsch_alloc(struct otx2_nic *pf, - struct nix_txsch_alloc_rsp *rsp) -{ - int lvl, schq; - - /* Setup transmit scheduler list */ - for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) - for (schq = 0; schq < rsp->schq[lvl]; schq++) - pf->hw.txschq_list[lvl][schq] = - rsp->schq_list[lvl][schq]; - - pf->hw.txschq_link_cfg_lvl = rsp->link_cfg_lvl; -} -EXPORT_SYMBOL(mbox_handler_nix_txsch_alloc); - void mbox_handler_npa_lf_alloc(struct otx2_nic *pfvf, struct npa_lf_alloc_rsp *rsp) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c +++ linux-6.2.0/drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c @@ -70,7 +70,7 @@ * link config level. These rest of the scheduler can be * same as hw.txschq_list. */ - for (lvl = 0; lvl < pfvf->hw.txschq_link_cfg_lvl; lvl++) + for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++) req->schq[lvl] = 1; rc = otx2_sync_mbox_msg(&pfvf->mbox); @@ -83,7 +83,7 @@ return PTR_ERR(rsp); /* Setup transmit scheduler list */ - for (lvl = 0; lvl < pfvf->hw.txschq_link_cfg_lvl; lvl++) { + for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++) { if (!rsp->schq[lvl]) return -ENOSPC; @@ -125,19 +125,12 @@ static int otx2_pfc_txschq_stop_one(struct otx2_nic *pfvf, u8 prio) { - struct nix_txsch_free_req *free_req; + int lvl; - mutex_lock(&pfvf->mbox.lock); /* free PFC TLx nodes */ - free_req = otx2_mbox_alloc_msg_nix_txsch_free(&pfvf->mbox); - if (!free_req) { - mutex_unlock(&pfvf->mbox.lock); - return -ENOMEM; - } - - free_req->flags = TXSCHQ_FREE_ALL; - otx2_sync_mbox_msg(&pfvf->mbox); - mutex_unlock(&pfvf->mbox.lock); + for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++) + otx2_txschq_free_one(pfvf, lvl, + pfvf->pfc_schq_list[lvl][prio]); pfvf->pfc_alloc_status[prio] = false; return 0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c +++ linux-6.2.0/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c @@ -405,7 +405,8 @@ container_of(attr, struct mlxsw_hwmon_attr, dev_attr); return sprintf(buf, "front panel %03u\n", - mlxsw_hwmon_attr->type_index); + mlxsw_hwmon_attr->type_index + 1 - + mlxsw_hwmon_attr->mlxsw_hwmon_dev->sensor_count); } static ssize_t only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/mellanox/mlxsw/i2c.c +++ linux-6.2.0/drivers/net/ethernet/mellanox/mlxsw/i2c.c @@ -48,6 +48,7 @@ #define MLXSW_I2C_MBOX_SIZE_BITS 12 #define MLXSW_I2C_ADDR_BUF_SIZE 4 #define MLXSW_I2C_BLK_DEF 32 +#define MLXSW_I2C_BLK_MAX 100 #define MLXSW_I2C_RETRY 5 #define MLXSW_I2C_TIMEOUT_MSECS 5000 #define MLXSW_I2C_MAX_DATA_SIZE 256 @@ -444,7 +445,7 @@ } else { /* No input mailbox is case of initialization query command. */ reg_size = MLXSW_I2C_MAX_DATA_SIZE; - num = reg_size / mlxsw_i2c->block_size; + num = DIV_ROUND_UP(reg_size, mlxsw_i2c->block_size); if (mutex_lock_interruptible(&mlxsw_i2c->cmd.lock) < 0) { dev_err(&client->dev, "Could not acquire lock"); @@ -653,7 +654,7 @@ return -EOPNOTSUPP; } - mlxsw_i2c->block_size = max_t(u16, MLXSW_I2C_BLK_DEF, + mlxsw_i2c->block_size = min_t(u16, MLXSW_I2C_BLK_MAX, min_t(u16, quirks->max_read_len, quirks->max_write_len)); } else { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c +++ linux-6.2.0/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c @@ -249,10 +249,9 @@ } /* Helper function to create a rule of a specific size */ -static struct vcap_rule * -test_vcap_xn_rule_creator(struct kunit *test, int cid, enum vcap_user user, - u16 priority, - int id, int size, int expected_addr) +static void test_vcap_xn_rule_creator(struct kunit *test, int cid, + enum vcap_user user, u16 priority, + int id, int size, int expected_addr) { struct vcap_rule *rule; struct vcap_rule_internal *ri; @@ -317,7 +316,7 @@ ret = vcap_add_rule(rule); KUNIT_EXPECT_EQ(test, 0, ret); KUNIT_EXPECT_EQ(test, expected_addr, ri->addr); - return rule; + vcap_free_rule(rule); } /* Prepare testing rule deletion */ @@ -1001,6 +1000,16 @@ KUNIT_EXPECT_EQ(test, (u32)0x00000000, actwords[11]); } +static void vcap_free_ckf(struct vcap_rule *rule) +{ + struct vcap_client_keyfield *ckf, *next_ckf; + + list_for_each_entry_safe(ckf, next_ckf, &rule->keyfields, ctrl.list) { + list_del(&ckf->ctrl.list); + kfree(ckf); + } +} + static void vcap_api_rule_add_keyvalue_test(struct kunit *test) { struct vcap_admin admin = { @@ -1033,6 +1042,7 @@ KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.value); KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.mask); + vcap_free_ckf(rule); INIT_LIST_HEAD(&rule->keyfields); ret = vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, VCAP_BIT_1); @@ -1045,6 +1055,7 @@ KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.value); KUNIT_EXPECT_EQ(test, 0x1, kf->data.u1.mask); + vcap_free_ckf(rule); INIT_LIST_HEAD(&rule->keyfields); ret = vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS, @@ -1058,6 +1069,7 @@ KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, kf->ctrl.type); KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.value); KUNIT_EXPECT_EQ(test, 0x0, kf->data.u1.mask); + vcap_free_ckf(rule); INIT_LIST_HEAD(&rule->keyfields); ret = vcap_rule_add_key_u32(rule, VCAP_KF_TYPE, 0x98765432, 0xff00ffab); @@ -1070,6 +1082,7 @@ KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, kf->ctrl.type); KUNIT_EXPECT_EQ(test, 0x98765432, kf->data.u32.value); KUNIT_EXPECT_EQ(test, 0xff00ffab, kf->data.u32.mask); + vcap_free_ckf(rule); INIT_LIST_HEAD(&rule->keyfields); ret = vcap_rule_add_key_u128(rule, VCAP_KF_L3_IP6_SIP, &dip); @@ -1084,6 +1097,18 @@ KUNIT_EXPECT_EQ(test, dip.value[idx], kf->data.u128.value[idx]); for (idx = 0; idx < ARRAY_SIZE(dip.mask); ++idx) KUNIT_EXPECT_EQ(test, dip.mask[idx], kf->data.u128.mask[idx]); + vcap_free_ckf(rule); +} + +static void vcap_free_caf(struct vcap_rule *rule) +{ + struct vcap_client_actionfield *caf, *next_caf; + + list_for_each_entry_safe(caf, next_caf, + &rule->actionfields, ctrl.list) { + list_del(&caf->ctrl.list); + kfree(caf); + } } static void vcap_api_rule_add_actionvalue_test(struct kunit *test) @@ -1111,6 +1136,7 @@ KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); KUNIT_EXPECT_EQ(test, 0x0, af->data.u1.value); + vcap_free_caf(rule); INIT_LIST_HEAD(&rule->actionfields); ret = vcap_rule_add_action_bit(rule, VCAP_AF_POLICE_ENA, VCAP_BIT_1); @@ -1122,6 +1148,7 @@ KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); KUNIT_EXPECT_EQ(test, 0x1, af->data.u1.value); + vcap_free_caf(rule); INIT_LIST_HEAD(&rule->actionfields); ret = vcap_rule_add_action_bit(rule, VCAP_AF_POLICE_ENA, VCAP_BIT_ANY); @@ -1133,6 +1160,7 @@ KUNIT_EXPECT_EQ(test, VCAP_AF_POLICE_ENA, af->ctrl.action); KUNIT_EXPECT_EQ(test, VCAP_FIELD_BIT, af->ctrl.type); KUNIT_EXPECT_EQ(test, 0x0, af->data.u1.value); + vcap_free_caf(rule); INIT_LIST_HEAD(&rule->actionfields); ret = vcap_rule_add_action_u32(rule, VCAP_AF_TYPE, 0x98765432); @@ -1144,6 +1172,7 @@ KUNIT_EXPECT_EQ(test, VCAP_AF_TYPE, af->ctrl.action); KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, af->ctrl.type); KUNIT_EXPECT_EQ(test, 0x98765432, af->data.u32.value); + vcap_free_caf(rule); INIT_LIST_HEAD(&rule->actionfields); ret = vcap_rule_add_action_u32(rule, VCAP_AF_MASK_MODE, 0xaabbccdd); @@ -1155,6 +1184,7 @@ KUNIT_EXPECT_EQ(test, VCAP_AF_MASK_MODE, af->ctrl.action); KUNIT_EXPECT_EQ(test, VCAP_FIELD_U32, af->ctrl.type); KUNIT_EXPECT_EQ(test, 0xaabbccdd, af->data.u32.value); + vcap_free_caf(rule); } static void vcap_api_rule_find_keyset_basic_test(struct kunit *test) @@ -1409,6 +1439,10 @@ ret = list_empty(&is2_admin.rules); KUNIT_EXPECT_EQ(test, false, ret); KUNIT_EXPECT_EQ(test, 0, ret); + + vcap_enable_lookups(&test_vctrl, &test_netdev, 0, 0, + rule->cookie, false); + vcap_free_rule(rule); /* Check that the rule has been freed: tricky to access since this @@ -1419,6 +1453,8 @@ KUNIT_EXPECT_EQ(test, true, ret); ret = list_empty(&rule->actionfields); KUNIT_EXPECT_EQ(test, true, ret); + + vcap_del_rule(&test_vctrl, &test_netdev, id); } static void vcap_api_set_rule_counter_test(struct kunit *test) @@ -1562,6 +1598,11 @@ test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774); test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771); test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768); + + vcap_del_rule(&test_vctrl, &test_netdev, 200); + vcap_del_rule(&test_vctrl, &test_netdev, 300); + vcap_del_rule(&test_vctrl, &test_netdev, 400); + vcap_del_rule(&test_vctrl, &test_netdev, 500); } static void vcap_api_rule_insert_reverse_order_test(struct kunit *test) @@ -1620,6 +1661,11 @@ ++idx; } KUNIT_EXPECT_EQ(test, 768, admin.last_used_addr); + + vcap_del_rule(&test_vctrl, &test_netdev, 500); + vcap_del_rule(&test_vctrl, &test_netdev, 400); + vcap_del_rule(&test_vctrl, &test_netdev, 300); + vcap_del_rule(&test_vctrl, &test_netdev, 200); } static void vcap_api_rule_remove_at_end_test(struct kunit *test) @@ -1820,6 +1866,9 @@ KUNIT_EXPECT_EQ(test, 786, test_init_start); KUNIT_EXPECT_EQ(test, 8, test_init_count); KUNIT_EXPECT_EQ(test, 794, admin.last_used_addr); + + vcap_del_rule(&test_vctrl, &test_netdev, 200); + vcap_del_rule(&test_vctrl, &test_netdev, 300); } static struct kunit_case vcap_api_rule_remove_test_cases[] = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/pensando/ionic/ionic_dev.h +++ linux-6.2.0/drivers/net/ethernet/pensando/ionic/ionic_dev.h @@ -182,6 +182,7 @@ struct ionic_desc_info *desc_info, struct ionic_cq_info *cq_info, void *cb_arg); +#define IONIC_MAX_BUF_LEN ((u16)-1) #define IONIC_PAGE_SIZE PAGE_SIZE #define IONIC_PAGE_SPLIT_SZ (PAGE_SIZE / 2) #define IONIC_PAGE_GFP_MASK (GFP_ATOMIC | __GFP_NOWARN |\ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +++ linux-6.2.0/drivers/net/ethernet/pensando/ionic/ionic_txrx.c @@ -207,7 +207,8 @@ return NULL; } - frag_len = min_t(u16, len, IONIC_PAGE_SIZE - buf_info->page_offset); + frag_len = min_t(u16, len, min_t(u32, IONIC_MAX_BUF_LEN, + IONIC_PAGE_SIZE - buf_info->page_offset)); len -= frag_len; dma_sync_single_for_cpu(dev, @@ -444,7 +445,8 @@ /* fill main descriptor - buf[0] */ desc->addr = cpu_to_le64(buf_info->dma_addr + buf_info->page_offset); - frag_len = min_t(u16, len, IONIC_PAGE_SIZE - buf_info->page_offset); + frag_len = min_t(u16, len, min_t(u32, IONIC_MAX_BUF_LEN, + IONIC_PAGE_SIZE - buf_info->page_offset)); desc->len = cpu_to_le16(frag_len); remain_len -= frag_len; buf_info++; @@ -463,7 +465,9 @@ } sg_elem->addr = cpu_to_le64(buf_info->dma_addr + buf_info->page_offset); - frag_len = min_t(u16, remain_len, IONIC_PAGE_SIZE - buf_info->page_offset); + frag_len = min_t(u16, remain_len, min_t(u32, IONIC_MAX_BUF_LEN, + IONIC_PAGE_SIZE - + buf_info->page_offset)); sg_elem->len = cpu_to_le16(frag_len); remain_len -= frag_len; buf_info++; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/qlogic/qed/qed_ll2.h +++ linux-6.2.0/drivers/net/ethernet/qlogic/qed/qed_ll2.h @@ -110,9 +110,9 @@ enum core_tx_dest tx_dest; u8 tx_stats_en; bool main_func_queue; + struct qed_ll2_cbs cbs; struct qed_ll2_rx_queue rx_queue; struct qed_ll2_tx_queue tx_queue; - struct qed_ll2_cbs cbs; }; extern const struct qed_ll2_ops qed_ll2_ops_pass; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/sfc/ptp.c +++ linux-6.2.0/drivers/net/ethernet/sfc/ptp.c @@ -1387,7 +1387,8 @@ goto fail; rc = efx_ptp_insert_eth_filter(efx); - if (rc < 0) + /* Not all firmware variants support this filter */ + if (rc < 0 && rc != -EPROTONOSUPPORT) goto fail; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c +++ linux-6.2.0/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c @@ -105,6 +105,7 @@ int (*parse_data)(struct stm32_dwmac *dwmac, struct device *dev); u32 syscfg_eth_mask; + bool clk_rx_enable_in_suspend; }; static int stm32_dwmac_init(struct plat_stmmacenet_data *plat_dat) @@ -122,7 +123,8 @@ if (ret) return ret; - if (!dwmac->dev->power.is_suspended) { + if (!dwmac->ops->clk_rx_enable_in_suspend || + !dwmac->dev->power.is_suspended) { ret = clk_prepare_enable(dwmac->clk_rx); if (ret) { clk_disable_unprepare(dwmac->clk_tx); @@ -515,7 +517,8 @@ .suspend = stm32mp1_suspend, .resume = stm32mp1_resume, .parse_data = stm32mp1_parse_data, - .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK + .syscfg_eth_mask = SYSCFG_MP1_ETH_MASK, + .clk_rx_enable_in_suspend = true }; static const struct of_device_id stm32_dwmac_match[] = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/phy/sfp-bus.c +++ linux-6.2.0/drivers/net/phy/sfp-bus.c @@ -254,6 +254,16 @@ switch (id->base.extended_cc) { case SFF8024_ECC_UNSPEC: break; + case SFF8024_ECC_100G_25GAUI_C2M_AOC: + if (br_min <= 28000 && br_max >= 25000) { + /* 25GBASE-R, possibly with FEC */ + __set_bit(PHY_INTERFACE_MODE_25GBASER, interfaces); + /* There is currently no link mode for 25000base + * with unspecified range, reuse SR. + */ + phylink_set(modes, 25000baseSR_Full); + } + break; case SFF8024_ECC_100GBASE_SR4_25GBASE_SR: phylink_set(modes, 100000baseSR4_Full); phylink_set(modes, 25000baseSR_Full); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/thunderbolt.c +++ linux-6.2.0/drivers/net/thunderbolt.c @@ -1005,12 +1005,11 @@ *tucso = ~csum_tcpudp_magic(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, 0, ip_hdr(skb)->protocol, 0); - } else if (skb_is_gso_v6(skb)) { + } else if (skb_is_gso(skb) && skb_is_gso_v6(skb)) { tucso = dest + ((void *)&(tcp_hdr(skb)->check) - data); *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 0, IPPROTO_TCP, 0); - return false; } else if (protocol == htons(ETH_P_IPV6)) { tucso = dest + skb_checksum_start_offset(skb) + skb->csum_offset; *tucso = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/vrf.c +++ linux-6.2.0/drivers/net/vrf.c @@ -664,7 +664,7 @@ skb->protocol = htons(ETH_P_IPV6); skb->dev = dev; - rcu_read_lock_bh(); + rcu_read_lock(); nexthop = rt6_nexthop((struct rt6_info *)dst, &ipv6_hdr(skb)->daddr); neigh = __ipv6_neigh_lookup_noref(dst->dev, nexthop); if (unlikely(!neigh)) @@ -672,10 +672,10 @@ if (!IS_ERR(neigh)) { sock_confirm_neigh(skb, neigh); ret = neigh_output(neigh, skb, false); - rcu_read_unlock_bh(); + rcu_read_unlock(); return ret; } - rcu_read_unlock_bh(); + rcu_read_unlock(); IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); @@ -889,7 +889,7 @@ } } - rcu_read_lock_bh(); + rcu_read_lock(); neigh = ip_neigh_for_gw(rt, skb, &is_v6gw); if (!IS_ERR(neigh)) { @@ -898,11 +898,11 @@ sock_confirm_neigh(skb, neigh); /* if crossing protocols, can not use the cached header */ ret = neigh_output(neigh, skb, is_v6gw); - rcu_read_unlock_bh(); + rcu_read_unlock(); return ret; } - rcu_read_unlock_bh(); + rcu_read_unlock(); vrf_tx_error(skb->dev, skb); return -EINVAL; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wan/fsl_ucc_hdlc.c +++ linux-6.2.0/drivers/net/wan/fsl_ucc_hdlc.c @@ -34,6 +34,8 @@ #define TDM_PPPOHT_SLIC_MAXIN #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S) +static int uhdlc_close(struct net_device *dev); + static struct ucc_tdm_info utdm_primary_info = { .uf_info = { .tsa = 0, @@ -708,6 +710,7 @@ hdlc_device *hdlc = dev_to_hdlc(dev); struct ucc_hdlc_private *priv = hdlc->priv; struct ucc_tdm *utdm = priv->utdm; + int rc = 0; if (priv->hdlc_busy != 1) { if (request_irq(priv->ut_info->uf_info.irq, @@ -731,10 +734,13 @@ napi_enable(&priv->napi); netdev_reset_queue(dev); netif_start_queue(dev); - hdlc_open(dev); + + rc = hdlc_open(dev); + if (rc) + uhdlc_close(dev); } - return 0; + return rc; } static void uhdlc_memclean(struct ucc_hdlc_private *priv) @@ -824,6 +830,8 @@ netdev_reset_queue(dev); priv->hdlc_busy = 0; + hdlc_close(dev); + return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/ath10k/pci.c +++ linux-6.2.0/drivers/net/wireless/ath/ath10k/pci.c @@ -1963,8 +1963,9 @@ ath10k_pci_irq_enable(ar); ath10k_pci_rx_post(ar); - pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL, - ar_pci->link_ctl); + pcie_capability_clear_and_set_word(ar_pci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_ASPMC, + ar_pci->link_ctl & PCI_EXP_LNKCTL_ASPMC); return 0; } @@ -2821,8 +2822,8 @@ pcie_capability_read_word(ar_pci->pdev, PCI_EXP_LNKCTL, &ar_pci->link_ctl); - pcie_capability_write_word(ar_pci->pdev, PCI_EXP_LNKCTL, - ar_pci->link_ctl & ~PCI_EXP_LNKCTL_ASPMC); + pcie_capability_clear_word(ar_pci->pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_ASPMC); /* * Bring the target up cleanly. only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/ath11k/dp.h +++ linux-6.2.0/drivers/net/wireless/ath/ath11k/dp.h @@ -303,12 +303,16 @@ #define HTT_TX_WBM_COMP_STATUS_OFFSET 8 +#define HTT_INVALID_PEER_ID 0xffff + /* HTT tx completion is overlaid in wbm_release_ring */ #define HTT_TX_WBM_COMP_INFO0_STATUS GENMASK(12, 9) #define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON GENMASK(16, 13) #define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON GENMASK(16, 13) #define HTT_TX_WBM_COMP_INFO1_ACK_RSSI GENMASK(31, 24) +#define HTT_TX_WBM_COMP_INFO2_SW_PEER_ID GENMASK(15, 0) +#define HTT_TX_WBM_COMP_INFO2_VALID BIT(21) struct htt_tx_wbm_completion { u32 info0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/ath11k/dp_tx.c +++ linux-6.2.0/drivers/net/wireless/ath/ath11k/dp_tx.c @@ -316,10 +316,12 @@ struct dp_tx_ring *tx_ring, struct ath11k_dp_htt_wbm_tx_status *ts) { + struct ieee80211_tx_status status = { 0 }; struct sk_buff *msdu; struct ieee80211_tx_info *info; struct ath11k_skb_cb *skb_cb; struct ath11k *ar; + struct ath11k_peer *peer; spin_lock(&tx_ring->tx_idr_lock); msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id); @@ -341,6 +343,11 @@ dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); + if (!skb_cb->vif) { + ieee80211_free_txskb(ar->hw, msdu); + return; + } + memset(&info->status, 0, sizeof(info->status)); if (ts->acked) { @@ -355,7 +362,23 @@ } } - ieee80211_tx_status(ar->hw, msdu); + spin_lock_bh(&ab->base_lock); + peer = ath11k_peer_find_by_id(ab, ts->peer_id); + if (!peer || !peer->sta) { + ath11k_dbg(ab, ATH11K_DBG_DATA, + "dp_tx: failed to find the peer with peer_id %d\n", + ts->peer_id); + spin_unlock_bh(&ab->base_lock); + ieee80211_free_txskb(ar->hw, msdu); + return; + } + spin_unlock_bh(&ab->base_lock); + + status.sta = peer->sta; + status.info = info; + status.skb = msdu; + + ieee80211_tx_status_ext(ar->hw, &status); } static void @@ -379,7 +402,15 @@ ts.msdu_id = msdu_id; ts.ack_rssi = FIELD_GET(HTT_TX_WBM_COMP_INFO1_ACK_RSSI, status_desc->info1); + + if (FIELD_GET(HTT_TX_WBM_COMP_INFO2_VALID, status_desc->info2)) + ts.peer_id = FIELD_GET(HTT_TX_WBM_COMP_INFO2_SW_PEER_ID, + status_desc->info2); + else + ts.peer_id = HTT_INVALID_PEER_ID; + ath11k_dp_tx_htt_tx_complete_buf(ab, tx_ring, &ts); + break; case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ: case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT: @@ -535,12 +566,12 @@ dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); if (unlikely(!rcu_access_pointer(ab->pdevs_active[ar->pdev_idx]))) { - dev_kfree_skb_any(msdu); + ieee80211_free_txskb(ar->hw, msdu); return; } if (unlikely(!skb_cb->vif)) { - dev_kfree_skb_any(msdu); + ieee80211_free_txskb(ar->hw, msdu); return; } @@ -593,7 +624,7 @@ "dp_tx: failed to find the peer with peer_id %d\n", ts->peer_id); spin_unlock_bh(&ab->base_lock); - dev_kfree_skb_any(msdu); + ieee80211_free_txskb(ar->hw, msdu); return; } arsta = (struct ath11k_sta *)peer->sta->drv_priv; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/ath11k/dp_tx.h +++ linux-6.2.0/drivers/net/wireless/ath/ath11k/dp_tx.h @@ -13,6 +13,7 @@ u32 msdu_id; bool acked; int ack_rssi; + u16 peer_id; }; void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/ath6kl/Makefile +++ linux-6.2.0/drivers/net/wireless/ath/ath6kl/Makefile @@ -36,11 +36,6 @@ ath6kl_core-y += core.o ath6kl_core-y += recovery.o -# FIXME: temporarily silence -Wdangling-pointer on non W=1+ builds -ifndef KBUILD_EXTRA_WARN -CFLAGS_htc_mbox.o += $(call cc-disable-warning, dangling-pointer) -endif - ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o ath6kl_core-$(CONFIG_ATH6KL_TRACING) += trace.o only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/ath9k/ahb.c +++ linux-6.2.0/drivers/net/wireless/ath/ath9k/ahb.c @@ -132,8 +132,8 @@ ah = sc->sc_ah; ath9k_hw_name(ah, hw_name, sizeof(hw_name)); - wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", - hw_name, (unsigned long)mem, irq); + wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n", + hw_name, mem, irq); return 0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ linux-6.2.0/drivers/net/wireless/ath/ath9k/htc_drv_debug.c @@ -491,7 +491,7 @@ priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME, priv->hw->wiphy->debugfsdir); - if (!priv->debug.debugfs_phy) + if (IS_ERR(priv->debug.debugfs_phy)) return -ENOMEM; ath9k_cmn_spectral_init_debug(&priv->spec_priv, priv->debug.debugfs_phy); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/ath9k/mac.h +++ linux-6.2.0/drivers/net/wireless/ath/ath9k/mac.h @@ -115,8 +115,10 @@ u8 qid; u16 desc_id; u8 tid; - u32 ba_low; - u32 ba_high; + struct_group(ba, + u32 ba_low; + u32 ba_high; + ); u32 evm0; u32 evm1; u32 evm2; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/ath9k/pci.c +++ linux-6.2.0/drivers/net/wireless/ath/ath9k/pci.c @@ -988,8 +988,8 @@ sc->sc_ah->msi_reg = 0; ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); - wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", - hw_name, (unsigned long)sc->mem, pdev->irq); + wiphy_info(hw->wiphy, "%s mem=0x%p, irq=%d\n", + hw_name, sc->mem, pdev->irq); return 0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/ath9k/xmit.c +++ linux-6.2.0/drivers/net/wireless/ath/ath9k/xmit.c @@ -462,7 +462,7 @@ isaggr = bf_isaggr(bf); if (isaggr) { seq_st = ts->ts_seqnum; - memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); + memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3); } while (bf) { @@ -545,7 +545,7 @@ if (isaggr && txok) { if (ts->ts_flags & ATH9K_TX_BA) { seq_st = ts->ts_seqnum; - memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); + memcpy(ba, &ts->ba, WME_BA_BMP_SIZE >> 3); } else { /* * AR5416 can become deaf/mute when BA only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/wil6210/txrx.c +++ linux-6.2.0/drivers/net/wireless/ath/wil6210/txrx.c @@ -666,7 +666,7 @@ struct wil_tid_crypto_rx *c = mc ? &s->group_crypto_rx : &s->tid_crypto_rx[tid]; struct wil_tid_crypto_rx_single *cc = &c->key_id[key_id]; - const u8 *pn = (u8 *)&d->mac.pn_15_0; + const u8 *pn = (u8 *)&d->mac.pn; if (!cc->key_set) { wil_err_ratelimited(wil, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/wil6210/txrx.h +++ linux-6.2.0/drivers/net/wireless/ath/wil6210/txrx.h @@ -343,8 +343,10 @@ u32 d0; u32 d1; u16 w4; - u16 pn_15_0; - u32 pn_47_16; + struct_group_attr(pn, __packed, + u16 pn_15_0; + u32 pn_47_16; + ); } __packed; /* Rx descriptor - DMA part only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ linux-6.2.0/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -548,7 +548,7 @@ s = &wil->sta[cid]; c = mc ? &s->group_crypto_rx : &s->tid_crypto_rx[tid]; cc = &c->key_id[key_id]; - pn = (u8 *)&st->ext.pn_15_0; + pn = (u8 *)&st->ext.pn; if (!cc->key_set) { wil_err_ratelimited(wil, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/ath/wil6210/txrx_edma.h +++ linux-6.2.0/drivers/net/wireless/ath/wil6210/txrx_edma.h @@ -330,8 +330,10 @@ u32 d0; u32 d1; __le16 seq_num; /* only lower 12 bits */ - u16 pn_15_0; - u32 pn_47_16; + struct_group_attr(pn, __packed, + u16 pn_15_0; + u32 pn_47_16; + ); } __packed; struct wil_rx_status_extended { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h +++ linux-6.2.0/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h @@ -383,7 +383,12 @@ * fixed parameter portion is assumed, otherwise * ssid in the fixed portion is ignored */ - __le16 channel_list[1]; /* list of chanspecs */ + union { + __le16 padding; /* Reserve space for at least 1 entry for abort + * which uses an on stack brcmf_scan_params_le + */ + DECLARE_FLEX_ARRAY(__le16, channel_list); /* chanspecs */ + }; }; struct brcmf_scan_results { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h +++ linux-6.2.0/drivers/net/wireless/intel/iwlwifi/fw/error-dump.h @@ -295,9 +295,9 @@ struct iwl_fw_ini_error_dump_range { __le32 range_data_size; union { - __le32 internal_base_addr; - __le64 dram_base_addr; - __le32 page_num; + __le32 internal_base_addr __packed; + __le64 dram_base_addr __packed; + __le32 page_num __packed; struct iwl_fw_ini_fifo_hdr fifo_hdr; struct iwl_cmd_header fw_pkt_hdr; }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +++ linux-6.2.0/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c @@ -965,8 +965,8 @@ } } - tlv_buf_left -= (sizeof(*tlv_rxba) + tlv_len); - tmp = (u8 *)tlv_rxba + tlv_len + sizeof(*tlv_rxba); + tlv_buf_left -= (sizeof(tlv_rxba->header) + tlv_len); + tmp = (u8 *)tlv_rxba + sizeof(tlv_rxba->header) + tlv_len; tlv_rxba = (struct mwifiex_ie_types_rxba_sync *)tmp; } } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/marvell/mwifiex/debugfs.c +++ linux-6.2.0/drivers/net/wireless/marvell/mwifiex/debugfs.c @@ -253,8 +253,11 @@ if (!p) return -ENOMEM; - if (!priv || !priv->hist_data) - return -EFAULT; + if (!priv || !priv->hist_data) { + ret = -EFAULT; + goto free_and_exit; + } + phist_data = priv->hist_data; p += sprintf(p, "\n" @@ -309,6 +312,8 @@ ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page, (unsigned long)p - page); +free_and_exit: + free_page(page); return ret; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/marvell/mwifiex/sta_rx.c +++ linux-6.2.0/drivers/net/wireless/marvell/mwifiex/sta_rx.c @@ -86,12 +86,23 @@ rx_pkt_len = le16_to_cpu(local_rx_pd->rx_pkt_length); rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_off; - if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, - sizeof(bridge_tunnel_header))) || - (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, - sizeof(rfc1042_header)) && - ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP && - ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX)) { + if (sizeof(rx_pkt_hdr->eth803_hdr) + sizeof(rfc1042_header) + + rx_pkt_off > skb->len) { + mwifiex_dbg(priv->adapter, ERROR, + "wrong rx packet offset: len=%d, rx_pkt_off=%d\n", + skb->len, rx_pkt_off); + priv->stats.rx_dropped++; + dev_kfree_skb_any(skb); + return -1; + } + + if (sizeof(*rx_pkt_hdr) + rx_pkt_off <= skb->len && + ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, + sizeof(bridge_tunnel_header))) || + (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, + sizeof(rfc1042_header)) && + ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_AARP && + ntohs(rx_pkt_hdr->rfc1042_hdr.snap_type) != ETH_P_IPX))) { /* * Replace the 803 header and rfc1042 header (llc/snap) with an * EthernetII header, keep the src/dst and snap_type @@ -194,7 +205,8 @@ rx_pkt_hdr = (void *)local_rx_pd + rx_pkt_offset; - if ((rx_pkt_offset + rx_pkt_length) > (u16) skb->len) { + if ((rx_pkt_offset + rx_pkt_length) > skb->len || + sizeof(rx_pkt_hdr->eth803_hdr) + rx_pkt_offset > skb->len) { mwifiex_dbg(adapter, ERROR, "wrong rx packet: len=%d, rx_pkt_offset=%d, rx_pkt_length=%d\n", skb->len, rx_pkt_offset, rx_pkt_length); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/marvell/mwifiex/tdls.c +++ linux-6.2.0/drivers/net/wireless/marvell/mwifiex/tdls.c @@ -735,6 +735,7 @@ int ret; u16 capab; struct ieee80211_ht_cap *ht_cap; + unsigned int extra; u8 radio, *pos; capab = priv->curr_bss_params.bss_descriptor.cap_info_bitmap; @@ -753,7 +754,10 @@ switch (action_code) { case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: - skb_put(skb, sizeof(mgmt->u.action.u.tdls_discover_resp) + 1); + /* See the layout of 'struct ieee80211_mgmt'. */ + extra = sizeof(mgmt->u.action.u.tdls_discover_resp) + + sizeof(mgmt->u.action.category); + skb_put(skb, extra); mgmt->u.action.category = WLAN_CATEGORY_PUBLIC; mgmt->u.action.u.tdls_discover_resp.action_code = WLAN_PUB_ACTION_TDLS_DISCOVER_RES; @@ -762,8 +766,7 @@ mgmt->u.action.u.tdls_discover_resp.capability = cpu_to_le16(capab); /* move back for addr4 */ - memmove(pos + ETH_ALEN, &mgmt->u.action.category, - sizeof(mgmt->u.action.u.tdls_discover_resp)); + memmove(pos + ETH_ALEN, &mgmt->u.action, extra); /* init address 4 */ eth_broadcast_addr(pos); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/marvell/mwifiex/uap_txrx.c +++ linux-6.2.0/drivers/net/wireless/marvell/mwifiex/uap_txrx.c @@ -103,6 +103,16 @@ return; } + if (sizeof(*rx_pkt_hdr) + + le16_to_cpu(uap_rx_pd->rx_pkt_offset) > skb->len) { + mwifiex_dbg(adapter, ERROR, + "wrong rx packet offset: len=%d,rx_pkt_offset=%d\n", + skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset)); + priv->stats.rx_dropped++; + dev_kfree_skb_any(skb); + return; + } + if ((!memcmp(&rx_pkt_hdr->rfc1042_hdr, bridge_tunnel_header, sizeof(bridge_tunnel_header))) || (!memcmp(&rx_pkt_hdr->rfc1042_hdr, rfc1042_header, @@ -243,7 +253,15 @@ if (is_multicast_ether_addr(ra)) { skb_uap = skb_copy(skb, GFP_ATOMIC); - mwifiex_uap_queue_bridged_pkt(priv, skb_uap); + if (likely(skb_uap)) { + mwifiex_uap_queue_bridged_pkt(priv, skb_uap); + } else { + mwifiex_dbg(adapter, ERROR, + "failed to copy skb for uAP\n"); + priv->stats.rx_dropped++; + dev_kfree_skb_any(skb); + return -1; + } } else { if (mwifiex_get_sta_entry(priv, ra)) { /* Requeue Intra-BSS packet */ @@ -367,6 +385,16 @@ rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type); rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); + if (le16_to_cpu(uap_rx_pd->rx_pkt_offset) + + sizeof(rx_pkt_hdr->eth803_hdr) > skb->len) { + mwifiex_dbg(adapter, ERROR, + "wrong rx packet for struct ethhdr: len=%d, offset=%d\n", + skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset)); + priv->stats.rx_dropped++; + dev_kfree_skb_any(skb); + return 0; + } + ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source); if ((le16_to_cpu(uap_rx_pd->rx_pkt_offset) + only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/marvell/mwifiex/util.c +++ linux-6.2.0/drivers/net/wireless/marvell/mwifiex/util.c @@ -393,11 +393,15 @@ } rx_pd = (struct rxpd *)skb->data; + pkt_len = le16_to_cpu(rx_pd->rx_pkt_length); + if (pkt_len < sizeof(struct ieee80211_hdr) + sizeof(pkt_len)) { + mwifiex_dbg(priv->adapter, ERROR, "invalid rx_pkt_length"); + return -1; + } skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset)); skb_pull(skb, sizeof(pkt_len)); - - pkt_len = le16_to_cpu(rx_pd->rx_pkt_length); + pkt_len -= sizeof(pkt_len); ieee_hdr = (void *)skb->data; if (ieee80211_is_mgmt(ieee_hdr->frame_control)) { @@ -410,7 +414,7 @@ skb->data + sizeof(struct ieee80211_hdr), pkt_len - sizeof(struct ieee80211_hdr)); - pkt_len -= ETH_ALEN + sizeof(pkt_len); + pkt_len -= ETH_ALEN; rx_pd->rx_pkt_length = cpu_to_le16(pkt_len); cfg80211_rx_mgmt(&priv->wdev, priv->roc_cfg.chan.center_freq, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76x02_eeprom.c @@ -131,15 +131,8 @@ s8 *lna_2g, s8 *lna_5g, struct ieee80211_channel *chan) { - u16 val; u8 lna; - val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1); - if (val & MT_EE_NIC_CONF_1_LNA_EXT_2G) - *lna_2g = 0; - if (val & MT_EE_NIC_CONF_1_LNA_EXT_5G) - memset(lna_5g, 0, sizeof(s8) * 3); - if (chan->band == NL80211_BAND_2GHZ) lna = *lna_2g; else if (chan->hw_value <= 64) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt76x2/eeprom.c @@ -256,7 +256,8 @@ struct ieee80211_channel *chan = dev->mphy.chandef.chan; int channel = chan->hw_value; s8 lna_5g[3], lna_2g; - u8 lna; + bool use_lna; + u8 lna = 0; u16 val; if (chan->band == NL80211_BAND_2GHZ) @@ -275,7 +276,15 @@ dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16; dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24; - lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); + val = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_1); + if (chan->band == NL80211_BAND_2GHZ) + use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_2G); + else + use_lna = !(val & MT_EE_NIC_CONF_1_LNA_EXT_5G); + + if (use_lna) + lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); + dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8); } EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/mediatek/mt76/mt7921/mac.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7921/mac.c @@ -1159,6 +1159,10 @@ if (unlikely(tx_info->skb->len <= ETH_HLEN)) return -EINVAL; + err = skb_cow_head(skb, MT_SDIO_TXD_SIZE + MT_SDIO_HDR_SIZE); + if (err) + return err; + if (!wcid) wcid = &dev->mt76.global_wcid; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/mediatek/mt76/mt7996/dma.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/mt7996/dma.c @@ -293,7 +293,7 @@ /* event from WA */ ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA], MT_RXQ_ID(MT_RXQ_MCU_WA), - MT7996_RX_MCU_RING_SIZE, + MT7996_RX_MCU_RING_SIZE_WA, MT_RX_BUF_SIZE, MT_RXQ_RING_BASE(MT_RXQ_MCU_WA)); if (ret) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/mediatek/mt76/testmode.c +++ linux-6.2.0/drivers/net/wireless/mediatek/mt76/testmode.c @@ -8,6 +8,7 @@ [MT76_TM_ATTR_RESET] = { .type = NLA_FLAG }, [MT76_TM_ATTR_STATE] = { .type = NLA_U8 }, [MT76_TM_ATTR_TX_COUNT] = { .type = NLA_U32 }, + [MT76_TM_ATTR_TX_LENGTH] = { .type = NLA_U32 }, [MT76_TM_ATTR_TX_RATE_MODE] = { .type = NLA_U8 }, [MT76_TM_ATTR_TX_RATE_NSS] = { .type = NLA_U8 }, [MT76_TM_ATTR_TX_RATE_IDX] = { .type = NLA_U8 }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/realtek/rtw88/rtw8723d.h +++ linux-6.2.0/drivers/net/wireless/realtek/rtw88/rtw8723d.h @@ -46,6 +46,7 @@ u8 vender_id[2]; /* 0x100 */ u8 product_id[2]; /* 0x102 */ u8 usb_option; /* 0x104 */ + u8 res5[2]; /* 0x105 */ u8 mac_addr[ETH_ALEN]; /* 0x107 */ }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c +++ linux-6.2.0/drivers/net/wireless/realtek/rtw89/rtw8852b_rfk.c @@ -846,7 +846,7 @@ case ID_NBTXK: rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x0); rtw89_phy_write32_mask(rtwdev, R_IQK_DIF4, B_IQK_DIF4_TXT, 0x011); - iqk_cmd = 0x308 | (1 << (4 + path)); + iqk_cmd = 0x408 | (1 << (4 + path)); break; case ID_NBRXK: rtw89_phy_write32_mask(rtwdev, R_P0_RFCTM, B_P0_RFCTM_EN, 0x1); @@ -1078,7 +1078,7 @@ { struct rtw89_iqk_info *iqk_info = &rtwdev->iqk; bool kfail; - u8 gp = 0x3; + u8 gp = 0x2; switch (iqk_info->iqk_band[path]) { case RTW89_BAND_2G: only in patch2: unchanged: --- linux-6.2.0.orig/drivers/nvdimm/nd_perf.c +++ linux-6.2.0/drivers/nvdimm/nd_perf.c @@ -308,8 +308,8 @@ rc = perf_pmu_register(&nd_pmu->pmu, nd_pmu->pmu.name, -1); if (rc) { - kfree(nd_pmu->pmu.attr_groups); nvdimm_pmu_free_hotplug_memory(nd_pmu); + kfree(nd_pmu->pmu.attr_groups); return rc; } @@ -324,6 +324,7 @@ { perf_pmu_unregister(&nd_pmu->pmu); nvdimm_pmu_free_hotplug_memory(nd_pmu); + kfree(nd_pmu->pmu.attr_groups); kfree(nd_pmu); } EXPORT_SYMBOL_GPL(unregister_nvdimm_pmu); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/nvme/host/fc.c +++ linux-6.2.0/drivers/nvme/host/fc.c @@ -1924,7 +1924,7 @@ struct nvme_fc_fcp_op *op = fcp_req_to_fcp_op(req); struct request *rq = op->rq; - if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq->bio) + if (!IS_ENABLED(CONFIG_BLK_CGROUP_FC_APPID) || !rq || !rq->bio) return NULL; return blkcg_get_fc_appid(rq->bio); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/nvme/target/io-cmd-file.c +++ linux-6.2.0/drivers/nvme/target/io-cmd-file.c @@ -73,13 +73,6 @@ return ret; } -static void nvmet_file_init_bvec(struct bio_vec *bv, struct scatterlist *sg) -{ - bv->bv_page = sg_page(sg); - bv->bv_offset = sg->offset; - bv->bv_len = sg->length; -} - static ssize_t nvmet_file_submit_bvec(struct nvmet_req *req, loff_t pos, unsigned long nr_segs, size_t count, int ki_flags) { @@ -146,7 +139,8 @@ memset(&req->f.iocb, 0, sizeof(struct kiocb)); for_each_sg(req->sg, sg, req->sg_cnt, i) { - nvmet_file_init_bvec(&req->f.bvec[bv_cnt], sg); + bvec_set_page(&req->f.bvec[bv_cnt], sg_page(sg), sg->length, + sg->offset); len += req->f.bvec[bv_cnt].bv_len; total_len += req->f.bvec[bv_cnt].bv_len; bv_cnt++; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/of/property.c +++ linux-6.2.0/drivers/of/property.c @@ -1062,20 +1062,6 @@ return of_device_get_match_data(dev); } -static bool of_is_ancestor_of(struct device_node *test_ancestor, - struct device_node *child) -{ - of_node_get(child); - while (child) { - if (child == test_ancestor) { - of_node_put(child); - return true; - } - child = of_get_next_parent(child); - } - return false; -} - static struct device_node *of_get_compat_node(struct device_node *np) { of_node_get(np); @@ -1106,71 +1092,27 @@ return node; } -/** - * of_link_to_phandle - Add fwnode link to supplier from supplier phandle - * @con_np: consumer device tree node - * @sup_np: supplier device tree node - * - * Given a phandle to a supplier device tree node (@sup_np), this function - * finds the device that owns the supplier device tree node and creates a - * device link from @dev consumer device to the supplier device. This function - * doesn't create device links for invalid scenarios such as trying to create a - * link with a parent device as the consumer of its child device. In such - * cases, it returns an error. - * - * Returns: - * - 0 if fwnode link successfully created to supplier - * - -EINVAL if the supplier link is invalid and should not be created - * - -ENODEV if struct device will never be create for supplier - */ -static int of_link_to_phandle(struct device_node *con_np, +static void of_link_to_phandle(struct device_node *con_np, struct device_node *sup_np) { - struct device *sup_dev; - struct device_node *tmp_np = sup_np; + struct device_node *tmp_np = of_node_get(sup_np); - /* - * Find the device node that contains the supplier phandle. It may be - * @sup_np or it may be an ancestor of @sup_np. - */ - sup_np = of_get_compat_node(sup_np); - if (!sup_np) { - pr_debug("Not linking %pOFP to %pOFP - No device\n", - con_np, tmp_np); - return -ENODEV; - } + /* Check that sup_np and its ancestors are available. */ + while (tmp_np) { + if (of_fwnode_handle(tmp_np)->dev) { + of_node_put(tmp_np); + break; + } - /* - * Don't allow linking a device node as a consumer of one of its - * descendant nodes. By definition, a child node can't be a functional - * dependency for the parent node. - */ - if (of_is_ancestor_of(con_np, sup_np)) { - pr_debug("Not linking %pOFP to %pOFP - is descendant\n", - con_np, sup_np); - of_node_put(sup_np); - return -EINVAL; - } + if (!of_device_is_available(tmp_np)) { + of_node_put(tmp_np); + return; + } - /* - * Don't create links to "early devices" that won't have struct devices - * created for them. - */ - sup_dev = get_dev_from_fwnode(&sup_np->fwnode); - if (!sup_dev && - (of_node_check_flag(sup_np, OF_POPULATED) || - sup_np->fwnode.flags & FWNODE_FLAG_NOT_DEVICE)) { - pr_debug("Not linking %pOFP to %pOFP - No struct device\n", - con_np, sup_np); - of_node_put(sup_np); - return -ENODEV; + tmp_np = of_get_next_parent(tmp_np); } - put_device(sup_dev); fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np)); - of_node_put(sup_np); - - return 0; } /** @@ -1324,6 +1266,7 @@ DEFINE_SIMPLE_PROP(resets, "resets", "#reset-cells") DEFINE_SIMPLE_PROP(leds, "leds", NULL) DEFINE_SIMPLE_PROP(backlight, "backlight", NULL) +DEFINE_SIMPLE_PROP(panel, "panel", NULL) DEFINE_SUFFIX_PROP(regulators, "-supply", NULL) DEFINE_SUFFIX_PROP(gpio, "-gpio", "#gpio-cells") @@ -1412,6 +1355,7 @@ { .parse_prop = parse_resets, }, { .parse_prop = parse_leds, }, { .parse_prop = parse_backlight, }, + { .parse_prop = parse_panel, }, { .parse_prop = parse_gpio_compat, }, { .parse_prop = parse_interrupts, }, { .parse_prop = parse_regulators, }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/parisc/iosapic.c +++ linux-6.2.0/drivers/parisc/iosapic.c @@ -202,9 +202,9 @@ static DEFINE_SPINLOCK(iosapic_lock); -static inline void iosapic_eoi(void __iomem *addr, unsigned int data) +static inline void iosapic_eoi(__le32 __iomem *addr, __le32 data) { - __raw_writel(data, addr); + __raw_writel((__force u32)data, addr); } /* only in patch2: unchanged: --- linux-6.2.0.orig/drivers/parisc/iosapic_private.h +++ linux-6.2.0/drivers/parisc/iosapic_private.h @@ -118,8 +118,8 @@ struct vector_info { struct iosapic_info *iosapic; /* I/O SAPIC this vector is on */ struct irt_entry *irte; /* IRT entry */ - u32 __iomem *eoi_addr; /* precalculate EOI reg address */ - u32 eoi_data; /* IA64: ? PA: swapped txn_data */ + __le32 __iomem *eoi_addr; /* precalculate EOI reg address */ + __le32 eoi_data; /* IA64: ? PA: swapped txn_data */ int txn_irq; /* virtual IRQ number for processor */ ulong txn_addr; /* IA64: id_eid PA: partial HPA */ u32 txn_data; /* CPU interrupt bit */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/parisc/led.c +++ linux-6.2.0/drivers/parisc/led.c @@ -56,8 +56,8 @@ static int led_type __read_mostly = -1; static unsigned char lastleds; /* LED state from most recent update */ static unsigned int led_heartbeat __read_mostly = 1; -static unsigned int led_diskio __read_mostly = 1; -static unsigned int led_lanrxtx __read_mostly = 1; +static unsigned int led_diskio __read_mostly; +static unsigned int led_lanrxtx __read_mostly; static char lcd_text[32] __read_mostly; static char lcd_text_default[32] __read_mostly; static int lcd_no_led_support __read_mostly = 0; /* KittyHawk doesn't support LED on its LCD */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/pci/access.c +++ linux-6.2.0/drivers/pci/access.c @@ -497,8 +497,8 @@ } EXPORT_SYMBOL(pcie_capability_write_dword); -int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, - u16 clear, u16 set) +int pcie_capability_clear_and_set_word_unlocked(struct pci_dev *dev, int pos, + u16 clear, u16 set) { int ret; u16 val; @@ -512,7 +512,21 @@ return ret; } -EXPORT_SYMBOL(pcie_capability_clear_and_set_word); +EXPORT_SYMBOL(pcie_capability_clear_and_set_word_unlocked); + +int pcie_capability_clear_and_set_word_locked(struct pci_dev *dev, int pos, + u16 clear, u16 set) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(&dev->pcie_cap_lock, flags); + ret = pcie_capability_clear_and_set_word_unlocked(dev, pos, clear, set); + spin_unlock_irqrestore(&dev->pcie_cap_lock, flags); + + return ret; +} +EXPORT_SYMBOL(pcie_capability_clear_and_set_word_locked); int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos, u32 clear, u32 set) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/pci/controller/dwc/pcie-fu740.c +++ linux-6.2.0/drivers/pci/controller/dwc/pcie-fu740.c @@ -299,6 +299,7 @@ pci->dev = dev; pci->ops = &dw_pcie_ops; pci->pp.ops = &fu740_pcie_host_ops; + pci->pp.num_vectors = MAX_MSI_IRQS; /* SiFive specific region: mgmt */ afp->mgmt_base = devm_platform_ioremap_resource_byname(pdev, "mgmt"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ linux-6.2.0/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -415,7 +415,7 @@ /* Gate Master AXI clock to MHI bus during L1SS */ val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); val &= ~PARF_MSTR_AXI_CLK_EN; - val = readl_relaxed(pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); + writel_relaxed(val, pcie_ep->parf + PARF_MHI_CLOCK_RESET_CTRL); dw_pcie_ep_init_notify(&pcie_ep->pci.ep); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/pci/controller/pcie-apple.c +++ linux-6.2.0/drivers/pci/controller/pcie-apple.c @@ -783,6 +783,10 @@ cfg->priv = pcie; INIT_LIST_HEAD(&pcie->ports); + ret = apple_msi_init(pcie); + if (ret) + return ret; + for_each_child_of_node(dev->of_node, of_port) { ret = apple_pcie_setup_port(pcie, of_port); if (ret) { @@ -792,7 +796,7 @@ } } - return apple_msi_init(pcie); + return 0; } static int apple_pcie_probe(struct platform_device *pdev) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/pci/controller/pcie-microchip-host.c +++ linux-6.2.0/drivers/pci/controller/pcie-microchip-host.c @@ -167,12 +167,12 @@ #define EVENT_PCIE_DLUP_EXIT 2 #define EVENT_SEC_TX_RAM_SEC_ERR 3 #define EVENT_SEC_RX_RAM_SEC_ERR 4 -#define EVENT_SEC_AXI2PCIE_RAM_SEC_ERR 5 -#define EVENT_SEC_PCIE2AXI_RAM_SEC_ERR 6 +#define EVENT_SEC_PCIE2AXI_RAM_SEC_ERR 5 +#define EVENT_SEC_AXI2PCIE_RAM_SEC_ERR 6 #define EVENT_DED_TX_RAM_DED_ERR 7 #define EVENT_DED_RX_RAM_DED_ERR 8 -#define EVENT_DED_AXI2PCIE_RAM_DED_ERR 9 -#define EVENT_DED_PCIE2AXI_RAM_DED_ERR 10 +#define EVENT_DED_PCIE2AXI_RAM_DED_ERR 9 +#define EVENT_DED_AXI2PCIE_RAM_DED_ERR 10 #define EVENT_LOCAL_DMA_END_ENGINE_0 11 #define EVENT_LOCAL_DMA_END_ENGINE_1 12 #define EVENT_LOCAL_DMA_ERROR_ENGINE_0 13 only in patch2: unchanged: --- linux-6.2.0.orig/drivers/perf/arm_smmuv3_pmu.c +++ linux-6.2.0/drivers/perf/arm_smmuv3_pmu.c @@ -115,6 +115,7 @@ #define SMMU_PMCG_PA_SHIFT 12 #define SMMU_PMCG_EVCNTR_RDONLY BIT(0) +#define SMMU_PMCG_HARDEN_DISABLE BIT(1) static int cpuhp_state_num; @@ -159,6 +160,20 @@ writel(SMMU_PMCG_CR_ENABLE, smmu_pmu->reg_base + SMMU_PMCG_CR); } +static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu, + struct perf_event *event, int idx); + +static inline void smmu_pmu_enable_quirk_hip08_09(struct pmu *pmu) +{ + struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu); + unsigned int idx; + + for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters) + smmu_pmu_apply_event_filter(smmu_pmu, smmu_pmu->events[idx], idx); + + smmu_pmu_enable(pmu); +} + static inline void smmu_pmu_disable(struct pmu *pmu) { struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu); @@ -167,6 +182,22 @@ writel(0, smmu_pmu->reg_base + SMMU_PMCG_IRQ_CTRL); } +static inline void smmu_pmu_disable_quirk_hip08_09(struct pmu *pmu) +{ + struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu); + unsigned int idx; + + /* + * The global disable of PMU sometimes fail to stop the counting. + * Harden this by writing an invalid event type to each used counter + * to forcibly stop counting. + */ + for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters) + writel(0xffff, smmu_pmu->reg_base + SMMU_PMCG_EVTYPER(idx)); + + smmu_pmu_disable(pmu); +} + static inline void smmu_pmu_counter_set_value(struct smmu_pmu *smmu_pmu, u32 idx, u64 value) { @@ -765,7 +796,10 @@ switch (model) { case IORT_SMMU_V3_PMCG_HISI_HIP08: /* HiSilicon Erratum 162001800 */ - smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY; + smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY | SMMU_PMCG_HARDEN_DISABLE; + break; + case IORT_SMMU_V3_PMCG_HISI_HIP09: + smmu_pmu->options |= SMMU_PMCG_HARDEN_DISABLE; break; } @@ -890,6 +924,16 @@ if (!dev->of_node) smmu_pmu_get_acpi_options(smmu_pmu); + /* + * For platforms suffer this quirk, the PMU disable sometimes fails to + * stop the counters. This will leads to inaccurate or error counting. + * Forcibly disable the counters with these quirk handler. + */ + if (smmu_pmu->options & SMMU_PMCG_HARDEN_DISABLE) { + smmu_pmu->pmu.pmu_enable = smmu_pmu_enable_quirk_hip08_09; + smmu_pmu->pmu.pmu_disable = smmu_pmu_disable_quirk_hip08_09; + } + /* Pick one CPU to be the preferred one to use */ smmu_pmu->on_cpu = raw_smp_processor_id(); WARN_ON(irq_set_affinity(smmu_pmu->irq, cpumask_of(smmu_pmu->on_cpu))); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/perf/fsl_imx8_ddr_perf.c +++ linux-6.2.0/drivers/perf/fsl_imx8_ddr_perf.c @@ -28,6 +28,8 @@ #define CNTL_CLEAR_MASK 0xFFFFFFFD #define CNTL_OVER_MASK 0xFFFFFFFE +#define CNTL_CP_SHIFT 16 +#define CNTL_CP_MASK (0xFF << CNTL_CP_SHIFT) #define CNTL_CSV_SHIFT 24 #define CNTL_CSV_MASK (0xFFU << CNTL_CSV_SHIFT) @@ -35,6 +37,8 @@ #define EVENT_CYCLES_COUNTER 0 #define NUM_COUNTERS 4 +/* For removing bias if cycle counter CNTL.CP is set to 0xf0 */ +#define CYCLES_COUNTER_MASK 0x0FFFFFFF #define AXI_MASKING_REVERT 0xffff0000 /* AXI_MASKING(MSB 16bits) + AXI_ID(LSB 16bits) */ #define to_ddr_pmu(p) container_of(p, struct ddr_pmu, pmu) @@ -102,6 +106,7 @@ const struct fsl_ddr_devtype_data *devtype_data; int irq; int id; + int active_counter; }; static ssize_t ddr_perf_identifier_show(struct device *dev, @@ -428,6 +433,17 @@ writel(0, pmu->base + reg); val = CNTL_EN | CNTL_CLEAR; val |= FIELD_PREP(CNTL_CSV_MASK, config); + + /* + * On i.MX8MP we need to bias the cycle counter to overflow more often. + * We do this by initializing bits [23:16] of the counter value via the + * COUNTER_CTRL Counter Parameter (CP) field. + */ + if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER_ENHANCED) { + if (counter == EVENT_CYCLES_COUNTER) + val |= FIELD_PREP(CNTL_CP_MASK, 0xf0); + } + writel(val, pmu->base + reg); } else { /* Disable counter */ @@ -467,6 +483,12 @@ int ret; new_raw_count = ddr_perf_read_counter(pmu, counter); + /* Remove the bias applied in ddr_perf_counter_enable(). */ + if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER_ENHANCED) { + if (counter == EVENT_CYCLES_COUNTER) + new_raw_count &= CYCLES_COUNTER_MASK; + } + local64_add(new_raw_count, &event->count); /* @@ -496,6 +518,10 @@ ddr_perf_counter_enable(pmu, event->attr.config, counter, true); + if (!pmu->active_counter++) + ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID, + EVENT_CYCLES_COUNTER, true); + hwc->state = 0; } @@ -550,6 +576,10 @@ ddr_perf_counter_enable(pmu, event->attr.config, counter, false); ddr_perf_event_update(event); + if (!--pmu->active_counter) + ddr_perf_counter_enable(pmu, EVENT_CYCLES_ID, + EVENT_CYCLES_COUNTER, false); + hwc->state |= PERF_HES_STOPPED; } @@ -568,25 +598,10 @@ static void ddr_perf_pmu_enable(struct pmu *pmu) { - struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu); - - /* enable cycle counter if cycle is not active event list */ - if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL) - ddr_perf_counter_enable(ddr_pmu, - EVENT_CYCLES_ID, - EVENT_CYCLES_COUNTER, - true); } static void ddr_perf_pmu_disable(struct pmu *pmu) { - struct ddr_pmu *ddr_pmu = to_ddr_pmu(pmu); - - if (ddr_pmu->events[EVENT_CYCLES_COUNTER] == NULL) - ddr_perf_counter_enable(ddr_pmu, - EVENT_CYCLES_ID, - EVENT_CYCLES_COUNTER, - false); } static int ddr_perf_init(struct ddr_pmu *pmu, void __iomem *base, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ linux-6.2.0/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c @@ -745,10 +745,12 @@ do_div(vco, (nd * (no_a == 1 ? no_b : no_a) * no_d * 2)); } - inno->pixclock = vco; - dev_dbg(inno->dev, "%s rate %lu\n", __func__, inno->pixclock); + inno->pixclock = DIV_ROUND_CLOSEST((unsigned long)vco, 1000) * 1000; - return vco; + dev_dbg(inno->dev, "%s rate %lu vco %llu\n", + __func__, inno->pixclock, vco); + + return inno->pixclock; } static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw, @@ -790,8 +792,8 @@ RK3328_PRE_PLL_POWER_DOWN); /* Configure pre-pll */ - inno_update_bits(inno, 0xa0, RK3228_PCLK_VCO_DIV_5_MASK, - RK3228_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); + inno_update_bits(inno, 0xa0, RK3328_PCLK_VCO_DIV_5_MASK, + RK3328_PCLK_VCO_DIV_5(cfg->vco_div_5_en)); inno_write(inno, 0xa1, RK3328_PRE_PLL_PRE_DIV(cfg->prediv)); val = RK3328_SPREAD_SPECTRUM_MOD_DISABLE; @@ -1021,9 +1023,10 @@ inno_write(inno, 0xac, RK3328_POST_PLL_FB_DIV_7_0(cfg->fbdiv)); if (cfg->postdiv == 1) { - inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS); inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | RK3328_POST_PLL_PRE_DIV(cfg->prediv)); + inno_write(inno, 0xaa, RK3328_POST_PLL_REFCLK_SEL_TMDS | + RK3328_POST_PLL_POWER_DOWN); } else { v = (cfg->postdiv / 2) - 1; v &= RK3328_POST_PLL_POST_DIV_MASK; @@ -1031,7 +1034,8 @@ inno_write(inno, 0xab, RK3328_POST_PLL_FB_DIV_8(cfg->fbdiv) | RK3328_POST_PLL_PRE_DIV(cfg->prediv)); inno_write(inno, 0xaa, RK3328_POST_PLL_POST_DIV_ENABLE | - RK3328_POST_PLL_REFCLK_SEL_TMDS); + RK3328_POST_PLL_REFCLK_SEL_TMDS | + RK3328_POST_PLL_POWER_DOWN); } for (v = 0; v < 14; v++) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/pinctrl/mediatek/pinctrl-mt7986.c +++ linux-6.2.0/drivers/pinctrl/mediatek/pinctrl-mt7986.c @@ -922,6 +922,10 @@ .ies_present = false, .base_names = mt7986_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names), + .bias_disable_set = mtk_pinconf_bias_disable_set, + .bias_disable_get = mtk_pinconf_bias_disable_get, + .bias_set = mtk_pinconf_bias_set, + .bias_get = mtk_pinconf_bias_get, .pull_type = mt7986_pull_type, .bias_set_combo = mtk_pinconf_bias_set_combo, .bias_get_combo = mtk_pinconf_bias_get_combo, @@ -944,6 +948,10 @@ .ies_present = false, .base_names = mt7986_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names), + .bias_disable_set = mtk_pinconf_bias_disable_set, + .bias_disable_get = mtk_pinconf_bias_disable_get, + .bias_set = mtk_pinconf_bias_set, + .bias_get = mtk_pinconf_bias_get, .pull_type = mt7986_pull_type, .bias_set_combo = mtk_pinconf_bias_set_combo, .bias_get_combo = mtk_pinconf_bias_get_combo, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/pinctrl/pinctrl-mcp23s08_spi.c +++ linux-6.2.0/drivers/pinctrl/pinctrl-mcp23s08_spi.c @@ -91,18 +91,28 @@ mcp->reg_shift = 0; mcp->chip.ngpio = 8; mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s08.%d", addr); + if (!mcp->chip.label) + return -ENOMEM; config = &mcp23x08_regmap; name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr); + if (!name) + return -ENOMEM; + break; case MCP_TYPE_S17: mcp->reg_shift = 1; mcp->chip.ngpio = 16; mcp->chip.label = devm_kasprintf(dev, GFP_KERNEL, "mcp23s17.%d", addr); + if (!mcp->chip.label) + return -ENOMEM; config = &mcp23x17_regmap; name = devm_kasprintf(dev, GFP_KERNEL, "%d", addr); + if (!name) + return -ENOMEM; + break; case MCP_TYPE_S18: only in patch2: unchanged: --- linux-6.2.0.orig/drivers/platform/chrome/chromeos_acpi.c +++ linux-6.2.0/drivers/platform/chrome/chromeos_acpi.c @@ -90,7 +90,36 @@ case ACPI_TYPE_STRING: return sysfs_emit(buf, "%s\n", element->string.pointer); case ACPI_TYPE_BUFFER: - return sysfs_emit(buf, "%s\n", element->buffer.pointer); + { + int i, r, at, room_left; + const int byte_per_line = 16; + + at = 0; + room_left = PAGE_SIZE - 1; + for (i = 0; i < element->buffer.length && room_left; i += byte_per_line) { + r = hex_dump_to_buffer(element->buffer.pointer + i, + element->buffer.length - i, + byte_per_line, 1, buf + at, room_left, + false); + if (r > room_left) + goto truncating; + at += r; + room_left -= r; + + r = sysfs_emit_at(buf, at, "\n"); + if (!r) + goto truncating; + at += r; + room_left -= r; + } + + buf[at] = 0; + return at; +truncating: + dev_info_once(dev, "truncating sysfs content for %s\n", name); + sysfs_emit_at(buf, PAGE_SIZE - 4, "..\n"); + return PAGE_SIZE - 1; + } default: dev_err(dev, "element type %d not supported\n", element->type); return -EINVAL; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c +++ linux-6.2.0/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c @@ -396,6 +396,7 @@ struct kobject *attr_name_kobj; //individual attribute names union acpi_object *obj = NULL; union acpi_object *elements; + struct kobject *duplicate; struct kset *tmp_set; int min_elements; @@ -454,9 +455,11 @@ else tmp_set = wmi_priv.main_dir_kset; - if (kset_find_obj(tmp_set, elements[ATTR_NAME].string.pointer)) { - pr_debug("duplicate attribute name found - %s\n", - elements[ATTR_NAME].string.pointer); + duplicate = kset_find_obj(tmp_set, elements[ATTR_NAME].string.pointer); + if (duplicate) { + pr_debug("Duplicate attribute name found - %s\n", + elements[ATTR_NAME].string.pointer); + kobject_put(duplicate); goto nextobj; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/platform/x86/huawei-wmi.c +++ linux-6.2.0/drivers/platform/x86/huawei-wmi.c @@ -85,6 +85,8 @@ { KE_IGNORE, 0x293, { KEY_KBDILLUMTOGGLE } }, { KE_IGNORE, 0x294, { KEY_KBDILLUMUP } }, { KE_IGNORE, 0x295, { KEY_KBDILLUMUP } }, + // Ignore Ambient Light Sensoring + { KE_KEY, 0x2c1, { KEY_RESERVED } }, { KE_END, 0 } }; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/platform/x86/intel_scu_ipc.c +++ linux-6.2.0/drivers/platform/x86/intel_scu_ipc.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -232,19 +233,15 @@ /* Wait till scu status is busy */ static inline int busy_loop(struct intel_scu_ipc_dev *scu) { - unsigned long end = jiffies + IPC_TIMEOUT; - - do { - u32 status; - - status = ipc_read_status(scu); - if (!(status & IPC_STATUS_BUSY)) - return (status & IPC_STATUS_ERR) ? -EIO : 0; + u8 status; + int err; - usleep_range(50, 100); - } while (time_before(jiffies, end)); + err = readx_poll_timeout(ipc_read_status, scu, status, !(status & IPC_STATUS_BUSY), + 100, jiffies_to_usecs(IPC_TIMEOUT)); + if (err) + return err; - return -ETIMEDOUT; + return (status & IPC_STATUS_ERR) ? -EIO : 0; } /* Wait till ipc ioc interrupt is received or timeout in 10 HZ */ @@ -252,10 +249,12 @@ { int status; - if (!wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT)) - return -ETIMEDOUT; + wait_for_completion_timeout(&scu->cmd_complete, IPC_TIMEOUT); status = ipc_read_status(scu); + if (status & IPC_STATUS_BUSY) + return -ETIMEDOUT; + if (status & IPC_STATUS_ERR) return -EIO; @@ -267,6 +266,24 @@ return scu->irq > 0 ? ipc_wait_for_interrupt(scu) : busy_loop(scu); } +static struct intel_scu_ipc_dev *intel_scu_ipc_get(struct intel_scu_ipc_dev *scu) +{ + u8 status; + + if (!scu) + scu = ipcdev; + if (!scu) + return ERR_PTR(-ENODEV); + + status = ipc_read_status(scu); + if (status & IPC_STATUS_BUSY) { + dev_dbg(&scu->dev, "device is busy\n"); + return ERR_PTR(-EBUSY); + } + + return scu; +} + /* Read/Write power control(PMIC in Langwell, MSIC in PenWell) registers */ static int pwr_reg_rdwr(struct intel_scu_ipc_dev *scu, u16 *addr, u8 *data, u32 count, u32 op, u32 id) @@ -280,11 +297,10 @@ memset(cbuf, 0, sizeof(cbuf)); mutex_lock(&ipclock); - if (!scu) - scu = ipcdev; - if (!scu) { + scu = intel_scu_ipc_get(scu); + if (IS_ERR(scu)) { mutex_unlock(&ipclock); - return -ENODEV; + return PTR_ERR(scu); } for (nc = 0; nc < count; nc++, offset += 2) { @@ -439,13 +455,12 @@ int err; mutex_lock(&ipclock); - if (!scu) - scu = ipcdev; - if (!scu) { + scu = intel_scu_ipc_get(scu); + if (IS_ERR(scu)) { mutex_unlock(&ipclock); - return -ENODEV; + return PTR_ERR(scu); } - scu = ipcdev; + cmdval = sub << 12 | cmd; ipc_command(scu, cmdval); err = intel_scu_ipc_check_status(scu); @@ -485,11 +500,10 @@ return -EINVAL; mutex_lock(&ipclock); - if (!scu) - scu = ipcdev; - if (!scu) { + scu = intel_scu_ipc_get(scu); + if (IS_ERR(scu)) { mutex_unlock(&ipclock); - return -ENODEV; + return PTR_ERR(scu); } memcpy(inbuf, in, inlen); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/power/supply/ab8500_chargalg.c +++ linux-6.2.0/drivers/power/supply/ab8500_chargalg.c @@ -1720,7 +1720,7 @@ static const struct power_supply_desc ab8500_chargalg_desc = { .name = "ab8500_chargalg", - .type = POWER_SUPPLY_TYPE_BATTERY, + .type = POWER_SUPPLY_TYPE_UNKNOWN, .properties = ab8500_chargalg_props, .num_properties = ARRAY_SIZE(ab8500_chargalg_props), .get_property = ab8500_chargalg_get_property, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/power/supply/mt6370-charger.c +++ linux-6.2.0/drivers/power/supply/mt6370-charger.c @@ -324,7 +324,7 @@ if (fl_strobe) { dev_err(priv->dev, "Flash led is still in strobe mode\n"); - return ret; + return -EINVAL; } /* cfo off */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/power/supply/ucs1002_power.c +++ linux-6.2.0/drivers/power/supply/ucs1002_power.c @@ -384,7 +384,8 @@ case POWER_SUPPLY_PROP_USB_TYPE: return ucs1002_get_usb_type(info, val); case POWER_SUPPLY_PROP_HEALTH: - return val->intval = info->health; + val->intval = info->health; + return 0; case POWER_SUPPLY_PROP_PRESENT: val->intval = info->present; return 0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/powercap/arm_scmi_powercap.c +++ linux-6.2.0/drivers/powercap/arm_scmi_powercap.c @@ -12,6 +12,7 @@ #include #include #include +#include #define to_scmi_powercap_zone(z) \ container_of(z, struct scmi_powercap_zone, zone) @@ -19,6 +20,8 @@ static const struct scmi_powercap_proto_ops *powercap_ops; struct scmi_powercap_zone { + bool registered; + bool invalid; unsigned int height; struct device *dev; struct scmi_protocol_handle *ph; @@ -32,6 +35,7 @@ unsigned int num_zones; struct scmi_powercap_zone *spzones; struct list_head *registered_zones; + struct list_head scmi_zones; }; static struct powercap_control_type *scmi_top_pcntrl; @@ -255,12 +259,6 @@ } } -static inline bool -scmi_powercap_is_zone_registered(struct scmi_powercap_zone *spz) -{ - return !list_empty(&spz->node); -} - static inline unsigned int scmi_powercap_get_zone_height(struct scmi_powercap_zone *spz) { @@ -279,11 +277,46 @@ return &spz->spzones[spz->info->parent_id]; } +static int scmi_powercap_register_zone(struct scmi_powercap_root *pr, + struct scmi_powercap_zone *spz, + struct scmi_powercap_zone *parent) +{ + int ret = 0; + struct powercap_zone *z; + + if (spz->invalid) { + list_del(&spz->node); + return -EINVAL; + } + + z = powercap_register_zone(&spz->zone, scmi_top_pcntrl, spz->info->name, + parent ? &parent->zone : NULL, + &zone_ops, 1, &constraint_ops); + if (!IS_ERR(z)) { + spz->height = scmi_powercap_get_zone_height(spz); + spz->registered = true; + list_move(&spz->node, &pr->registered_zones[spz->height]); + dev_dbg(spz->dev, "Registered node %s - parent %s - height:%d\n", + spz->info->name, parent ? parent->info->name : "ROOT", + spz->height); + } else { + list_del(&spz->node); + ret = PTR_ERR(z); + dev_err(spz->dev, + "Error registering node:%s - parent:%s - h:%d - ret:%d\n", + spz->info->name, + parent ? parent->info->name : "ROOT", + spz->height, ret); + } + + return ret; +} + /** - * scmi_powercap_register_zone - Register an SCMI powercap zone recursively + * scmi_zones_register- Register SCMI powercap zones starting from parent zones * + * @dev: A reference to the SCMI device * @pr: A reference to the root powercap zones descriptors - * @spz: A reference to the SCMI powercap zone to register * * When registering SCMI powercap zones with the powercap framework we should * take care to always register zones starting from the root ones and to @@ -293,10 +326,10 @@ * zones provided by the SCMI platform firmware is built to comply with such * requirement. * - * This function, given an SCMI powercap zone to register, takes care to walk - * the SCMI powercap zones tree up to the root looking recursively for - * unregistered parent zones before registering the provided zone; at the same - * time each registered zone height in such a tree is accounted for and each + * This function, given the set of SCMI powercap zones to register, takes care + * to walk the SCMI powercap zones trees up to the root registering any + * unregistered parent zone before registering the child zones; at the same + * time each registered-zone height in such a tree is accounted for and each * zone, once registered, is stored in the @registered_zones array that is * indexed by zone height: this way will be trivial, at unregister time, to walk * the @registered_zones array backward and unregister all the zones starting @@ -314,57 +347,55 @@ * * Return: 0 on Success */ -static int scmi_powercap_register_zone(struct scmi_powercap_root *pr, - struct scmi_powercap_zone *spz) +static int scmi_zones_register(struct device *dev, + struct scmi_powercap_root *pr) { int ret = 0; - struct scmi_powercap_zone *parent; + unsigned int sp = 0, reg_zones = 0; + struct scmi_powercap_zone *spz, **zones_stack; - if (!spz->info) - return ret; - - parent = scmi_powercap_get_parent_zone(spz); - if (parent && !scmi_powercap_is_zone_registered(parent)) { - /* - * Bail out if a parent domain was marked as unsupported: - * only domains participating as leaves can be skipped. - */ - if (!parent->info) - return -ENODEV; - - ret = scmi_powercap_register_zone(pr, parent); - if (ret) - return ret; - } - - if (!scmi_powercap_is_zone_registered(spz)) { - struct powercap_zone *z; + zones_stack = kcalloc(pr->num_zones, sizeof(spz), GFP_KERNEL); + if (!zones_stack) + return -ENOMEM; - z = powercap_register_zone(&spz->zone, - scmi_top_pcntrl, - spz->info->name, - parent ? &parent->zone : NULL, - &zone_ops, 1, &constraint_ops); - if (!IS_ERR(z)) { - spz->height = scmi_powercap_get_zone_height(spz); - list_add(&spz->node, - &pr->registered_zones[spz->height]); - dev_dbg(spz->dev, - "Registered node %s - parent %s - height:%d\n", - spz->info->name, - parent ? parent->info->name : "ROOT", - spz->height); - ret = 0; + spz = list_first_entry_or_null(&pr->scmi_zones, + struct scmi_powercap_zone, node); + while (spz) { + struct scmi_powercap_zone *parent; + + parent = scmi_powercap_get_parent_zone(spz); + if (parent && !parent->registered) { + zones_stack[sp++] = spz; + spz = parent; } else { - ret = PTR_ERR(z); - dev_err(spz->dev, - "Error registering node:%s - parent:%s - h:%d - ret:%d\n", - spz->info->name, - parent ? parent->info->name : "ROOT", - spz->height, ret); + ret = scmi_powercap_register_zone(pr, spz, parent); + if (!ret) { + reg_zones++; + } else if (sp) { + /* Failed to register a non-leaf zone. + * Bail-out. + */ + dev_err(dev, + "Failed to register non-leaf zone - ret:%d\n", + ret); + scmi_powercap_unregister_all_zones(pr); + reg_zones = 0; + goto out; + } + /* Pick next zone to process */ + if (sp) + spz = zones_stack[--sp]; + else + spz = list_first_entry_or_null(&pr->scmi_zones, + struct scmi_powercap_zone, + node); } } +out: + kfree(zones_stack); + dev_info(dev, "Registered %d SCMI Powercap domains !\n", reg_zones); + return ret; } @@ -408,6 +439,8 @@ if (!pr->registered_zones) return -ENOMEM; + INIT_LIST_HEAD(&pr->scmi_zones); + for (i = 0, spz = pr->spzones; i < pr->num_zones; i++, spz++) { /* * Powercap domains are validate by the protocol layer, i.e. @@ -422,6 +455,7 @@ INIT_LIST_HEAD(&spz->node); INIT_LIST_HEAD(&pr->registered_zones[i]); + list_add_tail(&spz->node, &pr->scmi_zones); /* * Forcibly skip powercap domains using an abstract scale. * Note that only leaves domains can be skipped, so this could @@ -432,7 +466,7 @@ dev_warn(dev, "Abstract power scale not supported. Skip %s.\n", spz->info->name); - spz->info = NULL; + spz->invalid = true; continue; } } @@ -441,21 +475,12 @@ * Scan array of retrieved SCMI powercap domains and register them * recursively starting from the root domains. */ - for (i = 0, spz = pr->spzones; i < pr->num_zones; i++, spz++) { - ret = scmi_powercap_register_zone(pr, spz); - if (ret) { - dev_err(dev, - "Failed to register powercap zone %s - ret:%d\n", - spz->info->name, ret); - scmi_powercap_unregister_all_zones(pr); - return ret; - } - } + ret = scmi_zones_register(dev, pr); + if (ret) + return ret; dev_set_drvdata(dev, pr); - dev_info(dev, "Registered %d SCMI Powercap domains !\n", pr->num_zones); - return ret; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/ptp/ptp_ocp.c +++ linux-6.2.0/drivers/ptp/ptp_ocp.c @@ -3991,7 +3991,6 @@ return 0; out: - ptp_ocp_dev_release(&bp->dev); put_device(&bp->dev); return err; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/pwm/pwm-atmel-tcb.c +++ linux-6.2.0/drivers/pwm/pwm-atmel-tcb.c @@ -422,13 +422,14 @@ struct atmel_tcb_pwm_chip *tcbpwm; const struct atmel_tcb_config *config; struct device_node *np = pdev->dev.of_node; - struct regmap *regmap; - struct clk *clk, *gclk = NULL; - struct clk *slow_clk; char clk_name[] = "t0_clk"; int err; int channel; + tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL); + if (tcbpwm == NULL) + return -ENOMEM; + err = of_property_read_u32(np, "reg", &channel); if (err < 0) { dev_err(&pdev->dev, @@ -437,49 +438,43 @@ return err; } - regmap = syscon_node_to_regmap(np->parent); - if (IS_ERR(regmap)) - return PTR_ERR(regmap); - - slow_clk = of_clk_get_by_name(np->parent, "slow_clk"); - if (IS_ERR(slow_clk)) - return PTR_ERR(slow_clk); + tcbpwm->regmap = syscon_node_to_regmap(np->parent); + if (IS_ERR(tcbpwm->regmap)) + return PTR_ERR(tcbpwm->regmap); + + tcbpwm->slow_clk = of_clk_get_by_name(np->parent, "slow_clk"); + if (IS_ERR(tcbpwm->slow_clk)) + return PTR_ERR(tcbpwm->slow_clk); clk_name[1] += channel; - clk = of_clk_get_by_name(np->parent, clk_name); - if (IS_ERR(clk)) - clk = of_clk_get_by_name(np->parent, "t0_clk"); - if (IS_ERR(clk)) - return PTR_ERR(clk); + tcbpwm->clk = of_clk_get_by_name(np->parent, clk_name); + if (IS_ERR(tcbpwm->clk)) + tcbpwm->clk = of_clk_get_by_name(np->parent, "t0_clk"); + if (IS_ERR(tcbpwm->clk)) { + err = PTR_ERR(tcbpwm->clk); + goto err_slow_clk; + } match = of_match_node(atmel_tcb_of_match, np->parent); config = match->data; if (config->has_gclk) { - gclk = of_clk_get_by_name(np->parent, "gclk"); - if (IS_ERR(gclk)) - return PTR_ERR(gclk); - } - - tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL); - if (tcbpwm == NULL) { - err = -ENOMEM; - goto err_slow_clk; + tcbpwm->gclk = of_clk_get_by_name(np->parent, "gclk"); + if (IS_ERR(tcbpwm->gclk)) { + err = PTR_ERR(tcbpwm->gclk); + goto err_clk; + } } tcbpwm->chip.dev = &pdev->dev; tcbpwm->chip.ops = &atmel_tcb_pwm_ops; tcbpwm->chip.npwm = NPWM; tcbpwm->channel = channel; - tcbpwm->regmap = regmap; - tcbpwm->clk = clk; - tcbpwm->gclk = gclk; - tcbpwm->slow_clk = slow_clk; tcbpwm->width = config->counter_width; - err = clk_prepare_enable(slow_clk); + err = clk_prepare_enable(tcbpwm->slow_clk); if (err) - goto err_slow_clk; + goto err_gclk; spin_lock_init(&tcbpwm->lock); @@ -494,23 +489,28 @@ err_disable_clk: clk_disable_unprepare(tcbpwm->slow_clk); +err_gclk: + clk_put(tcbpwm->gclk); + +err_clk: + clk_put(tcbpwm->clk); + err_slow_clk: - clk_put(slow_clk); + clk_put(tcbpwm->slow_clk); return err; } -static int atmel_tcb_pwm_remove(struct platform_device *pdev) +static void atmel_tcb_pwm_remove(struct platform_device *pdev) { struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev); pwmchip_remove(&tcbpwm->chip); clk_disable_unprepare(tcbpwm->slow_clk); - clk_put(tcbpwm->slow_clk); + clk_put(tcbpwm->gclk); clk_put(tcbpwm->clk); - - return 0; + clk_put(tcbpwm->slow_clk); } static const struct of_device_id atmel_tcb_pwm_dt_ids[] = { @@ -564,7 +564,7 @@ .pm = &atmel_tcb_pwm_pm_ops, }, .probe = atmel_tcb_pwm_probe, - .remove = atmel_tcb_pwm_remove, + .remove_new = atmel_tcb_pwm_remove, }; module_platform_driver(atmel_tcb_pwm_driver); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/pwm/pwm-lpc32xx.c +++ linux-6.2.0/drivers/pwm/pwm-lpc32xx.c @@ -51,10 +51,10 @@ if (duty_cycles > 255) duty_cycles = 255; - val = readl(lpc32xx->base + (pwm->hwpwm << 2)); + val = readl(lpc32xx->base); val &= ~0xFFFF; val |= (period_cycles << 8) | duty_cycles; - writel(val, lpc32xx->base + (pwm->hwpwm << 2)); + writel(val, lpc32xx->base); return 0; } @@ -69,9 +69,9 @@ if (ret) return ret; - val = readl(lpc32xx->base + (pwm->hwpwm << 2)); + val = readl(lpc32xx->base); val |= PWM_ENABLE; - writel(val, lpc32xx->base + (pwm->hwpwm << 2)); + writel(val, lpc32xx->base); return 0; } @@ -81,9 +81,9 @@ struct lpc32xx_pwm_chip *lpc32xx = to_lpc32xx_pwm_chip(chip); u32 val; - val = readl(lpc32xx->base + (pwm->hwpwm << 2)); + val = readl(lpc32xx->base); val &= ~PWM_ENABLE; - writel(val, lpc32xx->base + (pwm->hwpwm << 2)); + writel(val, lpc32xx->base); clk_disable_unprepare(lpc32xx->clk); } @@ -141,9 +141,9 @@ lpc32xx->chip.npwm = 1; /* If PWM is disabled, configure the output to the default value */ - val = readl(lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2)); + val = readl(lpc32xx->base); val &= ~PWM_PIN_LEVEL; - writel(val, lpc32xx->base + (lpc32xx->chip.pwms[0].hwpwm << 2)); + writel(val, lpc32xx->base); ret = devm_pwmchip_add(&pdev->dev, &lpc32xx->chip); if (ret < 0) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/regulator/mt6358-regulator.c +++ linux-6.2.0/drivers/regulator/mt6358-regulator.c @@ -35,19 +35,19 @@ }; #define MT6358_BUCK(match, vreg, min, max, step, \ - volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask, \ + vosel_mask, _da_vsel_reg, _da_vsel_mask, \ _modeset_reg, _modeset_shift) \ [MT6358_ID_##vreg] = { \ .desc = { \ .name = #vreg, \ .of_match = of_match_ptr(match), \ - .ops = &mt6358_volt_range_ops, \ + .ops = &mt6358_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .id = MT6358_ID_##vreg, \ .owner = THIS_MODULE, \ .n_voltages = ((max) - (min)) / (step) + 1, \ - .linear_ranges = volt_ranges, \ - .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ + .min_uV = (min), \ + .uV_step = (step), \ .vsel_reg = MT6358_BUCK_##vreg##_ELR0, \ .vsel_mask = vosel_mask, \ .enable_reg = MT6358_BUCK_##vreg##_CON0, \ @@ -87,7 +87,7 @@ } #define MT6358_LDO1(match, vreg, min, max, step, \ - volt_ranges, _da_vsel_reg, _da_vsel_mask, \ + _da_vsel_reg, _da_vsel_mask, \ vosel, vosel_mask) \ [MT6358_ID_##vreg] = { \ .desc = { \ @@ -98,8 +98,8 @@ .id = MT6358_ID_##vreg, \ .owner = THIS_MODULE, \ .n_voltages = ((max) - (min)) / (step) + 1, \ - .linear_ranges = volt_ranges, \ - .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ + .min_uV = (min), \ + .uV_step = (step), \ .vsel_reg = vosel, \ .vsel_mask = vosel_mask, \ .enable_reg = MT6358_LDO_##vreg##_CON0, \ @@ -131,19 +131,19 @@ } #define MT6366_BUCK(match, vreg, min, max, step, \ - volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask, \ + vosel_mask, _da_vsel_reg, _da_vsel_mask, \ _modeset_reg, _modeset_shift) \ [MT6366_ID_##vreg] = { \ .desc = { \ .name = #vreg, \ .of_match = of_match_ptr(match), \ - .ops = &mt6358_volt_range_ops, \ + .ops = &mt6358_buck_ops, \ .type = REGULATOR_VOLTAGE, \ .id = MT6366_ID_##vreg, \ .owner = THIS_MODULE, \ .n_voltages = ((max) - (min)) / (step) + 1, \ - .linear_ranges = volt_ranges, \ - .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ + .min_uV = (min), \ + .uV_step = (step), \ .vsel_reg = MT6358_BUCK_##vreg##_ELR0, \ .vsel_mask = vosel_mask, \ .enable_reg = MT6358_BUCK_##vreg##_CON0, \ @@ -183,7 +183,7 @@ } #define MT6366_LDO1(match, vreg, min, max, step, \ - volt_ranges, _da_vsel_reg, _da_vsel_mask, \ + _da_vsel_reg, _da_vsel_mask, \ vosel, vosel_mask) \ [MT6366_ID_##vreg] = { \ .desc = { \ @@ -194,8 +194,8 @@ .id = MT6366_ID_##vreg, \ .owner = THIS_MODULE, \ .n_voltages = ((max) - (min)) / (step) + 1, \ - .linear_ranges = volt_ranges, \ - .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ + .min_uV = (min), \ + .uV_step = (step), \ .vsel_reg = vosel, \ .vsel_mask = vosel_mask, \ .enable_reg = MT6358_LDO_##vreg##_CON0, \ @@ -226,21 +226,6 @@ .qi = BIT(15), \ } -static const struct linear_range buck_volt_range1[] = { - REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250), -}; - -static const struct linear_range buck_volt_range2[] = { - REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 12500), -}; - -static const struct linear_range buck_volt_range3[] = { - REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000), -}; - -static const struct linear_range buck_volt_range4[] = { - REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500), -}; static const unsigned int vdram2_voltages[] = { 600000, 1800000, @@ -463,9 +448,9 @@ } } -static const struct regulator_ops mt6358_volt_range_ops = { - .list_voltage = regulator_list_voltage_linear_range, - .map_voltage = regulator_map_voltage_linear_range, +static const struct regulator_ops mt6358_buck_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = mt6358_get_buck_voltage_sel, .set_voltage_time_sel = regulator_set_voltage_time_sel, @@ -477,6 +462,18 @@ .get_mode = mt6358_regulator_get_mode, }; +static const struct regulator_ops mt6358_volt_range_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = mt6358_get_buck_voltage_sel, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .get_status = mt6358_get_status, +}; + static const struct regulator_ops mt6358_volt_table_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_iterate, @@ -500,35 +497,23 @@ /* The array is indexed by id(MT6358_ID_XXX) */ static struct mt6358_regulator_info mt6358_regulators[] = { MT6358_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500, - buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, - MT6358_VDRAM1_ANA_CON0, 8), + 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8), MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, - MT6358_VCORE_VGPU_ANA_CON0, 1), - MT6358_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f, - MT6358_VCORE_VGPU_ANA_CON0, 1), + 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1), MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000, - buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, - MT6358_VPA_ANA_CON0, 3), + 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3), MT6358_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, - MT6358_VPROC_ANA_CON0, 1), + 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1), MT6358_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, - MT6358_VPROC_ANA_CON0, 2), + 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2), MT6358_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, - MT6358_VCORE_VGPU_ANA_CON0, 2), + 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2), MT6358_BUCK("buck_vs2", VS2, 500000, 2087500, 12500, - buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, - MT6358_VS2_ANA_CON0, 8), + 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8), MT6358_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, - MT6358_VMODEM_ANA_CON0, 8), + 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8), MT6358_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500, - buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, - MT6358_VS1_ANA_CON0, 8), + 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8), MT6358_REG_FIXED("ldo_vrf12", VRF12, MT6358_LDO_VRF12_CON0, 0, 1200000), MT6358_REG_FIXED("ldo_vio18", VIO18, @@ -582,55 +567,35 @@ MT6358_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx, MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00), MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250, - buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, - MT6358_LDO_VSRAM_CON0, 0x7f), + MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f), MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250, - buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, - MT6358_LDO_VSRAM_CON2, 0x7f), - MT6358_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000, - 1293750, 6250, buck_volt_range1, - MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f, - MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f), + MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f), MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250, - buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, - MT6358_LDO_VSRAM_CON3, 0x7f), + MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f), MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250, - buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, - MT6358_LDO_VSRAM_CON1, 0x7f), + MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f), }; /* The array is indexed by id(MT6366_ID_XXX) */ static struct mt6358_regulator_info mt6366_regulators[] = { MT6366_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500, - buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, - MT6358_VDRAM1_ANA_CON0, 8), + 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f, MT6358_VDRAM1_ANA_CON0, 8), MT6366_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, - MT6358_VCORE_VGPU_ANA_CON0, 1), - MT6366_BUCK("buck_vcore_sshub", VCORE_SSHUB, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_SSHUB_ELR0, 0x7f, - MT6358_VCORE_VGPU_ANA_CON0, 1), + 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 1), MT6366_BUCK("buck_vpa", VPA, 500000, 3650000, 50000, - buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, - MT6358_VPA_ANA_CON0, 3), + 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, MT6358_VPA_ANA_CON0, 3), MT6366_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, - MT6358_VPROC_ANA_CON0, 1), + 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 1), MT6366_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, - MT6358_VPROC_ANA_CON0, 2), + 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f, MT6358_VPROC_ANA_CON0, 2), MT6366_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, - MT6358_VCORE_VGPU_ANA_CON0, 2), + 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, MT6358_VCORE_VGPU_ANA_CON0, 2), MT6366_BUCK("buck_vs2", VS2, 500000, 2087500, 12500, - buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, - MT6358_VS2_ANA_CON0, 8), + 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, MT6358_VS2_ANA_CON0, 8), MT6366_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250, - buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, - MT6358_VMODEM_ANA_CON0, 8), + 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f, MT6358_VMODEM_ANA_CON0, 8), MT6366_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500, - buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, - MT6358_VS1_ANA_CON0, 8), + 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, MT6358_VS1_ANA_CON0, 8), MT6366_REG_FIXED("ldo_vrf12", VRF12, MT6358_LDO_VRF12_CON0, 0, 1200000), MT6366_REG_FIXED("ldo_vio18", VIO18, @@ -673,21 +638,13 @@ MT6366_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx, MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00), MT6366_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250, - buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, - MT6358_LDO_VSRAM_CON0, 0x7f), + MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON0, 0x7f), MT6366_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250, - buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, - MT6358_LDO_VSRAM_CON2, 0x7f), - MT6366_LDO1("ldo_vsram_others_sshub", VSRAM_OTHERS_SSHUB, 500000, - 1293750, 6250, buck_volt_range1, - MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f, - MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1, 0x7f), + MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON2, 0x7f), MT6366_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250, - buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, - MT6358_LDO_VSRAM_CON3, 0x7f), + MT6358_LDO_VSRAM_GPU_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON3, 0x7f), MT6366_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250, - buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, - MT6358_LDO_VSRAM_CON1, 0x7f), + MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f00, MT6358_LDO_VSRAM_CON1, 0x7f), }; static int mt6358_regulator_probe(struct platform_device *pdev) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/s390/block/dasd_devmap.c +++ linux-6.2.0/drivers/s390/block/dasd_devmap.c @@ -1377,16 +1377,12 @@ static DEVICE_ATTR(vendor, 0444, dasd_vendor_show, NULL); -#define UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 +\ - /* SSID */ 4 + 1 + /* unit addr */ 2 + 1 +\ - /* vduit */ 32 + 1) - static ssize_t dasd_uid_show(struct device *dev, struct device_attribute *attr, char *buf) { + char uid_string[DASD_UID_STRLEN]; struct dasd_device *device; struct dasd_uid uid; - char uid_string[UID_STRLEN]; char ua_string[3]; device = dasd_device_from_cdev(to_ccwdev(dev)); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/s390/block/dasd_int.h +++ linux-6.2.0/drivers/s390/block/dasd_int.h @@ -259,6 +259,10 @@ char vduit[33]; }; +#define DASD_UID_STRLEN ( /* vendor */ 3 + 1 + /* serial */ 14 + 1 + \ + /* SSID */ 4 + 1 + /* unit addr */ 2 + 1 + \ + /* vduit */ 32 + 1) + /* * PPRC Status data */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/s390/block/dcssblk.c +++ linux-6.2.0/drivers/s390/block/dcssblk.c @@ -411,6 +411,7 @@ } list_del(&dev_info->lh); + dax_remove_host(dev_info->gd); kill_dax(dev_info->dax_dev); put_dax(dev_info->dax_dev); del_gendisk(dev_info->gd); @@ -706,9 +707,9 @@ goto out; out_dax_host: + put_device(&dev_info->dev); dax_remove_host(dev_info->gd); out_dax: - put_device(&dev_info->dev); kill_dax(dev_info->dax_dev); put_dax(dev_info->dax_dev); put_dev: @@ -788,6 +789,7 @@ } list_del(&dev_info->lh); + dax_remove_host(dev_info->gd); kill_dax(dev_info->dax_dev); put_dax(dev_info->dax_dev); del_gendisk(dev_info->gd); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/s390/crypto/zcrypt_api.c +++ linux-6.2.0/drivers/s390/crypto/zcrypt_api.c @@ -437,6 +437,7 @@ ZCRYPT_NAME "_%d", (int)MINOR(devt)); nodename[sizeof(nodename) - 1] = '\0'; if (dev_set_name(&zcdndev->device, nodename)) { + kfree(zcdndev); rc = -EINVAL; goto unlockout; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/s390/crypto/zcrypt_ep11misc.c +++ linux-6.2.0/drivers/s390/crypto/zcrypt_ep11misc.c @@ -113,6 +113,50 @@ spin_unlock_bh(&card_list_lock); } +static int ep11_kb_split(const u8 *kb, size_t kblen, u32 kbver, + struct ep11kblob_header **kbhdr, size_t *kbhdrsize, + u8 **kbpl, size_t *kbplsize) +{ + struct ep11kblob_header *hdr = NULL; + size_t hdrsize, plsize = 0; + int rc = -EINVAL; + u8 *pl = NULL; + + if (kblen < sizeof(struct ep11kblob_header)) + goto out; + hdr = (struct ep11kblob_header *)kb; + + switch (kbver) { + case TOKVER_EP11_AES: + /* header overlays the payload */ + hdrsize = 0; + break; + case TOKVER_EP11_ECC_WITH_HEADER: + case TOKVER_EP11_AES_WITH_HEADER: + /* payload starts after the header */ + hdrsize = sizeof(struct ep11kblob_header); + break; + default: + goto out; + } + + plsize = kblen - hdrsize; + pl = (u8 *)kb + hdrsize; + + if (kbhdr) + *kbhdr = hdr; + if (kbhdrsize) + *kbhdrsize = hdrsize; + if (kbpl) + *kbpl = pl; + if (kbplsize) + *kbplsize = plsize; + + rc = 0; +out: + return rc; +} + /* * Simple check if the key blob is a valid EP11 AES key blob with header. */ @@ -664,8 +708,9 @@ */ #define KEY_ATTR_DEFAULTS 0x00200c00 -int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, - u8 *keybuf, size_t *keybufsize) +static int _ep11_genaeskey(u16 card, u16 domain, + u32 keybitsize, u32 keygenflags, + u8 *keybuf, size_t *keybufsize) { struct keygen_req_pl { struct pl_head head; @@ -701,7 +746,6 @@ struct ep11_cprb *req = NULL, *rep = NULL; struct ep11_target_dev target; struct ep11_urb *urb = NULL; - struct ep11keyblob *kb; int api, rc = -ENOMEM; switch (keybitsize) { @@ -780,14 +824,9 @@ goto out; } - /* copy key blob and set header values */ + /* copy key blob */ memcpy(keybuf, rep_pl->data, rep_pl->data_len); *keybufsize = rep_pl->data_len; - kb = (struct ep11keyblob *)keybuf; - kb->head.type = TOKTYPE_NON_CCA; - kb->head.len = rep_pl->data_len; - kb->head.version = TOKVER_EP11_AES; - kb->head.keybitlen = keybitsize; out: kfree(req); @@ -795,6 +834,43 @@ kfree(urb); return rc; } + +int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, + u8 *keybuf, size_t *keybufsize, u32 keybufver) +{ + struct ep11kblob_header *hdr; + size_t hdr_size, pl_size; + u8 *pl; + int rc; + + switch (keybufver) { + case TOKVER_EP11_AES: + case TOKVER_EP11_AES_WITH_HEADER: + break; + default: + return -EINVAL; + } + + rc = ep11_kb_split(keybuf, *keybufsize, keybufver, + &hdr, &hdr_size, &pl, &pl_size); + if (rc) + return rc; + + rc = _ep11_genaeskey(card, domain, keybitsize, keygenflags, + pl, &pl_size); + if (rc) + return rc; + + *keybufsize = hdr_size + pl_size; + + /* update header information */ + hdr->type = TOKTYPE_NON_CCA; + hdr->len = *keybufsize; + hdr->version = keybufver; + hdr->bitlen = keybitsize; + + return 0; +} EXPORT_SYMBOL(ep11_genaeskey); static int ep11_cryptsingle(u16 card, u16 domain, @@ -924,12 +1000,12 @@ return rc; } -static int ep11_unwrapkey(u16 card, u16 domain, - const u8 *kek, size_t keksize, - const u8 *enckey, size_t enckeysize, - u32 mech, const u8 *iv, - u32 keybitsize, u32 keygenflags, - u8 *keybuf, size_t *keybufsize) +static int _ep11_unwrapkey(u16 card, u16 domain, + const u8 *kek, size_t keksize, + const u8 *enckey, size_t enckeysize, + u32 mech, const u8 *iv, + u32 keybitsize, u32 keygenflags, + u8 *keybuf, size_t *keybufsize) { struct uw_req_pl { struct pl_head head; @@ -966,7 +1042,6 @@ struct ep11_cprb *req = NULL, *rep = NULL; struct ep11_target_dev target; struct ep11_urb *urb = NULL; - struct ep11keyblob *kb; size_t req_pl_size; int api, rc = -ENOMEM; u8 *p; @@ -1048,14 +1123,9 @@ goto out; } - /* copy key blob and set header values */ + /* copy key blob */ memcpy(keybuf, rep_pl->data, rep_pl->data_len); *keybufsize = rep_pl->data_len; - kb = (struct ep11keyblob *)keybuf; - kb->head.type = TOKTYPE_NON_CCA; - kb->head.len = rep_pl->data_len; - kb->head.version = TOKVER_EP11_AES; - kb->head.keybitlen = keybitsize; out: kfree(req); @@ -1064,6 +1134,42 @@ return rc; } +static int ep11_unwrapkey(u16 card, u16 domain, + const u8 *kek, size_t keksize, + const u8 *enckey, size_t enckeysize, + u32 mech, const u8 *iv, + u32 keybitsize, u32 keygenflags, + u8 *keybuf, size_t *keybufsize, + u8 keybufver) +{ + struct ep11kblob_header *hdr; + size_t hdr_size, pl_size; + u8 *pl; + int rc; + + rc = ep11_kb_split(keybuf, *keybufsize, keybufver, + &hdr, &hdr_size, &pl, &pl_size); + if (rc) + return rc; + + rc = _ep11_unwrapkey(card, domain, kek, keksize, enckey, enckeysize, + mech, iv, keybitsize, keygenflags, + pl, &pl_size); + if (rc) + return rc; + + *keybufsize = hdr_size + pl_size; + + /* update header information */ + hdr = (struct ep11kblob_header *)keybuf; + hdr->type = TOKTYPE_NON_CCA; + hdr->len = *keybufsize; + hdr->version = keybufver; + hdr->bitlen = keybitsize; + + return 0; +} + static int ep11_wrapkey(u16 card, u16 domain, const u8 *key, size_t keysize, u32 mech, const u8 *iv, @@ -1198,10 +1304,10 @@ } int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, - const u8 *clrkey, u8 *keybuf, size_t *keybufsize) + const u8 *clrkey, u8 *keybuf, size_t *keybufsize, + u32 keytype) { int rc; - struct ep11keyblob *kb; u8 encbuf[64], *kek = NULL; size_t clrkeylen, keklen, encbuflen = sizeof(encbuf); @@ -1223,17 +1329,15 @@ } /* Step 1: generate AES 256 bit random kek key */ - rc = ep11_genaeskey(card, domain, 256, - 0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */ - kek, &keklen); + rc = _ep11_genaeskey(card, domain, 256, + 0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */ + kek, &keklen); if (rc) { DEBUG_ERR( "%s generate kek key failed, rc=%d\n", __func__, rc); goto out; } - kb = (struct ep11keyblob *)kek; - memset(&kb->head, 0, sizeof(kb->head)); /* Step 2: encrypt clear key value with the kek key */ rc = ep11_cryptsingle(card, domain, 0, 0, def_iv, kek, keklen, @@ -1248,7 +1352,7 @@ /* Step 3: import the encrypted key value as a new key */ rc = ep11_unwrapkey(card, domain, kek, keklen, encbuf, encbuflen, 0, def_iv, - keybitsize, 0, keybuf, keybufsize); + keybitsize, 0, keybuf, keybufsize, keytype); if (rc) { DEBUG_ERR( "%s importing key value as new key failed,, rc=%d\n", only in patch2: unchanged: --- linux-6.2.0.orig/drivers/s390/crypto/zcrypt_ep11misc.h +++ linux-6.2.0/drivers/s390/crypto/zcrypt_ep11misc.h @@ -29,14 +29,7 @@ union { u8 session[32]; /* only used for PKEY_TYPE_EP11: */ - struct { - u8 type; /* 0x00 (TOKTYPE_NON_CCA) */ - u8 res0; /* unused */ - u16 len; /* total length in bytes of this blob */ - u8 version; /* 0x03 (TOKVER_EP11_AES) */ - u8 res1; /* unused */ - u16 keybitlen; /* clear key bit len, 0 for unknown */ - } head; + struct ep11kblob_header head; }; u8 wkvp[16]; /* wrapping key verification pattern */ u64 attr; /* boolean key attributes */ @@ -114,13 +107,14 @@ * Generate (random) EP11 AES secure key. */ int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags, - u8 *keybuf, size_t *keybufsize); + u8 *keybuf, size_t *keybufsize, u32 keybufver); /* * Generate EP11 AES secure key with given clear key value. */ int ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags, - const u8 *clrkey, u8 *keybuf, size_t *keybufsize); + const u8 *clrkey, u8 *keybuf, size_t *keybufsize, + u32 keytype); /* * Build a list of ep11 apqns meeting the following constrains: only in patch2: unchanged: --- linux-6.2.0.orig/drivers/s390/scsi/zfcp_aux.c +++ linux-6.2.0/drivers/s390/scsi/zfcp_aux.c @@ -518,12 +518,12 @@ if (port) { put_device(&port->dev); retval = -EEXIST; - goto err_out; + goto err_put; } port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); if (!port) - goto err_out; + goto err_put; rwlock_init(&port->unit_list_lock); INIT_LIST_HEAD(&port->unit_list); @@ -546,7 +546,7 @@ if (dev_set_name(&port->dev, "0x%016llx", (unsigned long long)wwpn)) { kfree(port); - goto err_out; + goto err_put; } retval = -EINVAL; @@ -563,7 +563,8 @@ return port; -err_out: +err_put: zfcp_ccw_adapter_put(adapter); +err_out: return ERR_PTR(retval); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/aacraid/aacraid.h +++ linux-6.2.0/drivers/scsi/aacraid/aacraid.h @@ -1678,6 +1678,7 @@ u32 handle_pci_error; bool init_reset; u8 soft_reset_support; + u8 use_map_queue; }; #define aac_adapter_interrupt(dev) \ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/aacraid/commsup.c +++ linux-6.2.0/drivers/scsi/aacraid/commsup.c @@ -223,8 +223,12 @@ struct fib *aac_fib_alloc_tag(struct aac_dev *dev, struct scsi_cmnd *scmd) { struct fib *fibptr; + u32 blk_tag; + int i; - fibptr = &dev->fibs[scsi_cmd_to_rq(scmd)->tag]; + blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); + i = blk_mq_unique_tag_to_tag(blk_tag); + fibptr = &dev->fibs[i]; /* * Null out fields that depend on being zero at the start of * each I/O @@ -1447,7 +1451,7 @@ #endif break; } - scsi_rescan_device(&device->sdev_gendev); + scsi_rescan_device(device); break; default: only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/aacraid/linit.c +++ linux-6.2.0/drivers/scsi/aacraid/linit.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -505,6 +506,15 @@ return 0; } +static void aac_map_queues(struct Scsi_Host *shost) +{ + struct aac_dev *aac = (struct aac_dev *)shost->hostdata; + + blk_mq_pci_map_queues(&shost->tag_set.map[HCTX_TYPE_DEFAULT], + aac->pdev, 0); + aac->use_map_queue = true; +} + /** * aac_change_queue_depth - alter queue depths * @sdev: SCSI device we are considering @@ -1489,6 +1499,7 @@ .bios_param = aac_biosparm, .shost_groups = aac_host_groups, .slave_configure = aac_slave_configure, + .map_queues = aac_map_queues, .change_queue_depth = aac_change_queue_depth, .sdev_groups = aac_dev_groups, .eh_abort_handler = aac_eh_abort, @@ -1776,6 +1787,8 @@ shost->max_lun = AAC_MAX_LUN; pci_set_drvdata(pdev, shost); + shost->nr_hw_queues = aac->max_msix; + shost->host_tagset = 1; error = scsi_add_host(shost, &pdev->dev); if (error) @@ -1908,6 +1921,7 @@ struct aac_dev *aac = (struct aac_dev *)shost->hostdata; aac_cancel_rescan_worker(aac); + aac->use_map_queue = false; scsi_remove_host(shost); __aac_shutdown(aac); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/aacraid/src.c +++ linux-6.2.0/drivers/scsi/aacraid/src.c @@ -493,6 +493,10 @@ #endif u16 vector_no; + struct scsi_cmnd *scmd; + u32 blk_tag; + struct Scsi_Host *shost = dev->scsi_host_ptr; + struct blk_mq_queue_map *qmap; atomic_inc(&q->numpending); @@ -505,8 +509,25 @@ if ((dev->comm_interface == AAC_COMM_MESSAGE_TYPE3) && dev->sa_firmware) vector_no = aac_get_vector(dev); - else - vector_no = fib->vector_no; + else { + if (!fib->vector_no || !fib->callback_data) { + if (shost && dev->use_map_queue) { + qmap = &shost->tag_set.map[HCTX_TYPE_DEFAULT]; + vector_no = qmap->mq_map[raw_smp_processor_id()]; + } + /* + * We hardcode the vector_no for + * reserved commands as a valid shost is + * absent during the init + */ + else + vector_no = 0; + } else { + scmd = (struct scsi_cmnd *)fib->callback_data; + blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); + vector_no = blk_mq_unique_tag_to_hwq(blk_tag); + } + } if (native_hba) { if (fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/be2iscsi/be_iscsi.c +++ linux-6.2.0/drivers/scsi/be2iscsi/be_iscsi.c @@ -450,6 +450,10 @@ } nla_for_each_attr(attrib, data, dt_len, rm_len) { + /* ignore nla_type as it is never used */ + if (nla_len(attrib) < sizeof(*iface_param)) + return -EINVAL; + iface_param = nla_data(attrib); if (iface_param->param_type != ISCSI_NET_PARAM) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/fcoe/fcoe_ctlr.c +++ linux-6.2.0/drivers/scsi/fcoe/fcoe_ctlr.c @@ -319,16 +319,17 @@ { struct fcoe_fcf *sel; struct fcoe_fcf *fcf; + unsigned long flags; mutex_lock(&fip->ctlr_mutex); - spin_lock_bh(&fip->ctlr_lock); + spin_lock_irqsave(&fip->ctlr_lock, flags); kfree_skb(fip->flogi_req); fip->flogi_req = NULL; list_for_each_entry(fcf, &fip->fcfs, list) fcf->flogi_sent = 0; - spin_unlock_bh(&fip->ctlr_lock); + spin_unlock_irqrestore(&fip->ctlr_lock, flags); sel = fip->sel_fcf; if (sel && ether_addr_equal(sel->fcf_mac, fip->dest_addr)) @@ -699,6 +700,7 @@ { struct fc_frame *fp; struct fc_frame_header *fh; + unsigned long flags; u16 old_xid; u8 op; u8 mac[ETH_ALEN]; @@ -732,11 +734,11 @@ op = FIP_DT_FLOGI; if (fip->mode == FIP_MODE_VN2VN) break; - spin_lock_bh(&fip->ctlr_lock); + spin_lock_irqsave(&fip->ctlr_lock, flags); kfree_skb(fip->flogi_req); fip->flogi_req = skb; fip->flogi_req_send = 1; - spin_unlock_bh(&fip->ctlr_lock); + spin_unlock_irqrestore(&fip->ctlr_lock, flags); schedule_work(&fip->timer_work); return -EINPROGRESS; case ELS_FDISC: @@ -1705,10 +1707,11 @@ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) { struct fcoe_fcf *fcf; + unsigned long flags; int error; mutex_lock(&fip->ctlr_mutex); - spin_lock_bh(&fip->ctlr_lock); + spin_lock_irqsave(&fip->ctlr_lock, flags); LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n"); fcf = fcoe_ctlr_select(fip); if (!fcf || fcf->flogi_sent) { @@ -1719,7 +1722,7 @@ fcoe_ctlr_solicit(fip, NULL); error = fcoe_ctlr_flogi_send_locked(fip); } - spin_unlock_bh(&fip->ctlr_lock); + spin_unlock_irqrestore(&fip->ctlr_lock, flags); mutex_unlock(&fip->ctlr_mutex); return error; } @@ -1736,8 +1739,9 @@ static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip) { struct fcoe_fcf *fcf; + unsigned long flags; - spin_lock_bh(&fip->ctlr_lock); + spin_lock_irqsave(&fip->ctlr_lock, flags); fcf = fip->sel_fcf; if (!fcf || !fip->flogi_req_send) goto unlock; @@ -1764,7 +1768,7 @@ } else /* XXX */ LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n"); unlock: - spin_unlock_bh(&fip->ctlr_lock); + spin_unlock_irqrestore(&fip->ctlr_lock, flags); } /** only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/lpfc/lpfc.h +++ linux-6.2.0/drivers/scsi/lpfc/lpfc.h @@ -895,6 +895,7 @@ enum lpfc_hba_bit_flags { FABRIC_COMANDS_BLOCKED, HBA_PCI_ERR, + MBX_TMO_ERR, }; struct lpfc_hba { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/lpfc/lpfc_bsg.c +++ linux-6.2.0/drivers/scsi/lpfc/lpfc_bsg.c @@ -889,7 +889,7 @@ struct lpfc_iocbq *piocbq) { uint32_t evt_req_id = 0; - uint32_t cmd; + u16 cmd; struct lpfc_dmabuf *dmabuf = NULL; struct lpfc_bsg_event *evt; struct event_data *evt_dat = NULL; @@ -915,7 +915,7 @@ ct_req = (struct lpfc_sli_ct_request *)bdeBuf1->virt; evt_req_id = ct_req->FsType; - cmd = ct_req->CommandResponse.bits.CmdRsp; + cmd = be16_to_cpu(ct_req->CommandResponse.bits.CmdRsp); spin_lock_irqsave(&phba->ct_ev_lock, flags); list_for_each_entry(evt, &phba->ct_ev_waiters, node) { @@ -3186,8 +3186,8 @@ ctreq->RevisionId.bits.InId = 0; ctreq->FsType = SLI_CT_ELX_LOOPBACK; ctreq->FsSubType = 0; - ctreq->CommandResponse.bits.CmdRsp = ELX_LOOPBACK_DATA; - ctreq->CommandResponse.bits.Size = size; + ctreq->CommandResponse.bits.CmdRsp = cpu_to_be16(ELX_LOOPBACK_DATA); + ctreq->CommandResponse.bits.Size = cpu_to_be16(size); segment_offset = ELX_LOOPBACK_HEADER_SZ; } else segment_offset = 0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/lpfc/lpfc_scsi.c +++ linux-6.2.0/drivers/scsi/lpfc/lpfc_scsi.c @@ -109,8 +109,6 @@ } } -#define LPFC_INVALID_REFTAG ((u32)-1) - /** * lpfc_rampdown_queue_depth - Post RAMP_DOWN_QUEUE event to worker thread * @phba: The Hba for which this call is being executed. @@ -978,8 +976,6 @@ sgpe = scsi_prot_sglist(sc); lba = scsi_prot_ref_tag(sc); - if (lba == LPFC_INVALID_REFTAG) - return 0; /* First check if we need to match the LBA */ if (phba->lpfc_injerr_lba != LPFC_INJERR_LBA_OFF) { @@ -1560,8 +1556,6 @@ /* extract some info from the scsi command for pde*/ reftag = scsi_prot_ref_tag(sc); - if (reftag == LPFC_INVALID_REFTAG) - goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -1723,8 +1717,6 @@ /* extract some info from the scsi command */ blksize = scsi_prot_interval(sc); reftag = scsi_prot_ref_tag(sc); - if (reftag == LPFC_INVALID_REFTAG) - goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -1954,8 +1946,6 @@ /* extract some info from the scsi command for pde*/ reftag = scsi_prot_ref_tag(sc); - if (reftag == LPFC_INVALID_REFTAG) - goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -2155,8 +2145,6 @@ /* extract some info from the scsi command */ blksize = scsi_prot_interval(sc); reftag = scsi_prot_ref_tag(sc); - if (reftag == LPFC_INVALID_REFTAG) - goto out; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS rc = lpfc_bg_err_inject(phba, sc, &reftag, NULL, 1); @@ -2748,8 +2736,6 @@ src = (struct scsi_dif_tuple *)sg_virt(sgpe); start_ref_tag = scsi_prot_ref_tag(cmd); - if (start_ref_tag == LPFC_INVALID_REFTAG) - goto out; start_app_tag = src->app_tag; len = sgpe->length; while (src && protsegcnt) { @@ -3495,11 +3481,11 @@ scsi_cmnd->sc_data_direction); lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, - "9084 Cannot setup S/G List for HBA" - "IO segs %d/%d SGL %d SCSI %d: %d %d\n", + "9084 Cannot setup S/G List for HBA " + "IO segs %d/%d SGL %d SCSI %d: %d %d %d\n", lpfc_cmd->seg_cnt, lpfc_cmd->prot_seg_cnt, phba->cfg_total_seg_cnt, phba->cfg_sg_seg_cnt, - prot_group_type, num_sge); + prot_group_type, num_sge, ret); lpfc_cmd->seg_cnt = 0; lpfc_cmd->prot_seg_cnt = 0; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/mpt3sas/mpt3sas_base.h +++ linux-6.2.0/drivers/scsi/mpt3sas/mpt3sas_base.h @@ -1618,6 +1618,7 @@ u8 diag_trigger_active; u8 atomic_desc_capable; BASE_READ_REG base_readl; + BASE_READ_REG base_readl_ext_retry; struct SL_WH_MASTER_TRIGGER_T diag_trigger_master; struct SL_WH_EVENT_TRIGGERS_T diag_trigger_event; struct SL_WH_SCSI_TRIGGERS_T diag_trigger_scsi; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/mvumi.c +++ linux-6.2.0/drivers/scsi/mvumi.c @@ -1500,7 +1500,7 @@ sdev = scsi_device_lookup(mhba->shost, 0, id, 0); if (sdev) { - scsi_rescan_device(&sdev->sdev_gendev); + scsi_rescan_device(sdev); scsi_device_put(sdev); } } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/pm8001/pm8001_hwi.c +++ linux-6.2.0/drivers/scsi/pm8001/pm8001_hwi.c @@ -4179,7 +4179,7 @@ payload.sas_identify.dev_type = SAS_END_DEVICE; payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; memcpy(payload.sas_identify.sas_addr, - pm8001_ha->sas_addr, SAS_ADDR_SIZE); + &pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE); payload.sas_identify.phy_id = phy_id; return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/pm8001/pm8001_init.c +++ linux-6.2.0/drivers/scsi/pm8001/pm8001_init.c @@ -274,7 +274,6 @@ return ret; } -static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha); static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha); /** @@ -295,13 +294,6 @@ pm8001_dbg(pm8001_ha, INIT, "pm8001_alloc: PHY:%x\n", pm8001_ha->chip->n_phy); - /* Setup Interrupt */ - rc = pm8001_setup_irq(pm8001_ha); - if (rc) { - pm8001_dbg(pm8001_ha, FAIL, - "pm8001_setup_irq failed [ret: %d]\n", rc); - goto err_out; - } /* Request Interrupt */ rc = pm8001_request_irq(pm8001_ha); if (rc) @@ -1019,47 +1011,38 @@ } #endif -static u32 pm8001_setup_irq(struct pm8001_hba_info *pm8001_ha) -{ - struct pci_dev *pdev; - - pdev = pm8001_ha->pdev; - -#ifdef PM8001_USE_MSIX - if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) - return pm8001_setup_msix(pm8001_ha); - pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n"); -#endif - return 0; -} - /** * pm8001_request_irq - register interrupt * @pm8001_ha: our ha struct. */ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) { - struct pci_dev *pdev; + struct pci_dev *pdev = pm8001_ha->pdev; +#ifdef PM8001_USE_MSIX int rc; - pdev = pm8001_ha->pdev; + if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { + rc = pm8001_setup_msix(pm8001_ha); + if (rc) { + pm8001_dbg(pm8001_ha, FAIL, + "pm8001_setup_irq failed [ret: %d]\n", rc); + return rc; + } -#ifdef PM8001_USE_MSIX - if (pdev->msix_cap && pci_msi_enabled()) - return pm8001_request_msix(pm8001_ha); - else { - pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n"); - goto intx; + if (pdev->msix_cap && pci_msi_enabled()) + return pm8001_request_msix(pm8001_ha); } + + pm8001_dbg(pm8001_ha, INIT, "MSIX not supported!!!\n"); #endif -intx: /* initialize the INT-X interrupt */ pm8001_ha->irq_vector[0].irq_id = 0; pm8001_ha->irq_vector[0].drv_inst = pm8001_ha; - rc = request_irq(pdev->irq, pm8001_interrupt_handler_intx, IRQF_SHARED, - pm8001_ha->name, SHOST_TO_SAS_HA(pm8001_ha->shost)); - return rc; + + return request_irq(pdev->irq, pm8001_interrupt_handler_intx, + IRQF_SHARED, pm8001_ha->name, + SHOST_TO_SAS_HA(pm8001_ha->shost)); } /** only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/pm8001/pm80xx_hwi.c +++ linux-6.2.0/drivers/scsi/pm8001/pm80xx_hwi.c @@ -3636,10 +3636,12 @@ (struct set_ctrl_cfg_resp *)(piomb + 4); u32 status = le32_to_cpu(pPayload->status); u32 err_qlfr_pgcd = le32_to_cpu(pPayload->err_qlfr_pgcd); + u32 tag = le32_to_cpu(pPayload->tag); pm8001_dbg(pm8001_ha, MSG, "SET CONTROLLER RESP: status 0x%x qlfr_pgcd 0x%x\n", status, err_qlfr_pgcd); + pm8001_tag_free(pm8001_ha, tag); return 0; } @@ -4641,7 +4643,7 @@ payload.sas_identify.dev_type = SAS_END_DEVICE; payload.sas_identify.initiator_bits = SAS_PROTOCOL_ALL; memcpy(payload.sas_identify.sas_addr, - &pm8001_ha->sas_addr, SAS_ADDR_SIZE); + &pm8001_ha->phy[phy_id].dev_sas_addr, SAS_ADDR_SIZE); payload.sas_identify.phy_id = phy_id; return pm8001_mpi_build_cmd(pm8001_ha, 0, opcode, &payload, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/qedf/qedf_dbg.h +++ linux-6.2.0/drivers/scsi/qedf/qedf_dbg.h @@ -59,6 +59,8 @@ #define QEDF_LOG_NOTICE 0x40000000 /* Notice logs */ #define QEDF_LOG_WARN 0x80000000 /* Warning logs */ +#define QEDF_DEBUGFS_LOG_LEN (2 * PAGE_SIZE) + /* Debug context structure */ struct qedf_dbg_ctx { unsigned int host_no; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/qedf/qedf_debugfs.c +++ linux-6.2.0/drivers/scsi/qedf/qedf_debugfs.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "qedf.h" #include "qedf_dbg.h" @@ -98,7 +99,9 @@ qedf_dbg_fp_int_cmd_read(struct file *filp, char __user *buffer, size_t count, loff_t *ppos) { + ssize_t ret; size_t cnt = 0; + char *cbuf; int id; struct qedf_fastpath *fp = NULL; struct qedf_dbg_ctx *qedf_dbg = @@ -108,19 +111,25 @@ QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n"); - cnt = sprintf(buffer, "\nFastpath I/O completions\n\n"); + cbuf = vmalloc(QEDF_DEBUGFS_LOG_LEN); + if (!cbuf) + return 0; + + cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt, "\nFastpath I/O completions\n\n"); for (id = 0; id < qedf->num_queues; id++) { fp = &(qedf->fp_array[id]); if (fp->sb_id == QEDF_SB_ID_NULL) continue; - cnt += sprintf((buffer + cnt), "#%d: %lu\n", id, - fp->completions); + cnt += scnprintf(cbuf + cnt, QEDF_DEBUGFS_LOG_LEN - cnt, + "#%d: %lu\n", id, fp->completions); } - cnt = min_t(int, count, cnt - *ppos); - *ppos += cnt; - return cnt; + ret = simple_read_from_buffer(buffer, count, ppos, cbuf, cnt); + + vfree(cbuf); + + return ret; } static ssize_t @@ -138,15 +147,14 @@ loff_t *ppos) { int cnt; + char cbuf[32]; struct qedf_dbg_ctx *qedf_dbg = (struct qedf_dbg_ctx *)filp->private_data; QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "debug mask=0x%x\n", qedf_debug); - cnt = sprintf(buffer, "debug mask = 0x%x\n", qedf_debug); + cnt = scnprintf(cbuf, sizeof(cbuf), "debug mask = 0x%x\n", qedf_debug); - cnt = min_t(int, count, cnt - *ppos); - *ppos += cnt; - return cnt; + return simple_read_from_buffer(buffer, count, ppos, cbuf, cnt); } static ssize_t @@ -185,18 +193,17 @@ size_t count, loff_t *ppos) { int cnt; + char cbuf[7]; struct qedf_dbg_ctx *qedf_dbg = (struct qedf_dbg_ctx *)filp->private_data; struct qedf_ctx *qedf = container_of(qedf_dbg, struct qedf_ctx, dbg_ctx); QEDF_INFO(qedf_dbg, QEDF_LOG_DEBUGFS, "entered\n"); - cnt = sprintf(buffer, "%s\n", + cnt = scnprintf(cbuf, sizeof(cbuf), "%s\n", qedf->stop_io_on_error ? "true" : "false"); - cnt = min_t(int, count, cnt - *ppos); - *ppos += cnt; - return cnt; + return simple_read_from_buffer(buffer, count, ppos, cbuf, cnt); } static ssize_t only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/qedf/qedf_io.c +++ linux-6.2.0/drivers/scsi/qedf/qedf_io.c @@ -1904,6 +1904,7 @@ goto drop_rdata_kref; } + spin_lock_irqsave(&fcport->rport_lock, flags); if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) || test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) || test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) { @@ -1911,17 +1912,20 @@ "io_req xid=0x%x sc_cmd=%p already in cleanup or abort processing or already completed.\n", io_req->xid, io_req->sc_cmd); rc = 1; + spin_unlock_irqrestore(&fcport->rport_lock, flags); goto drop_rdata_kref; } + /* Set the command type to abort */ + io_req->cmd_type = QEDF_ABTS; + spin_unlock_irqrestore(&fcport->rport_lock, flags); + kref_get(&io_req->refcount); xid = io_req->xid; qedf->control_requests++; qedf->packet_aborts++; - /* Set the command type to abort */ - io_req->cmd_type = QEDF_ABTS; io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; set_bit(QEDF_CMD_IN_ABORT, &io_req->flags); @@ -2210,7 +2214,9 @@ refcount, fcport, fcport->rdata->ids.port_id); /* Cleanup cmds re-use the same TID as the original I/O */ + spin_lock_irqsave(&fcport->rport_lock, flags); io_req->cmd_type = QEDF_CLEANUP; + spin_unlock_irqrestore(&fcport->rport_lock, flags); io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts; init_completion(&io_req->cleanup_done); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/qla2xxx/qla_dbg.c +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_dbg.c @@ -18,7 +18,7 @@ * | Queue Command and IO tracing | 0x3074 | 0x300b | * | | | 0x3027-0x3028 | * | | | 0x303d-0x3041 | - * | | | 0x302d,0x3033 | + * | | | 0x302e,0x3033 | * | | | 0x3036,0x3038 | * | | | 0x303a | * | DPC Thread | 0x4023 | 0x4002,0x4013 | only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/qla2xxx/qla_mbx.c +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_mbx.c @@ -273,7 +273,6 @@ spin_unlock_irqrestore(&ha->hardware_lock, flags); wait_time = jiffies; - atomic_inc(&ha->num_pend_mbx_stage3); if (!wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ)) { ql_dbg(ql_dbg_mbx, vha, 0x117a, @@ -290,7 +289,6 @@ spin_unlock_irqrestore(&ha->hardware_lock, flags); atomic_dec(&ha->num_pend_mbx_stage2); - atomic_dec(&ha->num_pend_mbx_stage3); rval = QLA_ABORTED; goto premature_exit; } @@ -302,11 +300,9 @@ ha->flags.mbox_busy = 0; spin_unlock_irqrestore(&ha->hardware_lock, flags); atomic_dec(&ha->num_pend_mbx_stage2); - atomic_dec(&ha->num_pend_mbx_stage3); rval = QLA_ABORTED; goto premature_exit; } - atomic_dec(&ha->num_pend_mbx_stage3); if (time_after(jiffies, wait_time + 5 * HZ)) ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n", @@ -2213,6 +2209,9 @@ ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1054, "Entered %s.\n", __func__); + if (!ha->flags.fw_started) + return QLA_FUNCTION_FAILED; + mcp->mb[0] = MBC_GET_FIRMWARE_STATE; mcp->out_mb = MBX_0; if (IS_FWI2_CAPABLE(vha->hw)) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/qla2xxx/qla_target.c +++ linux-6.2.0/drivers/scsi/qla2xxx/qla_target.c @@ -1085,10 +1085,6 @@ (struct imm_ntfy_from_isp *)sess->iocb, SRB_NACK_LOGO); } - spin_lock_irqsave(&vha->work_lock, flags); - sess->flags &= ~FCF_ASYNC_SENT; - spin_unlock_irqrestore(&vha->work_lock, flags); - spin_lock_irqsave(&ha->tgt.sess_lock, flags); if (sess->se_sess) { sess->se_sess = NULL; @@ -1098,7 +1094,6 @@ qla2x00_set_fcport_disc_state(sess, DSC_DELETED); sess->fw_login_state = DSC_LS_PORT_UNAVAIL; - sess->deleted = QLA_SESS_DELETED; if (sess->login_succ && !IS_SW_RESV_ADDR(sess->d_id)) { vha->fcport_count--; @@ -1150,10 +1145,15 @@ sess->explicit_logout = 0; spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); - sess->free_pending = 0; qla2x00_dfs_remove_rport(vha, sess); + spin_lock_irqsave(&vha->work_lock, flags); + sess->flags &= ~FCF_ASYNC_SENT; + sess->deleted = QLA_SESS_DELETED; + sess->free_pending = 0; + spin_unlock_irqrestore(&vha->work_lock, flags); + ql_dbg(ql_dbg_disc, vha, 0xf001, "Unregistration of sess %p %8phC finished fcp_cnt %d\n", sess, sess->port_name, vha->fcport_count); @@ -1202,12 +1202,12 @@ * management from being sent. */ sess->flags |= FCF_ASYNC_SENT; + sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; spin_unlock_irqrestore(&sess->vha->work_lock, flags); if (sess->se_sess) vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess); - sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND); sess->last_rscn_gen = sess->rscn_gen; sess->last_login_gen = sess->login_gen; @@ -4442,8 +4442,7 @@ queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, &cmd->work); } else if (ha->msix_count) { if (cmd->atio.u.isp24.fcp_cmnd.rddata) - queue_work_on(smp_processor_id(), qla_tgt_wq, - &cmd->work); + queue_work(qla_tgt_wq, &cmd->work); else queue_work_on(cmd->se_cmd.cpuid, qla_tgt_wq, &cmd->work); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ linux-6.2.0/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -310,7 +310,7 @@ cmd->trc_flags |= TRC_CMD_DONE; INIT_WORK(&cmd->work, tcm_qla2xxx_complete_free); - queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); + queue_work(tcm_qla2xxx_free_wq, &cmd->work); } /* @@ -557,7 +557,7 @@ cmd->trc_flags |= TRC_DATA_IN; cmd->cmd_in_wq = 1; INIT_WORK(&cmd->work, tcm_qla2xxx_handle_data_work); - queue_work_on(smp_processor_id(), tcm_qla2xxx_free_wq, &cmd->work); + queue_work(tcm_qla2xxx_free_wq, &cmd->work); } static int tcm_qla2xxx_chk_dif_tags(uint32_t tag) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/qla4xxx/ql4_os.c +++ linux-6.2.0/drivers/scsi/qla4xxx/ql4_os.c @@ -968,6 +968,11 @@ memset(&chap_rec, 0, sizeof(chap_rec)); nla_for_each_attr(attr, data, len, rem) { + if (nla_len(attr) < sizeof(*param_info)) { + rc = -EINVAL; + goto exit_set_chap; + } + param_info = nla_data(attr); switch (param_info->param) { @@ -2750,6 +2755,11 @@ } nla_for_each_attr(attr, data, len, rem) { + if (nla_len(attr) < sizeof(*iface_param)) { + rval = -EINVAL; + goto exit_init_fw_cb; + } + iface_param = nla_data(attr); if (iface_param->param_type == ISCSI_NET_PARAM) { @@ -8104,6 +8114,11 @@ memset((void *)&chap_tbl, 0, sizeof(chap_tbl)); nla_for_each_attr(attr, data, len, rem) { + if (nla_len(attr) < sizeof(*fnode_param)) { + rc = -EINVAL; + goto exit_set_param; + } + fnode_param = nla_data(attr); switch (fnode_param->param) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/scsi_priv.h +++ linux-6.2.0/drivers/scsi/scsi_priv.h @@ -132,7 +132,6 @@ extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, unsigned int, u64, enum scsi_scan_mode); extern void scsi_forget_host(struct Scsi_Host *); -extern void scsi_rescan_device(struct device *); /* scsi_sysctl.c */ #ifdef CONFIG_SYSCTL only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/scsi_sysfs.c +++ linux-6.2.0/drivers/scsi/scsi_sysfs.c @@ -746,7 +746,7 @@ store_rescan_field (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - scsi_rescan_device(dev); + scsi_rescan_device(to_scsi_device(dev)); return count; } static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field); @@ -839,7 +839,7 @@ * waiting for pending I/O to finish. */ blk_mq_run_hw_queues(sdev->request_queue, true); - scsi_rescan_device(dev); + scsi_rescan_device(sdev); } return ret == 0 ? count : -EINVAL; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/scsi_transport_iscsi.c +++ linux-6.2.0/drivers/scsi/scsi_transport_iscsi.c @@ -3013,14 +3013,15 @@ } static int -iscsi_if_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev) +iscsi_if_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen) { char *data = (char*)ev + sizeof(*ev); struct iscsi_cls_conn *conn; struct iscsi_cls_session *session; int err = 0, value = 0, state; - if (ev->u.set_param.len > PAGE_SIZE) + if (ev->u.set_param.len > rlen || + ev->u.set_param.len > PAGE_SIZE) return -EINVAL; session = iscsi_session_lookup(ev->u.set_param.sid); @@ -3028,6 +3029,10 @@ if (!conn || !session) return -EINVAL; + /* data will be regarded as NULL-ended string, do length check */ + if (strlen(data) > ev->u.set_param.len) + return -EINVAL; + switch (ev->u.set_param.param) { case ISCSI_PARAM_SESS_RECOVERY_TMO: sscanf(data, "%d", &value); @@ -3117,7 +3122,7 @@ static int iscsi_if_transport_ep(struct iscsi_transport *transport, - struct iscsi_uevent *ev, int msg_type) + struct iscsi_uevent *ev, int msg_type, u32 rlen) { struct iscsi_endpoint *ep; int rc = 0; @@ -3125,7 +3130,10 @@ switch (msg_type) { case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST: case ISCSI_UEVENT_TRANSPORT_EP_CONNECT: - rc = iscsi_if_ep_connect(transport, ev, msg_type); + if (rlen < sizeof(struct sockaddr)) + rc = -EINVAL; + else + rc = iscsi_if_ep_connect(transport, ev, msg_type); break; case ISCSI_UEVENT_TRANSPORT_EP_POLL: if (!transport->ep_poll) @@ -3149,12 +3157,15 @@ static int iscsi_tgt_dscvr(struct iscsi_transport *transport, - struct iscsi_uevent *ev) + struct iscsi_uevent *ev, u32 rlen) { struct Scsi_Host *shost; struct sockaddr *dst_addr; int err; + if (rlen < sizeof(*dst_addr)) + return -EINVAL; + if (!transport->tgt_dscvr) return -EINVAL; @@ -3175,7 +3186,7 @@ static int iscsi_set_host_param(struct iscsi_transport *transport, - struct iscsi_uevent *ev) + struct iscsi_uevent *ev, u32 rlen) { char *data = (char*)ev + sizeof(*ev); struct Scsi_Host *shost; @@ -3184,7 +3195,8 @@ if (!transport->set_host_param) return -ENOSYS; - if (ev->u.set_host_param.len > PAGE_SIZE) + if (ev->u.set_host_param.len > rlen || + ev->u.set_host_param.len > PAGE_SIZE) return -EINVAL; shost = scsi_host_lookup(ev->u.set_host_param.host_no); @@ -3194,6 +3206,10 @@ return -ENODEV; } + /* see similar check in iscsi_if_set_param() */ + if (strlen(data) > ev->u.set_host_param.len) + return -EINVAL; + err = transport->set_host_param(shost, ev->u.set_host_param.param, data, ev->u.set_host_param.len); scsi_host_put(shost); @@ -3201,12 +3217,15 @@ } static int -iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev) +iscsi_set_path(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen) { struct Scsi_Host *shost; struct iscsi_path *params; int err; + if (rlen < sizeof(*params)) + return -EINVAL; + if (!transport->set_path) return -ENOSYS; @@ -3266,12 +3285,15 @@ } static int -iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev) +iscsi_send_ping(struct iscsi_transport *transport, struct iscsi_uevent *ev, u32 rlen) { struct Scsi_Host *shost; struct sockaddr *dst_addr; int err; + if (rlen < sizeof(*dst_addr)) + return -EINVAL; + if (!transport->send_ping) return -ENOSYS; @@ -3769,13 +3791,12 @@ } static int iscsi_if_transport_conn(struct iscsi_transport *transport, - struct nlmsghdr *nlh) + struct nlmsghdr *nlh, u32 pdu_len) { struct iscsi_uevent *ev = nlmsg_data(nlh); struct iscsi_cls_session *session; struct iscsi_cls_conn *conn = NULL; struct iscsi_endpoint *ep; - uint32_t pdu_len; int err = 0; switch (nlh->nlmsg_type) { @@ -3860,8 +3881,6 @@ break; case ISCSI_UEVENT_SEND_PDU: - pdu_len = nlh->nlmsg_len - sizeof(*nlh) - sizeof(*ev); - if ((ev->u.send_pdu.hdr_size > pdu_len) || (ev->u.send_pdu.data_size > (pdu_len - ev->u.send_pdu.hdr_size))) { err = -EINVAL; @@ -3891,6 +3910,7 @@ struct iscsi_internal *priv; struct iscsi_cls_session *session; struct iscsi_endpoint *ep = NULL; + u32 rlen; if (!netlink_capable(skb, CAP_SYS_ADMIN)) return -EPERM; @@ -3910,6 +3930,13 @@ portid = NETLINK_CB(skb).portid; + /* + * Even though the remaining payload may not be regarded as nlattr, + * (like address or something else), calculate the remaining length + * here to ease following length checks. + */ + rlen = nlmsg_attrlen(nlh, sizeof(*ev)); + switch (nlh->nlmsg_type) { case ISCSI_UEVENT_CREATE_SESSION: err = iscsi_if_create_session(priv, ep, ev, @@ -3966,7 +3993,7 @@ err = -EINVAL; break; case ISCSI_UEVENT_SET_PARAM: - err = iscsi_if_set_param(transport, ev); + err = iscsi_if_set_param(transport, ev, rlen); break; case ISCSI_UEVENT_CREATE_CONN: case ISCSI_UEVENT_DESTROY_CONN: @@ -3974,7 +4001,7 @@ case ISCSI_UEVENT_START_CONN: case ISCSI_UEVENT_BIND_CONN: case ISCSI_UEVENT_SEND_PDU: - err = iscsi_if_transport_conn(transport, nlh); + err = iscsi_if_transport_conn(transport, nlh, rlen); break; case ISCSI_UEVENT_GET_STATS: err = iscsi_if_get_stats(transport, nlh); @@ -3983,23 +4010,22 @@ case ISCSI_UEVENT_TRANSPORT_EP_POLL: case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT: case ISCSI_UEVENT_TRANSPORT_EP_CONNECT_THROUGH_HOST: - err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type); + err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type, rlen); break; case ISCSI_UEVENT_TGT_DSCVR: - err = iscsi_tgt_dscvr(transport, ev); + err = iscsi_tgt_dscvr(transport, ev, rlen); break; case ISCSI_UEVENT_SET_HOST_PARAM: - err = iscsi_set_host_param(transport, ev); + err = iscsi_set_host_param(transport, ev, rlen); break; case ISCSI_UEVENT_PATH_UPDATE: - err = iscsi_set_path(transport, ev); + err = iscsi_set_path(transport, ev, rlen); break; case ISCSI_UEVENT_SET_IFACE_PARAMS: - err = iscsi_set_iface_params(transport, ev, - nlmsg_attrlen(nlh, sizeof(*ev))); + err = iscsi_set_iface_params(transport, ev, rlen); break; case ISCSI_UEVENT_PING: - err = iscsi_send_ping(transport, ev); + err = iscsi_send_ping(transport, ev, rlen); break; case ISCSI_UEVENT_GET_CHAP: err = iscsi_get_chap(transport, nlh); @@ -4008,13 +4034,10 @@ err = iscsi_delete_chap(transport, ev); break; case ISCSI_UEVENT_SET_FLASHNODE_PARAMS: - err = iscsi_set_flashnode_param(transport, ev, - nlmsg_attrlen(nlh, - sizeof(*ev))); + err = iscsi_set_flashnode_param(transport, ev, rlen); break; case ISCSI_UEVENT_NEW_FLASHNODE: - err = iscsi_new_flashnode(transport, ev, - nlmsg_attrlen(nlh, sizeof(*ev))); + err = iscsi_new_flashnode(transport, ev, rlen); break; case ISCSI_UEVENT_DEL_FLASHNODE: err = iscsi_del_flashnode(transport, ev); @@ -4029,8 +4052,7 @@ err = iscsi_logout_flashnode_sid(transport, ev); break; case ISCSI_UEVENT_SET_CHAP: - err = iscsi_set_chap(transport, ev, - nlmsg_attrlen(nlh, sizeof(*ev))); + err = iscsi_set_chap(transport, ev, rlen); break; case ISCSI_UEVENT_GET_HOST_STATS: err = iscsi_get_host_stats(transport, nlh); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/sd.h +++ linux-6.2.0/drivers/scsi/sd.h @@ -131,6 +131,7 @@ u8 provisioning_mode; u8 zeroing_mode; u8 nr_actuators; /* Number of actuators */ + bool suspended; /* Disk is suspended (stopped) */ unsigned ATO : 1; /* state of disk ATO bit */ unsigned cache_override : 1; /* temp override of WCE,RCD */ unsigned WCE : 1; /* state of disk WCE bit */ only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/smartpqi/smartpqi_init.c +++ linux-6.2.0/drivers/scsi/smartpqi/smartpqi_init.c @@ -2291,7 +2291,7 @@ device->advertised_queue_depth = device->queue_depth; scsi_change_queue_depth(device->sdev, device->advertised_queue_depth); if (device->rescan) { - scsi_rescan_device(&device->sdev->sdev_gendev); + scsi_rescan_device(device->sdev); device->rescan = false; } } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/scsi/virtio_scsi.c +++ linux-6.2.0/drivers/scsi/virtio_scsi.c @@ -325,7 +325,7 @@ /* Handle "Parameters changed", "Mode parameters changed", and "Capacity data has changed". */ if (asc == 0x2a && (ascq == 0x00 || ascq == 0x01 || ascq == 0x09)) - scsi_rescan_device(&sdev->sdev_gendev); + scsi_rescan_device(sdev); scsi_device_put(sdev); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/soc/imx/soc-imx8m.c +++ linux-6.2.0/drivers/soc/imx/soc-imx8m.c @@ -100,6 +100,7 @@ { void __iomem *ocotp_base; struct device_node *np; + struct clk *clk; u32 offset = of_machine_is_compatible("fsl,imx8mp") ? IMX8MP_OCOTP_UID_OFFSET : 0; @@ -109,11 +110,20 @@ ocotp_base = of_iomap(np, 0); WARN_ON(!ocotp_base); + clk = of_clk_get_by_name(np, NULL); + if (IS_ERR(clk)) { + WARN_ON(IS_ERR(clk)); + return; + } + + clk_prepare_enable(clk); soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH + offset); soc_uid <<= 32; soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW + offset); + clk_disable_unprepare(clk); + clk_put(clk); iounmap(ocotp_base); of_node_put(np); } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/soc/qcom/ocmem.c +++ linux-6.2.0/drivers/soc/qcom/ocmem.c @@ -76,8 +76,12 @@ #define OCMEM_REG_GFX_MPU_START 0x00001004 #define OCMEM_REG_GFX_MPU_END 0x00001008 -#define OCMEM_HW_PROFILE_NUM_PORTS(val) FIELD_PREP(0x0000000f, (val)) -#define OCMEM_HW_PROFILE_NUM_MACROS(val) FIELD_PREP(0x00003f00, (val)) +#define OCMEM_HW_VERSION_MAJOR(val) FIELD_GET(GENMASK(31, 28), val) +#define OCMEM_HW_VERSION_MINOR(val) FIELD_GET(GENMASK(27, 16), val) +#define OCMEM_HW_VERSION_STEP(val) FIELD_GET(GENMASK(15, 0), val) + +#define OCMEM_HW_PROFILE_NUM_PORTS(val) FIELD_GET(0x0000000f, (val)) +#define OCMEM_HW_PROFILE_NUM_MACROS(val) FIELD_GET(0x00003f00, (val)) #define OCMEM_HW_PROFILE_LAST_REGN_HALFSIZE 0x00010000 #define OCMEM_HW_PROFILE_INTERLEAVING 0x00020000 @@ -355,6 +359,12 @@ } } + reg = ocmem_read(ocmem, OCMEM_REG_HW_VERSION); + dev_dbg(dev, "OCMEM hardware version: %lu.%lu.%lu\n", + OCMEM_HW_VERSION_MAJOR(reg), + OCMEM_HW_VERSION_MINOR(reg), + OCMEM_HW_VERSION_STEP(reg)); + reg = ocmem_read(ocmem, OCMEM_REG_HW_PROFILE); ocmem->num_ports = OCMEM_HW_PROFILE_NUM_PORTS(reg); ocmem->num_macros = OCMEM_HW_PROFILE_NUM_MACROS(reg); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/soc/qcom/qmi_encdec.c +++ linux-6.2.0/drivers/soc/qcom/qmi_encdec.c @@ -534,8 +534,8 @@ decoded_bytes += rc; } - if (string_len > temp_ei->elem_len) { - pr_err("%s: String len %d > Max Len %d\n", + if (string_len >= temp_ei->elem_len) { + pr_err("%s: String len %d >= Max Len %d\n", __func__, string_len, temp_ei->elem_len); return -ETOOSMALL; } else if (string_len > tlv_len) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/soc/qcom/smem.c +++ linux-6.2.0/drivers/soc/qcom/smem.c @@ -723,7 +723,7 @@ static bool addr_in_range(void __iomem *base, size_t size, void *addr) { - return base && (addr >= base && addr < base + size); + return base && ((void __iomem *)addr >= base && (void __iomem *)addr < base + size); } /** only in patch2: unchanged: --- linux-6.2.0.orig/drivers/spi/spi-gxp.c +++ linux-6.2.0/drivers/spi/spi-gxp.c @@ -195,7 +195,7 @@ return ret; } - return write_len; + return 0; } static int do_gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/spi/spi-intel-pci.c +++ linux-6.2.0/drivers/spi/spi-intel-pci.c @@ -72,6 +72,7 @@ { PCI_VDEVICE(INTEL, 0x4da4), (unsigned long)&bxt_info }, { PCI_VDEVICE(INTEL, 0x51a4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x54a4), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0x5794), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x7a24), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x7aa4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0x7e23), (unsigned long)&cnl_info }, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/spi/spi-nxp-fspi.c +++ linux-6.2.0/drivers/spi/spi-nxp-fspi.c @@ -1029,6 +1029,13 @@ fspi_writel(f, FSPI_AHBCR_PREF_EN | FSPI_AHBCR_RDADDROPT, base + FSPI_AHBCR); + /* Reset the FLSHxCR1 registers. */ + reg = FSPI_FLSHXCR1_TCSH(0x3) | FSPI_FLSHXCR1_TCSS(0x3); + fspi_writel(f, reg, base + FSPI_FLSHA1CR1); + fspi_writel(f, reg, base + FSPI_FLSHA2CR1); + fspi_writel(f, reg, base + FSPI_FLSHB1CR1); + fspi_writel(f, reg, base + FSPI_FLSHB2CR1); + /* AHB Read - Set lut sequence ID for all CS. */ fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA1CR2); fspi_writel(f, SEQID_LUT, base + FSPI_FLSHA2CR2); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/spi/spi-stm32.c +++ linux-6.2.0/drivers/spi/spi-stm32.c @@ -268,6 +268,7 @@ * @fifo_size: size of the embedded fifo in bytes * @cur_midi: master inter-data idleness in ns * @cur_speed: speed configured in Hz + * @cur_half_period: time of a half bit in us * @cur_bpw: number of bits in a single SPI data frame * @cur_fthlv: fifo threshold level (data frames in a single data packet) * @cur_comm: SPI communication mode @@ -294,6 +295,7 @@ unsigned int cur_midi; unsigned int cur_speed; + unsigned int cur_half_period; unsigned int cur_bpw; unsigned int cur_fthlv; unsigned int cur_comm; @@ -454,6 +456,8 @@ spi->cur_speed = spi->clk_rate / (1 << mbrdiv); + spi->cur_half_period = DIV_ROUND_CLOSEST(USEC_PER_SEC, 2 * spi->cur_speed); + return mbrdiv - 1; } @@ -695,6 +699,10 @@ return; } + /* Add a delay to make sure that transmission is ended. */ + if (spi->cur_half_period) + udelay(spi->cur_half_period); + if (spi->cur_usedma && spi->dma_tx) dmaengine_terminate_all(spi->dma_tx); if (spi->cur_usedma && spi->dma_rx) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/spi/spi-sun6i.c +++ linux-6.2.0/drivers/spi/spi-sun6i.c @@ -95,6 +95,7 @@ struct reset_control *rstc; struct completion done; + struct completion dma_rx_done; const u8 *tx_buf; u8 *rx_buf; @@ -189,6 +190,13 @@ return SUN6I_MAX_XFER_SIZE - 1; } +static void sun6i_spi_dma_rx_cb(void *param) +{ + struct sun6i_spi *sspi = param; + + complete(&sspi->dma_rx_done); +} + static int sun6i_spi_prepare_dma(struct sun6i_spi *sspi, struct spi_transfer *tfr) { @@ -200,7 +208,7 @@ struct dma_slave_config rxconf = { .direction = DMA_DEV_TO_MEM, .src_addr = sspi->dma_addr_rx, - .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, + .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, .src_maxburst = 8, }; @@ -213,6 +221,8 @@ DMA_PREP_INTERRUPT); if (!rxdesc) return -EINVAL; + rxdesc->callback_param = sspi; + rxdesc->callback = sun6i_spi_dma_rx_cb; } txdesc = NULL; @@ -268,6 +278,7 @@ return -EINVAL; reinit_completion(&sspi->done); + reinit_completion(&sspi->dma_rx_done); sspi->tx_buf = tfr->tx_buf; sspi->rx_buf = tfr->rx_buf; sspi->len = tfr->len; @@ -426,6 +437,22 @@ start = jiffies; timeout = wait_for_completion_timeout(&sspi->done, msecs_to_jiffies(tx_time)); + + if (!use_dma) { + sun6i_spi_drain_fifo(sspi); + } else { + if (timeout && rx_len) { + /* + * Even though RX on the peripheral side has finished + * RX DMA might still be in flight + */ + timeout = wait_for_completion_timeout(&sspi->dma_rx_done, + timeout); + if (!timeout) + dev_warn(&master->dev, "RX DMA timeout\n"); + } + } + end = jiffies; if (!timeout) { dev_warn(&master->dev, @@ -453,7 +480,6 @@ /* Transfer complete */ if (status & SUN6I_INT_CTL_TC) { sun6i_spi_write(sspi, SUN6I_INT_STA_REG, SUN6I_INT_CTL_TC); - sun6i_spi_drain_fifo(sspi); complete(&sspi->done); return IRQ_HANDLED; } @@ -611,6 +637,7 @@ } init_completion(&sspi->done); + init_completion(&sspi->dma_rx_done); sspi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(sspi->rstc)) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/spi/spi-tegra20-sflash.c +++ linux-6.2.0/drivers/spi/spi-tegra20-sflash.c @@ -455,7 +455,11 @@ goto exit_free_master; } - tsd->irq = platform_get_irq(pdev, 0); + ret = platform_get_irq(pdev, 0); + if (ret < 0) + goto exit_free_master; + tsd->irq = ret; + ret = request_irq(tsd->irq, tegra_sflash_isr, 0, dev_name(&pdev->dev), tsd); if (ret < 0) { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/spi/spi-zynqmp-gqspi.c +++ linux-6.2.0/drivers/spi/spi-zynqmp-gqspi.c @@ -1342,9 +1342,9 @@ return 0; clk_dis_all: - pm_runtime_put_sync(&pdev->dev); - pm_runtime_set_suspended(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); clk_disable_unprepare(xqspi->refclk); clk_dis_pclk: clk_disable_unprepare(xqspi->pclk); @@ -1368,11 +1368,15 @@ { struct zynqmp_qspi *xqspi = platform_get_drvdata(pdev); + pm_runtime_get_sync(&pdev->dev); + zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0); + + pm_runtime_disable(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); clk_disable_unprepare(xqspi->refclk); clk_disable_unprepare(xqspi->pclk); - pm_runtime_set_suspended(&pdev->dev); - pm_runtime_disable(&pdev->dev); return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/spi/spi.c +++ linux-6.2.0/drivers/spi/spi.c @@ -4449,6 +4449,11 @@ return NOTIFY_OK; } + /* + * Clear the flag before adding the device so that fw_devlink + * doesn't skip adding consumers to this device. + */ + rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE; spi = of_register_spi_device(ctlr, rd->dn); put_device(&ctlr->dev); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/staging/fbtft/fb_ili9341.c +++ linux-6.2.0/drivers/staging/fbtft/fb_ili9341.c @@ -145,7 +145,7 @@ }, }; -FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9341", &display); +FBTFT_REGISTER_SPI_DRIVER(DRVNAME, "ilitek", "ili9341", &display); MODULE_ALIAS("spi:" DRVNAME); MODULE_ALIAS("platform:" DRVNAME); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/target/iscsi/iscsi_target_configfs.c +++ linux-6.2.0/drivers/target/iscsi/iscsi_target_configfs.c @@ -533,102 +533,102 @@ spin_lock_bh(&se_nacl->nacl_sess_lock); se_sess = se_nacl->nacl_sess; if (!se_sess) { - rb += sprintf(page+rb, "No active iSCSI Session for Initiator" + rb += sysfs_emit_at(page, rb, "No active iSCSI Session for Initiator" " Endpoint: %s\n", se_nacl->initiatorname); } else { sess = se_sess->fabric_sess_ptr; - rb += sprintf(page+rb, "InitiatorName: %s\n", + rb += sysfs_emit_at(page, rb, "InitiatorName: %s\n", sess->sess_ops->InitiatorName); - rb += sprintf(page+rb, "InitiatorAlias: %s\n", + rb += sysfs_emit_at(page, rb, "InitiatorAlias: %s\n", sess->sess_ops->InitiatorAlias); - rb += sprintf(page+rb, + rb += sysfs_emit_at(page, rb, "LIO Session ID: %u ISID: 0x%6ph TSIH: %hu ", sess->sid, sess->isid, sess->tsih); - rb += sprintf(page+rb, "SessionType: %s\n", + rb += sysfs_emit_at(page, rb, "SessionType: %s\n", (sess->sess_ops->SessionType) ? "Discovery" : "Normal"); - rb += sprintf(page+rb, "Session State: "); + rb += sysfs_emit_at(page, rb, "Session State: "); switch (sess->session_state) { case TARG_SESS_STATE_FREE: - rb += sprintf(page+rb, "TARG_SESS_FREE\n"); + rb += sysfs_emit_at(page, rb, "TARG_SESS_FREE\n"); break; case TARG_SESS_STATE_ACTIVE: - rb += sprintf(page+rb, "TARG_SESS_STATE_ACTIVE\n"); + rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_ACTIVE\n"); break; case TARG_SESS_STATE_LOGGED_IN: - rb += sprintf(page+rb, "TARG_SESS_STATE_LOGGED_IN\n"); + rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_LOGGED_IN\n"); break; case TARG_SESS_STATE_FAILED: - rb += sprintf(page+rb, "TARG_SESS_STATE_FAILED\n"); + rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_FAILED\n"); break; case TARG_SESS_STATE_IN_CONTINUE: - rb += sprintf(page+rb, "TARG_SESS_STATE_IN_CONTINUE\n"); + rb += sysfs_emit_at(page, rb, "TARG_SESS_STATE_IN_CONTINUE\n"); break; default: - rb += sprintf(page+rb, "ERROR: Unknown Session" + rb += sysfs_emit_at(page, rb, "ERROR: Unknown Session" " State!\n"); break; } - rb += sprintf(page+rb, "---------------------[iSCSI Session" + rb += sysfs_emit_at(page, rb, "---------------------[iSCSI Session" " Values]-----------------------\n"); - rb += sprintf(page+rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN" + rb += sysfs_emit_at(page, rb, " CmdSN/WR : CmdSN/WC : ExpCmdSN" " : MaxCmdSN : ITT : TTT\n"); max_cmd_sn = (u32) atomic_read(&sess->max_cmd_sn); - rb += sprintf(page+rb, " 0x%08x 0x%08x 0x%08x 0x%08x" + rb += sysfs_emit_at(page, rb, " 0x%08x 0x%08x 0x%08x 0x%08x" " 0x%08x 0x%08x\n", sess->cmdsn_window, (max_cmd_sn - sess->exp_cmd_sn) + 1, sess->exp_cmd_sn, max_cmd_sn, sess->init_task_tag, sess->targ_xfer_tag); - rb += sprintf(page+rb, "----------------------[iSCSI" + rb += sysfs_emit_at(page, rb, "----------------------[iSCSI" " Connections]-------------------------\n"); spin_lock(&sess->conn_lock); list_for_each_entry(conn, &sess->sess_conn_list, conn_list) { - rb += sprintf(page+rb, "CID: %hu Connection" + rb += sysfs_emit_at(page, rb, "CID: %hu Connection" " State: ", conn->cid); switch (conn->conn_state) { case TARG_CONN_STATE_FREE: - rb += sprintf(page+rb, + rb += sysfs_emit_at(page, rb, "TARG_CONN_STATE_FREE\n"); break; case TARG_CONN_STATE_XPT_UP: - rb += sprintf(page+rb, + rb += sysfs_emit_at(page, rb, "TARG_CONN_STATE_XPT_UP\n"); break; case TARG_CONN_STATE_IN_LOGIN: - rb += sprintf(page+rb, + rb += sysfs_emit_at(page, rb, "TARG_CONN_STATE_IN_LOGIN\n"); break; case TARG_CONN_STATE_LOGGED_IN: - rb += sprintf(page+rb, + rb += sysfs_emit_at(page, rb, "TARG_CONN_STATE_LOGGED_IN\n"); break; case TARG_CONN_STATE_IN_LOGOUT: - rb += sprintf(page+rb, + rb += sysfs_emit_at(page, rb, "TARG_CONN_STATE_IN_LOGOUT\n"); break; case TARG_CONN_STATE_LOGOUT_REQUESTED: - rb += sprintf(page+rb, + rb += sysfs_emit_at(page, rb, "TARG_CONN_STATE_LOGOUT_REQUESTED\n"); break; case TARG_CONN_STATE_CLEANUP_WAIT: - rb += sprintf(page+rb, + rb += sysfs_emit_at(page, rb, "TARG_CONN_STATE_CLEANUP_WAIT\n"); break; default: - rb += sprintf(page+rb, + rb += sysfs_emit_at(page, rb, "ERROR: Unknown Connection State!\n"); break; } - rb += sprintf(page+rb, " Address %pISc %s", &conn->login_sockaddr, + rb += sysfs_emit_at(page, rb, " Address %pISc %s", &conn->login_sockaddr, (conn->network_transport == ISCSI_TCP) ? "TCP" : "SCTP"); - rb += sprintf(page+rb, " StatSN: 0x%08x\n", + rb += sysfs_emit_at(page, rb, " StatSN: 0x%08x\n", conn->stat_sn); } spin_unlock(&sess->conn_lock); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/thermal/imx8mm_thermal.c +++ linux-6.2.0/drivers/thermal/imx8mm_thermal.c @@ -180,10 +180,8 @@ int ret; ret = nvmem_cell_read_u32(&pdev->dev, "calib", &ana0); - if (ret) { - dev_warn(dev, "Failed to read OCOTP nvmem cell (%d).\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Failed to read OCOTP nvmem cell\n"); writel(FIELD_PREP(TASR_BUF_VREF_MASK, FIELD_GET(ANA0_BUF_VREF_MASK, ana0)) | only in patch2: unchanged: --- linux-6.2.0.orig/drivers/thermal/thermal_of.c +++ linux-6.2.0/drivers/thermal/thermal_of.c @@ -149,8 +149,10 @@ */ for_each_child_of_node(trips, t) { - if (t == trip) + if (t == trip) { + of_node_put(t); goto out; + } i++; } @@ -409,13 +411,13 @@ ret = of_parse_phandle_with_args(map_np, "cooling-device", "#cooling-cells", index, &cooling_spec); - of_node_put(cooling_spec.np); - if (ret < 0) { pr_err("Invalid cooling-device entry\n"); return ret; } + of_node_put(cooling_spec.np); + if (cooling_spec.args_count < 2) { pr_err("wrong reference to cooling device, missing limits\n"); return -EINVAL; @@ -442,13 +444,13 @@ ret = of_parse_phandle_with_args(map_np, "cooling-device", "#cooling-cells", index, &cooling_spec); - of_node_put(cooling_spec.np); - if (ret < 0) { pr_err("Invalid cooling-device entry\n"); return ret; } + of_node_put(cooling_spec.np); + if (cooling_spec.args_count < 2) { pr_err("wrong reference to cooling device, missing limits\n"); return -EINVAL; @@ -519,8 +521,10 @@ for_each_child_of_node(cm_np, child) { ret = thermal_of_for_each_cooling_device(tz_np, child, tz, cdev, action); - if (ret) + if (ret) { + of_node_put(child); break; + } } of_node_put(cm_np); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/tty/serial/cpm_uart/cpm_uart_core.c +++ linux-6.2.0/drivers/tty/serial/cpm_uart/cpm_uart_core.c @@ -1256,19 +1256,14 @@ { struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; unsigned long flags; - int nolock = oops_in_progress; - if (unlikely(nolock)) { + if (unlikely(oops_in_progress)) { local_irq_save(flags); - } else { - spin_lock_irqsave(&pinfo->port.lock, flags); - } - - cpm_uart_early_write(pinfo, s, count, true); - - if (unlikely(nolock)) { + cpm_uart_early_write(pinfo, s, count, true); local_irq_restore(flags); } else { + spin_lock_irqsave(&pinfo->port.lock, flags); + cpm_uart_early_write(pinfo, s, count, true); spin_unlock_irqrestore(&pinfo->port.lock, flags); } } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/tty/serial/sprd_serial.c +++ linux-6.2.0/drivers/tty/serial/sprd_serial.c @@ -364,7 +364,7 @@ if (sp->rx_dma.virt) dma_free_coherent(sp->port.dev, SPRD_UART_RX_SIZE, sp->rx_dma.virt, sp->rx_dma.phys_addr); - + sp->rx_dma.virt = NULL; } static int sprd_rx_dma_config(struct uart_port *port, u32 burst) @@ -1106,7 +1106,7 @@ static int sprd_clk_init(struct uart_port *uport) { struct clk *clk_uart, *clk_parent; - struct sprd_uart_port *u = sprd_port[uport->line]; + struct sprd_uart_port *u = container_of(uport, struct sprd_uart_port, port); clk_uart = devm_clk_get(uport->dev, "uart"); if (IS_ERR(clk_uart)) { @@ -1149,22 +1149,22 @@ { struct resource *res; struct uart_port *up; + struct sprd_uart_port *sport; int irq; int index; int ret; index = of_alias_get_id(pdev->dev.of_node, "serial"); - if (index < 0 || index >= ARRAY_SIZE(sprd_port)) { + if (index < 0 || index >= UART_NR_MAX) { dev_err(&pdev->dev, "got a wrong serial alias id %d\n", index); return -EINVAL; } - sprd_port[index] = devm_kzalloc(&pdev->dev, sizeof(*sprd_port[index]), - GFP_KERNEL); - if (!sprd_port[index]) + sport = devm_kzalloc(&pdev->dev, sizeof(*sport), GFP_KERNEL); + if (!sport) return -ENOMEM; - up = &sprd_port[index]->port; + up = &sport->port; up->dev = &pdev->dev; up->line = index; up->type = PORT_SPRD; @@ -1195,7 +1195,7 @@ * Allocate one dma buffer to prepare for receive transfer, in case * memory allocation failure at runtime. */ - ret = sprd_rx_alloc_buf(sprd_port[index]); + ret = sprd_rx_alloc_buf(sport); if (ret) return ret; @@ -1203,17 +1203,27 @@ ret = uart_register_driver(&sprd_uart_driver); if (ret < 0) { pr_err("Failed to register SPRD-UART driver\n"); - return ret; + goto free_rx_buf; } } + sprd_ports_num++; + sprd_port[index] = sport; ret = uart_add_one_port(&sprd_uart_driver, up); if (ret) - sprd_remove(pdev); + goto clean_port; platform_set_drvdata(pdev, up); + return 0; + +clean_port: + sprd_port[index] = NULL; + if (--sprd_ports_num == 0) + uart_unregister_driver(&sprd_uart_driver); +free_rx_buf: + sprd_rx_free_buf(sport); return ret; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/usb/cdns3/cdns3-plat.c +++ linux-6.2.0/drivers/usb/cdns3/cdns3-plat.c @@ -256,9 +256,10 @@ cdns3_set_platform_suspend(cdns->dev, false, false); spin_lock_irqsave(&cdns->lock, flags); - cdns_resume(cdns, !PMSG_IS_AUTO(msg)); + cdns_resume(cdns); cdns->in_lpm = false; spin_unlock_irqrestore(&cdns->lock, flags); + cdns_set_active(cdns, !PMSG_IS_AUTO(msg)); if (cdns->wakeup_pending) { cdns->wakeup_pending = false; enable_irq(cdns->wakeup_irq); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/usb/cdns3/core.c +++ linux-6.2.0/drivers/usb/cdns3/core.c @@ -522,9 +522,8 @@ } EXPORT_SYMBOL_GPL(cdns_suspend); -int cdns_resume(struct cdns *cdns, u8 set_active) +int cdns_resume(struct cdns *cdns) { - struct device *dev = cdns->dev; enum usb_role real_role; bool role_changed = false; int ret = 0; @@ -556,15 +555,23 @@ if (cdns->roles[cdns->role]->resume) cdns->roles[cdns->role]->resume(cdns, cdns_power_is_lost(cdns)); + return 0; +} +EXPORT_SYMBOL_GPL(cdns_resume); + +void cdns_set_active(struct cdns *cdns, u8 set_active) +{ + struct device *dev = cdns->dev; + if (set_active) { pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); } - return 0; + return; } -EXPORT_SYMBOL_GPL(cdns_resume); +EXPORT_SYMBOL_GPL(cdns_set_active); #endif /* CONFIG_PM_SLEEP */ MODULE_AUTHOR("Peter Chen "); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/usb/cdns3/core.h +++ linux-6.2.0/drivers/usb/cdns3/core.h @@ -125,10 +125,13 @@ int cdns_remove(struct cdns *cdns); #ifdef CONFIG_PM_SLEEP -int cdns_resume(struct cdns *cdns, u8 set_active); +int cdns_resume(struct cdns *cdns); int cdns_suspend(struct cdns *cdns); +void cdns_set_active(struct cdns *cdns, u8 set_active); #else /* CONFIG_PM_SLEEP */ -static inline int cdns_resume(struct cdns *cdns, u8 set_active) +static inline int cdns_resume(struct cdns *cdns) +{ return 0; } +static inline int cdns_set_active(struct cdns *cdns, u8 set_active) { return 0; } static inline int cdns_suspend(struct cdns *cdns) { return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/usb/chipidea/host.c +++ linux-6.2.0/drivers/usb/chipidea/host.c @@ -151,6 +151,7 @@ ehci->has_hostpc = ci->hw_bank.lpm; ehci->has_tdi_phy_lpm = ci->hw_bank.lpm; ehci->imx28_write_fix = ci->imx28_write_fix; + ehci->has_ci_pec_bug = ci->has_portsc_pec_bug; priv = (struct ehci_ci_priv *)ehci->priv; priv->reg_vbus = NULL; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/usb/gadget/function/f_mass_storage.c +++ linux-6.2.0/drivers/usb/gadget/function/f_mass_storage.c @@ -927,7 +927,7 @@ { struct file *filp = curlun->filp; struct inode *inode = file_inode(filp); - unsigned long rc; + unsigned long __maybe_unused rc; rc = invalidate_mapping_pages(inode->i_mapping, 0, -1); VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/usb/gadget/udc/fsl_qe_udc.c +++ linux-6.2.0/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -1959,9 +1959,13 @@ } else if ((request_type & USB_RECIP_MASK) == USB_RECIP_ENDPOINT) { /* Get endpoint status */ int pipe = index & USB_ENDPOINT_NUMBER_MASK; - struct qe_ep *target_ep = &udc->eps[pipe]; + struct qe_ep *target_ep; u16 usep; + if (pipe >= USB_MAX_ENDPOINTS) + goto stall; + target_ep = &udc->eps[pipe]; + /* stall if endpoint doesn't exist */ if (!target_ep->ep.desc) goto stall; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/usb/host/ehci-hcd.c +++ linux-6.2.0/drivers/usb/host/ehci-hcd.c @@ -755,10 +755,14 @@ /* normal [4.15.1.2] or error [4.15.1.1] completion */ if (likely ((status & (STS_INT|STS_ERR)) != 0)) { - if (likely ((status & STS_ERR) == 0)) + if (likely ((status & STS_ERR) == 0)) { INCR(ehci->stats.normal); - else + } else { + /* Force to check port status */ + if (ehci->has_ci_pec_bug) + status |= STS_PCD; INCR(ehci->stats.error); + } bh = 1; } only in patch2: unchanged: --- linux-6.2.0.orig/drivers/usb/host/ehci-hub.c +++ linux-6.2.0/drivers/usb/host/ehci-hub.c @@ -674,7 +674,8 @@ if ((temp & mask) != 0 || test_bit(i, &ehci->port_c_suspend) || (ehci->reset_done[i] && time_after_eq( - jiffies, ehci->reset_done[i]))) { + jiffies, ehci->reset_done[i])) + || ehci_has_ci_pec_bug(ehci, temp)) { if (i < 7) buf [0] |= 1 << (i + 1); else @@ -875,6 +876,13 @@ if (temp & PORT_PEC) status |= USB_PORT_STAT_C_ENABLE << 16; + if (ehci_has_ci_pec_bug(ehci, temp)) { + status |= USB_PORT_STAT_C_ENABLE << 16; + ehci_info(ehci, + "PE is cleared by HW port:%d PORTSC:%08x\n", + wIndex + 1, temp); + } + if ((temp & PORT_OCC) && (!ignore_oc && !ehci->spurious_oc)){ status |= USB_PORT_STAT_C_OVERCURRENT << 16; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/usb/host/ehci.h +++ linux-6.2.0/drivers/usb/host/ehci.h @@ -207,6 +207,7 @@ unsigned has_fsl_port_bug:1; /* FreeScale */ unsigned has_fsl_hs_errata:1; /* Freescale HS quirk */ unsigned has_fsl_susp_errata:1; /* NXP SUSP quirk */ + unsigned has_ci_pec_bug:1; /* ChipIdea PEC bug */ unsigned big_endian_mmio:1; unsigned big_endian_desc:1; unsigned big_endian_capbase:1; @@ -708,6 +709,15 @@ #define ehci_has_fsl_susp_errata(e) ((e)->has_fsl_susp_errata) /* + * Some Freescale/NXP processors using ChipIdea IP have a bug in which + * disabling the port (PE is cleared) does not cause PEC to be asserted + * when frame babble is detected. + */ +#define ehci_has_ci_pec_bug(e, portsc) \ + ((e)->has_ci_pec_bug && ((e)->command & CMD_PSE) \ + && !(portsc & PORT_PEC) && !(portsc & PORT_PE)) + +/* * While most USB host controllers implement their registers in * little-endian format, a minority (celleb companion chip) implement * them in big endian format. only in patch2: unchanged: --- linux-6.2.0.orig/drivers/usb/phy/phy-mxs-usb.c +++ linux-6.2.0/drivers/usb/phy/phy-mxs-usb.c @@ -388,14 +388,8 @@ static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy) { - void __iomem *base = mxs_phy->phy.io_priv; - u32 phyctrl = readl(base + HW_USBPHY_CTRL); - - if (IS_ENABLED(CONFIG_USB_OTG) && - !(phyctrl & BM_USBPHY_CTRL_OTG_ID_VALUE)) - return true; - - return false; + return IS_ENABLED(CONFIG_USB_OTG) && + mxs_phy->phy.last_event == USB_EVENT_ID; } static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on) only in patch2: unchanged: --- linux-6.2.0.orig/drivers/usb/typec/bus.c +++ linux-6.2.0/drivers/usb/typec/bus.c @@ -154,12 +154,20 @@ * * Notifies the partner of @adev about Attention command. */ -void typec_altmode_attention(struct typec_altmode *adev, u32 vdo) +int typec_altmode_attention(struct typec_altmode *adev, u32 vdo) { - struct typec_altmode *pdev = &to_altmode(adev)->partner->adev; + struct altmode *partner = to_altmode(adev)->partner; + struct typec_altmode *pdev; + + if (!partner) + return -ENODEV; + + pdev = &partner->adev; if (pdev->ops && pdev->ops->attention) pdev->ops->attention(pdev, vdo); + + return 0; } EXPORT_SYMBOL_GPL(typec_altmode_attention); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/vfio/mdev/mdev_sysfs.c +++ linux-6.2.0/drivers/vfio/mdev/mdev_sysfs.c @@ -233,7 +233,8 @@ out_err: while (--i >= 0) mdev_type_remove(parent->types[i]); - return 0; + kset_unregister(parent->mdev_types_kset); + return ret; } static ssize_t remove_store(struct device *dev, struct device_attribute *attr, only in patch2: unchanged: --- linux-6.2.0.orig/drivers/video/backlight/bd6107.c +++ linux-6.2.0/drivers/video/backlight/bd6107.c @@ -104,7 +104,7 @@ { struct bd6107 *bd = bl_get_data(backlight); - return bd->pdata->fbdev == NULL || bd->pdata->fbdev == info->dev; + return bd->pdata->fbdev == NULL || bd->pdata->fbdev == info->device; } static const struct backlight_ops bd6107_backlight_ops = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/video/backlight/gpio_backlight.c +++ linux-6.2.0/drivers/video/backlight/gpio_backlight.c @@ -35,7 +35,7 @@ { struct gpio_backlight *gbl = bl_get_data(bl); - return gbl->fbdev == NULL || gbl->fbdev == info->dev; + return gbl->fbdev == NULL || gbl->fbdev == info->device; } static const struct backlight_ops gpio_backlight_ops = { @@ -87,8 +87,7 @@ /* Not booted with device tree or no phandle link to the node */ bl->props.power = def_value ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; - else if (gpiod_get_direction(gbl->gpiod) == 0 && - gpiod_get_value_cansleep(gbl->gpiod) == 0) + else if (gpiod_get_value_cansleep(gbl->gpiod) == 0) bl->props.power = FB_BLANK_POWERDOWN; else bl->props.power = FB_BLANK_UNBLANK; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/video/backlight/lv5207lp.c +++ linux-6.2.0/drivers/video/backlight/lv5207lp.c @@ -67,7 +67,7 @@ { struct lv5207lp *lv = bl_get_data(backlight); - return lv->pdata->fbdev == NULL || lv->pdata->fbdev == info->dev; + return lv->pdata->fbdev == NULL || lv->pdata->fbdev == info->device; } static const struct backlight_ops lv5207lp_backlight_ops = { only in patch2: unchanged: --- linux-6.2.0.orig/drivers/video/fbdev/Kconfig +++ linux-6.2.0/drivers/video/fbdev/Kconfig @@ -2050,7 +2050,7 @@ config FB_SH7760 bool "SH7760/SH7763/SH7720/SH7721 LCDC support" - depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ + depends on FB=y && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) select FB_CFB_FILLRECT select FB_CFB_COPYAREA only in patch2: unchanged: --- linux-6.2.0.orig/drivers/video/fbdev/ep93xx-fb.c +++ linux-6.2.0/drivers/video/fbdev/ep93xx-fb.c @@ -474,7 +474,6 @@ if (!info) return -ENOMEM; - info->dev = &pdev->dev; platform_set_drvdata(pdev, info); fbi = info->par; fbi->mach_info = mach_info; only in patch2: unchanged: --- linux-6.2.0.orig/drivers/watchdog/intel-mid_wdt.c +++ linux-6.2.0/drivers/watchdog/intel-mid_wdt.c @@ -203,3 +203,4 @@ MODULE_AUTHOR("David Cohen "); MODULE_DESCRIPTION("Watchdog Driver for Intel MID platform"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:intel_mid_wdt"); only in patch2: unchanged: --- linux-6.2.0.orig/drivers/xen/events/events_base.c +++ linux-6.2.0/drivers/xen/events/events_base.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -96,6 +97,7 @@ struct irq_info { struct list_head list; struct list_head eoi_list; + struct rcu_work rwork; short refcnt; u8 spurious_cnt; u8 is_accounted; @@ -146,22 +148,12 @@ static DEFINE_MUTEX(irq_mapping_update_lock); /* - * Lock protecting event handling loop against removing event channels. - * Adding of event channels is no issue as the associated IRQ becomes active - * only after everything is setup (before request_[threaded_]irq() the handler - * can't be entered for an event, as the event channel will be unmasked only - * then). - */ -static DEFINE_RWLOCK(evtchn_rwlock); - -/* * Lock hierarchy: * * irq_mapping_update_lock - * evtchn_rwlock - * IRQ-desc lock - * percpu eoi_list_lock - * irq_info->lock + * IRQ-desc lock + * percpu eoi_list_lock + * irq_info->lock */ static LIST_HEAD(xen_irq_list_head); @@ -305,6 +297,22 @@ info->is_accounted = 1; } +static void delayed_free_irq(struct work_struct *work) +{ + struct irq_info *info = container_of(to_rcu_work(work), struct irq_info, + rwork); + unsigned int irq = info->irq; + + /* Remove the info pointer only now, with no potential users left. */ + set_info_for_irq(irq, NULL); + + kfree(info); + + /* Legacy IRQ descriptors are managed by the arch. */ + if (irq >= nr_legacy_irqs()) + irq_free_desc(irq); +} + /* Constructors for packed IRQ information. */ static int xen_irq_info_common_setup(struct irq_info *info, unsigned irq, @@ -667,33 +675,36 @@ eoi = container_of(to_delayed_work(work), struct lateeoi_work, delayed); - read_lock_irqsave(&evtchn_rwlock, flags); + rcu_read_lock(); while (true) { - spin_lock(&eoi->eoi_list_lock); + spin_lock_irqsave(&eoi->eoi_list_lock, flags); info = list_first_entry_or_null(&eoi->eoi_list, struct irq_info, eoi_list); - if (info == NULL || now < info->eoi_time) { - spin_unlock(&eoi->eoi_list_lock); + if (info == NULL) + break; + + if (now < info->eoi_time) { + mod_delayed_work_on(info->eoi_cpu, system_wq, + &eoi->delayed, + info->eoi_time - now); break; } list_del_init(&info->eoi_list); - spin_unlock(&eoi->eoi_list_lock); + spin_unlock_irqrestore(&eoi->eoi_list_lock, flags); info->eoi_time = 0; xen_irq_lateeoi_locked(info, false); } - if (info) - mod_delayed_work_on(info->eoi_cpu, system_wq, - &eoi->delayed, info->eoi_time - now); + spin_unlock_irqrestore(&eoi->eoi_list_lock, flags); - read_unlock_irqrestore(&evtchn_rwlock, flags); + rcu_read_unlock(); } static void xen_cpu_init_eoi(unsigned int cpu) @@ -708,16 +719,15 @@ void xen_irq_lateeoi(unsigned int irq, unsigned int eoi_flags) { struct irq_info *info; - unsigned long flags; - read_lock_irqsave(&evtchn_rwlock, flags); + rcu_read_lock(); info = info_for_irq(irq); if (info) xen_irq_lateeoi_locked(info, eoi_flags & XEN_EOI_FLAG_SPURIOUS); - read_unlock_irqrestore(&evtchn_rwlock, flags); + rcu_read_unlock(); } EXPORT_SYMBOL_GPL(xen_irq_lateeoi); @@ -731,6 +741,7 @@ info->type = IRQT_UNBOUND; info->refcnt = -1; + INIT_RCU_WORK(&info->rwork, delayed_free_irq); set_info_for_irq(irq, info); /* @@ -788,31 +799,18 @@ static void xen_free_irq(unsigned irq) { struct irq_info *info = info_for_irq(irq); - unsigned long flags; if (WARN_ON(!info)) return; - write_lock_irqsave(&evtchn_rwlock, flags); - if (!list_empty(&info->eoi_list)) lateeoi_list_del(info); list_del(&info->list); - set_info_for_irq(irq, NULL); - WARN_ON(info->refcnt > 0); - write_unlock_irqrestore(&evtchn_rwlock, flags); - - kfree(info); - - /* Legacy IRQ descriptors are managed by the arch. */ - if (irq < nr_legacy_irqs()) - return; - - irq_free_desc(irq); + queue_rcu_work(system_wq, &info->rwork); } static void xen_evtchn_close(evtchn_port_t port) @@ -1716,7 +1714,14 @@ int cpu = smp_processor_id(); struct evtchn_loop_ctrl ctrl = { 0 }; - read_lock(&evtchn_rwlock); + /* + * When closing an event channel the associated IRQ must not be freed + * until all cpus have left the event handling loop. This is ensured + * by taking the rcu_read_lock() while handling events, as freeing of + * the IRQ is handled via queue_rcu_work() _after_ closing the event + * channel. + */ + rcu_read_lock(); do { vcpu_info->evtchn_upcall_pending = 0; @@ -1729,7 +1734,7 @@ } while (vcpu_info->evtchn_upcall_pending); - read_unlock(&evtchn_rwlock); + rcu_read_unlock(); /* * Increment irq_epoch only now to defer EOIs only for only in patch2: unchanged: --- linux-6.2.0.orig/fs/autofs/waitq.c +++ linux-6.2.0/fs/autofs/waitq.c @@ -32,8 +32,9 @@ wq->status = -ENOENT; /* Magic is gone - report failure */ kfree(wq->name.name - wq->offset); wq->name.name = NULL; - wq->wait_ctr--; wake_up_interruptible(&wq->queue); + if (!--wq->wait_ctr) + kfree(wq); wq = nwq; } fput(sbi->pipe); /* Close the pipe */ only in patch2: unchanged: --- linux-6.2.0.orig/fs/binfmt_elf_fdpic.c +++ linux-6.2.0/fs/binfmt_elf_fdpic.c @@ -345,10 +345,9 @@ /* there's now no turning back... the old userspace image is dead, * defunct, deceased, etc. */ + SET_PERSONALITY(exec_params.hdr); if (elf_check_fdpic(&exec_params.hdr)) - set_personality(PER_LINUX_FDPIC); - else - set_personality(PER_LINUX); + current->personality |= PER_LINUX_FDPIC; if (elf_read_implies_exec(&exec_params.hdr, executable_stack)) current->personality |= READ_IMPLIES_EXEC; only in patch2: unchanged: --- linux-6.2.0.orig/fs/btrfs/delayed-inode.c +++ linux-6.2.0/fs/btrfs/delayed-inode.c @@ -412,6 +412,7 @@ static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) { + struct btrfs_delayed_node *delayed_node = delayed_item->delayed_node; struct rb_root_cached *root; struct btrfs_delayed_root *delayed_root; @@ -419,18 +420,21 @@ if (RB_EMPTY_NODE(&delayed_item->rb_node)) return; - delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root; + /* If it's in a rbtree, then we need to have delayed node locked. */ + lockdep_assert_held(&delayed_node->mutex); + + delayed_root = delayed_node->root->fs_info->delayed_root; BUG_ON(!delayed_root); if (delayed_item->type == BTRFS_DELAYED_INSERTION_ITEM) - root = &delayed_item->delayed_node->ins_root; + root = &delayed_node->ins_root; else - root = &delayed_item->delayed_node->del_root; + root = &delayed_node->del_root; rb_erase_cached(&delayed_item->rb_node, root); RB_CLEAR_NODE(&delayed_item->rb_node); - delayed_item->delayed_node->count--; + delayed_node->count--; finish_one_item(delayed_root); } @@ -1153,20 +1157,33 @@ ret = __btrfs_commit_inode_delayed_items(trans, path, curr_node); if (ret) { - btrfs_release_delayed_node(curr_node); - curr_node = NULL; btrfs_abort_transaction(trans, ret); break; } prev_node = curr_node; curr_node = btrfs_next_delayed_node(curr_node); + /* + * See the comment below about releasing path before releasing + * node. If the commit of delayed items was successful the path + * should always be released, but in case of an error, it may + * point to locked extent buffers (a leaf at the very least). + */ + ASSERT(path->nodes[0] == NULL); btrfs_release_delayed_node(prev_node); } + /* + * Release the path to avoid a potential deadlock and lockdep splat when + * releasing the delayed node, as that requires taking the delayed node's + * mutex. If another task starts running delayed items before we take + * the mutex, it will first lock the mutex and then it may try to lock + * the same btree path (leaf). + */ + btrfs_free_path(path); + if (curr_node) btrfs_release_delayed_node(curr_node); - btrfs_free_path(path); trans->block_rsv = block_rsv; return ret; @@ -1413,7 +1430,29 @@ btrfs_wq_run_delayed_node(delayed_root, fs_info, BTRFS_DELAYED_BATCH); } -/* Will return 0 or -ENOMEM */ +static void btrfs_release_dir_index_item_space(struct btrfs_trans_handle *trans) +{ + struct btrfs_fs_info *fs_info = trans->fs_info; + const u64 bytes = btrfs_calc_insert_metadata_size(fs_info, 1); + + if (test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags)) + return; + + /* + * Adding the new dir index item does not require touching another + * leaf, so we can release 1 unit of metadata that was previously + * reserved when starting the transaction. This applies only to + * the case where we had a transaction start and excludes the + * transaction join case (when replaying log trees). + */ + trace_btrfs_space_reservation(fs_info, "transaction", + trans->transid, bytes, 0); + btrfs_block_rsv_release(fs_info, trans->block_rsv, bytes, NULL); + ASSERT(trans->bytes_reserved >= bytes); + trans->bytes_reserved -= bytes; +} + +/* Will return 0, -ENOMEM or -EEXIST (index number collision, unexpected). */ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, const char *name, int name_len, struct btrfs_inode *dir, @@ -1455,6 +1494,27 @@ mutex_lock(&delayed_node->mutex); + /* + * First attempt to insert the delayed item. This is to make the error + * handling path simpler in case we fail (-EEXIST). There's no risk of + * any other task coming in and running the delayed item before we do + * the metadata space reservation below, because we are holding the + * delayed node's mutex and that mutex must also be locked before the + * node's delayed items can be run. + */ + ret = __btrfs_add_delayed_item(delayed_node, delayed_item); + if (unlikely(ret)) { + btrfs_err(trans->fs_info, +"error adding delayed dir index item, name: %.*s, index: %llu, root: %llu, dir: %llu, dir->index_cnt: %llu, delayed_node->index_cnt: %llu, error: %d", + name_len, name, index, btrfs_root_id(delayed_node->root), + delayed_node->inode_id, dir->index_cnt, + delayed_node->index_cnt, ret); + btrfs_release_delayed_item(delayed_item); + btrfs_release_dir_index_item_space(trans); + mutex_unlock(&delayed_node->mutex); + goto release_node; + } + if (delayed_node->index_item_leaves == 0 || delayed_node->curr_index_batch_size + data_len > leaf_data_size) { delayed_node->curr_index_batch_size = data_len; @@ -1472,36 +1532,14 @@ * impossible. */ if (WARN_ON(ret)) { - mutex_unlock(&delayed_node->mutex); btrfs_release_delayed_item(delayed_item); + mutex_unlock(&delayed_node->mutex); goto release_node; } delayed_node->index_item_leaves++; - } else if (!test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags)) { - const u64 bytes = btrfs_calc_insert_metadata_size(fs_info, 1); - - /* - * Adding the new dir index item does not require touching another - * leaf, so we can release 1 unit of metadata that was previously - * reserved when starting the transaction. This applies only to - * the case where we had a transaction start and excludes the - * transaction join case (when replaying log trees). - */ - trace_btrfs_space_reservation(fs_info, "transaction", - trans->transid, bytes, 0); - btrfs_block_rsv_release(fs_info, trans->block_rsv, bytes, NULL); - ASSERT(trans->bytes_reserved >= bytes); - trans->bytes_reserved -= bytes; - } - - ret = __btrfs_add_delayed_item(delayed_node, delayed_item); - if (unlikely(ret)) { - btrfs_err(trans->fs_info, - "err add delayed dir index item(name: %.*s) into the insertion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)", - name_len, name, delayed_node->root->root_key.objectid, - delayed_node->inode_id, ret); - BUG(); + } else { + btrfs_release_dir_index_item_space(trans); } mutex_unlock(&delayed_node->mutex); only in patch2: unchanged: --- linux-6.2.0.orig/fs/btrfs/file.c +++ linux-6.2.0/fs/btrfs/file.c @@ -1469,8 +1469,13 @@ if (iocb->ki_flags & IOCB_NOWAIT) ilock_flags |= BTRFS_ILOCK_TRY; - /* If the write DIO is within EOF, use a shared lock */ - if (iocb->ki_pos + iov_iter_count(from) <= i_size_read(inode)) + /* + * If the write DIO is within EOF, use a shared lock and also only if + * security bits will likely not be dropped by file_remove_privs() called + * from btrfs_write_check(). Either will need to be rechecked after the + * lock was acquired. + */ + if (iocb->ki_pos + iov_iter_count(from) <= i_size_read(inode) && IS_NOSEC(inode)) ilock_flags |= BTRFS_ILOCK_SHARED; relock: @@ -1478,6 +1483,13 @@ if (err < 0) return err; + /* Shared lock cannot be used with security bits set. */ + if ((ilock_flags & BTRFS_ILOCK_SHARED) && !IS_NOSEC(inode)) { + btrfs_inode_unlock(BTRFS_I(inode), ilock_flags); + ilock_flags &= ~BTRFS_ILOCK_SHARED; + goto relock; + } + err = generic_write_checks(iocb, from); if (err <= 0) { btrfs_inode_unlock(BTRFS_I(inode), ilock_flags); only in patch2: unchanged: --- linux-6.2.0.orig/fs/btrfs/ordered-data.c +++ linux-6.2.0/fs/btrfs/ordered-data.c @@ -583,7 +583,7 @@ refcount_inc(&trans->use_count); spin_unlock(&fs_info->trans_lock); - ASSERT(trans); + ASSERT(trans || BTRFS_FS_ERROR(fs_info)); if (trans) { if (atomic_dec_and_test(&trans->pending_ordered)) wake_up(&trans->pending_wait); only in patch2: unchanged: --- linux-6.2.0.orig/fs/btrfs/volumes.h +++ linux-6.2.0/fs/btrfs/volumes.h @@ -695,5 +695,6 @@ bool btrfs_repair_one_zone(struct btrfs_fs_info *fs_info, u64 logical); bool btrfs_pinned_by_swapfile(struct btrfs_fs_info *fs_info, void *ptr); +u8 *btrfs_sb_fsid_ptr(struct btrfs_super_block *sb); #endif only in patch2: unchanged: --- linux-6.2.0.orig/fs/ceph/quota.c +++ linux-6.2.0/fs/ceph/quota.c @@ -47,25 +47,23 @@ struct inode *inode; struct ceph_inode_info *ci; + if (!ceph_inc_mds_stopping_blocker(mdsc, session)) + return; + if (msg->front.iov_len < sizeof(*h)) { pr_err("%s corrupt message mds%d len %d\n", __func__, session->s_mds, (int)msg->front.iov_len); ceph_msg_dump(msg); - return; + goto out; } - /* increment msg sequence number */ - mutex_lock(&session->s_mutex); - inc_session_sequence(session); - mutex_unlock(&session->s_mutex); - /* lookup inode */ vino.ino = le64_to_cpu(h->ino); vino.snap = CEPH_NOSNAP; inode = ceph_find_inode(sb, vino); if (!inode) { pr_warn("Failed to find inode %llu\n", vino.ino); - return; + goto out; } ci = ceph_inode(inode); @@ -78,6 +76,8 @@ spin_unlock(&ci->i_ceph_lock); iput(inode); +out: + ceph_dec_mds_stopping_blocker(mdsc); } static struct ceph_quotarealm_inode * only in patch2: unchanged: --- linux-6.2.0.orig/fs/eventfd.c +++ linux-6.2.0/fs/eventfd.c @@ -189,7 +189,7 @@ { lockdep_assert_held(&ctx->wqh.lock); - *cnt = (ctx->flags & EFD_SEMAPHORE) ? 1 : ctx->count; + *cnt = ((ctx->flags & EFD_SEMAPHORE) && ctx->count) ? 1 : ctx->count; ctx->count -= *cnt; } EXPORT_SYMBOL_GPL(eventfd_ctx_do_read); only in patch2: unchanged: --- linux-6.2.0.orig/fs/ext2/xattr.c +++ linux-6.2.0/fs/ext2/xattr.c @@ -744,10 +744,10 @@ /* We need to allocate a new block */ ext2_fsblk_t goal = ext2_group_first_block_no(sb, EXT2_I(inode)->i_block_group); - int block = ext2_new_block(inode, goal, &error); + ext2_fsblk_t block = ext2_new_block(inode, goal, &error); if (error) goto cleanup; - ea_idebug(inode, "creating block %d", block); + ea_idebug(inode, "creating block %lu", block); new_bh = sb_getblk(sb, block); if (unlikely(!new_bh)) { only in patch2: unchanged: --- linux-6.2.0.orig/fs/ext4/block_validity.c +++ linux-6.2.0/fs/ext4/block_validity.c @@ -215,7 +215,6 @@ struct ext4_system_blocks *system_blks; struct ext4_group_desc *gdp; ext4_group_t i; - int flex_size = ext4_flex_bg_size(sbi); int ret; system_blks = kzalloc(sizeof(*system_blks), GFP_KERNEL); @@ -223,12 +222,13 @@ return -ENOMEM; for (i=0; i < ngroups; i++) { + unsigned int meta_blks = ext4_num_base_meta_blocks(sb, i); + cond_resched(); - if (ext4_bg_has_super(sb, i) && - ((i < 5) || ((i % flex_size) == 0))) { + if (meta_blks != 0) { ret = add_system_zone(system_blks, ext4_group_first_block_no(sb, i), - ext4_bg_num_gdb(sb, i) + 1, 0); + meta_blks, 0); if (ret) goto err; } only in patch2: unchanged: --- linux-6.2.0.orig/fs/ext4/crypto.c +++ linux-6.2.0/fs/ext4/crypto.c @@ -33,6 +33,8 @@ #if IS_ENABLED(CONFIG_UNICODE) err = ext4_fname_setup_ci_filename(dir, iname, fname); + if (err) + ext4_fname_free_filename(fname); #endif return err; } @@ -51,6 +53,8 @@ #if IS_ENABLED(CONFIG_UNICODE) err = ext4_fname_setup_ci_filename(dir, &dentry->d_name, fname); + if (err) + ext4_fname_free_filename(fname); #endif return err; } only in patch2: unchanged: --- linux-6.2.0.orig/fs/fuse/readdir.c +++ linux-6.2.0/fs/fuse/readdir.c @@ -243,8 +243,16 @@ dput(dentry); dentry = alias; } - if (IS_ERR(dentry)) + if (IS_ERR(dentry)) { + if (!IS_ERR(inode)) { + struct fuse_inode *fi = get_fuse_inode(inode); + + spin_lock(&fi->lock); + fi->nlookup--; + spin_unlock(&fi->lock); + } return PTR_ERR(dentry); + } } if (fc->readdirplus_auto) set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state); only in patch2: unchanged: --- linux-6.2.0.orig/fs/gfs2/log.c +++ linux-6.2.0/fs/gfs2/log.c @@ -1285,9 +1285,6 @@ { unsigned int used_blocks = sdp->sd_jdesc->jd_blocks - atomic_read(&sdp->sd_log_blks_free); - if (test_and_clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags)) - return 1; - return used_blocks + atomic_read(&sdp->sd_log_blks_needed) >= atomic_read(&sdp->sd_log_thresh2); } @@ -1304,7 +1301,6 @@ { struct gfs2_sbd *sdp = data; unsigned long t = 1; - DEFINE_WAIT(wait); while (!kthread_should_stop()) { @@ -1329,7 +1325,9 @@ GFS2_LFC_LOGD_JFLUSH_REQD); } - if (gfs2_ail_flush_reqd(sdp)) { + if (test_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags) || + gfs2_ail_flush_reqd(sdp)) { + clear_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags); gfs2_ail1_start(sdp); gfs2_ail1_wait(sdp); gfs2_ail1_empty(sdp, 0); @@ -1341,17 +1339,12 @@ try_to_freeze(); - do { - prepare_to_wait(&sdp->sd_logd_waitq, &wait, - TASK_INTERRUPTIBLE); - if (!gfs2_ail_flush_reqd(sdp) && - !gfs2_jrnl_flush_reqd(sdp) && - !kthread_should_stop()) - t = schedule_timeout(t); - } while(t && !gfs2_ail_flush_reqd(sdp) && - !gfs2_jrnl_flush_reqd(sdp) && - !kthread_should_stop()); - finish_wait(&sdp->sd_logd_waitq, &wait); + t = wait_event_interruptible_timeout(sdp->sd_logd_waitq, + test_bit(SDF_FORCE_AIL_FLUSH, &sdp->sd_flags) || + gfs2_ail_flush_reqd(sdp) || + gfs2_jrnl_flush_reqd(sdp) || + kthread_should_stop(), + t); } return 0; only in patch2: unchanged: --- linux-6.2.0.orig/fs/iomap/buffered-io.c +++ linux-6.2.0/fs/iomap/buffered-io.c @@ -488,11 +488,6 @@ WARN_ON_ONCE(folio_test_writeback(folio)); folio_cancel_dirty(folio); iomap_page_release(folio); - } else if (folio_test_large(folio)) { - /* Must release the iop so the page can be split */ - WARN_ON_ONCE(!folio_test_uptodate(folio) && - folio_test_dirty(folio)); - iomap_page_release(folio); } } EXPORT_SYMBOL_GPL(iomap_invalidate_folio); only in patch2: unchanged: --- linux-6.2.0.orig/fs/jbd2/recovery.c +++ linux-6.2.0/fs/jbd2/recovery.c @@ -229,12 +229,8 @@ /* Make sure we wrap around the log correctly! */ #define wrap(journal, var) \ do { \ - unsigned long _wrap_last = \ - jbd2_has_feature_fast_commit(journal) ? \ - (journal)->j_fc_last : (journal)->j_last; \ - \ - if (var >= _wrap_last) \ - var -= (_wrap_last - (journal)->j_first); \ + if (var >= (journal)->j_last) \ + var -= ((journal)->j_last - (journal)->j_first); \ } while (0) static int fc_do_one_pass(journal_t *journal, @@ -517,9 +513,7 @@ break; jbd2_debug(2, "Scanning for sequence ID %u at %lu/%lu\n", - next_commit_ID, next_log_block, - jbd2_has_feature_fast_commit(journal) ? - journal->j_fc_last : journal->j_last); + next_commit_ID, next_log_block, journal->j_last); /* Skip over each chunk of the transaction looking * either the next descriptor block or the final commit only in patch2: unchanged: --- linux-6.2.0.orig/fs/jfs/jfs_extent.c +++ linux-6.2.0/fs/jfs/jfs_extent.c @@ -311,6 +311,11 @@ * blocks in the map. in that case, we'll start off with the * maximum free. */ + + /* give up if no space left */ + if (bmp->db_maxfreebud == -1) + return -ENOSPC; + max = (s64) 1 << bmp->db_maxfreebud; if (*nblocks >= max && *nblocks > nbperpage) nb = nblks = (max > nbperpage) ? max : nbperpage; only in patch2: unchanged: --- linux-6.2.0.orig/fs/jfs/jfs_imap.c +++ linux-6.2.0/fs/jfs/jfs_imap.c @@ -193,6 +193,7 @@ * free in-memory control structure */ kfree(imap); + JFS_IP(ipimap)->i_imap = NULL; return (0); } only in patch2: unchanged: --- linux-6.2.0.orig/fs/lockd/mon.c +++ linux-6.2.0/fs/lockd/mon.c @@ -276,6 +276,9 @@ { struct nsm_handle *new; + if (!hostname) + return NULL; + new = kzalloc(sizeof(*new) + hostname_len + 1, GFP_KERNEL); if (unlikely(new == NULL)) return NULL; only in patch2: unchanged: --- linux-6.2.0.orig/fs/netfs/buffered_read.c +++ linux-6.2.0/fs/netfs/buffered_read.c @@ -47,12 +47,14 @@ xas_for_each(&xas, folio, last_page) { loff_t pg_end; bool pg_failed = false; + bool folio_started; if (xas_retry(&xas, folio)) continue; pg_end = folio_pos(folio) + folio_size(folio) - 1; + folio_started = false; for (;;) { loff_t sreq_end; @@ -60,8 +62,10 @@ pg_failed = true; break; } - if (test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags)) + if (!folio_started && test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags)) { folio_start_fscache(folio); + folio_started = true; + } pg_failed |= subreq_failed; sreq_end = subreq->start + subreq->len - 1; if (pg_end < sreq_end) only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfs/blocklayout/dev.c +++ linux-6.2.0/fs/nfs/blocklayout/dev.c @@ -402,7 +402,7 @@ int ret, i; d->children = kcalloc(v->concat.volumes_count, - sizeof(struct pnfs_block_dev), GFP_KERNEL); + sizeof(struct pnfs_block_dev), gfp_mask); if (!d->children) return -ENOMEM; @@ -431,7 +431,7 @@ int ret, i; d->children = kcalloc(v->stripe.volumes_count, - sizeof(struct pnfs_block_dev), GFP_KERNEL); + sizeof(struct pnfs_block_dev), gfp_mask); if (!d->children) return -ENOMEM; only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfs/flexfilelayout/flexfilelayout.c +++ linux-6.2.0/fs/nfs/flexfilelayout/flexfilelayout.c @@ -1235,6 +1235,7 @@ case -EPFNOSUPPORT: case -EPROTONOSUPPORT: case -EOPNOTSUPP: + case -EINVAL: case -ECONNREFUSED: case -ECONNRESET: case -EHOSTDOWN: only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfs/nfs2xdr.c +++ linux-6.2.0/fs/nfs/nfs2xdr.c @@ -949,7 +949,7 @@ error = decode_filename_inline(xdr, &entry->name, &entry->len); if (unlikely(error)) - return -EAGAIN; + return error == -ENAMETOOLONG ? -ENAMETOOLONG : -EAGAIN; /* * The type (size and byte order) of nfscookie isn't defined in only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfs/nfs3xdr.c +++ linux-6.2.0/fs/nfs/nfs3xdr.c @@ -1991,7 +1991,7 @@ error = decode_inline_filename3(xdr, &entry->name, &entry->len); if (unlikely(error)) - return -EAGAIN; + return error == -ENAMETOOLONG ? -ENAMETOOLONG : -EAGAIN; error = decode_cookie3(xdr, &new_cookie); if (unlikely(error)) only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfs/nfs42.h +++ linux-6.2.0/fs/nfs/nfs42.h @@ -13,6 +13,7 @@ * more? Need to consider not to pre-alloc too much for a compound. */ #define PNFS_LAYOUTSTATS_MAXDEV (4) +#define READ_PLUS_SCRATCH_SIZE (16) /* nfs4.2proc.c */ #ifdef CONFIG_NFS_V4_2 only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfs/nfs42xdr.c +++ linux-6.2.0/fs/nfs/nfs42xdr.c @@ -51,10 +51,16 @@ (1 /* data_content4 */ + \ 2 /* data_info4.di_offset */ + \ 1 /* data_info4.di_length */) +#define NFS42_READ_PLUS_HOLE_SEGMENT_SIZE \ + (1 /* data_content4 */ + \ + 2 /* data_info4.di_offset */ + \ + 2 /* data_info4.di_length */) +#define READ_PLUS_SEGMENT_SIZE_DIFF (NFS42_READ_PLUS_HOLE_SEGMENT_SIZE - \ + NFS42_READ_PLUS_DATA_SEGMENT_SIZE) #define decode_read_plus_maxsz (op_decode_hdr_maxsz + \ 1 /* rpr_eof */ + \ 1 /* rpr_contents count */ + \ - NFS42_READ_PLUS_DATA_SEGMENT_SIZE) + NFS42_READ_PLUS_HOLE_SEGMENT_SIZE) #define encode_seek_maxsz (op_encode_hdr_maxsz + \ encode_stateid_maxsz + \ 2 /* offset */ + \ @@ -781,8 +787,8 @@ encode_putfh(xdr, args->fh, &hdr); encode_read_plus(xdr, args, &hdr); - rpc_prepare_reply_pages(req, args->pages, args->pgbase, - args->count, hdr.replen); + rpc_prepare_reply_pages(req, args->pages, args->pgbase, args->count, + hdr.replen - READ_PLUS_SEGMENT_SIZE_DIFF); encode_nops(&hdr); } @@ -1122,7 +1128,6 @@ uint32_t segments; struct read_plus_segment *segs; int status, i; - char scratch_buf[16]; __be32 *p; status = decode_op_hdr(xdr, OP_READ_PLUS); @@ -1137,14 +1142,12 @@ res->eof = be32_to_cpup(p++); segments = be32_to_cpup(p++); if (segments == 0) - return status; + return 0; segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL); if (!segs) return -ENOMEM; - xdr_set_scratch_buffer(xdr, &scratch_buf, sizeof(scratch_buf)); - status = -EIO; for (i = 0; i < segments; i++) { status = decode_read_plus_segment(xdr, &segs[i]); if (status < 0) @@ -1348,6 +1351,8 @@ struct compound_hdr hdr; int status; + xdr_set_scratch_buffer(xdr, res->scratch, READ_PLUS_SCRATCH_SIZE); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfs/nfs4client.c +++ linux-6.2.0/fs/nfs/nfs4client.c @@ -231,6 +231,8 @@ __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); __set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags); + if (test_bit(NFS_CS_DS, &cl_init->init_flags)) + __set_bit(NFS_CS_DS, &clp->cl_flags); /* * Set up the connection to the server before we add add to the * global list. @@ -414,6 +416,8 @@ .net = old->cl_net, .servername = old->cl_hostname, }; + int max_connect = test_bit(NFS_CS_PNFS, &clp->cl_flags) ? + clp->cl_max_connect : old->cl_max_connect; if (clp->cl_proto != old->cl_proto) return; @@ -427,7 +431,7 @@ xprt_args.addrlen = clp_salen; rpc_clnt_add_xprt(old->cl_rpcclient, &xprt_args, - rpc_clnt_test_and_add_xprt, NULL); + rpc_clnt_test_and_add_xprt, &max_connect); } /** @@ -993,6 +997,9 @@ if (mds_srv->flags & NFS_MOUNT_NORESVPORT) __set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags); + __set_bit(NFS_CS_DS, &cl_init.init_flags); + __set_bit(NFS_CS_PNFS, &cl_init.init_flags); + cl_init.max_connect = NFS_MAX_TRANSPORTS; /* * Set an authflavor equual to the MDS value. Use the MDS nfs_client * cl_ipaddr so as to use the same EXCHANGE_ID co_ownerid as the MDS only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfs/pnfs_dev.c +++ linux-6.2.0/fs/nfs/pnfs_dev.c @@ -154,7 +154,7 @@ set_bit(NFS_DEVICEID_NOCACHE, &d->flags); out_free_pages: - for (i = 0; i < max_pages; i++) + while (--i >= 0) __free_page(pages[i]); kfree(pages); out_free_pdev: only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfs/pnfs_nfs.c +++ linux-6.2.0/fs/nfs/pnfs_nfs.c @@ -943,7 +943,7 @@ * Test this address for session trunking and * add as an alias */ - xprtdata.cred = nfs4_get_clid_cred(clp), + xprtdata.cred = nfs4_get_clid_cred(clp); rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args, rpc_clnt_setup_test_and_add_xprt, &rpcdata); only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfs/sysfs.c +++ linux-6.2.0/fs/nfs/sysfs.c @@ -18,7 +18,7 @@ #include "sysfs.h" struct kobject *nfs_client_kobj; -static struct kset *nfs_client_kset; +static struct kset *nfs_kset; static void nfs_netns_object_release(struct kobject *kobj) { @@ -55,13 +55,13 @@ int nfs_sysfs_init(void) { - nfs_client_kset = kset_create_and_add("nfs", NULL, fs_kobj); - if (!nfs_client_kset) + nfs_kset = kset_create_and_add("nfs", NULL, fs_kobj); + if (!nfs_kset) return -ENOMEM; - nfs_client_kobj = nfs_netns_object_alloc("net", nfs_client_kset, NULL); + nfs_client_kobj = nfs_netns_object_alloc("net", nfs_kset, NULL); if (!nfs_client_kobj) { - kset_unregister(nfs_client_kset); - nfs_client_kset = NULL; + kset_unregister(nfs_kset); + nfs_kset = NULL; return -ENOMEM; } return 0; @@ -70,7 +70,7 @@ void nfs_sysfs_exit(void) { kobject_put(nfs_client_kobj); - kset_unregister(nfs_client_kset); + kset_unregister(nfs_kset); } static ssize_t nfs_netns_identifier_show(struct kobject *kobj, @@ -159,7 +159,7 @@ p = kzalloc(sizeof(*p), GFP_KERNEL); if (p) { p->net = net; - p->kobject.kset = nfs_client_kset; + p->kobject.kset = nfs_kset; if (kobject_init_and_add(&p->kobject, &nfs_netns_client_type, parent, "nfs_client") == 0) return p; only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfsd/blocklayoutxdr.c +++ linux-6.2.0/fs/nfsd/blocklayoutxdr.c @@ -83,6 +83,15 @@ int len = sizeof(__be32), ret, i; __be32 *p; + /* + * See paragraph 5 of RFC 8881 S18.40.3. + */ + if (!gdp->gd_maxcount) { + if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT) + return nfserr_resource; + return nfs_ok; + } + p = xdr_reserve_space(xdr, len + sizeof(__be32)); if (!p) return nfserr_resource; only in patch2: unchanged: --- linux-6.2.0.orig/fs/nfsd/flexfilelayoutxdr.c +++ linux-6.2.0/fs/nfsd/flexfilelayoutxdr.c @@ -85,6 +85,15 @@ int addr_len; __be32 *p; + /* + * See paragraph 5 of RFC 8881 S18.40.3. + */ + if (!gdp->gd_maxcount) { + if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT) + return nfserr_resource; + return nfs_ok; + } + /* len + padding for two strings */ addr_len = 16 + da->netaddr.netid_len + da->netaddr.addr_len; ver_len = 20; only in patch2: unchanged: --- linux-6.2.0.orig/fs/nilfs2/gcinode.c +++ linux-6.2.0/fs/nilfs2/gcinode.c @@ -73,10 +73,8 @@ struct the_nilfs *nilfs = inode->i_sb->s_fs_info; err = nilfs_dat_translate(nilfs->ns_dat, vbn, &pbn); - if (unlikely(err)) { /* -EIO, -ENOMEM, -ENOENT */ - brelse(bh); + if (unlikely(err)) /* -EIO, -ENOMEM, -ENOENT */ goto failed; - } } lock_buffer(bh); @@ -102,6 +100,8 @@ failed: unlock_page(bh->b_page); put_page(bh->b_page); + if (unlikely(err)) + brelse(bh); return err; } only in patch2: unchanged: --- linux-6.2.0.orig/fs/nls/nls_base.c +++ linux-6.2.0/fs/nls/nls_base.c @@ -272,7 +272,7 @@ return -EINVAL; } -static struct nls_table *find_nls(char *charset) +static struct nls_table *find_nls(const char *charset) { struct nls_table *nls; spin_lock(&nls_lock); @@ -288,7 +288,7 @@ return nls; } -struct nls_table *load_nls(char *charset) +struct nls_table *load_nls(const char *charset) { return try_then_request_module(find_nls(charset), "nls_%s", charset); } only in patch2: unchanged: --- linux-6.2.0.orig/fs/reiserfs/journal.c +++ linux-6.2.0/fs/reiserfs/journal.c @@ -2326,7 +2326,7 @@ int i, j; bh = __getblk(dev, block, bufsize); - if (buffer_uptodate(bh)) + if (!bh || buffer_uptodate(bh)) return (bh); if (block + BUFNR > max_block) { @@ -2336,6 +2336,8 @@ j = 1; for (i = 1; i < blocks; i++) { bh = __getblk(dev, block + i, bufsize); + if (!bh) + break; if (buffer_uptodate(bh)) { brelse(bh); break; only in patch2: unchanged: --- linux-6.2.0.orig/fs/tracefs/inode.c +++ linux-6.2.0/fs/tracefs/inode.c @@ -556,6 +556,9 @@ */ struct dentry *tracefs_create_dir(const char *name, struct dentry *parent) { + if (security_locked_down(LOCKDOWN_TRACEFS)) + return NULL; + return __create_dir(name, parent, &simple_dir_inode_operations); } only in patch2: unchanged: --- linux-6.2.0.orig/fs/udf/balloc.c +++ linux-6.2.0/fs/udf/balloc.c @@ -36,18 +36,41 @@ unsigned long bitmap_nr) { struct buffer_head *bh = NULL; - int retval = 0; + int i; + int max_bits, off, count; struct kernel_lb_addr loc; loc.logicalBlockNum = bitmap->s_extPosition; loc.partitionReferenceNum = UDF_SB(sb)->s_partition; bh = udf_tread(sb, udf_get_lb_pblock(sb, &loc, block)); + bitmap->s_block_bitmap[bitmap_nr] = bh; if (!bh) - retval = -EIO; + return -EIO; - bitmap->s_block_bitmap[bitmap_nr] = bh; - return retval; + /* Check consistency of Space Bitmap buffer. */ + max_bits = sb->s_blocksize * 8; + if (!bitmap_nr) { + off = sizeof(struct spaceBitmapDesc) << 3; + count = min(max_bits - off, bitmap->s_nr_groups); + } else { + /* + * Rough check if bitmap number is too big to have any bitmap + * blocks reserved. + */ + if (bitmap_nr > + (bitmap->s_nr_groups >> (sb->s_blocksize_bits + 3)) + 2) + return 0; + off = 0; + count = bitmap->s_nr_groups - bitmap_nr * max_bits + + (sizeof(struct spaceBitmapDesc) << 3); + count = min(count, max_bits); + } + + for (i = 0; i < count; i++) + if (udf_test_bit(i + off, bh->b_data)) + return -EFSCORRUPTED; + return 0; } static int __load_block_bitmap(struct super_block *sb, only in patch2: unchanged: --- linux-6.2.0.orig/fs/verity/signature.c +++ linux-6.2.0/fs/verity/signature.c @@ -54,6 +54,22 @@ return 0; } + if (fsverity_keyring->keys.nr_leaves_on_tree == 0) { + /* + * The ".fs-verity" keyring is empty, due to builtin signatures + * being supported by the kernel but not actually being used. + * In this case, verify_pkcs7_signature() would always return an + * error, usually ENOKEY. It could also be EBADMSG if the + * PKCS#7 is malformed, but that isn't very important to + * distinguish. So, just skip to ENOKEY to avoid the attack + * surface of the PKCS#7 parser, which would otherwise be + * reachable by any task able to execute FS_IOC_ENABLE_VERITY. + */ + fsverity_err(inode, + "fs-verity keyring is empty, rejecting signed file!"); + return -ENOKEY; + } + d = kzalloc(sizeof(*d) + hash_alg->digest_size, GFP_KERNEL); if (!d) return -ENOMEM; only in patch2: unchanged: --- linux-6.2.0.orig/include/dt-bindings/clock/qcom,gcc-sc8280xp.h +++ linux-6.2.0/include/dt-bindings/clock/qcom,gcc-sc8280xp.h @@ -492,5 +492,17 @@ #define USB30_MP_GDSC 9 #define USB30_PRIM_GDSC 10 #define USB30_SEC_GDSC 11 +#define EMAC_0_GDSC 12 +#define EMAC_1_GDSC 13 +#define USB4_1_GDSC 14 +#define USB4_GDSC 15 +#define HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC 16 +#define HLOS1_VOTE_MMNOC_MMU_TBU_HF1_GDSC 17 +#define HLOS1_VOTE_MMNOC_MMU_TBU_SF0_GDSC 18 +#define HLOS1_VOTE_MMNOC_MMU_TBU_SF1_GDSC 19 +#define HLOS1_VOTE_TURING_MMU_TBU0_GDSC 20 +#define HLOS1_VOTE_TURING_MMU_TBU1_GDSC 21 +#define HLOS1_VOTE_TURING_MMU_TBU2_GDSC 22 +#define HLOS1_VOTE_TURING_MMU_TBU3_GDSC 23 #endif only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/acpi_iort.h +++ linux-6.2.0/include/linux/acpi_iort.h @@ -21,6 +21,7 @@ */ #define IORT_SMMU_V3_PMCG_GENERIC 0x00000000 /* Generic SMMUv3 PMCG */ #define IORT_SMMU_V3_PMCG_HISI_HIP08 0x00000001 /* HiSilicon HIP08 PMCG */ +#define IORT_SMMU_V3_PMCG_HISI_HIP09 0x00000002 /* HiSilicon HIP09 PMCG */ int iort_register_domain_token(int trans_id, phys_addr_t base, struct fwnode_handle *fw_node); only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/arm_sdei.h +++ linux-6.2.0/include/linux/arm_sdei.h @@ -47,10 +47,12 @@ int sdei_mask_local_cpu(void); int sdei_unmask_local_cpu(void); void __init sdei_init(void); +void sdei_handler_abort(void); #else static inline int sdei_mask_local_cpu(void) { return 0; } static inline int sdei_unmask_local_cpu(void) { return 0; } static inline void sdei_init(void) { } +static inline void sdei_handler_abort(void) { } #endif /* CONFIG_ARM_SDE_INTERFACE */ only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/btf_ids.h +++ linux-6.2.0/include/linux/btf_ids.h @@ -49,7 +49,7 @@ ____BTF_ID(symbol, word) #define __ID(prefix) \ - __PASTE(prefix, __COUNTER__) + __PASTE(__PASTE(prefix, __COUNTER__), __LINE__) /* * The BTF_ID defines unique symbol for each ID pointing only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/bvec.h +++ linux-6.2.0/include/linux/bvec.h @@ -35,6 +35,21 @@ unsigned int bv_offset; }; +/** + * bvec_set_page - initialize a bvec based off a struct page + * @bv: bvec to initialize + * @page: page the bvec should point to + * @len: length of the bvec + * @offset: offset into the page + */ +static inline void bvec_set_page(struct bio_vec *bv, struct page *page, + unsigned int len, unsigned int offset) +{ + bv->bv_page = page; + bv->bv_len = len; + bv->bv_offset = offset; +} + struct bvec_iter { sector_t bi_sector; /* device address in 512 byte sectors */ only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/clk-provider.h +++ linux-6.2.0/include/linux/clk-provider.h @@ -1363,7 +1363,13 @@ struct clk_hw *hws[]; }; -#define CLK_OF_DECLARE(name, compat, fn) OF_DECLARE_1(clk, name, compat, fn) +#define CLK_OF_DECLARE(name, compat, fn) \ + static void __init __##name##_of_clk_init_declare(struct device_node *np) \ + { \ + fn(np); \ + fwnode_dev_initialized(of_fwnode_handle(np), true); \ + } \ + OF_DECLARE_1(clk, name, compat, __##name##_of_clk_init_declare) /* * Use this macro when you have a driver that requires two initialization only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/if_arp.h +++ linux-6.2.0/include/linux/if_arp.h @@ -53,6 +53,10 @@ case ARPHRD_NONE: case ARPHRD_RAWIP: case ARPHRD_PIMREG: + /* PPP adds its l2 header automatically in ppp_start_xmit(). + * This makes it look like an l3 device to __bpf_redirect() and tcf_mirred_init(). + */ + case ARPHRD_PPP: return false; default: return true; only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/instruction_pointer.h +++ linux-6.2.0/include/linux/instruction_pointer.h @@ -2,7 +2,12 @@ #ifndef _LINUX_INSTRUCTION_POINTER_H #define _LINUX_INSTRUCTION_POINTER_H +#include + #define _RET_IP_ (unsigned long)__builtin_return_address(0) + +#ifndef _THIS_IP_ #define _THIS_IP_ ({ __label__ __here; __here: (unsigned long)&&__here; }) +#endif #endif /* _LINUX_INSTRUCTION_POINTER_H */ only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/interrupt.h +++ linux-6.2.0/include/linux/interrupt.h @@ -569,8 +569,12 @@ * 2) rcu_report_dead() reports the final quiescent states. * * _ IRQ_POLL: irq_poll_cpu_dead() migrates the queue + * + * _ (HR)TIMER_SOFTIRQ: (hr)timers_dead_cpu() migrates the queue */ -#define SOFTIRQ_HOTPLUG_SAFE_MASK (BIT(RCU_SOFTIRQ) | BIT(IRQ_POLL_SOFTIRQ)) +#define SOFTIRQ_HOTPLUG_SAFE_MASK (BIT(TIMER_SOFTIRQ) | BIT(IRQ_POLL_SOFTIRQ) |\ + BIT(HRTIMER_SOFTIRQ) | BIT(RCU_SOFTIRQ)) + /* map softirq index to softirq name. update 'softirq_to_name' in * kernel/softirq.c when adding a new softirq. only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/ipv6.h +++ linux-6.2.0/include/linux/ipv6.h @@ -33,6 +33,7 @@ __s32 accept_ra_defrtr; __u32 ra_defrtr_metric; __s32 accept_ra_min_hop_limit; + __s32 accept_ra_min_lft; __s32 accept_ra_pinfo; __s32 ignore_routes_with_linkdown; #ifdef CONFIG_IPV6_ROUTER_PREF @@ -146,6 +147,7 @@ #define IP6SKB_JUMBOGRAM 128 #define IP6SKB_SEG6 256 #define IP6SKB_FAKEJUMBO 512 +#define IP6SKB_MULTIPATH 1024 }; #if defined(CONFIG_NET_L3_MASTER_DEV) only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/kernfs.h +++ linux-6.2.0/include/linux/kernfs.h @@ -550,6 +550,10 @@ const struct iattr *iattr) { return -ENOSYS; } +static inline __poll_t kernfs_generic_poll(struct kernfs_open_file *of, + struct poll_table_struct *pt) +{ return -ENOSYS; } + static inline void kernfs_notify(struct kernfs_node *kn) { } static inline int kernfs_xattr_get(struct kernfs_node *kn, const char *name, only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/memcontrol.h +++ linux-6.2.0/include/linux/memcontrol.h @@ -283,6 +283,11 @@ atomic_long_t memory_events[MEMCG_NR_MEMORY_EVENTS]; atomic_long_t memory_events_local[MEMCG_NR_MEMORY_EVENTS]; + /* + * Hint of reclaim pressure for socket memroy management. Note + * that this indicator should NOT be used in legacy cgroup mode + * where socket memory is accounted/charged separately. + */ unsigned long socket_pressure; /* Legacy tcp memory accounting */ @@ -901,7 +906,7 @@ return READ_ONCE(mz->lru_zone_size[zone_idx][lru]); } -void mem_cgroup_handle_over_high(void); +void mem_cgroup_handle_over_high(gfp_t gfp_mask); unsigned long mem_cgroup_get_max(struct mem_cgroup *memcg); @@ -1443,7 +1448,7 @@ rcu_read_unlock(); } -static inline void mem_cgroup_handle_over_high(void) +static inline void mem_cgroup_handle_over_high(gfp_t gfp_mask) { } @@ -1715,8 +1720,8 @@ void mem_cgroup_sk_free(struct sock *sk); static inline bool mem_cgroup_under_socket_pressure(struct mem_cgroup *memcg) { - if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && memcg->tcpmem_pressure) - return true; + if (!cgroup_subsys_on_dfl(memory_cgrp_subsys)) + return !!memcg->tcpmem_pressure; do { if (time_before(jiffies, READ_ONCE(memcg->socket_pressure))) return true; only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/micrel_phy.h +++ linux-6.2.0/include/linux/micrel_phy.h @@ -38,9 +38,9 @@ #define PHY_ID_KSZ9477 0x00221631 /* struct phy_device dev_flags definitions */ -#define MICREL_PHY_50MHZ_CLK 0x00000001 -#define MICREL_PHY_FXEN 0x00000002 -#define MICREL_KSZ8_P1_ERRATA 0x00000003 +#define MICREL_PHY_50MHZ_CLK BIT(0) +#define MICREL_PHY_FXEN BIT(1) +#define MICREL_KSZ8_P1_ERRATA BIT(2) #define MICREL_KSZ9021_EXTREG_CTRL 0xB #define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/mm_inline.h +++ linux-6.2.0/include/linux/mm_inline.h @@ -256,9 +256,9 @@ lru_gen_update_size(lruvec, folio, -1, gen); /* for folio_rotate_reclaimable() */ if (reclaiming) - list_add_tail(&folio->lru, &lrugen->lists[gen][type][zone]); + list_add_tail(&folio->lru, &lrugen->folios[gen][type][zone]); else - list_add(&folio->lru, &lrugen->lists[gen][type][zone]); + list_add(&folio->lru, &lrugen->folios[gen][type][zone]); return true; } only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/mmzone.h +++ linux-6.2.0/include/linux/mmzone.h @@ -312,7 +312,7 @@ * They form a sliding window of a variable size [MIN_NR_GENS, MAX_NR_GENS]. An * offset within MAX_NR_GENS, i.e., gen, indexes the LRU list of the * corresponding generation. The gen counter in folio->flags stores gen+1 while - * a page is on one of lrugen->lists[]. Otherwise it stores 0. + * a page is on one of lrugen->folios[]. Otherwise it stores 0. * * A page is added to the youngest generation on faulting. The aging needs to * check the accessed bit at least twice before handing this page over to the @@ -324,8 +324,8 @@ * rest of generations, if they exist, are considered inactive. See * lru_gen_is_active(). * - * PG_active is always cleared while a page is on one of lrugen->lists[] so that - * the aging needs not to worry about it. And it's set again when a page + * PG_active is always cleared while a page is on one of lrugen->folios[] so + * that the aging needs not to worry about it. And it's set again when a page * considered active is isolated for non-reclaiming purposes, e.g., migration. * See lru_gen_add_folio() and lru_gen_del_folio(). * @@ -412,7 +412,7 @@ /* the birth time of each generation in jiffies */ unsigned long timestamps[MAX_NR_GENS]; /* the multi-gen LRU lists, lazily sorted on eviction */ - struct list_head lists[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; + struct list_head folios[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; /* the multi-gen LRU sizes, eventually consistent */ long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES]; /* the exponential moving average of refaulted */ only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/netfilter/nf_conntrack_sctp.h +++ linux-6.2.0/include/linux/netfilter/nf_conntrack_sctp.h @@ -9,6 +9,7 @@ enum sctp_conntrack state; __be32 vtag[IP_CT_DIR_MAX]; + u8 init[IP_CT_DIR_MAX]; u8 last_dir; u8 flags; }; only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/nfs_fs_sb.h +++ linux-6.2.0/include/linux/nfs_fs_sb.h @@ -48,6 +48,7 @@ #define NFS_CS_NOPING 6 /* - don't ping on connect */ #define NFS_CS_DS 7 /* - Server is a DS */ #define NFS_CS_REUSEPORT 8 /* - reuse src port on reconnect */ +#define NFS_CS_PNFS 9 /* - Server used for pnfs */ struct sockaddr_storage cl_addr; /* server identifier */ size_t cl_addrlen; char * cl_hostname; /* hostname of server */ only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/nfs_xdr.h +++ linux-6.2.0/include/linux/nfs_xdr.h @@ -670,6 +670,7 @@ struct { unsigned int replen; /* used by read */ int eof; /* used by read */ + void * scratch; /* used by read */ }; struct { struct nfs_writeverf * verf; /* used by write */ only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/nls.h +++ linux-6.2.0/include/linux/nls.h @@ -47,7 +47,7 @@ /* nls_base.c */ extern int __register_nls(struct nls_table *, struct module *); extern int unregister_nls(struct nls_table *); -extern struct nls_table *load_nls(char *); +extern struct nls_table *load_nls(const char *charset); extern void unload_nls(struct nls_table *); extern struct nls_table *load_nls_default(void); #define register_nls(nls) __register_nls((nls), THIS_MODULE) only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/regulator/mt6358-regulator.h +++ linux-6.2.0/include/linux/regulator/mt6358-regulator.h @@ -48,8 +48,6 @@ MT6358_ID_VLDO28, MT6358_ID_VAUD28, MT6358_ID_VSIM2, - MT6358_ID_VCORE_SSHUB, - MT6358_ID_VSRAM_OTHERS_SSHUB, MT6358_ID_RG_MAX, }; @@ -90,8 +88,6 @@ MT6366_ID_VMC, MT6366_ID_VAUD28, MT6366_ID_VSIM2, - MT6366_ID_VCORE_SSHUB, - MT6366_ID_VSRAM_OTHERS_SSHUB, MT6366_ID_RG_MAX, }; only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/resume_user_mode.h +++ linux-6.2.0/include/linux/resume_user_mode.h @@ -55,7 +55,7 @@ } #endif - mem_cgroup_handle_over_high(); + mem_cgroup_handle_over_high(GFP_KERNEL); blkcg_maybe_throttle_current(); rseq_handle_notify_resume(NULL, regs); only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/sched/task.h +++ linux-6.2.0/include/linux/sched/task.h @@ -112,10 +112,36 @@ } extern void __put_task_struct(struct task_struct *t); +extern void __put_task_struct_rcu_cb(struct rcu_head *rhp); static inline void put_task_struct(struct task_struct *t) { - if (refcount_dec_and_test(&t->usage)) + if (!refcount_dec_and_test(&t->usage)) + return; + + /* + * under PREEMPT_RT, we can't call put_task_struct + * in atomic context because it will indirectly + * acquire sleeping locks. + * + * call_rcu() will schedule delayed_put_task_struct_rcu() + * to be called in process context. + * + * __put_task_struct() is called when + * refcount_dec_and_test(&t->usage) succeeds. + * + * This means that it can't "conflict" with + * put_task_struct_rcu_user() which abuses ->rcu the same + * way; rcu_users has a reference so task->usage can't be + * zero after rcu_users 1 -> 0 transition. + * + * delayed_free_task() also uses ->rcu, but it is only called + * when it fails to fork a process. Therefore, there is no + * way it can conflict with put_task_struct(). + */ + if (IS_ENABLED(CONFIG_PREEMPT_RT) && !preemptible()) + call_rcu(&t->rcu, __put_task_struct_rcu_cb); + else __put_task_struct(t); } only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/seqlock.h +++ linux-6.2.0/include/linux/seqlock.h @@ -512,8 +512,8 @@ static inline void do_write_seqcount_begin_nested(seqcount_t *s, int subclass) { - do_raw_write_seqcount_begin(s); seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_); + do_raw_write_seqcount_begin(s); } /** only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/tca6416_keypad.h +++ linux-6.2.0/include/linux/tca6416_keypad.h @@ -25,7 +25,6 @@ unsigned int rep:1; /* enable input subsystem auto repeat */ uint16_t pinmask; uint16_t invert; - int irq_is_gpio; int use_polling; /* use polling if Interrupt is not connected*/ }; #endif only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/trace_events.h +++ linux-6.2.0/include/linux/trace_events.h @@ -863,7 +863,8 @@ extern void perf_uprobe_destroy(struct perf_event *event); extern int bpf_get_uprobe_info(const struct perf_event *event, u32 *fd_type, const char **filename, - u64 *probe_offset, bool perf_type_tracepoint); + u64 *probe_offset, u64 *probe_addr, + bool perf_type_tracepoint); #endif extern int ftrace_profile_set_filter(struct perf_event *event, int event_id, char *filter_str); only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/usb/chipidea.h +++ linux-6.2.0/include/linux/usb/chipidea.h @@ -63,6 +63,7 @@ #define CI_HDRC_IMX_IS_HSIC BIT(14) #define CI_HDRC_PMQOS BIT(15) #define CI_HDRC_PHY_VBUS_CONTROL BIT(16) +#define CI_HDRC_HAS_PORTSC_PEC_MISSED BIT(17) enum usb_dr_mode dr_mode; #define CI_HDRC_CONTROLLER_RESET_EVENT 0 #define CI_HDRC_CONTROLLER_STOPPED_EVENT 1 only in patch2: unchanged: --- linux-6.2.0.orig/include/linux/usb/typec_altmode.h +++ linux-6.2.0/include/linux/usb/typec_altmode.h @@ -67,7 +67,7 @@ int typec_altmode_enter(struct typec_altmode *altmode, u32 *vdo); int typec_altmode_exit(struct typec_altmode *altmode); -void typec_altmode_attention(struct typec_altmode *altmode, u32 vdo); +int typec_altmode_attention(struct typec_altmode *altmode, u32 vdo); int typec_altmode_vdm(struct typec_altmode *altmode, const u32 header, const u32 *vdo, int count); int typec_altmode_notify(struct typec_altmode *altmode, unsigned long conf, only in patch2: unchanged: --- linux-6.2.0.orig/include/media/cec.h +++ linux-6.2.0/include/media/cec.h @@ -113,22 +113,25 @@ #define CEC_FREE_TIME_TO_USEC(ft) ((ft) * 2400) struct cec_adap_ops { - /* Low-level callbacks */ + /* Low-level callbacks, called with adap->lock held */ int (*adap_enable)(struct cec_adapter *adap, bool enable); int (*adap_monitor_all_enable)(struct cec_adapter *adap, bool enable); int (*adap_monitor_pin_enable)(struct cec_adapter *adap, bool enable); int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); - void (*adap_configured)(struct cec_adapter *adap, bool configured); + void (*adap_unconfigured)(struct cec_adapter *adap); int (*adap_transmit)(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg); + void (*adap_nb_transmit_canceled)(struct cec_adapter *adap, + const struct cec_msg *msg); void (*adap_status)(struct cec_adapter *adap, struct seq_file *file); void (*adap_free)(struct cec_adapter *adap); - /* Error injection callbacks */ + /* Error injection callbacks, called without adap->lock held */ int (*error_inj_show)(struct cec_adapter *adap, struct seq_file *sf); bool (*error_inj_parse_line)(struct cec_adapter *adap, char *line); - /* High-level CEC message callback */ + /* High-level CEC message callback, called without adap->lock held */ + void (*configured)(struct cec_adapter *adap); int (*received)(struct cec_adapter *adap, struct cec_msg *msg); }; only in patch2: unchanged: --- linux-6.2.0.orig/include/net/arp.h +++ linux-6.2.0/include/net/arp.h @@ -38,11 +38,11 @@ { struct neighbour *n; - rcu_read_lock_bh(); + rcu_read_lock(); n = __ipv4_neigh_lookup_noref(dev, key); if (n && !refcount_inc_not_zero(&n->refcnt)) n = NULL; - rcu_read_unlock_bh(); + rcu_read_unlock(); return n; } @@ -51,10 +51,10 @@ { struct neighbour *n; - rcu_read_lock_bh(); + rcu_read_lock(); n = __ipv4_neigh_lookup_noref(dev, key); neigh_confirm(n); - rcu_read_unlock_bh(); + rcu_read_unlock(); } void arp_init(void); only in patch2: unchanged: --- linux-6.2.0.orig/include/net/ip6_fib.h +++ linux-6.2.0/include/net/ip6_fib.h @@ -472,13 +472,10 @@ rcu_read_lock(); from = rcu_dereference(rt->from); - if (from) { + if (from) *addr = from->fib6_prefsrc.addr; - } else { - struct in6_addr in6_zero = {}; - - *addr = in6_zero; - } + else + *addr = in6addr_any; rcu_read_unlock(); } @@ -610,7 +607,10 @@ if (!net->ipv6.fib6_rules_require_fldissect) return false; - skb_flow_dissect_flow_keys(skb, flkeys, flag); + memset(flkeys, 0, sizeof(*flkeys)); + __skb_flow_dissect(net, skb, &flow_keys_dissector, + flkeys, NULL, 0, 0, 0, flag); + fl6->fl6_sport = flkeys->ports.src; fl6->fl6_dport = flkeys->ports.dst; fl6->flowi6_proto = flkeys->basic.ip_proto; only in patch2: unchanged: --- linux-6.2.0.orig/include/net/ip_fib.h +++ linux-6.2.0/include/net/ip_fib.h @@ -418,7 +418,10 @@ if (!net->ipv4.fib_rules_require_fldissect) return false; - skb_flow_dissect_flow_keys(skb, flkeys, flag); + memset(flkeys, 0, sizeof(*flkeys)); + __skb_flow_dissect(net, skb, &flow_keys_dissector, + flkeys, NULL, 0, 0, 0, flag); + fl4->fl4_sport = flkeys->ports.src; fl4->fl4_dport = flkeys->ports.dst; fl4->flowi4_proto = flkeys->basic.ip_proto; only in patch2: unchanged: --- linux-6.2.0.orig/include/net/lwtunnel.h +++ linux-6.2.0/include/net/lwtunnel.h @@ -16,9 +16,12 @@ #define LWTUNNEL_STATE_INPUT_REDIRECT BIT(1) #define LWTUNNEL_STATE_XMIT_REDIRECT BIT(2) +/* LWTUNNEL_XMIT_CONTINUE should be distinguishable from dst_output return + * values (NET_XMIT_xxx and NETDEV_TX_xxx in linux/netdevice.h) for safety. + */ enum { LWTUNNEL_XMIT_DONE, - LWTUNNEL_XMIT_CONTINUE, + LWTUNNEL_XMIT_CONTINUE = 0x100, }; only in patch2: unchanged: --- linux-6.2.0.orig/include/net/ndisc.h +++ linux-6.2.0/include/net/ndisc.h @@ -395,11 +395,11 @@ { struct neighbour *n; - rcu_read_lock_bh(); + rcu_read_lock(); n = __ipv6_neigh_lookup_noref(dev, pkey); if (n && !refcount_inc_not_zero(&n->refcnt)) n = NULL; - rcu_read_unlock_bh(); + rcu_read_unlock(); return n; } @@ -409,10 +409,10 @@ { struct neighbour *n; - rcu_read_lock_bh(); + rcu_read_lock(); n = __ipv6_neigh_lookup_noref(dev, pkey); neigh_confirm(n); - rcu_read_unlock_bh(); + rcu_read_unlock(); } static inline void __ipv6_confirm_neigh_stub(struct net_device *dev, @@ -420,10 +420,10 @@ { struct neighbour *n; - rcu_read_lock_bh(); + rcu_read_lock(); n = __ipv6_neigh_lookup_noref_stub(dev, pkey); neigh_confirm(n); - rcu_read_unlock_bh(); + rcu_read_unlock(); } /* uses ipv6_stub and is meant for use outside of IPv6 core */ only in patch2: unchanged: --- linux-6.2.0.orig/include/net/nexthop.h +++ linux-6.2.0/include/net/nexthop.h @@ -497,29 +497,6 @@ return NULL; } -/* Variant of nexthop_fib6_nh(). - * Caller should either hold rcu_read_lock_bh(), or RTNL. - */ -static inline struct fib6_nh *nexthop_fib6_nh_bh(struct nexthop *nh) -{ - struct nh_info *nhi; - - if (nh->is_group) { - struct nh_group *nh_grp; - - nh_grp = rcu_dereference_bh_rtnl(nh->nh_grp); - nh = nexthop_mpath_select(nh_grp, 0); - if (!nh) - return NULL; - } - - nhi = rcu_dereference_bh_rtnl(nh->nh_info); - if (nhi->family == AF_INET6) - return &nhi->fib6_nh; - - return NULL; -} - static inline struct net_device *fib6_info_nh_dev(struct fib6_info *f6i) { struct fib6_nh *fib6_nh; only in patch2: unchanged: --- linux-6.2.0.orig/include/scsi/scsi_host.h +++ linux-6.2.0/include/scsi/scsi_host.h @@ -758,12 +758,12 @@ #define scsi_template_proc_dir(sht) NULL #endif extern void scsi_scan_host(struct Scsi_Host *); -extern void scsi_rescan_device(struct device *); +extern int scsi_rescan_device(struct scsi_device *sdev); extern void scsi_remove_host(struct Scsi_Host *); extern struct Scsi_Host *scsi_host_get(struct Scsi_Host *); extern int scsi_host_busy(struct Scsi_Host *shost); extern void scsi_host_put(struct Scsi_Host *t); -extern struct Scsi_Host *scsi_host_lookup(unsigned short); +extern struct Scsi_Host *scsi_host_lookup(unsigned int hostnum); extern const char *scsi_host_state_name(enum scsi_host_state); extern void scsi_host_complete_all_commands(struct Scsi_Host *shost, enum scsi_host_status status); only in patch2: unchanged: --- linux-6.2.0.orig/include/trace/events/fib.h +++ linux-6.2.0/include/trace/events/fib.h @@ -36,7 +36,6 @@ ), TP_fast_assign( - struct in6_addr in6_zero = {}; struct net_device *dev; struct in6_addr *in6; __be32 *p32; @@ -74,7 +73,7 @@ *p32 = nhc->nhc_gw.ipv4; in6 = (struct in6_addr *)__entry->gw6; - *in6 = in6_zero; + *in6 = in6addr_any; } else if (nhc->nhc_gw_family == AF_INET6) { p32 = (__be32 *) __entry->gw4; *p32 = 0; @@ -87,7 +86,7 @@ *p32 = 0; in6 = (struct in6_addr *)__entry->gw6; - *in6 = in6_zero; + *in6 = in6addr_any; } ), only in patch2: unchanged: --- linux-6.2.0.orig/include/trace/events/fib6.h +++ linux-6.2.0/include/trace/events/fib6.h @@ -68,11 +68,8 @@ strcpy(__entry->name, "-"); } if (res->f6i == net->ipv6.fib6_null_entry) { - struct in6_addr in6_zero = {}; - in6 = (struct in6_addr *)__entry->gw; - *in6 = in6_zero; - + *in6 = in6addr_any; } else if (res->nh) { in6 = (struct in6_addr *)__entry->gw; *in6 = res->nh->fib_nh_gw6; only in patch2: unchanged: --- linux-6.2.0.orig/include/uapi/linux/ipv6.h +++ linux-6.2.0/include/uapi/linux/ipv6.h @@ -198,6 +198,7 @@ DEVCONF_IOAM6_ID_WIDE, DEVCONF_NDISC_EVICT_NOCARRIER, DEVCONF_ACCEPT_UNTRACKED_NA, + DEVCONF_ACCEPT_RA_MIN_LFT, DEVCONF_MAX }; only in patch2: unchanged: --- linux-6.2.0.orig/include/uapi/linux/netfilter_bridge/ebtables.h +++ linux-6.2.0/include/uapi/linux/netfilter_bridge/ebtables.h @@ -182,12 +182,14 @@ unsigned char sourcemsk[ETH_ALEN]; unsigned char destmac[ETH_ALEN]; unsigned char destmsk[ETH_ALEN]; - /* sizeof ebt_entry + matches */ - unsigned int watchers_offset; - /* sizeof ebt_entry + matches + watchers */ - unsigned int target_offset; - /* sizeof ebt_entry + matches + watchers + target */ - unsigned int next_offset; + __struct_group(/* no tag */, offsets, /* no attrs */, + /* sizeof ebt_entry + matches */ + unsigned int watchers_offset; + /* sizeof ebt_entry + matches + watchers */ + unsigned int target_offset; + /* sizeof ebt_entry + matches + watchers + target */ + unsigned int next_offset; + ); unsigned char elems[0] __attribute__ ((aligned (__alignof__(struct ebt_replace)))); }; only in patch2: unchanged: --- linux-6.2.0.orig/include/uapi/linux/stddef.h +++ linux-6.2.0/include/uapi/linux/stddef.h @@ -29,6 +29,11 @@ struct TAG { MEMBERS } ATTRS NAME; \ } +#ifdef __cplusplus +/* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */ +#define __DECLARE_FLEX_ARRAY(T, member) \ + T member[0] +#else /** * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union * @@ -45,3 +50,4 @@ TYPE NAME[]; \ } #endif +#endif only in patch2: unchanged: --- linux-6.2.0.orig/include/uapi/linux/sync_file.h +++ linux-6.2.0/include/uapi/linux/sync_file.h @@ -52,7 +52,7 @@ * @name: name of fence * @status: status of fence. 1: signaled 0:active <0:error * @flags: sync_file_info flags - * @num_fences number of fences in the sync_file + * @num_fences: number of fences in the sync_file * @pad: padding for 64-bit alignment, should always be zero * @sync_fence_info: pointer to array of structs sync_fence_info with all * fences in the sync_file only in patch2: unchanged: --- linux-6.2.0.orig/include/uapi/linux/v4l2-controls.h +++ linux-6.2.0/include/uapi/linux/v4l2-controls.h @@ -2381,6 +2381,9 @@ * @poc_st_curr_after: provides the index of the short term after references * in DPB array * @poc_lt_curr: provides the index of the long term references in DPB array + * @num_delta_pocs_of_ref_rps_idx: same as the derived value NumDeltaPocs[RefRpsIdx], + * can be used to parse the RPS data in slice headers + * instead of skipping it with @short_term_ref_pic_set_size. * @reserved: padding field. Should be zeroed by applications. * @dpb: the decoded picture buffer, for meta-data about reference frames * @flags: see V4L2_HEVC_DECODE_PARAM_FLAG_{} @@ -2396,7 +2399,8 @@ __u8 poc_st_curr_before[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; __u8 poc_st_curr_after[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; __u8 poc_lt_curr[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; - __u8 reserved[4]; + __u8 num_delta_pocs_of_ref_rps_idx; + __u8 reserved[3]; struct v4l2_hevc_dpb_entry dpb[V4L2_HEVC_DPB_ENTRIES_NUM_MAX]; __u64 flags; }; only in patch2: unchanged: --- linux-6.2.0.orig/io_uring/fs.c +++ linux-6.2.0/io_uring/fs.c @@ -243,7 +243,7 @@ struct io_link *lnk = io_kiocb_to_cmd(req, struct io_link); const char __user *oldf, *newf; - if (sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in) + if (sqe->buf_index || sqe->splice_fd_in) return -EINVAL; if (unlikely(req->flags & REQ_F_FIXED_FILE)) return -EBADF; only in patch2: unchanged: --- linux-6.2.0.orig/io_uring/io-wq.c +++ linux-6.2.0/io_uring/io-wq.c @@ -181,6 +181,16 @@ complete(&wq->worker_done); } +bool io_wq_worker_stopped(void) +{ + struct io_worker *worker = current->worker_private; + + if (WARN_ON_ONCE(!io_wq_current_is_worker())) + return true; + + return test_bit(IO_WQ_BIT_EXIT, &worker->wqe->wq->state); +} + static void io_worker_cancel_cb(struct io_worker *worker) { struct io_wqe_acct *acct = io_wqe_get_acct(worker); @@ -1340,13 +1350,16 @@ return __io_wq_cpu_online(wq, cpu, false); } -int io_wq_cpu_affinity(struct io_wq *wq, cpumask_var_t mask) +int io_wq_cpu_affinity(struct io_uring_task *tctx, cpumask_var_t mask) { int i; + if (!tctx || !tctx->io_wq) + return -EINVAL; + rcu_read_lock(); for_each_node(i) { - struct io_wqe *wqe = wq->wqes[i]; + struct io_wqe *wqe = tctx->io_wq->wqes[i]; if (mask) cpumask_copy(wqe->cpu_mask, mask); only in patch2: unchanged: --- linux-6.2.0.orig/io_uring/io-wq.h +++ linux-6.2.0/io_uring/io-wq.h @@ -50,8 +50,9 @@ void io_wq_enqueue(struct io_wq *wq, struct io_wq_work *work); void io_wq_hash_work(struct io_wq_work *work, void *val); -int io_wq_cpu_affinity(struct io_wq *wq, cpumask_var_t mask); +int io_wq_cpu_affinity(struct io_uring_task *tctx, cpumask_var_t mask); int io_wq_max_workers(struct io_wq *wq, int *new_count); +bool io_wq_worker_stopped(void); static inline bool io_wq_is_hashed(struct io_wq_work *work) { only in patch2: unchanged: --- linux-6.2.0.orig/io_uring/sqpoll.h +++ linux-6.2.0/io_uring/sqpoll.h @@ -27,3 +27,4 @@ void io_sq_thread_unpark(struct io_sq_data *sqd); void io_put_sq_data(struct io_sq_data *sqd); int io_sqpoll_wait_sq(struct io_ring_ctx *ctx); +int io_sqpoll_wq_cpu_affinity(struct io_ring_ctx *ctx, cpumask_var_t mask); only in patch2: unchanged: --- linux-6.2.0.orig/kernel/cgroup/namespace.c +++ linux-6.2.0/kernel/cgroup/namespace.c @@ -149,9 +149,3 @@ .install = cgroupns_install, .owner = cgroupns_owner, }; - -static __init int cgroup_namespaces_init(void) -{ - return 0; -} -subsys_initcall(cgroup_namespaces_init); only in patch2: unchanged: --- linux-6.2.0.orig/kernel/cpu.c +++ linux-6.2.0/kernel/cpu.c @@ -1215,8 +1215,22 @@ return ret; } +struct cpu_down_work { + unsigned int cpu; + enum cpuhp_state target; +}; + +static long __cpu_down_maps_locked(void *arg) +{ + struct cpu_down_work *work = arg; + + return _cpu_down(work->cpu, 0, work->target); +} + static int cpu_down_maps_locked(unsigned int cpu, enum cpuhp_state target) { + struct cpu_down_work work = { .cpu = cpu, .target = target, }; + /* * If the platform does not support hotplug, report it explicitly to * differentiate it from a transient offlining failure. @@ -1225,7 +1239,15 @@ return -EOPNOTSUPP; if (cpu_hotplug_disabled) return -EBUSY; - return _cpu_down(cpu, 0, target); + + /* + * Ensure that the control task does not run on the to be offlined + * CPU to prevent a deadlock against cfs_b->period_timer. + */ + cpu = cpumask_any_but(cpu_online_mask, cpu); + if (cpu >= nr_cpu_ids) + return -EBUSY; + return work_on_cpu(cpu, __cpu_down_maps_locked, &work); } static int cpu_down(unsigned int cpu, enum cpuhp_state target) only in patch2: unchanged: --- linux-6.2.0.orig/kernel/dma/debug.c +++ linux-6.2.0/kernel/dma/debug.c @@ -603,15 +603,19 @@ return entry; } -static void __dma_entry_alloc_check_leak(void) +/* + * This should be called outside of free_entries_lock scope to avoid potential + * deadlocks with serial consoles that use DMA. + */ +static void __dma_entry_alloc_check_leak(u32 nr_entries) { - u32 tmp = nr_total_entries % nr_prealloc_entries; + u32 tmp = nr_entries % nr_prealloc_entries; /* Shout each time we tick over some multiple of the initial pool */ if (tmp < DMA_DEBUG_DYNAMIC_ENTRIES) { pr_info("dma_debug_entry pool grown to %u (%u00%%)\n", - nr_total_entries, - (nr_total_entries / nr_prealloc_entries)); + nr_entries, + (nr_entries / nr_prealloc_entries)); } } @@ -622,8 +626,10 @@ */ static struct dma_debug_entry *dma_entry_alloc(void) { + bool alloc_check_leak = false; struct dma_debug_entry *entry; unsigned long flags; + u32 nr_entries; spin_lock_irqsave(&free_entries_lock, flags); if (num_free_entries == 0) { @@ -633,13 +639,17 @@ pr_err("debugging out of memory - disabling\n"); return NULL; } - __dma_entry_alloc_check_leak(); + alloc_check_leak = true; + nr_entries = nr_total_entries; } entry = __dma_entry_alloc(); spin_unlock_irqrestore(&free_entries_lock, flags); + if (alloc_check_leak) + __dma_entry_alloc_check_leak(nr_entries); + #ifdef CONFIG_STACKTRACE entry->stack_len = stack_trace_save(entry->stack_entries, ARRAY_SIZE(entry->stack_entries), only in patch2: unchanged: --- linux-6.2.0.orig/kernel/printk/printk.c +++ linux-6.2.0/kernel/printk/printk.c @@ -2360,7 +2360,11 @@ preempt_enable(); } - wake_up_klogd(); + if (in_sched) + defer_console_output(); + else + wake_up_klogd(); + return printed_len; } EXPORT_SYMBOL(vprintk_emit); @@ -2643,6 +2647,25 @@ return 0; } +/* + * Return true when this CPU should unlock console_sem without pushing all + * messages to the console. This reduces the chance that the console is + * locked when the panic CPU tries to use it. + */ +static bool abandon_console_lock_in_panic(void) +{ + if (!panic_in_progress()) + return false; + + /* + * We can use raw_smp_processor_id() here because it is impossible for + * the task to be migrated to the panic_cpu, or away from it. If + * panic_cpu has already been set, and we're not currently executing on + * that CPU, then we never will be. + */ + return atomic_read(&panic_cpu) != raw_smp_processor_id(); +} + /** * console_lock - block the console subsystem from printing * @@ -2655,6 +2678,10 @@ { might_sleep(); + /* On panic, the console_lock must be left to the panic cpu. */ + while (abandon_console_lock_in_panic()) + msleep(1000); + down_console_sem(); if (console_suspended) return; @@ -2673,6 +2700,9 @@ */ int console_trylock(void) { + /* On panic, the console_lock must be left to the panic cpu. */ + if (abandon_console_lock_in_panic()) + return 0; if (down_trylock_console_sem()) return 0; if (console_suspended) { @@ -2692,25 +2722,6 @@ EXPORT_SYMBOL(is_console_locked); /* - * Return true when this CPU should unlock console_sem without pushing all - * messages to the console. This reduces the chance that the console is - * locked when the panic CPU tries to use it. - */ -static bool abandon_console_lock_in_panic(void) -{ - if (!panic_in_progress()) - return false; - - /* - * We can use raw_smp_processor_id() here because it is impossible for - * the task to be migrated to the panic_cpu, or away from it. If - * panic_cpu has already been set, and we're not currently executing on - * that CPU, then we never will be. - */ - return atomic_read(&panic_cpu) != raw_smp_processor_id(); -} - -/* * Check if the given console is currently capable and allowed to print * records. * @@ -3757,11 +3768,33 @@ preempt_enable(); } +/** + * wake_up_klogd - Wake kernel logging daemon + * + * Use this function when new records have been added to the ringbuffer + * and the console printing of those records has already occurred or is + * known to be handled by some other context. This function will only + * wake the logging daemon. + * + * Context: Any context. + */ void wake_up_klogd(void) { __wake_up_klogd(PRINTK_PENDING_WAKEUP); } +/** + * defer_console_output - Wake kernel logging daemon and trigger + * console printing in a deferred context + * + * Use this function when new records have been added to the ringbuffer, + * this context is responsible for console printing those records, but + * the current context is not allowed to perform the console printing. + * Trigger an irq_work context to perform the console printing. This + * function also wakes the logging daemon. + * + * Context: Any context. + */ void defer_console_output(void) { /* @@ -3778,12 +3811,7 @@ int vprintk_deferred(const char *fmt, va_list args) { - int r; - - r = vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args); - defer_console_output(); - - return r; + return vprintk_emit(0, LOGLEVEL_SCHED, NULL, fmt, args); } int _printk_deferred(const char *fmt, ...) only in patch2: unchanged: --- linux-6.2.0.orig/kernel/printk/printk_ringbuffer.c +++ linux-6.2.0/kernel/printk/printk_ringbuffer.c @@ -1735,7 +1735,7 @@ if (!buf || !buf_size) return true; - data_size = min_t(u16, buf_size, len); + data_size = min_t(unsigned int, buf_size, len); memcpy(&buf[0], data, data_size); /* LMM(copy_data:A) */ return true; only in patch2: unchanged: --- linux-6.2.0.orig/kernel/printk/printk_safe.c +++ linux-6.2.0/kernel/printk/printk_safe.c @@ -38,13 +38,8 @@ * Use the main logbuf even in NMI. But avoid calling console * drivers that might have their own locks. */ - if (this_cpu_read(printk_context) || in_nmi()) { - int len; - - len = vprintk_store(0, LOGLEVEL_DEFAULT, NULL, fmt, args); - defer_console_output(); - return len; - } + if (this_cpu_read(printk_context) || in_nmi()) + return vprintk_deferred(fmt, args); /* No obstacles. */ return vprintk_default(fmt, args); only in patch2: unchanged: --- linux-6.2.0.orig/kernel/scftorture.c +++ linux-6.2.0/kernel/scftorture.c @@ -171,7 +171,8 @@ scfs.n_all_wait += scf_stats_p[i].n_all_wait; } if (atomic_read(&n_errs) || atomic_read(&n_mb_in_errs) || - atomic_read(&n_mb_out_errs) || atomic_read(&n_alloc_errs)) + atomic_read(&n_mb_out_errs) || + (!IS_ENABLED(CONFIG_KASAN) && atomic_read(&n_alloc_errs))) bangstr = "!!! "; pr_alert("%s %sscf_invoked_count %s: %lld resched: %lld single: %lld/%lld single_ofl: %lld/%lld single_rpc: %lld single_rpc_ofl: %lld many: %lld/%lld all: %lld/%lld ", SCFTORT_FLAG, bangstr, isdone ? "VER" : "ver", invoked_count, scfs.n_resched, @@ -323,7 +324,8 @@ preempt_disable(); if (scfsp->scfs_prim == SCF_PRIM_SINGLE || scfsp->scfs_wait) { scfcp = kmalloc(sizeof(*scfcp), GFP_ATOMIC); - if (WARN_ON_ONCE(!scfcp)) { + if (!scfcp) { + WARN_ON_ONCE(!IS_ENABLED(CONFIG_KASAN)); atomic_inc(&n_alloc_errs); } else { scfcp->scfc_cpu = -1; only in patch2: unchanged: --- linux-6.2.0.orig/kernel/sched/cpupri.c +++ linux-6.2.0/kernel/sched/cpupri.c @@ -101,6 +101,7 @@ if (lowest_mask) { cpumask_and(lowest_mask, &p->cpus_mask, vec->mask); + cpumask_and(lowest_mask, lowest_mask, cpu_active_mask); /* * We have to ensure that we have at least one bit only in patch2: unchanged: --- linux-6.2.0.orig/kernel/sched/idle.c +++ linux-6.2.0/kernel/sched/idle.c @@ -394,6 +394,7 @@ void cpu_startup_entry(enum cpuhp_state state) { + current->flags |= PF_IDLE; arch_cpu_idle_prepare(); cpuhp_online_idle(state); while (1) only in patch2: unchanged: --- linux-6.2.0.orig/kernel/trace/trace_events_inject.c +++ linux-6.2.0/kernel/trace/trace_events_inject.c @@ -328,7 +328,8 @@ } const struct file_operations event_inject_fops = { - .open = tracing_open_generic, + .open = tracing_open_file_tr, .read = event_inject_read, .write = event_inject_write, + .release = tracing_release_file_tr, }; only in patch2: unchanged: --- linux-6.2.0.orig/lib/idr.c +++ linux-6.2.0/lib/idr.c @@ -100,7 +100,7 @@ * @end: The maximum ID (exclusive). * @gfp: Memory allocation flags. * - * Allocates an unused ID in the range specified by @nextid and @end. If + * Allocates an unused ID in the range specified by @start and @end. If * @end is <= 0, it is treated as one larger than %INT_MAX. This allows * callers to use @start + N as @end as long as N is within integer range. * The search for an unused ID will start at the last ID allocated and will only in patch2: unchanged: --- linux-6.2.0.orig/lib/mpi/mpi-cmp.c +++ linux-6.2.0/lib/mpi/mpi-cmp.c @@ -25,8 +25,12 @@ mpi_limb_t limb = v; mpi_normalize(u); - if (!u->nlimbs && !limb) - return 0; + if (u->nlimbs == 0) { + if (v == 0) + return 0; + else + return -1; + } if (u->sign) return -1; if (u->nlimbs > 1) only in patch2: unchanged: --- linux-6.2.0.orig/lib/test_meminit.c +++ linux-6.2.0/lib/test_meminit.c @@ -93,7 +93,7 @@ int failures = 0, num_tests = 0; int i; - for (i = 0; i < 10; i++) + for (i = 0; i <= MAX_ORDER; i++) num_tests += do_alloc_pages_order(i, &failures); REPORT_FAILURES_IN_FN(); only in patch2: unchanged: --- linux-6.2.0.orig/lib/test_scanf.c +++ linux-6.2.0/lib/test_scanf.c @@ -606,7 +606,7 @@ #define test_number_prefix(T, str, scan_fmt, expect0, expect1, n_args, fn) \ do { \ const T expect[2] = { expect0, expect1 }; \ - T result[2] = {~expect[0], ~expect[1]}; \ + T result[2] = { (T)~expect[0], (T)~expect[1] }; \ \ _test(fn, &expect, str, scan_fmt, n_args, &result[0], &result[1]); \ } while (0) only in patch2: unchanged: --- linux-6.2.0.orig/lib/xarray.c +++ linux-6.2.0/lib/xarray.c @@ -204,7 +204,7 @@ void *entry = xa_entry(xas->xa, node, offset); xas->xa_node = node; - if (xa_is_sibling(entry)) { + while (xa_is_sibling(entry)) { offset = xa_to_sibling(entry); entry = xa_entry(xas->xa, node, offset); if (node->shift && xa_is_node(entry)) only in patch2: unchanged: --- linux-6.2.0.orig/mm/damon/vaddr-test.h +++ linux-6.2.0/mm/damon/vaddr-test.h @@ -140,6 +140,8 @@ KUNIT_EXPECT_EQ(test, r->ar.start, expected[i * 2]); KUNIT_EXPECT_EQ(test, r->ar.end, expected[i * 2 + 1]); } + + damon_destroy_target(t); } /* only in patch2: unchanged: --- linux-6.2.0.orig/mm/slab_common.c +++ linux-6.2.0/mm/slab_common.c @@ -479,7 +479,7 @@ void kmem_cache_destroy(struct kmem_cache *s) { - int refcnt; + int err = -EBUSY; bool rcu_set; if (unlikely(!s) || !kasan_check_byte(s)) @@ -490,17 +490,17 @@ rcu_set = s->flags & SLAB_TYPESAFE_BY_RCU; - refcnt = --s->refcount; - if (refcnt) + s->refcount--; + if (s->refcount) goto out_unlock; - WARN(shutdown_cache(s), - "%s %s: Slab cache still has objects when called from %pS", + err = shutdown_cache(s); + WARN(err, "%s %s: Slab cache still has objects when called from %pS", __func__, s->name, (void *)_RET_IP_); out_unlock: mutex_unlock(&slab_mutex); cpus_read_unlock(); - if (!refcnt && !rcu_set) + if (!err && !rcu_set) kmem_cache_release(s); } EXPORT_SYMBOL(kmem_cache_destroy); only in patch2: unchanged: --- linux-6.2.0.orig/mm/util.c +++ linux-6.2.0/mm/util.c @@ -1048,7 +1048,9 @@ if (vmalloc_dump_obj(object)) return; - if (virt_addr_valid(object)) + if (is_vmalloc_addr(object)) + type = "vmalloc memory"; + else if (virt_addr_valid(object)) type = "non-slab/vmalloc memory"; else if (object == NULL) type = "NULL pointer"; only in patch2: unchanged: --- linux-6.2.0.orig/mm/vmpressure.c +++ linux-6.2.0/mm/vmpressure.c @@ -244,6 +244,14 @@ if (mem_cgroup_disabled()) return; + /* + * The in-kernel users only care about the reclaim efficiency + * for this @memcg rather than the whole subtree, and there + * isn't and won't be any in-kernel user in a legacy cgroup. + */ + if (!cgroup_subsys_on_dfl(memory_cgrp_subsys) && !tree) + return; + vmpr = memcg_to_vmpressure(memcg); /* only in patch2: unchanged: --- linux-6.2.0.orig/net/9p/trans_virtio.c +++ linux-6.2.0/net/9p/trans_virtio.c @@ -384,7 +384,7 @@ void *to = req->rc.sdata + in_hdr_len; // Fits entirely into the static data? Nothing to do. - if (req->rc.size < in_hdr_len) + if (req->rc.size < in_hdr_len || !pages) return; // Really long error message? Tough, truncate the reply. Might get @@ -428,7 +428,7 @@ struct page **in_pages = NULL, **out_pages = NULL; struct virtio_chan *chan = client->trans; struct scatterlist *sgs[4]; - size_t offs; + size_t offs = 0; int need_drop = 0; int kicked = 0; only in patch2: unchanged: --- linux-6.2.0.orig/net/bluetooth/hci_request.h +++ linux-6.2.0/net/bluetooth/hci_request.h @@ -71,7 +71,5 @@ void hci_req_add_le_scan_disable(struct hci_request *req, bool rpa_le_conn); void hci_req_add_le_passive_scan(struct hci_request *req); -void hci_req_prepare_suspend(struct hci_dev *hdev, enum suspended_state next); - void hci_request_setup(struct hci_dev *hdev); void hci_request_cancel_all(struct hci_dev *hdev); only in patch2: unchanged: --- linux-6.2.0.orig/net/bridge/br_arp_nd_proxy.c +++ linux-6.2.0/net/bridge/br_arp_nd_proxy.c @@ -192,7 +192,7 @@ if (n) { struct net_bridge_fdb_entry *f; - if (!(n->nud_state & NUD_VALID)) { + if (!(READ_ONCE(n->nud_state) & NUD_VALID)) { neigh_release(n); return; } @@ -452,7 +452,7 @@ if (n) { struct net_bridge_fdb_entry *f; - if (!(n->nud_state & NUD_VALID)) { + if (!(READ_ONCE(n->nud_state) & NUD_VALID)) { neigh_release(n); return; } only in patch2: unchanged: --- linux-6.2.0.orig/net/bridge/br_input.c +++ linux-6.2.0/net/bridge/br_input.c @@ -181,12 +181,12 @@ if ((mdst && mdst->host_joined) || br_multicast_is_router(brmctx, skb)) { local_rcv = true; - br->dev->stats.multicast++; + DEV_STATS_INC(br->dev, multicast); } mcast_hit = true; } else { local_rcv = true; - br->dev->stats.multicast++; + DEV_STATS_INC(br->dev, multicast); } break; case BR_PKT_UNICAST: only in patch2: unchanged: --- linux-6.2.0.orig/net/core/flow_dissector.c +++ linux-6.2.0/net/core/flow_dissector.c @@ -1368,7 +1368,7 @@ break; } - nhoff += ntohs(hdr->message_length); + nhoff += sizeof(struct ptp_header); fdret = FLOW_DISSECT_RET_OUT_GOOD; break; } @@ -1740,8 +1740,7 @@ memset(&keys, 0, sizeof(keys)); __skb_flow_dissect(NULL, skb, &flow_keys_dissector_symmetric, - &keys, NULL, 0, 0, 0, - FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL); + &keys, NULL, 0, 0, 0, 0); return __flow_hash_from_keys(&keys, &hashrnd); } only in patch2: unchanged: --- linux-6.2.0.orig/net/core/lwt_bpf.c +++ linux-6.2.0/net/core/lwt_bpf.c @@ -60,9 +60,8 @@ ret = BPF_OK; } else { skb_reset_mac_header(skb); - ret = skb_do_redirect(skb); - if (ret == 0) - ret = BPF_REDIRECT; + skb_do_redirect(skb); + ret = BPF_REDIRECT; } break; @@ -255,7 +254,7 @@ err = dst_output(dev_net(skb_dst(skb)->dev), skb->sk, skb); if (unlikely(err)) - return err; + return net_xmit_errno(err); /* ip[6]_finish_output2 understand LWTUNNEL_XMIT_DONE */ return LWTUNNEL_XMIT_DONE; only in patch2: unchanged: --- linux-6.2.0.orig/net/hsr/hsr_forward.c +++ linux-6.2.0/net/hsr/hsr_forward.c @@ -594,6 +594,7 @@ proto = vlan_hdr->vlanhdr.h_vlan_encapsulated_proto; /* FIXME: */ netdev_warn_once(skb->dev, "VLAN not yet supported"); + return -EINVAL; } frame->is_from_san = false; only in patch2: unchanged: --- linux-6.2.0.orig/net/hsr/hsr_main.h +++ linux-6.2.0/net/hsr/hsr_main.h @@ -83,7 +83,7 @@ struct hsr_sup_tlv { u8 HSR_TLV_type; u8 HSR_TLV_length; -}; +} __packed; /* HSR/PRP Supervision Frame data types. * Field names as defined in the IEC:2010 standard for HSR. only in patch2: unchanged: --- linux-6.2.0.orig/net/ipv4/arp.c +++ linux-6.2.0/net/ipv4/arp.c @@ -375,7 +375,7 @@ probes -= NEIGH_VAR(neigh->parms, UCAST_PROBES); if (probes < 0) { - if (!(neigh->nud_state & NUD_VALID)) + if (!(READ_ONCE(neigh->nud_state) & NUD_VALID)) pr_debug("trying to ucast probe in NUD_INVALID\n"); neigh_ha_snapshot(dst_ha, neigh, dev); dst_hw = dst_ha; @@ -1123,7 +1123,7 @@ neigh = neigh_lookup(&arp_tbl, &ip, dev); if (neigh) { - if (!(neigh->nud_state & NUD_NOARP)) { + if (!(READ_ONCE(neigh->nud_state) & NUD_NOARP)) { read_lock_bh(&neigh->lock); memcpy(r->arp_ha.sa_data, neigh->ha, dev->addr_len); r->arp_flags = arp_state_to_flags(neigh); @@ -1144,12 +1144,12 @@ struct neigh_table *tbl = &arp_tbl; if (neigh) { - if ((neigh->nud_state & NUD_VALID) && !force) { + if ((READ_ONCE(neigh->nud_state) & NUD_VALID) && !force) { neigh_release(neigh); return 0; } - if (neigh->nud_state & ~NUD_NOARP) + if (READ_ONCE(neigh->nud_state) & ~NUD_NOARP) err = neigh_update(neigh, NULL, NUD_FAILED, NEIGH_UPDATE_F_OVERRIDE| NEIGH_UPDATE_F_ADMIN, 0); only in patch2: unchanged: --- linux-6.2.0.orig/net/ipv4/devinet.c +++ linux-6.2.0/net/ipv4/devinet.c @@ -355,14 +355,14 @@ { struct in_ifaddr *promote = NULL; struct in_ifaddr *ifa, *ifa1; - struct in_ifaddr *last_prim; + struct in_ifaddr __rcu **last_prim; struct in_ifaddr *prev_prom = NULL; int do_promote = IN_DEV_PROMOTE_SECONDARIES(in_dev); ASSERT_RTNL(); ifa1 = rtnl_dereference(*ifap); - last_prim = rtnl_dereference(in_dev->ifa_list); + last_prim = ifap; if (in_dev->dead) goto no_promotions; @@ -376,7 +376,7 @@ while ((ifa = rtnl_dereference(*ifap1)) != NULL) { if (!(ifa->ifa_flags & IFA_F_SECONDARY) && ifa1->ifa_scope <= ifa->ifa_scope) - last_prim = ifa; + last_prim = &ifa->ifa_next; if (!(ifa->ifa_flags & IFA_F_SECONDARY) || ifa1->ifa_mask != ifa->ifa_mask || @@ -440,9 +440,9 @@ rcu_assign_pointer(prev_prom->ifa_next, next_sec); - last_sec = rtnl_dereference(last_prim->ifa_next); + last_sec = rtnl_dereference(*last_prim); rcu_assign_pointer(promote->ifa_next, last_sec); - rcu_assign_pointer(last_prim->ifa_next, promote); + rcu_assign_pointer(*last_prim, promote); } promote->ifa_flags &= ~IFA_F_SECONDARY; only in patch2: unchanged: --- linux-6.2.0.orig/net/ipv4/fib_semantics.c +++ linux-6.2.0/net/ipv4/fib_semantics.c @@ -278,7 +278,8 @@ hlist_del(&nexthop_nh->nh_hash); } endfor_nexthops(fi) } - fi->fib_dead = 1; + /* Paired with READ_ONCE() from fib_table_lookup() */ + WRITE_ONCE(fi->fib_dead, 1); fib_info_put(fi); } spin_unlock_bh(&fib_info_lock); @@ -563,7 +564,7 @@ n = NULL; if (n) { - state = n->nud_state; + state = READ_ONCE(n->nud_state); neigh_release(n); } else { return 0; @@ -1581,6 +1582,7 @@ link_it: ofi = fib_find_info(fi); if (ofi) { + /* fib_table_lookup() should not see @fi yet. */ fi->fib_dead = 1; free_fib_info(fi); refcount_inc(&ofi->fib_treeref); @@ -1619,6 +1621,7 @@ failure: if (fi) { + /* fib_table_lookup() should not see @fi yet. */ fi->fib_dead = 1; free_fib_info(fi); } @@ -2191,7 +2194,7 @@ if (nh->fib_nh_scope == RT_SCOPE_LINK) { struct neighbour *n; - rcu_read_lock_bh(); + rcu_read_lock(); if (likely(nh->fib_nh_gw_family == AF_INET)) n = __ipv4_neigh_lookup_noref(nh->fib_nh_dev, @@ -2202,9 +2205,9 @@ else n = NULL; if (n) - state = n->nud_state; + state = READ_ONCE(n->nud_state); - rcu_read_unlock_bh(); + rcu_read_unlock(); } return !!(state & NUD_VALID); only in patch2: unchanged: --- linux-6.2.0.orig/net/ipv4/fib_trie.c +++ linux-6.2.0/net/ipv4/fib_trie.c @@ -1582,7 +1582,8 @@ if (fa->fa_dscp && inet_dscp_to_dsfield(fa->fa_dscp) != flp->flowi4_tos) continue; - if (fi->fib_dead) + /* Paired with WRITE_ONCE() in fib_release_info() */ + if (READ_ONCE(fi->fib_dead)) continue; if (fa->fa_info->fib_scope < flp->flowi4_scope) continue; only in patch2: unchanged: --- linux-6.2.0.orig/net/ipv4/ip_input.c +++ linux-6.2.0/net/ipv4/ip_input.c @@ -584,7 +584,8 @@ static struct sk_buff *ip_extract_route_hint(const struct net *net, struct sk_buff *skb, int rt_type) { - if (fib4_has_custom_rules(net) || rt_type == RTN_BROADCAST) + if (fib4_has_custom_rules(net) || rt_type == RTN_BROADCAST || + IPCB(skb)->flags & IPSKB_MULTIPATH) return NULL; return skb; only in patch2: unchanged: --- linux-6.2.0.orig/net/ipv6/ip6_fib.c +++ linux-6.2.0/net/ipv6/ip6_fib.c @@ -2491,7 +2491,7 @@ const struct net_device *dev; if (rt->nh) - fib6_nh = nexthop_fib6_nh_bh(rt->nh); + fib6_nh = nexthop_fib6_nh(rt->nh); seq_printf(seq, "%pi6 %02x ", &rt->fib6_dst.addr, rt->fib6_dst.plen); @@ -2556,14 +2556,14 @@ if (tbl) { h = (tbl->tb6_id & (FIB6_TABLE_HASHSZ - 1)) + 1; - node = rcu_dereference_bh(hlist_next_rcu(&tbl->tb6_hlist)); + node = rcu_dereference(hlist_next_rcu(&tbl->tb6_hlist)); } else { h = 0; node = NULL; } while (!node && h < FIB6_TABLE_HASHSZ) { - node = rcu_dereference_bh( + node = rcu_dereference( hlist_first_rcu(&net->ipv6.fib_table_hash[h++])); } return hlist_entry_safe(node, struct fib6_table, tb6_hlist); @@ -2593,7 +2593,7 @@ if (!v) goto iter_table; - n = rcu_dereference_bh(((struct fib6_info *)v)->fib6_next); + n = rcu_dereference(((struct fib6_info *)v)->fib6_next); if (n) return n; @@ -2619,12 +2619,12 @@ } static void *ipv6_route_seq_start(struct seq_file *seq, loff_t *pos) - __acquires(RCU_BH) + __acquires(RCU) { struct net *net = seq_file_net(seq); struct ipv6_route_iter *iter = seq->private; - rcu_read_lock_bh(); + rcu_read_lock(); iter->tbl = ipv6_route_seq_next_table(NULL, net); iter->skip = *pos; @@ -2645,7 +2645,7 @@ } static void ipv6_route_native_seq_stop(struct seq_file *seq, void *v) - __releases(RCU_BH) + __releases(RCU) { struct net *net = seq_file_net(seq); struct ipv6_route_iter *iter = seq->private; @@ -2653,7 +2653,7 @@ if (ipv6_route_iter_active(iter)) fib6_walker_unlink(net, &iter->w); - rcu_read_unlock_bh(); + rcu_read_unlock(); } #if IS_BUILTIN(CONFIG_IPV6) && defined(CONFIG_BPF_SYSCALL) only in patch2: unchanged: --- linux-6.2.0.orig/net/kcm/kcmsock.c +++ linux-6.2.0/net/kcm/kcmsock.c @@ -1065,15 +1065,18 @@ out_error: kcm_push(kcm); - if (copied && sock->type == SOCK_SEQPACKET) { + if (sock->type == SOCK_SEQPACKET) { /* Wrote some bytes before encountering an * error, return partial success. */ - goto partial_message; - } - - if (head != kcm->seq_skb) + if (copied) + goto partial_message; + if (head != kcm->seq_skb) + kfree_skb(head); + } else { kfree_skb(head); + kcm->seq_skb = NULL; + } err = sk_stream_error(sk, msg->msg_flags, err); @@ -1981,6 +1984,8 @@ * that all multiplexors and psocks have been destroyed. */ WARN_ON(!list_empty(&knet->mux_list)); + + mutex_destroy(&knet->mutex); } static struct pernet_operations kcm_net_ops = { only in patch2: unchanged: --- linux-6.2.0.orig/net/mac80211/key.c +++ linux-6.2.0/net/mac80211/key.c @@ -901,7 +901,7 @@ */ if (ieee80211_key_identical(sdata, old_key, key)) { ieee80211_key_free_unused(key); - ret = 0; + ret = -EALREADY; goto out; } only in patch2: unchanged: --- linux-6.2.0.orig/net/netfilter/nf_conntrack_bpf.c +++ linux-6.2.0/net/netfilter/nf_conntrack_bpf.c @@ -381,6 +381,8 @@ struct nf_conn *nfct = (struct nf_conn *)nfct_i; int err; + if (!nf_ct_is_confirmed(nfct)) + nfct->timeout += nfct_time_stamp; nfct->status |= IPS_CONFIRMED; err = nf_conntrack_hash_check_insert(nfct); if (err < 0) { only in patch2: unchanged: --- linux-6.2.0.orig/net/netfilter/nf_conntrack_extend.c +++ linux-6.2.0/net/netfilter/nf_conntrack_extend.c @@ -40,10 +40,10 @@ [NF_CT_EXT_ECACHE] = sizeof(struct nf_conntrack_ecache), #endif #ifdef CONFIG_NF_CONNTRACK_TIMESTAMP - [NF_CT_EXT_TSTAMP] = sizeof(struct nf_conn_acct), + [NF_CT_EXT_TSTAMP] = sizeof(struct nf_conn_tstamp), #endif #ifdef CONFIG_NF_CONNTRACK_TIMEOUT - [NF_CT_EXT_TIMEOUT] = sizeof(struct nf_conn_tstamp), + [NF_CT_EXT_TIMEOUT] = sizeof(struct nf_conn_timeout), #endif #ifdef CONFIG_NF_CONNTRACK_LABELS [NF_CT_EXT_LABELS] = sizeof(struct nf_conn_labels), only in patch2: unchanged: --- linux-6.2.0.orig/net/netfilter/nft_inner.c +++ linux-6.2.0/net/netfilter/nft_inner.c @@ -298,6 +298,7 @@ int err; if (!tb[NFTA_INNER_FLAGS] || + !tb[NFTA_INNER_NUM] || !tb[NFTA_INNER_HDRSIZE] || !tb[NFTA_INNER_TYPE] || !tb[NFTA_INNER_EXPR]) only in patch2: unchanged: --- linux-6.2.0.orig/net/netlink/af_netlink.h +++ linux-6.2.0/net/netlink/af_netlink.h @@ -8,14 +8,16 @@ #include /* flags */ -#define NETLINK_F_KERNEL_SOCKET 0x1 -#define NETLINK_F_RECV_PKTINFO 0x2 -#define NETLINK_F_BROADCAST_SEND_ERROR 0x4 -#define NETLINK_F_RECV_NO_ENOBUFS 0x8 -#define NETLINK_F_LISTEN_ALL_NSID 0x10 -#define NETLINK_F_CAP_ACK 0x20 -#define NETLINK_F_EXT_ACK 0x40 -#define NETLINK_F_STRICT_CHK 0x80 +enum { + NETLINK_F_KERNEL_SOCKET, + NETLINK_F_RECV_PKTINFO, + NETLINK_F_BROADCAST_SEND_ERROR, + NETLINK_F_RECV_NO_ENOBUFS, + NETLINK_F_LISTEN_ALL_NSID, + NETLINK_F_CAP_ACK, + NETLINK_F_EXT_ACK, + NETLINK_F_STRICT_CHK, +}; #define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) #define NLGRPLONGS(x) (NLGRPSZ(x)/sizeof(unsigned long)) @@ -23,10 +25,10 @@ struct netlink_sock { /* struct sock has to be the first member of netlink_sock */ struct sock sk; + unsigned long flags; u32 portid; u32 dst_portid; u32 dst_group; - u32 flags; u32 subscriptions; u32 ngroups; unsigned long *groups; @@ -54,6 +56,8 @@ return container_of(sk, struct netlink_sock, sk); } +#define nlk_test_bit(nr, sk) test_bit(NETLINK_F_##nr, &nlk_sk(sk)->flags) + struct netlink_table { struct rhashtable hash; struct hlist_head mc_list; only in patch2: unchanged: --- linux-6.2.0.orig/net/netrom/af_netrom.c +++ linux-6.2.0/net/netrom/af_netrom.c @@ -660,6 +660,11 @@ goto out_release; } + if (sock->state == SS_CONNECTING) { + err = -EALREADY; + goto out_release; + } + sk->sk_state = TCP_CLOSE; sock->state = SS_UNCONNECTED; only in patch2: unchanged: --- linux-6.2.0.orig/net/rds/rdma_transport.c +++ linux-6.2.0/net/rds/rdma_transport.c @@ -86,11 +86,13 @@ break; case RDMA_CM_EVENT_ADDR_RESOLVED: - rdma_set_service_type(cm_id, conn->c_tos); - rdma_set_min_rnr_timer(cm_id, IB_RNR_TIMER_000_32); - /* XXX do we need to clean up if this fails? */ - ret = rdma_resolve_route(cm_id, - RDS_RDMA_RESOLVE_TIMEOUT_MS); + if (conn) { + rdma_set_service_type(cm_id, conn->c_tos); + rdma_set_min_rnr_timer(cm_id, IB_RNR_TIMER_000_32); + /* XXX do we need to clean up if this fails? */ + ret = rdma_resolve_route(cm_id, + RDS_RDMA_RESOLVE_TIMEOUT_MS); + } break; case RDMA_CM_EVENT_ROUTE_RESOLVED: only in patch2: unchanged: --- linux-6.2.0.orig/net/rds/tcp_connect.c +++ linux-6.2.0/net/rds/tcp_connect.c @@ -173,7 +173,7 @@ * own the socket */ rds_tcp_set_callbacks(sock, cp); - ret = sock->ops->connect(sock, addr, addrlen, O_NONBLOCK); + ret = kernel_connect(sock, addr, addrlen, O_NONBLOCK); rdsdebug("connect to address %pI6c returned %d\n", &conn->c_faddr, ret); if (ret == -EINPROGRESS) only in patch2: unchanged: --- linux-6.2.0.orig/net/sched/em_meta.c +++ linux-6.2.0/net/sched/em_meta.c @@ -502,7 +502,7 @@ *err = -1; return; } - dst->value = sk->sk_lingertime / HZ; + dst->value = READ_ONCE(sk->sk_lingertime) / HZ; } META_COLLECTOR(int_sk_err_qlen) @@ -568,7 +568,7 @@ *err = -1; return; } - dst->value = sk->sk_rcvtimeo / HZ; + dst->value = READ_ONCE(sk->sk_rcvtimeo) / HZ; } META_COLLECTOR(int_sk_sndtimeo) @@ -579,7 +579,7 @@ *err = -1; return; } - dst->value = sk->sk_sndtimeo / HZ; + dst->value = READ_ONCE(sk->sk_sndtimeo) / HZ; } META_COLLECTOR(int_sk_sendmsg_off) only in patch2: unchanged: --- linux-6.2.0.orig/net/sctp/associola.c +++ linux-6.2.0/net/sctp/associola.c @@ -1159,8 +1159,7 @@ /* Add any peer addresses from the new association. */ list_for_each_entry(trans, &new->peer.transport_addr_list, transports) - if (!sctp_assoc_lookup_paddr(asoc, &trans->ipaddr) && - !sctp_assoc_add_peer(asoc, &trans->ipaddr, + if (!sctp_assoc_add_peer(asoc, &trans->ipaddr, GFP_ATOMIC, trans->state)) return -ENOMEM; only in patch2: unchanged: --- linux-6.2.0.orig/net/sctp/proc.c +++ linux-6.2.0/net/sctp/proc.c @@ -282,7 +282,7 @@ assoc->init_retries, assoc->shutdown_retries, assoc->rtx_data_chunks, refcount_read(&sk->sk_wmem_alloc), - sk->sk_wmem_queued, + READ_ONCE(sk->sk_wmem_queued), sk->sk_sndbuf, sk->sk_rcvbuf); seq_printf(seq, "\n"); only in patch2: unchanged: --- linux-6.2.0.orig/net/sctp/sm_sideeffect.c +++ linux-6.2.0/net/sctp/sm_sideeffect.c @@ -1251,7 +1251,10 @@ default: pr_err("impossible disposition %d in state %d, event_type %d, event_id %d\n", status, state, event_type, subtype.chunk); - BUG(); + error = status; + if (error >= 0) + error = -EINVAL; + WARN_ON_ONCE(1); break; } only in patch2: unchanged: --- linux-6.2.0.orig/net/unix/scm.c +++ linux-6.2.0/net/unix/scm.c @@ -63,7 +63,7 @@ /* Paired with READ_ONCE() in wait_for_unix_gc() */ WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + 1); } - user->unix_inflight++; + WRITE_ONCE(user->unix_inflight, user->unix_inflight + 1); spin_unlock(&unix_gc_lock); } @@ -84,7 +84,7 @@ /* Paired with READ_ONCE() in wait_for_unix_gc() */ WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - 1); } - user->unix_inflight--; + WRITE_ONCE(user->unix_inflight, user->unix_inflight - 1); spin_unlock(&unix_gc_lock); } @@ -98,7 +98,7 @@ { struct user_struct *user = current_user(); - if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE))) + if (unlikely(READ_ONCE(user->unix_inflight) > task_rlimit(p, RLIMIT_NOFILE))) return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN); return false; } only in patch2: unchanged: --- linux-6.2.0.orig/net/wireless/core.h +++ linux-6.2.0/net/wireless/core.h @@ -108,6 +108,12 @@ /* lock for all wdev lists */ spinlock_t mgmt_registrations_lock; + struct work_struct wiphy_work; + struct list_head wiphy_work_list; + /* protects the list above */ + spinlock_t wiphy_work_lock; + bool suspended; + /* must be last because of the way we do wiphy_priv(), * and it should at least be aligned to NETDEV_ALIGN */ struct wiphy wiphy __aligned(NETDEV_ALIGN); @@ -289,12 +295,17 @@ }; struct cfg80211_cqm_config { + struct rcu_head rcu_head; u32 rssi_hyst; s32 last_rssi_event_value; + enum nl80211_cqm_rssi_threshold_event last_rssi_event_type; int n_rssi_thresholds; s32 rssi_thresholds[]; }; +void cfg80211_cqm_rssi_notify_work(struct wiphy *wiphy, + struct wiphy_work *work); + void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev); /* free object */ @@ -453,6 +464,7 @@ struct net_device *dev, enum nl80211_iftype ntype, struct vif_params *params); void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); +void cfg80211_process_wiphy_works(struct cfg80211_registered_device *rdev); void cfg80211_process_wdev_events(struct wireless_dev *wdev); bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, @@ -559,8 +571,6 @@ #define CFG80211_DEV_WARN_ON(cond) ({bool __r = (cond); __r; }) #endif -void cfg80211_cqm_config_free(struct wireless_dev *wdev); - void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid); void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev); void cfg80211_pmsr_free_wk(struct work_struct *work); only in patch2: unchanged: --- linux-6.2.0.orig/net/wireless/mlme.c +++ linux-6.2.0/net/wireless/mlme.c @@ -52,7 +52,8 @@ cr.links[link_id].bssid = data->links[link_id].bss->bssid; cr.links[link_id].addr = data->links[link_id].addr; /* need to have local link addresses for MLO connections */ - WARN_ON(cr.ap_mld_addr && !cr.links[link_id].addr); + WARN_ON(cr.ap_mld_addr && + !is_valid_ether_addr(cr.links[link_id].addr)); BUG_ON(!cr.links[link_id].bss->channel); @@ -281,6 +282,11 @@ ether_addr_equal(req->bss->bssid, wdev->u.client.connected_addr)) return -EALREADY; + if (ether_addr_equal(req->bss->bssid, dev->dev_addr) || + (req->link_id >= 0 && + ether_addr_equal(req->ap_mld_addr, dev->dev_addr))) + return -EINVAL; + return rdev_auth(rdev, dev, req); } @@ -335,6 +341,9 @@ if (req->links[i].bss == req->links[j].bss) return -EINVAL; } + + if (ether_addr_equal(req->links[i].bss->bssid, dev->dev_addr)) + return -EINVAL; } if (wdev->connected && @@ -342,6 +351,11 @@ !ether_addr_equal(wdev->u.client.connected_addr, req->prev_bssid))) return -EALREADY; + if ((req->bss && ether_addr_equal(req->bss->bssid, dev->dev_addr)) || + (req->link_id >= 0 && + ether_addr_equal(req->ap_mld_addr, dev->dev_addr))) + return -EINVAL; + cfg80211_oper_and_ht_capa(&req->ht_capa_mask, rdev->wiphy.ht_capa_mod_mask); cfg80211_oper_and_vht_capa(&req->vht_capa_mask, only in patch2: unchanged: --- linux-6.2.0.orig/net/wireless/ocb.c +++ linux-6.2.0/net/wireless/ocb.c @@ -68,6 +68,9 @@ if (!rdev->ops->leave_ocb) return -EOPNOTSUPP; + if (!wdev->u.ocb.chandef.chan) + return -ENOTCONN; + err = rdev_leave_ocb(rdev, dev); if (!err) memset(&wdev->u.ocb.chandef, 0, sizeof(wdev->u.ocb.chandef)); only in patch2: unchanged: --- linux-6.2.0.orig/net/wireless/sysfs.c +++ linux-6.2.0/net/wireless/sysfs.c @@ -5,7 +5,7 @@ * * Copyright 2005-2006 Jiri Benc * Copyright 2006 Johannes Berg - * Copyright (C) 2020-2021 Intel Corporation + * Copyright (C) 2020-2021, 2023 Intel Corporation */ #include @@ -105,14 +105,18 @@ cfg80211_leave_all(rdev); cfg80211_process_rdev_events(rdev); } + cfg80211_process_wiphy_works(rdev); if (rdev->ops->suspend) ret = rdev_suspend(rdev, rdev->wiphy.wowlan_config); if (ret == 1) { /* Driver refuse to configure wowlan */ cfg80211_leave_all(rdev); cfg80211_process_rdev_events(rdev); + cfg80211_process_wiphy_works(rdev); ret = rdev_suspend(rdev, NULL); } + if (ret == 0) + rdev->suspended = true; } wiphy_unlock(&rdev->wiphy); rtnl_unlock(); @@ -132,6 +136,8 @@ wiphy_lock(&rdev->wiphy); if (rdev->wiphy.registered && rdev->ops->resume) ret = rdev_resume(rdev); + rdev->suspended = false; + schedule_work(&rdev->wiphy_work); wiphy_unlock(&rdev->wiphy); if (ret) only in patch2: unchanged: --- linux-6.2.0.orig/net/wireless/util.c +++ linux-6.2.0/net/wireless/util.c @@ -5,7 +5,7 @@ * Copyright 2007-2009 Johannes Berg * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright 2017 Intel Deutschland GmbH - * Copyright (C) 2018-2022 Intel Corporation + * Copyright (C) 2018-2023 Intel Corporation */ #include #include @@ -2481,6 +2481,13 @@ { unsigned int link_id; + /* + * links are controlled by upper layers (userspace/cfg) + * only for AP mode, so only remove them here for AP + */ + if (wdev->iftype != NL80211_IFTYPE_AP) + return; + wdev_lock(wdev); if (wdev->valid_links) { for_each_valid_link(wdev, link_id) only in patch2: unchanged: --- linux-6.2.0.orig/net/xdp/xsk_diag.c +++ linux-6.2.0/net/xdp/xsk_diag.c @@ -111,6 +111,9 @@ sock_diag_save_cookie(sk, msg->xdiag_cookie); mutex_lock(&xs->mutex); + if (READ_ONCE(xs->state) == XSK_UNBOUND) + goto out_nlmsg_trim; + if ((req->xdiag_show & XDP_SHOW_INFO) && xsk_diag_put_info(xs, nlskb)) goto out_nlmsg_trim; only in patch2: unchanged: --- linux-6.2.0.orig/samples/bpf/tracex3_kern.c +++ linux-6.2.0/samples/bpf/tracex3_kern.c @@ -11,6 +11,12 @@ #include #include +struct start_key { + dev_t dev; + u32 _pad; + sector_t sector; +}; + struct { __uint(type, BPF_MAP_TYPE_HASH); __type(key, long); @@ -18,16 +24,17 @@ __uint(max_entries, 4096); } my_map SEC(".maps"); -/* kprobe is NOT a stable ABI. If kernel internals change this bpf+kprobe - * example will no longer be meaningful - */ -SEC("kprobe/blk_mq_start_request") -int bpf_prog1(struct pt_regs *ctx) +/* from /sys/kernel/tracing/events/block/block_io_start/format */ +SEC("tracepoint/block/block_io_start") +int bpf_prog1(struct trace_event_raw_block_rq *ctx) { - long rq = PT_REGS_PARM1(ctx); u64 val = bpf_ktime_get_ns(); + struct start_key key = { + .dev = ctx->dev, + .sector = ctx->sector + }; - bpf_map_update_elem(&my_map, &rq, &val, BPF_ANY); + bpf_map_update_elem(&my_map, &key, &val, BPF_ANY); return 0; } @@ -49,21 +56,26 @@ __uint(max_entries, SLOTS); } lat_map SEC(".maps"); -SEC("kprobe/__blk_account_io_done") -int bpf_prog2(struct pt_regs *ctx) +/* from /sys/kernel/tracing/events/block/block_io_done/format */ +SEC("tracepoint/block/block_io_done") +int bpf_prog2(struct trace_event_raw_block_rq *ctx) { - long rq = PT_REGS_PARM1(ctx); + struct start_key key = { + .dev = ctx->dev, + .sector = ctx->sector + }; + u64 *value, l, base; u32 index; - value = bpf_map_lookup_elem(&my_map, &rq); + value = bpf_map_lookup_elem(&my_map, &key); if (!value) return 0; u64 cur_time = bpf_ktime_get_ns(); u64 delta = cur_time - *value; - bpf_map_delete_elem(&my_map, &rq); + bpf_map_delete_elem(&my_map, &key); /* the lines below are computing index = log10(delta)*10 * using integer arithmetic only in patch2: unchanged: --- linux-6.2.0.orig/samples/bpf/tracex6_kern.c +++ linux-6.2.0/samples/bpf/tracex6_kern.c @@ -2,6 +2,8 @@ #include #include #include +#include +#include struct { __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); @@ -45,13 +47,24 @@ return 0; } -SEC("kprobe/htab_map_lookup_elem") -int bpf_prog2(struct pt_regs *ctx) +/* + * Since *_map_lookup_elem can't be expected to trigger bpf programs + * due to potential deadlocks (bpf_disable_instrumentation), this bpf + * program will be attached to bpf_map_copy_value (which is called + * from map_lookup_elem) and will only filter the hashtable type. + */ +SEC("kprobe/bpf_map_copy_value") +int BPF_KPROBE(bpf_prog2, struct bpf_map *map) { u32 key = bpf_get_smp_processor_id(); struct bpf_perf_event_value *val, buf; + enum bpf_map_type type; int error; + type = BPF_CORE_READ(map, map_type); + if (type != BPF_MAP_TYPE_HASH) + return 0; + error = bpf_perf_event_read_value(&counters, key, &buf, sizeof(buf)); if (error) return 0; only in patch2: unchanged: --- linux-6.2.0.orig/samples/hw_breakpoint/data_breakpoint.c +++ linux-6.2.0/samples/hw_breakpoint/data_breakpoint.c @@ -70,7 +70,9 @@ static void __exit hw_break_module_exit(void) { unregister_wide_hw_breakpoint(sample_hbp); - symbol_put(ksym_name); +#ifdef CONFIG_MODULE_UNLOAD + __symbol_put(ksym_name); +#endif printk(KERN_INFO "HW Breakpoint for %s write uninstalled\n", ksym_name); } only in patch2: unchanged: --- linux-6.2.0.orig/scripts/kconfig/preprocess.c +++ linux-6.2.0/scripts/kconfig/preprocess.c @@ -396,6 +396,9 @@ p++; } + + if (new_argc >= FUNCTION_MAX_ARGS) + pperror("too many function arguments"); new_argv[new_argc++] = prev; /* only in patch2: unchanged: --- linux-6.2.0.orig/scripts/mod/file2alias.c +++ linux-6.2.0/scripts/mod/file2alias.c @@ -1577,7 +1577,7 @@ /* First handle the "special" cases */ if (sym_is(name, namelen, "usb")) do_usb_table(symval, sym->st_size, mod); - if (sym_is(name, namelen, "of")) + else if (sym_is(name, namelen, "of")) do_of_table(symval, sym->st_size, mod); else if (sym_is(name, namelen, "pnp")) do_pnp_device_entry(symval, sym->st_size, mod); only in patch2: unchanged: --- linux-6.2.0.orig/scripts/package/mkspec +++ linux-6.2.0/scripts/package/mkspec @@ -57,7 +57,7 @@ # $UTS_MACHINE as a fallback of _arch in case # /usr/lib/rpm/platform/*/macros was not included. - %define _arch %{?_arch:$UTS_MACHINE} + %{!?_arch: %define _arch $UTS_MACHINE} %define __spec_install_post /usr/lib/rpm/brp-compress || : %define debug_package %{nil} only in patch2: unchanged: --- linux-6.2.0.orig/security/keys/keyctl.c +++ linux-6.2.0/security/keys/keyctl.c @@ -980,14 +980,19 @@ ret = -EACCES; down_write(&key->sem); - if (!capable(CAP_SYS_ADMIN)) { + { + bool is_privileged_op = false; + /* only the sysadmin can chown a key to some other UID */ if (user != (uid_t) -1 && !uid_eq(key->uid, uid)) - goto error_put; + is_privileged_op = true; /* only the sysadmin can set the key's GID to a group other * than one of those that the current process subscribes to */ if (group != (gid_t) -1 && !gid_eq(gid, key->gid) && !in_group_p(gid)) + is_privileged_op = true; + + if (is_privileged_op && !capable(CAP_SYS_ADMIN)) goto error_put; } @@ -1088,7 +1093,7 @@ down_write(&key->sem); /* if we're not the sysadmin, we can only change a key that we own */ - if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) { + if (uid_eq(key->uid, current_fsuid()) || capable(CAP_SYS_ADMIN)) { key->perm = perm; notify_key(key, NOTIFY_KEY_SETATTR, 0); ret = 0; only in patch2: unchanged: --- linux-6.2.0.orig/sound/Kconfig +++ linux-6.2.0/sound/Kconfig @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only menuconfig SOUND tristate "Sound card support" - depends on HAS_IOMEM + depends on HAS_IOMEM || UML help If you have a sound card in your computer, i.e. if it can say more than an occasional beep, say Y. only in patch2: unchanged: --- linux-6.2.0.orig/sound/core/pcm_compat.c +++ linux-6.2.0/sound/core/pcm_compat.c @@ -253,10 +253,14 @@ goto error; } - if (refine) + if (refine) { err = snd_pcm_hw_refine(substream, data); - else + if (err < 0) + goto error; + err = fixup_unreferenced_params(substream, data); + } else { err = snd_pcm_hw_params(substream, data); + } if (err < 0) goto error; if (copy_to_user(data32, data, sizeof(*data32)) || only in patch2: unchanged: --- linux-6.2.0.orig/sound/core/seq/oss/seq_oss_midi.c +++ linux-6.2.0/sound/core/seq/oss/seq_oss_midi.c @@ -37,6 +37,7 @@ struct snd_midi_event *coder; /* MIDI event coder */ struct seq_oss_devinfo *devinfo; /* assigned OSSseq device */ snd_use_lock_t use_lock; + struct mutex open_mutex; }; @@ -172,6 +173,7 @@ mdev->flags = pinfo->capability; mdev->opened = 0; snd_use_lock_init(&mdev->use_lock); + mutex_init(&mdev->open_mutex); /* copy and truncate the name of synth device */ strscpy(mdev->name, pinfo->name, sizeof(mdev->name)); @@ -322,15 +324,17 @@ int perm; struct seq_oss_midi *mdev; struct snd_seq_port_subscribe subs; + int err; mdev = get_mididev(dp, dev); if (!mdev) return -ENODEV; + mutex_lock(&mdev->open_mutex); /* already used? */ if (mdev->opened && mdev->devinfo != dp) { - snd_use_lock_free(&mdev->use_lock); - return -EBUSY; + err = -EBUSY; + goto unlock; } perm = 0; @@ -340,14 +344,14 @@ perm |= PERM_READ; perm &= mdev->flags; if (perm == 0) { - snd_use_lock_free(&mdev->use_lock); - return -ENXIO; + err = -ENXIO; + goto unlock; } /* already opened? */ if ((mdev->opened & perm) == perm) { - snd_use_lock_free(&mdev->use_lock); - return 0; + err = 0; + goto unlock; } perm &= ~mdev->opened; @@ -372,13 +376,17 @@ } if (! mdev->opened) { - snd_use_lock_free(&mdev->use_lock); - return -ENXIO; + err = -ENXIO; + goto unlock; } mdev->devinfo = dp; + err = 0; + + unlock: + mutex_unlock(&mdev->open_mutex); snd_use_lock_free(&mdev->use_lock); - return 0; + return err; } /* @@ -393,10 +401,9 @@ mdev = get_mididev(dp, dev); if (!mdev) return -ENODEV; - if (! mdev->opened || mdev->devinfo != dp) { - snd_use_lock_free(&mdev->use_lock); - return 0; - } + mutex_lock(&mdev->open_mutex); + if (!mdev->opened || mdev->devinfo != dp) + goto unlock; memset(&subs, 0, sizeof(subs)); if (mdev->opened & PERM_WRITE) { @@ -415,6 +422,8 @@ mdev->opened = 0; mdev->devinfo = NULL; + unlock: + mutex_unlock(&mdev->open_mutex); snd_use_lock_free(&mdev->use_lock); return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/sound/hda/intel-sdw-acpi.c +++ linux-6.2.0/sound/hda/intel-sdw-acpi.c @@ -23,7 +23,7 @@ module_param_named(sdw_link_mask, ctrl_link_mask, int, 0444); MODULE_PARM_DESC(sdw_link_mask, "Intel link mask (one bit per link)"); -static bool is_link_enabled(struct fwnode_handle *fw_node, int i) +static bool is_link_enabled(struct fwnode_handle *fw_node, u8 idx) { struct fwnode_handle *link; char name[32]; @@ -31,7 +31,7 @@ /* Find master handle */ snprintf(name, sizeof(name), - "mipi-sdw-link-%d-subproperties", i); + "mipi-sdw-link-%hhu-subproperties", idx); link = fwnode_get_named_child_node(fw_node, name); if (!link) @@ -51,8 +51,8 @@ sdw_intel_scan_controller(struct sdw_intel_acpi_info *info) { struct acpi_device *adev = acpi_fetch_acpi_dev(info->handle); - int ret, i; - u8 count; + u8 count, i; + int ret; if (!adev) return -EINVAL; only in patch2: unchanged: --- linux-6.2.0.orig/sound/pci/hda/patch_cs8409.c +++ linux-6.2.0/sound/pci/hda/patch_cs8409.c @@ -888,7 +888,7 @@ /* Initialize CS42L42 companion codec */ cs8409_i2c_bulk_write(cs42l42, cs42l42->init_seq, cs42l42->init_seq_num); - usleep_range(30000, 35000); + msleep(CS42L42_INIT_TIMEOUT_MS); /* Clear interrupts, by reading interrupt status registers */ cs8409_i2c_bulk_read(cs42l42, irq_regs, ARRAY_SIZE(irq_regs)); only in patch2: unchanged: --- linux-6.2.0.orig/sound/pci/hda/patch_cs8409.h +++ linux-6.2.0/sound/pci/hda/patch_cs8409.h @@ -229,6 +229,7 @@ #define CS42L42_I2C_SLEEP_US (2000) #define CS42L42_PDN_TIMEOUT_US (250000) #define CS42L42_PDN_SLEEP_US (2000) +#define CS42L42_INIT_TIMEOUT_MS (45) #define CS42L42_FULL_SCALE_VOL_MASK (2) #define CS42L42_FULL_SCALE_VOL_0DB (1) #define CS42L42_FULL_SCALE_VOL_MINUS6DB (0) only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/atmel/atmel-i2s.c +++ linux-6.2.0/sound/soc/atmel/atmel-i2s.c @@ -163,11 +163,14 @@ #define I2S_MCK_12M288 12288000UL #define I2S_MCK_11M2896 11289600UL +#define I2S_MCK_6M144 6144000UL /* mck = (32 * (imckfs+1) / (imckdiv+1)) * fs */ static const struct atmel_i2s_gck_param gck_params[] = { + /* mck = 6.144Mhz */ + { 8000, I2S_MCK_6M144, 1, 47}, /* mck = 768 fs */ + /* mck = 12.288MHz */ - { 8000, I2S_MCK_12M288, 0, 47}, /* mck = 1536 fs */ { 16000, I2S_MCK_12M288, 1, 47}, /* mck = 768 fs */ { 24000, I2S_MCK_12M288, 3, 63}, /* mck = 512 fs */ { 32000, I2S_MCK_12M288, 3, 47}, /* mck = 384 fs */ only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/codecs/cs42l42.c +++ linux-6.2.0/sound/soc/codecs/cs42l42.c @@ -2280,6 +2280,16 @@ if (cs42l42->reset_gpio) { dev_dbg(cs42l42->dev, "Found reset GPIO\n"); + + /* + * ACPI can override the default GPIO state we requested + * so ensure that we start with RESET low. + */ + gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); + + /* Ensure minimum reset pulse width */ + usleep_range(10, 500); + gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); } usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/codecs/cs43130.h +++ linux-6.2.0/sound/soc/codecs/cs43130.h @@ -381,88 +381,88 @@ /* frm_size = 16 */ static const struct cs43130_clk_gen cs43130_16_clk_gen[] = { - { 22579200, 32000, .v = { 441, 10, }, }, - { 22579200, 44100, .v = { 32, 1, }, }, - { 22579200, 48000, .v = { 147, 5, }, }, - { 22579200, 88200, .v = { 16, 1, }, }, - { 22579200, 96000, .v = { 147, 10, }, }, - { 22579200, 176400, .v = { 8, 1, }, }, - { 22579200, 192000, .v = { 147, 20, }, }, - { 22579200, 352800, .v = { 4, 1, }, }, - { 22579200, 384000, .v = { 147, 40, }, }, - { 24576000, 32000, .v = { 48, 1, }, }, - { 24576000, 44100, .v = { 5120, 147, }, }, - { 24576000, 48000, .v = { 32, 1, }, }, - { 24576000, 88200, .v = { 2560, 147, }, }, - { 24576000, 96000, .v = { 16, 1, }, }, - { 24576000, 176400, .v = { 1280, 147, }, }, - { 24576000, 192000, .v = { 8, 1, }, }, - { 24576000, 352800, .v = { 640, 147, }, }, - { 24576000, 384000, .v = { 4, 1, }, }, + { 22579200, 32000, .v = { 10, 441, }, }, + { 22579200, 44100, .v = { 1, 32, }, }, + { 22579200, 48000, .v = { 5, 147, }, }, + { 22579200, 88200, .v = { 1, 16, }, }, + { 22579200, 96000, .v = { 10, 147, }, }, + { 22579200, 176400, .v = { 1, 8, }, }, + { 22579200, 192000, .v = { 20, 147, }, }, + { 22579200, 352800, .v = { 1, 4, }, }, + { 22579200, 384000, .v = { 40, 147, }, }, + { 24576000, 32000, .v = { 1, 48, }, }, + { 24576000, 44100, .v = { 147, 5120, }, }, + { 24576000, 48000, .v = { 1, 32, }, }, + { 24576000, 88200, .v = { 147, 2560, }, }, + { 24576000, 96000, .v = { 1, 16, }, }, + { 24576000, 176400, .v = { 147, 1280, }, }, + { 24576000, 192000, .v = { 1, 8, }, }, + { 24576000, 352800, .v = { 147, 640, }, }, + { 24576000, 384000, .v = { 1, 4, }, }, }; /* frm_size = 32 */ static const struct cs43130_clk_gen cs43130_32_clk_gen[] = { - { 22579200, 32000, .v = { 441, 20, }, }, - { 22579200, 44100, .v = { 16, 1, }, }, - { 22579200, 48000, .v = { 147, 10, }, }, - { 22579200, 88200, .v = { 8, 1, }, }, - { 22579200, 96000, .v = { 147, 20, }, }, - { 22579200, 176400, .v = { 4, 1, }, }, - { 22579200, 192000, .v = { 147, 40, }, }, - { 22579200, 352800, .v = { 2, 1, }, }, - { 22579200, 384000, .v = { 147, 80, }, }, - { 24576000, 32000, .v = { 24, 1, }, }, - { 24576000, 44100, .v = { 2560, 147, }, }, - { 24576000, 48000, .v = { 16, 1, }, }, - { 24576000, 88200, .v = { 1280, 147, }, }, - { 24576000, 96000, .v = { 8, 1, }, }, - { 24576000, 176400, .v = { 640, 147, }, }, - { 24576000, 192000, .v = { 4, 1, }, }, - { 24576000, 352800, .v = { 320, 147, }, }, - { 24576000, 384000, .v = { 2, 1, }, }, + { 22579200, 32000, .v = { 20, 441, }, }, + { 22579200, 44100, .v = { 1, 16, }, }, + { 22579200, 48000, .v = { 10, 147, }, }, + { 22579200, 88200, .v = { 1, 8, }, }, + { 22579200, 96000, .v = { 20, 147, }, }, + { 22579200, 176400, .v = { 1, 4, }, }, + { 22579200, 192000, .v = { 40, 147, }, }, + { 22579200, 352800, .v = { 1, 2, }, }, + { 22579200, 384000, .v = { 80, 147, }, }, + { 24576000, 32000, .v = { 1, 24, }, }, + { 24576000, 44100, .v = { 147, 2560, }, }, + { 24576000, 48000, .v = { 1, 16, }, }, + { 24576000, 88200, .v = { 147, 1280, }, }, + { 24576000, 96000, .v = { 1, 8, }, }, + { 24576000, 176400, .v = { 147, 640, }, }, + { 24576000, 192000, .v = { 1, 4, }, }, + { 24576000, 352800, .v = { 147, 320, }, }, + { 24576000, 384000, .v = { 1, 2, }, }, }; /* frm_size = 48 */ static const struct cs43130_clk_gen cs43130_48_clk_gen[] = { - { 22579200, 32000, .v = { 147, 100, }, }, - { 22579200, 44100, .v = { 32, 3, }, }, - { 22579200, 48000, .v = { 49, 5, }, }, - { 22579200, 88200, .v = { 16, 3, }, }, - { 22579200, 96000, .v = { 49, 10, }, }, - { 22579200, 176400, .v = { 8, 3, }, }, - { 22579200, 192000, .v = { 49, 20, }, }, - { 22579200, 352800, .v = { 4, 3, }, }, - { 22579200, 384000, .v = { 49, 40, }, }, - { 24576000, 32000, .v = { 16, 1, }, }, - { 24576000, 44100, .v = { 5120, 441, }, }, - { 24576000, 48000, .v = { 32, 3, }, }, - { 24576000, 88200, .v = { 2560, 441, }, }, - { 24576000, 96000, .v = { 16, 3, }, }, - { 24576000, 176400, .v = { 1280, 441, }, }, - { 24576000, 192000, .v = { 8, 3, }, }, - { 24576000, 352800, .v = { 640, 441, }, }, - { 24576000, 384000, .v = { 4, 3, }, }, + { 22579200, 32000, .v = { 100, 147, }, }, + { 22579200, 44100, .v = { 3, 32, }, }, + { 22579200, 48000, .v = { 5, 49, }, }, + { 22579200, 88200, .v = { 3, 16, }, }, + { 22579200, 96000, .v = { 10, 49, }, }, + { 22579200, 176400, .v = { 3, 8, }, }, + { 22579200, 192000, .v = { 20, 49, }, }, + { 22579200, 352800, .v = { 3, 4, }, }, + { 22579200, 384000, .v = { 40, 49, }, }, + { 24576000, 32000, .v = { 1, 16, }, }, + { 24576000, 44100, .v = { 441, 5120, }, }, + { 24576000, 48000, .v = { 3, 32, }, }, + { 24576000, 88200, .v = { 441, 2560, }, }, + { 24576000, 96000, .v = { 3, 16, }, }, + { 24576000, 176400, .v = { 441, 1280, }, }, + { 24576000, 192000, .v = { 3, 8, }, }, + { 24576000, 352800, .v = { 441, 640, }, }, + { 24576000, 384000, .v = { 3, 4, }, }, }; /* frm_size = 64 */ static const struct cs43130_clk_gen cs43130_64_clk_gen[] = { - { 22579200, 32000, .v = { 441, 40, }, }, - { 22579200, 44100, .v = { 8, 1, }, }, - { 22579200, 48000, .v = { 147, 20, }, }, - { 22579200, 88200, .v = { 4, 1, }, }, - { 22579200, 96000, .v = { 147, 40, }, }, - { 22579200, 176400, .v = { 2, 1, }, }, - { 22579200, 192000, .v = { 147, 80, }, }, + { 22579200, 32000, .v = { 40, 441, }, }, + { 22579200, 44100, .v = { 1, 8, }, }, + { 22579200, 48000, .v = { 20, 147, }, }, + { 22579200, 88200, .v = { 1, 4, }, }, + { 22579200, 96000, .v = { 40, 147, }, }, + { 22579200, 176400, .v = { 1, 2, }, }, + { 22579200, 192000, .v = { 80, 147, }, }, { 22579200, 352800, .v = { 1, 1, }, }, - { 24576000, 32000, .v = { 12, 1, }, }, - { 24576000, 44100, .v = { 1280, 147, }, }, - { 24576000, 48000, .v = { 8, 1, }, }, - { 24576000, 88200, .v = { 640, 147, }, }, - { 24576000, 96000, .v = { 4, 1, }, }, - { 24576000, 176400, .v = { 320, 147, }, }, - { 24576000, 192000, .v = { 2, 1, }, }, - { 24576000, 352800, .v = { 160, 147, }, }, + { 24576000, 32000, .v = { 1, 12, }, }, + { 24576000, 44100, .v = { 147, 1280, }, }, + { 24576000, 48000, .v = { 1, 8, }, }, + { 24576000, 88200, .v = { 147, 640, }, }, + { 24576000, 96000, .v = { 1, 4, }, }, + { 24576000, 176400, .v = { 147, 320, }, }, + { 24576000, 192000, .v = { 1, 2, }, }, + { 24576000, 352800, .v = { 147, 160, }, }, { 24576000, 384000, .v = { 1, 1, }, }, }; only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/codecs/da7219-aad.c +++ linux-6.2.0/sound/soc/codecs/da7219-aad.c @@ -352,7 +352,7 @@ struct da7219_priv *da7219 = snd_soc_component_get_drvdata(component); u8 events[DA7219_AAD_IRQ_REG_MAX]; u8 statusa, srm_st; - int i, report = 0, mask = 0; + int i, ret, report = 0, mask = 0; srm_st = snd_soc_component_read(component, DA7219_PLL_SRM_STS) & DA7219_PLL_SRM_STS_MCLK; msleep(da7219_aad->gnd_switch_delay * ((srm_st == 0x0) ? 2 : 1) - 4); @@ -360,8 +360,12 @@ snd_soc_component_update_bits(component, 0xFB, 0x01, 0x01); /* Read current IRQ events */ - regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A, - events, DA7219_AAD_IRQ_REG_MAX); + ret = regmap_bulk_read(da7219->regmap, DA7219_ACCDET_IRQ_EVENT_A, + events, DA7219_AAD_IRQ_REG_MAX); + if (ret) { + dev_warn_ratelimited(component->dev, "Failed to read IRQ events: %d\n", ret); + return IRQ_NONE; + } if (!events[DA7219_AAD_IRQ_REG_A] && !events[DA7219_AAD_IRQ_REG_B]) return IRQ_NONE; @@ -893,6 +897,8 @@ } } } + + synchronize_irq(da7219_aad->irq); } void da7219_aad_resume(struct snd_soc_component *component) only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/codecs/nau8821.c +++ linux-6.2.0/sound/soc/codecs/nau8821.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,13 @@ #include #include "nau8821.h" +#define NAU8821_JD_ACTIVE_HIGH BIT(0) + +static int nau8821_quirk; +static int quirk_override = -1; +module_param_named(quirk, quirk_override, uint, 0444); +MODULE_PARM_DESC(quirk, "Board-specific quirk override"); + #define NAU_FREF_MAX 13500000 #define NAU_FVCO_MAX 100000000 #define NAU_FVCO_MIN 90000000 @@ -1696,6 +1704,33 @@ return 0; } +/* Please keep this list alphabetically sorted */ +static const struct dmi_system_id nau8821_quirk_table[] = { + { + /* Positivo CW14Q01P-V2 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Positivo Tecnologia SA"), + DMI_MATCH(DMI_BOARD_NAME, "CW14Q01P-V2"), + }, + .driver_data = (void *)(NAU8821_JD_ACTIVE_HIGH), + }, + {} +}; + +static void nau8821_check_quirks(void) +{ + const struct dmi_system_id *dmi_id; + + if (quirk_override != -1) { + nau8821_quirk = quirk_override; + return; + } + + dmi_id = dmi_first_match(nau8821_quirk_table); + if (dmi_id) + nau8821_quirk = (unsigned long)dmi_id->driver_data; +} + static int nau8821_i2c_probe(struct i2c_client *i2c) { struct device *dev = &i2c->dev; @@ -1716,6 +1751,12 @@ nau8821->dev = dev; nau8821->irq = i2c->irq; + + nau8821_check_quirks(); + + if (nau8821_quirk & NAU8821_JD_ACTIVE_HIGH) + nau8821->jkdet_polarity = 0; + nau8821_print_device_properties(nau8821); nau8821_reset_chip(nau8821->regmap); only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/codecs/rt5682-sdw.c +++ linux-6.2.0/sound/soc/codecs/rt5682-sdw.c @@ -776,8 +776,15 @@ if (!rt5682->first_hw_init) return 0; - if (!slave->unattach_request) + if (!slave->unattach_request) { + if (rt5682->disable_irq == true) { + mutex_lock(&rt5682->disable_irq_lock); + sdw_write_no_pm(slave, SDW_SCP_INTMASK1, SDW_SCP_INT1_IMPL_DEF); + rt5682->disable_irq = false; + mutex_unlock(&rt5682->disable_irq_lock); + } goto regmap_sync; + } time = wait_for_completion_timeout(&slave->initialization_complete, msecs_to_jiffies(RT5682_PROBE_TIMEOUT)); only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/codecs/rt711-sdw.c +++ linux-6.2.0/sound/soc/codecs/rt711-sdw.c @@ -541,8 +541,15 @@ if (!rt711->first_hw_init) return 0; - if (!slave->unattach_request) + if (!slave->unattach_request) { + if (rt711->disable_irq == true) { + mutex_lock(&rt711->disable_irq_lock); + sdw_write_no_pm(slave, SDW_SCP_INTMASK1, SDW_SCP_INT1_IMPL_DEF); + rt711->disable_irq = false; + mutex_unlock(&rt711->disable_irq_lock); + } goto regmap_sync; + } time = wait_for_completion_timeout(&slave->initialization_complete, msecs_to_jiffies(RT711_PROBE_TIMEOUT)); only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/fsl/imx-pcm-rpmsg.c +++ linux-6.2.0/sound/soc/fsl/imx-pcm-rpmsg.c @@ -19,6 +19,7 @@ static struct snd_pcm_hardware imx_rpmsg_pcm_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_BATCH | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP | only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/fsl/imx-rpmsg.c +++ linux-6.2.0/sound/soc/fsl/imx-rpmsg.c @@ -89,6 +89,14 @@ SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC; + /* + * i.MX rpmsg sound cards work on codec slave mode. MCLK will be + * disabled by CPU DAI driver in hw_free(). Some codec requires MCLK + * present at power up/down sequence. So need to set ignore_pmdown_time + * to power down codec immediately before MCLK is turned off. + */ + data->dai.ignore_pmdown_time = 1; + /* Optional codec node */ ret = of_parse_phandle_with_fixed_args(np, "audio-codec", 0, 0, &args); if (ret) { only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/intel/avs/boards/hdaudio.c +++ linux-6.2.0/sound/soc/intel/avs/boards/hdaudio.c @@ -55,6 +55,9 @@ return -ENOMEM; dl[i].codecs->name = devm_kstrdup(dev, cname, GFP_KERNEL); + if (!dl[i].codecs->name) + return -ENOMEM; + dl[i].codecs->dai_name = pcm->name; dl[i].num_codecs = 1; dl[i].num_cpus = 1; only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/meson/axg-spdifin.c +++ linux-6.2.0/sound/soc/meson/axg-spdifin.c @@ -112,34 +112,6 @@ return 0; } -static int axg_spdifin_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); - int ret; - - ret = clk_prepare_enable(priv->refclk); - if (ret) { - dev_err(dai->dev, - "failed to enable spdifin reference clock\n"); - return ret; - } - - regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, - SPDIFIN_CTRL0_EN); - - return 0; -} - -static void axg_spdifin_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); - - regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0); - clk_disable_unprepare(priv->refclk); -} - static void axg_spdifin_write_mode_param(struct regmap *map, int mode, unsigned int val, unsigned int num_per_reg, @@ -251,25 +223,38 @@ ret = axg_spdifin_sample_mode_config(dai, priv); if (ret) { dev_err(dai->dev, "mode configuration failed\n"); - clk_disable_unprepare(priv->pclk); - return ret; + goto pclk_err; } + ret = clk_prepare_enable(priv->refclk); + if (ret) { + dev_err(dai->dev, + "failed to enable spdifin reference clock\n"); + goto pclk_err; + } + + regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, + SPDIFIN_CTRL0_EN); + return 0; + +pclk_err: + clk_disable_unprepare(priv->pclk); + return ret; } static int axg_spdifin_dai_remove(struct snd_soc_dai *dai) { struct axg_spdifin *priv = snd_soc_dai_get_drvdata(dai); + regmap_update_bits(priv->map, SPDIFIN_CTRL0, SPDIFIN_CTRL0_EN, 0); + clk_disable_unprepare(priv->refclk); clk_disable_unprepare(priv->pclk); return 0; } static const struct snd_soc_dai_ops axg_spdifin_ops = { .prepare = axg_spdifin_prepare, - .startup = axg_spdifin_startup, - .shutdown = axg_spdifin_shutdown, }; static int axg_spdifin_iec958_info(struct snd_kcontrol *kcontrol, only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/soc-utils.c +++ linux-6.2.0/sound/soc/soc-utils.c @@ -217,6 +217,7 @@ return 1; return 0; } +EXPORT_SYMBOL_GPL(snd_soc_dai_is_dummy); int snd_soc_component_is_dummy(struct snd_soc_component *component) { only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/sof/amd/acp.c +++ linux-6.2.0/sound/soc/sof/amd/acp.c @@ -351,9 +351,9 @@ unsigned int val; val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET); - if (val) { - val |= ACP_DSP_TO_HOST_IRQ; - snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET, val); + if (val & ACP_DSP_TO_HOST_IRQ) { + snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET, + ACP_DSP_TO_HOST_IRQ); return IRQ_WAKE_THREAD; } only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/sof/intel/mtl.c +++ linux-6.2.0/sound/soc/sof/intel/mtl.c @@ -429,7 +429,7 @@ /* step 3: wait for IPC DONE bit from ROM */ ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR, chip->ipc_ack, status, ((status & chip->ipc_ack_mask) == chip->ipc_ack_mask), - HDA_DSP_REG_POLL_INTERVAL_US, MTL_DSP_PURGE_TIMEOUT_US); + HDA_DSP_REG_POLL_INTERVAL_US, HDA_DSP_INIT_TIMEOUT_US); if (ret < 0) { if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) dev_err(sdev->dev, "timeout waiting for purge IPC done\n"); only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/sof/intel/mtl.h +++ linux-6.2.0/sound/soc/sof/intel/mtl.h @@ -56,7 +56,6 @@ #define MTL_DSP_IRQSTS_IPC BIT(0) #define MTL_DSP_IRQSTS_SDW BIT(6) -#define MTL_DSP_PURGE_TIMEOUT_US 20000000 /* 20s */ #define MTL_DSP_REG_POLL_INTERVAL_US 10 /* 10 us */ /* Memory windows */ only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/tegra/tegra210_sfc.c +++ linux-6.2.0/sound/soc/tegra/tegra210_sfc.c @@ -2,7 +2,7 @@ // // tegra210_sfc.c - Tegra210 SFC driver // -// Copyright (c) 2021 NVIDIA CORPORATION. All rights reserved. +// Copyright (c) 2021-2023 NVIDIA CORPORATION. All rights reserved. #include #include @@ -42,6 +42,7 @@ 32000, 44100, 48000, + 64000, 88200, 96000, 176400, @@ -2857,6 +2858,7 @@ coef_8to32, coef_8to44, coef_8to48, + UNSUPP_CONV, coef_8to88, coef_8to96, UNSUPP_CONV, @@ -2872,6 +2874,7 @@ coef_11to32, coef_11to44, coef_11to48, + UNSUPP_CONV, coef_11to88, coef_11to96, UNSUPP_CONV, @@ -2887,6 +2890,7 @@ coef_16to32, coef_16to44, coef_16to48, + UNSUPP_CONV, coef_16to88, coef_16to96, coef_16to176, @@ -2902,6 +2906,7 @@ coef_22to32, coef_22to44, coef_22to48, + UNSUPP_CONV, coef_22to88, coef_22to96, coef_22to176, @@ -2917,6 +2922,7 @@ coef_24to32, coef_24to44, coef_24to48, + UNSUPP_CONV, coef_24to88, coef_24to96, coef_24to176, @@ -2932,6 +2938,7 @@ BYPASS_CONV, coef_32to44, coef_32to48, + UNSUPP_CONV, coef_32to88, coef_32to96, coef_32to176, @@ -2947,6 +2954,7 @@ coef_44to32, BYPASS_CONV, coef_44to48, + UNSUPP_CONV, coef_44to88, coef_44to96, coef_44to176, @@ -2962,11 +2970,28 @@ coef_48to32, coef_48to44, BYPASS_CONV, + UNSUPP_CONV, coef_48to88, coef_48to96, coef_48to176, coef_48to192, }, + /* Convertions from 64 kHz */ + { + UNSUPP_CONV, + UNSUPP_CONV, + UNSUPP_CONV, + UNSUPP_CONV, + UNSUPP_CONV, + UNSUPP_CONV, + UNSUPP_CONV, + UNSUPP_CONV, + UNSUPP_CONV, + UNSUPP_CONV, + UNSUPP_CONV, + UNSUPP_CONV, + UNSUPP_CONV, + }, /* Convertions from 88.2 kHz */ { coef_88to8, @@ -2977,6 +3002,7 @@ coef_88to32, coef_88to44, coef_88to48, + UNSUPP_CONV, BYPASS_CONV, coef_88to96, coef_88to176, @@ -2991,6 +3017,7 @@ coef_96to32, coef_96to44, coef_96to48, + UNSUPP_CONV, coef_96to88, BYPASS_CONV, coef_96to176, @@ -3006,6 +3033,7 @@ coef_176to32, coef_176to44, coef_176to48, + UNSUPP_CONV, coef_176to88, coef_176to96, BYPASS_CONV, @@ -3021,6 +3049,7 @@ coef_192to32, coef_192to44, coef_192to48, + UNSUPP_CONV, coef_192to88, coef_192to96, coef_192to176, only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/tegra/tegra210_sfc.h +++ linux-6.2.0/sound/soc/tegra/tegra210_sfc.h @@ -2,7 +2,7 @@ /* * tegra210_sfc.h - Definitions for Tegra210 SFC driver * - * Copyright (c) 2021 NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2021-2023 NVIDIA CORPORATION. All rights reserved. * */ @@ -47,7 +47,7 @@ #define TEGRA210_SFC_EN_SHIFT 0 #define TEGRA210_SFC_EN (1 << TEGRA210_SFC_EN_SHIFT) -#define TEGRA210_SFC_NUM_RATES 12 +#define TEGRA210_SFC_NUM_RATES 13 /* Fields in TEGRA210_SFC_COEF_RAM */ #define TEGRA210_SFC_COEF_RAM_EN BIT(0) only in patch2: unchanged: --- linux-6.2.0.orig/sound/soc/tegra/tegra_audio_graph_card.c +++ linux-6.2.0/sound/soc/tegra/tegra_audio_graph_card.c @@ -10,6 +10,7 @@ #include #include #include +#include #define MAX_PLLA_OUT0_DIV 128 @@ -44,6 +45,21 @@ unsigned int plla_out0_rates[NUM_RATE_TYPE]; }; +static bool need_clk_update(struct snd_soc_dai *dai) +{ + if (snd_soc_dai_is_dummy(dai) || + !dai->driver->ops || + !dai->driver->name) + return false; + + if (strstr(dai->driver->name, "I2S") || + strstr(dai->driver->name, "DMIC") || + strstr(dai->driver->name, "DSPK")) + return true; + + return false; +} + /* Setup PLL clock as per the given sample rate */ static int tegra_audio_graph_update_pll(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) @@ -140,19 +156,7 @@ struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); int err; - /* - * This gets called for each DAI link (FE or BE) when DPCM is used. - * We may not want to update PLLA rate for each call. So PLLA update - * must be restricted to external I/O links (I2S, DMIC or DSPK) since - * they actually depend on it. I/O modules update their clocks in - * hw_param() of their respective component driver and PLLA rate - * update here helps them to derive appropriate rates. - * - * TODO: When more HW accelerators get added (like sample rate - * converter, volume gain controller etc., which don't really - * depend on PLLA) we need a better way to filter here. - */ - if (cpu_dai->driver->ops && rtd->dai_link->no_pcm) { + if (need_clk_update(cpu_dai)) { err = tegra_audio_graph_update_pll(substream, params); if (err) return err; only in patch2: unchanged: --- linux-6.2.0.orig/sound/usb/mixer_maps.c +++ linux-6.2.0/sound/usb/mixer_maps.c @@ -374,6 +374,15 @@ { 0 } }; +/* Microsoft USB Link headset */ +/* a guess work: raw playback volume values are from 2 to 129 */ +static const struct usbmix_dB_map ms_usb_link_dB = { -3225, 0, true }; +static const struct usbmix_name_map ms_usb_link_map[] = { + { 9, NULL, .dB = &ms_usb_link_dB }, + { 10, NULL }, /* Headset Capture volume; seems non-working, disabled */ + { 0 } /* terminator */ +}; + /* ASUS ROG Zenith II with Realtek ALC1220-VB */ static const struct usbmix_name_map asus_zenith_ii_map[] = { { 19, NULL, 12 }, /* FU, Input Gain Pad - broken response, disabled */ @@ -668,6 +677,11 @@ .id = USB_ID(0x1395, 0x0025), .map = sennheiser_pc8_map, }, + { + /* Microsoft USB Link headset */ + .id = USB_ID(0x045e, 0x083c), + .map = ms_usb_link_map, + }, { 0 } /* terminator */ }; only in patch2: unchanged: --- linux-6.2.0.orig/tools/bpf/bpftool/skeleton/pid_iter.bpf.c +++ linux-6.2.0/tools/bpf/bpftool/skeleton/pid_iter.bpf.c @@ -15,6 +15,19 @@ BPF_OBJ_BTF, }; +struct bpf_perf_link___local { + struct bpf_link link; + struct file *perf_file; +} __attribute__((preserve_access_index)); + +struct perf_event___local { + u64 bpf_cookie; +} __attribute__((preserve_access_index)); + +enum bpf_link_type___local { + BPF_LINK_TYPE_PERF_EVENT___local = 7, +}; + extern const void bpf_link_fops __ksym; extern const void bpf_map_fops __ksym; extern const void bpf_prog_fops __ksym; @@ -41,10 +54,10 @@ /* could be used only with BPF_LINK_TYPE_PERF_EVENT links */ static __u64 get_bpf_cookie(struct bpf_link *link) { - struct bpf_perf_link *perf_link; - struct perf_event *event; + struct bpf_perf_link___local *perf_link; + struct perf_event___local *event; - perf_link = container_of(link, struct bpf_perf_link, link); + perf_link = container_of(link, struct bpf_perf_link___local, link); event = BPF_CORE_READ(perf_link, perf_file, private_data); return BPF_CORE_READ(event, bpf_cookie); } @@ -84,10 +97,13 @@ e.pid = task->tgid; e.id = get_obj_id(file->private_data, obj_type); - if (obj_type == BPF_OBJ_LINK) { + if (obj_type == BPF_OBJ_LINK && + bpf_core_enum_value_exists(enum bpf_link_type___local, + BPF_LINK_TYPE_PERF_EVENT___local)) { struct bpf_link *link = (struct bpf_link *) file->private_data; - if (BPF_CORE_READ(link, type) == BPF_LINK_TYPE_PERF_EVENT) { + if (link->type == bpf_core_enum_value(enum bpf_link_type___local, + BPF_LINK_TYPE_PERF_EVENT___local)) { e.has_bpf_cookie = true; e.bpf_cookie = get_bpf_cookie(link); } only in patch2: unchanged: --- linux-6.2.0.orig/tools/bpf/bpftool/skeleton/profiler.bpf.c +++ linux-6.2.0/tools/bpf/bpftool/skeleton/profiler.bpf.c @@ -4,6 +4,12 @@ #include #include +struct bpf_perf_event_value___local { + __u64 counter; + __u64 enabled; + __u64 running; +} __attribute__((preserve_access_index)); + /* map of perf event fds, num_cpu * num_metric entries */ struct { __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); @@ -15,14 +21,14 @@ struct { __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); __uint(key_size, sizeof(u32)); - __uint(value_size, sizeof(struct bpf_perf_event_value)); + __uint(value_size, sizeof(struct bpf_perf_event_value___local)); } fentry_readings SEC(".maps"); /* accumulated readings */ struct { __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); __uint(key_size, sizeof(u32)); - __uint(value_size, sizeof(struct bpf_perf_event_value)); + __uint(value_size, sizeof(struct bpf_perf_event_value___local)); } accum_readings SEC(".maps"); /* sample counts, one per cpu */ @@ -39,7 +45,7 @@ SEC("fentry/XXX") int BPF_PROG(fentry_XXX) { - struct bpf_perf_event_value *ptrs[MAX_NUM_MATRICS]; + struct bpf_perf_event_value___local *ptrs[MAX_NUM_MATRICS]; u32 key = bpf_get_smp_processor_id(); u32 i; @@ -53,10 +59,10 @@ } for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) { - struct bpf_perf_event_value reading; + struct bpf_perf_event_value___local reading; int err; - err = bpf_perf_event_read_value(&events, key, &reading, + err = bpf_perf_event_read_value(&events, key, (void *)&reading, sizeof(reading)); if (err) return 0; @@ -68,14 +74,14 @@ } static inline void -fexit_update_maps(u32 id, struct bpf_perf_event_value *after) +fexit_update_maps(u32 id, struct bpf_perf_event_value___local *after) { - struct bpf_perf_event_value *before, diff; + struct bpf_perf_event_value___local *before, diff; before = bpf_map_lookup_elem(&fentry_readings, &id); /* only account samples with a valid fentry_reading */ if (before && before->counter) { - struct bpf_perf_event_value *accum; + struct bpf_perf_event_value___local *accum; diff.counter = after->counter - before->counter; diff.enabled = after->enabled - before->enabled; @@ -93,7 +99,7 @@ SEC("fexit/XXX") int BPF_PROG(fexit_XXX) { - struct bpf_perf_event_value readings[MAX_NUM_MATRICS]; + struct bpf_perf_event_value___local readings[MAX_NUM_MATRICS]; u32 cpu = bpf_get_smp_processor_id(); u32 i, zero = 0; int err; @@ -102,7 +108,8 @@ /* read all events before updating the maps, to reduce error */ for (i = 0; i < num_metric && i < MAX_NUM_MATRICS; i++) { err = bpf_perf_event_read_value(&events, cpu + i * num_cpu, - readings + i, sizeof(*readings)); + (void *)(readings + i), + sizeof(*readings)); if (err) return 0; } only in patch2: unchanged: --- linux-6.2.0.orig/tools/bpf/resolve_btfids/Build +++ linux-6.2.0/tools/bpf/resolve_btfids/Build @@ -1,3 +1,5 @@ +hostprogs := resolve_btfids + resolve_btfids-y += main.o resolve_btfids-y += rbtree.o resolve_btfids-y += zalloc.o @@ -7,4 +9,4 @@ $(OUTPUT)%.o: ../../lib/%.c FORCE $(call rule_mkdir) - $(call if_changed_dep,cc_o_c) + $(call if_changed_dep,host_cc_o_c) only in patch2: unchanged: --- linux-6.2.0.orig/tools/bpf/resolve_btfids/Makefile +++ linux-6.2.0/tools/bpf/resolve_btfids/Makefile @@ -17,15 +17,15 @@ MAKEFLAGS=--no-print-directory endif -# always use the host compiler -AR = $(HOSTAR) -CC = $(HOSTCC) -LD = $(HOSTLD) -ARCH = $(HOSTARCH) +# Overrides for the prepare step libraries. +HOST_OVERRIDES := AR="$(HOSTAR)" CC="$(HOSTCC)" LD="$(HOSTLD)" ARCH="$(HOSTARCH)" \ + CROSS_COMPILE="" EXTRA_CFLAGS="$(HOSTCFLAGS)" + RM ?= rm +HOSTCC ?= gcc +HOSTLD ?= ld +HOSTAR ?= ar CROSS_COMPILE = -CFLAGS := $(KBUILD_HOSTCFLAGS) -LDFLAGS := $(KBUILD_HOSTLDFLAGS) OUTPUT ?= $(srctree)/tools/bpf/resolve_btfids/ @@ -35,51 +35,64 @@ BPFOBJ := $(OUTPUT)/libbpf/libbpf.a LIBBPF_OUT := $(abspath $(dir $(BPFOBJ)))/ SUBCMDOBJ := $(OUTPUT)/libsubcmd/libsubcmd.a +SUBCMD_OUT := $(abspath $(dir $(SUBCMDOBJ)))/ LIBBPF_DESTDIR := $(LIBBPF_OUT) LIBBPF_INCLUDE := $(LIBBPF_DESTDIR)include +SUBCMD_DESTDIR := $(SUBCMD_OUT) +SUBCMD_INCLUDE := $(SUBCMD_DESTDIR)include + BINARY := $(OUTPUT)/resolve_btfids BINARY_IN := $(BINARY)-in.o all: $(BINARY) +prepare: $(BPFOBJ) $(SUBCMDOBJ) + $(OUTPUT) $(OUTPUT)/libsubcmd $(LIBBPF_OUT): $(call msg,MKDIR,,$@) $(Q)mkdir -p $(@) $(SUBCMDOBJ): fixdep FORCE | $(OUTPUT)/libsubcmd - $(Q)$(MAKE) -C $(SUBCMD_SRC) OUTPUT=$(abspath $(dir $@))/ $(abspath $@) + $(Q)$(MAKE) -C $(SUBCMD_SRC) OUTPUT=$(SUBCMD_OUT) \ + DESTDIR=$(SUBCMD_DESTDIR) $(HOST_OVERRIDES) prefix= subdir= \ + $(abspath $@) install_headers $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OUT) $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC) OUTPUT=$(LIBBPF_OUT) \ - DESTDIR=$(LIBBPF_DESTDIR) prefix= EXTRA_CFLAGS="$(CFLAGS)" \ + DESTDIR=$(LIBBPF_DESTDIR) $(HOST_OVERRIDES) prefix= subdir= \ $(abspath $@) install_headers -CFLAGS += -g \ +LIBELF_FLAGS := $(shell $(HOSTPKG_CONFIG) libelf --cflags 2>/dev/null) +LIBELF_LIBS := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf) + +HOSTCFLAGS_resolve_btfids += -g \ -I$(srctree)/tools/include \ -I$(srctree)/tools/include/uapi \ -I$(LIBBPF_INCLUDE) \ - -I$(SUBCMD_SRC) + -I$(SUBCMD_INCLUDE) \ + $(LIBELF_FLAGS) -LIBS = -lelf -lz +LIBS = $(LIBELF_LIBS) -lz -export srctree OUTPUT CFLAGS Q +export srctree OUTPUT HOSTCFLAGS_resolve_btfids Q HOSTCC HOSTLD HOSTAR include $(srctree)/tools/build/Makefile.include -$(BINARY_IN): $(BPFOBJ) fixdep FORCE | $(OUTPUT) +$(BINARY_IN): fixdep FORCE prepare | $(OUTPUT) $(Q)$(MAKE) $(build)=resolve_btfids $(BINARY): $(BPFOBJ) $(SUBCMDOBJ) $(BINARY_IN) $(call msg,LINK,$@) - $(Q)$(CC) $(BINARY_IN) $(LDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS) + $(Q)$(HOSTCC) $(BINARY_IN) $(KBUILD_HOSTLDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS) clean_objects := $(wildcard $(OUTPUT)/*.o \ $(OUTPUT)/.*.o.cmd \ $(OUTPUT)/.*.o.d \ $(LIBBPF_OUT) \ $(LIBBPF_DESTDIR) \ - $(OUTPUT)/libsubcmd \ + $(SUBCMD_OUT) \ + $(SUBCMD_DESTDIR) \ $(OUTPUT)/resolve_btfids) ifneq ($(clean_objects),) @@ -96,4 +109,4 @@ FORCE: -.PHONY: all FORCE clean tags +.PHONY: all FORCE clean tags prepare only in patch2: unchanged: --- linux-6.2.0.orig/tools/bpf/resolve_btfids/main.c +++ linux-6.2.0/tools/bpf/resolve_btfids/main.c @@ -75,7 +75,7 @@ #include #include #include -#include +#include #define BTF_IDS_SECTION ".BTF_ids" #define BTF_ID "__BTF_ID__" only in patch2: unchanged: --- linux-6.2.0.orig/tools/hv/vmbus_testing +++ linux-6.2.0/tools/hv/vmbus_testing @@ -164,7 +164,7 @@ def get_all_devices_test_status(file_map): for device in file_map: - if (get_test_state(locate_state(device, file_map)) is 1): + if (get_test_state(locate_state(device, file_map)) == 1): print("Testing = ON for: {}" .format(device.split("/")[5])) else: @@ -203,7 +203,7 @@ def set_test_state(state_path, state_value, quiet): write_test_files(state_path, state_value) - if (get_test_state(state_path) is 1): + if (get_test_state(state_path) == 1): if (not quiet): print("Testing = ON for device: {}" .format(state_path.split("/")[5])) only in patch2: unchanged: --- linux-6.2.0.orig/tools/iio/iio_generic_buffer.c +++ linux-6.2.0/tools/iio/iio_generic_buffer.c @@ -51,9 +51,9 @@ * Has the side effect of filling the channels[i].location values used * in processing the buffer output. **/ -static int size_from_channelarray(struct iio_channel_info *channels, int num_channels) +static unsigned int size_from_channelarray(struct iio_channel_info *channels, int num_channels) { - int bytes = 0; + unsigned int bytes = 0; int i = 0; while (i < num_channels) { @@ -348,7 +348,7 @@ ssize_t read_size; int dev_num = -1, trig_num = -1; char *buffer_access = NULL; - int scan_size; + unsigned int scan_size; int noevents = 0; int notrigger = 0; char *dummy; @@ -674,7 +674,16 @@ } scan_size = size_from_channelarray(channels, num_channels); - data = malloc(scan_size * buf_len); + + size_t total_buf_len = scan_size * buf_len; + + if (scan_size > 0 && total_buf_len / scan_size != buf_len) { + ret = -EFAULT; + perror("Integer overflow happened when calculate scan_size * buf_len"); + goto error; + } + + data = malloc(total_buf_len); if (!data) { ret = -ENOMEM; goto error; only in patch2: unchanged: --- linux-6.2.0.orig/tools/include/linux/btf_ids.h +++ linux-6.2.0/tools/include/linux/btf_ids.h @@ -38,7 +38,7 @@ ____BTF_ID(symbol) #define __ID(prefix) \ - __PASTE(prefix, __COUNTER__) + __PASTE(__PASTE(prefix, __COUNTER__), __LINE__) /* * The BTF_ID defines unique symbol for each ID pointing only in patch2: unchanged: --- linux-6.2.0.orig/tools/include/linux/mm.h +++ linux-6.2.0/tools/include/linux/mm.h @@ -11,8 +11,6 @@ #define PHYS_ADDR_MAX (~(phys_addr_t)0) -#define __ALIGN_KERNEL(x, a) __ALIGN_KERNEL_MASK(x, (typeof(x))(a) - 1) -#define __ALIGN_KERNEL_MASK(x, mask) (((x) + (mask)) & ~(mask)) #define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) #define ALIGN_DOWN(x, a) __ALIGN_KERNEL((x) - ((a) - 1), (a)) only in patch2: unchanged: --- linux-6.2.0.orig/tools/include/linux/seq_file.h +++ linux-6.2.0/tools/include/linux/seq_file.h @@ -1,4 +1,6 @@ #ifndef _TOOLS_INCLUDE_LINUX_SEQ_FILE_H #define _TOOLS_INCLUDE_LINUX_SEQ_FILE_H +struct seq_file; + #endif /* _TOOLS_INCLUDE_LINUX_SEQ_FILE_H */ only in patch2: unchanged: --- linux-6.2.0.orig/tools/lib/bpf/usdt.c +++ linux-6.2.0/tools/lib/bpf/usdt.c @@ -852,8 +852,11 @@ * system is so exhausted on memory, it's the least of user's * concerns, probably. * So just do our best here to return those IDs to usdt_manager. + * Another edge case when we can legitimately get NULL is when + * new_cnt is zero, which can happen in some edge cases, so we + * need to be careful about that. */ - if (new_free_ids) { + if (new_free_ids || new_cnt == 0) { memcpy(new_free_ids + man->free_spec_cnt, usdt_link->spec_ids, usdt_link->spec_cnt * sizeof(*usdt_link->spec_ids)); man->free_spec_ids = new_free_ids; only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/builtin-top.c +++ linux-6.2.0/tools/perf/builtin-top.c @@ -1749,6 +1749,7 @@ top.session = perf_session__new(NULL, NULL); if (IS_ERR(top.session)) { status = PTR_ERR(top.session); + top.session = NULL; goto out_delete_evlist; } only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/builtin-trace.c +++ linux-6.2.0/tools/perf/builtin-trace.c @@ -2288,7 +2288,7 @@ if (!sc) return; - free(sc->arg_fmt); + zfree(&sc->arg_fmt); } static int trace__sys_enter(struct trace *trace, struct evsel *evsel, @@ -3121,13 +3121,8 @@ struct evsel *evsel; evlist__for_each_entry(evlist, evsel) { - struct evsel_trace *et = evsel->priv; - - if (!et || !evsel->tp_format || strcmp(evsel->tp_format->system, "syscalls")) - continue; - - free(et->fmt); - free(et); + evsel_trace__delete(evsel->priv); + evsel->priv = NULL; } } @@ -4672,11 +4667,11 @@ int i; strlist__delete(trace->ev_qualifier); - free(trace->ev_qualifier_ids.entries); + zfree(&trace->ev_qualifier_ids.entries); if (trace->syscalls.table) { for (i = 0; i <= trace->sctbl->syscalls.max_id; i++) syscall__exit(&trace->syscalls.table[i]); - free(trace->syscalls.table); + zfree(&trace->syscalls.table); } syscalltbl__delete(trace->sctbl); zfree(&trace->perfconfig_events); only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/pmu-events/arch/powerpc/power10/cache.json +++ linux-6.2.0/tools/perf/pmu-events/arch/powerpc/power10/cache.json @@ -17,7 +17,7 @@ { "EventCode": "0x34056", "EventName": "PM_EXEC_STALL_LOAD_FINISH", - "BriefDescription": "Cycles in which the oldest instruction in the pipeline was finishing a load after its data was reloaded from a data source beyond the local L1; cycles in which the LSU was processing an L1-hit; cycles in which the NTF instruction merged with another load in the LMQ; cycles in which the NTF instruction is waiting for a data reload for a load miss, but the data comes back with a non-NTF instruction." + "BriefDescription": "Cycles in which the oldest instruction in the pipeline was finishing a load after its data was reloaded from a data source beyond the local L1; cycles in which the LSU was processing an L1-hit; cycles in which the next-to-finish (NTF) instruction merged with another load in the LMQ; cycles in which the NTF instruction is waiting for a data reload for a load miss, but the data comes back with a non-NTF instruction." }, { "EventCode": "0x3006C", @@ -27,7 +27,7 @@ { "EventCode": "0x300F4", "EventName": "PM_RUN_INST_CMPL_CONC", - "BriefDescription": "PowerPC instructions completed by this thread when all threads in the core had the run-latch set." + "BriefDescription": "PowerPC instruction completed by this thread when all threads in the core had the run-latch set." }, { "EventCode": "0x4C016", only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/pmu-events/arch/powerpc/power10/frontend.json +++ linux-6.2.0/tools/perf/pmu-events/arch/powerpc/power10/frontend.json @@ -7,7 +7,7 @@ { "EventCode": "0x10006", "EventName": "PM_DISP_STALL_HELD_OTHER_CYC", - "BriefDescription": "Cycles in which the NTC instruction is held at dispatch for any other reason." + "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch for any other reason." }, { "EventCode": "0x10010", @@ -32,12 +32,12 @@ { "EventCode": "0x1D05E", "EventName": "PM_DISP_STALL_HELD_HALT_CYC", - "BriefDescription": "Cycles in which the NTC instruction is held at dispatch because of power management." + "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch because of power management." }, { "EventCode": "0x1E050", "EventName": "PM_DISP_STALL_HELD_STF_MAPPER_CYC", - "BriefDescription": "Cycles in which the NTC instruction is held at dispatch because the STF mapper/SRB was full. Includes GPR (count, link, tar), VSR, VMR, FPR." + "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch because the STF mapper/SRB was full. Includes GPR (count, link, tar), VSR, VMR, FPR." }, { "EventCode": "0x1F054", @@ -67,7 +67,7 @@ { "EventCode": "0x100F6", "EventName": "PM_IERAT_MISS", - "BriefDescription": "IERAT Reloaded to satisfy an IERAT miss. All page sizes are counted by this event." + "BriefDescription": "IERAT Reloaded to satisfy an IERAT miss. All page sizes are counted by this event. This event only counts instruction demand access." }, { "EventCode": "0x100F8", @@ -77,7 +77,7 @@ { "EventCode": "0x20006", "EventName": "PM_DISP_STALL_HELD_ISSQ_FULL_CYC", - "BriefDescription": "Cycles in which the NTC instruction is held at dispatch due to Issue queue full. Includes issue queue and branch queue." + "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch due to Issue queue full. Includes issue queue and branch queue." }, { "EventCode": "0x20114", @@ -102,7 +102,7 @@ { "EventCode": "0x2D01A", "EventName": "PM_DISP_STALL_IC_MISS", - "BriefDescription": "Cycles when dispatch was stalled for this thread due to an Icache Miss." + "BriefDescription": "Cycles when dispatch was stalled for this thread due to an instruction cache miss." }, { "EventCode": "0x2E018", @@ -112,7 +112,7 @@ { "EventCode": "0x2E01A", "EventName": "PM_DISP_STALL_HELD_XVFC_MAPPER_CYC", - "BriefDescription": "Cycles in which the NTC instruction is held at dispatch because the XVFC mapper/SRB was full." + "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch because the XVFC mapper/SRB was full." }, { "EventCode": "0x2C142", @@ -137,7 +137,7 @@ { "EventCode": "0x30004", "EventName": "PM_DISP_STALL_FLUSH", - "BriefDescription": "Cycles when dispatch was stalled because of a flush that happened to an instruction(s) that was not yet NTC. PM_EXEC_STALL_NTC_FLUSH only includes instructions that were flushed after becoming NTC." + "BriefDescription": "Cycles when dispatch was stalled because of a flush that happened to an instruction(s) that was not yet next-to-complete (NTC). PM_EXEC_STALL_NTC_FLUSH only includes instructions that were flushed after becoming NTC." }, { "EventCode": "0x3000A", @@ -157,7 +157,7 @@ { "EventCode": "0x30018", "EventName": "PM_DISP_STALL_HELD_SCOREBOARD_CYC", - "BriefDescription": "Cycles in which the NTC instruction is held at dispatch while waiting on the Scoreboard. This event combines VSCR and FPSCR together." + "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch while waiting on the Scoreboard. This event combines VSCR and FPSCR together." }, { "EventCode": "0x30026", @@ -182,7 +182,7 @@ { "EventCode": "0x3D05C", "EventName": "PM_DISP_STALL_HELD_RENAME_CYC", - "BriefDescription": "Cycles in which the NTC instruction is held at dispatch because the mapper/SRB was full. Includes GPR (count, link, tar), VSR, VMR, FPR and XVFC." + "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch because the mapper/SRB was full. Includes GPR (count, link, tar), VSR, VMR, FPR and XVFC." }, { "EventCode": "0x3E052", @@ -192,7 +192,7 @@ { "EventCode": "0x3E054", "EventName": "PM_LD_MISS_L1", - "BriefDescription": "Load Missed L1, counted at execution time (can be greater than loads finished). LMQ merges are not included in this count. i.e. if a load instruction misses on an address that is already allocated on the LMQ, this event will not increment for that load). Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load." + "BriefDescription": "Load missed L1, counted at finish time. LMQ merges are not included in this count. i.e. if a load instruction misses on an address that is already allocated on the LMQ, this event will not increment for that load). Note that this count is per slice, so if a load spans multiple slices this event will increment multiple times for a single load." }, { "EventCode": "0x301EA", @@ -202,7 +202,7 @@ { "EventCode": "0x300FA", "EventName": "PM_INST_FROM_L3MISS", - "BriefDescription": "The processor's instruction cache was reloaded from a source other than the local core's L1, L2, or L3 due to a demand miss." + "BriefDescription": "The processor's instruction cache was reloaded from beyond the local core's L3 due to a demand miss." }, { "EventCode": "0x40006", @@ -232,16 +232,16 @@ { "EventCode": "0x4E01A", "EventName": "PM_DISP_STALL_HELD_CYC", - "BriefDescription": "Cycles in which the NTC instruction is held at dispatch for any reason." + "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch for any reason." }, { "EventCode": "0x4003C", "EventName": "PM_DISP_STALL_HELD_SYNC_CYC", - "BriefDescription": "Cycles in which the NTC instruction is held at dispatch because of a synchronizing instruction that requires the ICT to be empty before dispatch." + "BriefDescription": "Cycles in which the next-to-complete (NTC) instruction is held at dispatch because of a synchronizing instruction that requires the ICT to be empty before dispatch." }, { "EventCode": "0x44056", "EventName": "PM_VECTOR_ST_CMPL", - "BriefDescription": "Vector store instructions completed." + "BriefDescription": "Vector store instruction completed." } ] only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/pmu-events/arch/powerpc/power10/marked.json +++ linux-6.2.0/tools/perf/pmu-events/arch/powerpc/power10/marked.json @@ -20,11 +20,6 @@ "BriefDescription": "Marked Branch Taken instruction completed." }, { - "EventCode": "0x20112", - "EventName": "PM_MRK_NTF_FIN", - "BriefDescription": "The marked instruction became the oldest in the pipeline before it finished. It excludes instructions that finish at dispatch." - }, - { "EventCode": "0x2C01C", "EventName": "PM_EXEC_STALL_DMISS_OFF_CHIP", "BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for a load miss to resolve from a remote chip." @@ -62,17 +57,12 @@ { "EventCode": "0x200FD", "EventName": "PM_L1_ICACHE_MISS", - "BriefDescription": "Demand iCache Miss." - }, - { - "EventCode": "0x30130", - "EventName": "PM_MRK_INST_FIN", - "BriefDescription": "marked instruction finished. Excludes instructions that finish at dispatch. Note that stores always finish twice since the address gets issued to the LSU and the data gets issued to the VSU." + "BriefDescription": "Demand instruction cache miss." }, { "EventCode": "0x34146", "EventName": "PM_MRK_LD_CMPL", - "BriefDescription": "Marked loads completed." + "BriefDescription": "Marked load instruction completed." }, { "EventCode": "0x3E158", @@ -82,12 +72,12 @@ { "EventCode": "0x3E15A", "EventName": "PM_MRK_ST_FIN", - "BriefDescription": "The marked instruction was a store of any kind." + "BriefDescription": "Marked store instruction finished." }, { "EventCode": "0x30068", "EventName": "PM_L1_ICACHE_RELOADED_PREF", - "BriefDescription": "Counts all Icache prefetch reloads ( includes demand turned into prefetch)." + "BriefDescription": "Counts all instruction cache prefetch reloads (includes demand turned into prefetch)." }, { "EventCode": "0x301E4", @@ -102,12 +92,12 @@ { "EventCode": "0x300FE", "EventName": "PM_DATA_FROM_L3MISS", - "BriefDescription": "The processor's data cache was reloaded from a source other than the local core's L1, L2, or L3 due to a demand miss." + "BriefDescription": "The processor's L1 data cache was reloaded from beyond the local core's L3 due to a demand miss." }, { "EventCode": "0x40012", "EventName": "PM_L1_ICACHE_RELOADED_ALL", - "BriefDescription": "Counts all Icache reloads includes demand, prefetch, prefetch turned into demand and demand turned into prefetch." + "BriefDescription": "Counts all instruction cache reloads includes demand, prefetch, prefetch turned into demand and demand turned into prefetch." }, { "EventCode": "0x40134", @@ -117,22 +107,22 @@ { "EventCode": "0x4505A", "EventName": "PM_SP_FLOP_CMPL", - "BriefDescription": "Single Precision floating point instructions completed." + "BriefDescription": "Single Precision floating point instruction completed." }, { "EventCode": "0x4D058", "EventName": "PM_VECTOR_FLOP_CMPL", - "BriefDescription": "Vector floating point instructions completed." + "BriefDescription": "Vector floating point instruction completed." }, { "EventCode": "0x4D05A", "EventName": "PM_NON_MATH_FLOP_CMPL", - "BriefDescription": "Non Math instructions completed." + "BriefDescription": "Non Math instruction completed." }, { "EventCode": "0x401E0", "EventName": "PM_MRK_INST_CMPL", - "BriefDescription": "marked instruction completed." + "BriefDescription": "Marked instruction completed." }, { "EventCode": "0x400FE", only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/pmu-events/arch/powerpc/power10/memory.json +++ linux-6.2.0/tools/perf/pmu-events/arch/powerpc/power10/memory.json @@ -47,7 +47,7 @@ { "EventCode": "0x10062", "EventName": "PM_LD_L3MISS_PEND_CYC", - "BriefDescription": "Cycles L3 miss was pending for this thread." + "BriefDescription": "Cycles in which an L3 miss was pending for this thread." }, { "EventCode": "0x20010", @@ -132,7 +132,7 @@ { "EventCode": "0x300FC", "EventName": "PM_DTLB_MISS", - "BriefDescription": "The DPTEG required for the load/store instruction in execution was missing from the TLB. It includes pages of all sizes for demand and prefetch activity." + "BriefDescription": "The DPTEG required for the load/store instruction in execution was missing from the TLB. This event only counts for demand misses." }, { "EventCode": "0x4D02C", @@ -142,7 +142,7 @@ { "EventCode": "0x4003E", "EventName": "PM_LD_CMPL", - "BriefDescription": "Loads completed." + "BriefDescription": "Load instruction completed." }, { "EventCode": "0x4C040", only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/pmu-events/arch/powerpc/power10/metrics.json +++ linux-6.2.0/tools/perf/pmu-events/arch/powerpc/power10/metrics.json @@ -454,12 +454,6 @@ "MetricName": "LOADS_PER_INST" }, { - "BriefDescription": "Average number of finished stores per completed instruction", - "MetricExpr": "PM_ST_FIN / PM_RUN_INST_CMPL", - "MetricGroup": "General", - "MetricName": "STORES_PER_INST" - }, - { "BriefDescription": "Percentage of demand loads that reloaded from beyond the L2 per completed instruction", "MetricExpr": "PM_DATA_FROM_L2MISS / PM_RUN_INST_CMPL * 100", "MetricGroup": "dL1_Reloads", only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/pmu-events/arch/powerpc/power10/others.json +++ linux-6.2.0/tools/perf/pmu-events/arch/powerpc/power10/others.json @@ -2,12 +2,12 @@ { "EventCode": "0x10016", "EventName": "PM_VSU0_ISSUE", - "BriefDescription": "VSU instructions issued to VSU pipe 0." + "BriefDescription": "VSU instruction issued to VSU pipe 0." }, { "EventCode": "0x1001C", "EventName": "PM_ULTRAVISOR_INST_CMPL", - "BriefDescription": "PowerPC instructions that completed while the thread was in ultravisor state." + "BriefDescription": "PowerPC instruction completed while the thread was in ultravisor state." }, { "EventCode": "0x100F0", @@ -17,12 +17,12 @@ { "EventCode": "0x10134", "EventName": "PM_MRK_ST_DONE_L2", - "BriefDescription": "Marked stores completed in L2 (RC machine done)." + "BriefDescription": "Marked store completed in L2." }, { "EventCode": "0x1505E", "EventName": "PM_LD_HIT_L1", - "BriefDescription": "Loads that finished without experiencing an L1 miss." + "BriefDescription": "Load finished without experiencing an L1 miss." }, { "EventCode": "0x1F056", @@ -30,11 +30,6 @@ "BriefDescription": "Cycles in which Superslice 0 dispatches either 1 or 2 instructions." }, { - "EventCode": "0x1F15C", - "EventName": "PM_MRK_STCX_L2_CYC", - "BriefDescription": "Cycles spent in the nest portion of a marked Stcx instruction. It starts counting when the operation starts to drain to the L2 and it stops counting when the instruction retires from the Instruction Completion Table (ICT) in the Instruction Sequencing Unit (ISU)." - }, - { "EventCode": "0x10066", "EventName": "PM_ADJUNCT_CYC", "BriefDescription": "Cycles in which the thread is in Adjunct state. MSR[S HV PR] bits = 011." @@ -42,7 +37,7 @@ { "EventCode": "0x101E4", "EventName": "PM_MRK_L1_ICACHE_MISS", - "BriefDescription": "Marked Instruction suffered an icache Miss." + "BriefDescription": "Marked instruction suffered an instruction cache miss." }, { "EventCode": "0x101EA", @@ -72,7 +67,7 @@ { "EventCode": "0x2E010", "EventName": "PM_ADJUNCT_INST_CMPL", - "BriefDescription": "PowerPC instructions that completed while the thread is in Adjunct state." + "BriefDescription": "PowerPC instruction completed while the thread was in Adjunct state." }, { "EventCode": "0x2E014", @@ -122,7 +117,7 @@ { "EventCode": "0x201E4", "EventName": "PM_MRK_DATA_FROM_L3MISS", - "BriefDescription": "The processor's data cache was reloaded from a source other than the local core's L1, L2, or L3 due to a demand miss for a marked load." + "BriefDescription": "The processor's L1 data cache was reloaded from beyond the local core's L3 due to a demand miss for a marked instruction." }, { "EventCode": "0x201E8", @@ -132,17 +127,17 @@ { "EventCode": "0x200F2", "EventName": "PM_INST_DISP", - "BriefDescription": "PowerPC instructions dispatched." + "BriefDescription": "PowerPC instruction dispatched." }, { "EventCode": "0x30132", "EventName": "PM_MRK_VSU_FIN", - "BriefDescription": "VSU marked instructions finished. Excludes simple FX instructions issued to the Store Unit." + "BriefDescription": "VSU marked instruction finished. Excludes simple FX instructions issued to the Store Unit." }, { "EventCode": "0x30038", "EventName": "PM_EXEC_STALL_DMISS_LMEM", - "BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for a load miss to resolve from the local memory, local OpenCapp cache, or local OpenCapp memory." + "BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for a load miss to resolve from the local memory, local OpenCAPI cache, or local OpenCAPI memory." }, { "EventCode": "0x3F04A", @@ -152,12 +147,12 @@ { "EventCode": "0x3405A", "EventName": "PM_PRIVILEGED_INST_CMPL", - "BriefDescription": "PowerPC Instructions that completed while the thread is in Privileged state." + "BriefDescription": "PowerPC instruction completed while the thread was in Privileged state." }, { "EventCode": "0x3F150", "EventName": "PM_MRK_ST_DRAIN_CYC", - "BriefDescription": "cycles to drain st from core to L2." + "BriefDescription": "Cycles in which the marked store drained from the core to the L2." }, { "EventCode": "0x3F054", @@ -182,7 +177,7 @@ { "EventCode": "0x4001C", "EventName": "PM_VSU_FIN", - "BriefDescription": "VSU instructions finished." + "BriefDescription": "VSU instruction finished." }, { "EventCode": "0x4C01A", @@ -197,7 +192,7 @@ { "EventCode": "0x4D022", "EventName": "PM_HYPERVISOR_INST_CMPL", - "BriefDescription": "PowerPC instructions that completed while the thread is in hypervisor state." + "BriefDescription": "PowerPC instruction completed while the thread was in hypervisor state." }, { "EventCode": "0x4D026", @@ -212,32 +207,32 @@ { "EventCode": "0x40030", "EventName": "PM_INST_FIN", - "BriefDescription": "Instructions finished." + "BriefDescription": "Instruction finished." }, { "EventCode": "0x44146", "EventName": "PM_MRK_STCX_CORE_CYC", - "BriefDescription": "Cycles spent in the core portion of a marked Stcx instruction. It starts counting when the instruction is decoded and stops counting when it drains into the L2." + "BriefDescription": "Cycles spent in the core portion of a marked STCX instruction. It starts counting when the instruction is decoded and stops counting when it drains into the L2." }, { "EventCode": "0x44054", "EventName": "PM_VECTOR_LD_CMPL", - "BriefDescription": "Vector load instructions completed." + "BriefDescription": "Vector load instruction completed." }, { "EventCode": "0x45054", "EventName": "PM_FMA_CMPL", - "BriefDescription": "Two floating point instructions completed (FMA class of instructions: fmadd, fnmadd, fmsub, fnmsub). Scalar instructions only." + "BriefDescription": "Two floating point instruction completed (FMA class of instructions: fmadd, fnmadd, fmsub, fnmsub). Scalar instructions only." }, { "EventCode": "0x45056", "EventName": "PM_SCALAR_FLOP_CMPL", - "BriefDescription": "Scalar floating point instructions completed." + "BriefDescription": "Scalar floating point instruction completed." }, { "EventCode": "0x4505C", "EventName": "PM_MATH_FLOP_CMPL", - "BriefDescription": "Math floating point instructions completed." + "BriefDescription": "Math floating point instruction completed." }, { "EventCode": "0x4D05E", @@ -252,21 +247,21 @@ { "EventCode": "0x401E6", "EventName": "PM_MRK_INST_FROM_L3MISS", - "BriefDescription": "The processor's instruction cache was reloaded from a source other than the local core's L1, L2, or L3 due to a demand miss for a marked instruction." + "BriefDescription": "The processor's instruction cache was reloaded from beyond the local core's L3 due to a demand miss for a marked instruction." }, { "EventCode": "0x401E8", "EventName": "PM_MRK_DATA_FROM_L2MISS", - "BriefDescription": "The processor's data cache was reloaded from a source other than the local core's L1 or L2 due to a demand miss for a marked load." + "BriefDescription": "The processor's L1 data cache was reloaded from a source beyond the local core's L2 due to a demand miss for a marked instruction." }, { "EventCode": "0x400F0", "EventName": "PM_LD_DEMAND_MISS_L1_FIN", - "BriefDescription": "Load Missed L1, counted at finish time." + "BriefDescription": "Load missed L1, counted at finish time." }, { "EventCode": "0x400FA", "EventName": "PM_RUN_INST_CMPL", - "BriefDescription": "Completed PowerPC instructions gated by the run latch." + "BriefDescription": "PowerPC instruction completed while the run latch is set." } ] only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/pmu-events/arch/powerpc/power10/pipeline.json +++ linux-6.2.0/tools/perf/pmu-events/arch/powerpc/power10/pipeline.json @@ -2,7 +2,7 @@ { "EventCode": "0x100FE", "EventName": "PM_INST_CMPL", - "BriefDescription": "PowerPC instructions completed." + "BriefDescription": "PowerPC instruction completed." }, { "EventCode": "0x1000C", @@ -12,7 +12,7 @@ { "EventCode": "0x1000E", "EventName": "PM_MMA_ISSUED", - "BriefDescription": "MMA instructions issued." + "BriefDescription": "MMA instruction issued." }, { "EventCode": "0x10012", @@ -107,7 +107,7 @@ { "EventCode": "0x2D012", "EventName": "PM_VSU1_ISSUE", - "BriefDescription": "VSU instructions issued to VSU pipe 1." + "BriefDescription": "VSU instruction issued to VSU pipe 1." }, { "EventCode": "0x2D018", @@ -122,7 +122,7 @@ { "EventCode": "0x2E01E", "EventName": "PM_EXEC_STALL_NTC_FLUSH", - "BriefDescription": "Cycles in which the oldest instruction in the pipeline was executing in any unit before it was flushed. Note that if the flush of the oldest instruction happens after finish, the cycles from dispatch to issue will be included in PM_DISP_STALL and the cycles from issue to finish will be included in PM_EXEC_STALL and its corresponding children. This event will also count cycles when the previous NTF instruction is still completing and the new NTF instruction is stalled at dispatch." + "BriefDescription": "Cycles in which the oldest instruction in the pipeline was executing in any unit before it was flushed. Note that if the flush of the oldest instruction happens after finish, the cycles from dispatch to issue will be included in PM_DISP_STALL and the cycles from issue to finish will be included in PM_EXEC_STALL and its corresponding children. This event will also count cycles when the previous next-to-finish (NTF) instruction is still completing and the new NTF instruction is stalled at dispatch." }, { "EventCode": "0x2013C", @@ -137,7 +137,7 @@ { "EventCode": "0x201E2", "EventName": "PM_MRK_LD_MISS_L1", - "BriefDescription": "Marked DL1 Demand Miss counted at finish time." + "BriefDescription": "Marked demand data load miss counted at finish time." }, { "EventCode": "0x200F4", @@ -172,7 +172,7 @@ { "EventCode": "0x30028", "EventName": "PM_CMPL_STALL_MEM_ECC", - "BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for the non-speculative finish of either a stcx waiting for its result or a load waiting for non-critical sectors of data and ECC." + "BriefDescription": "Cycles in which the oldest instruction in the pipeline was waiting for the non-speculative finish of either a STCX waiting for its result or a load waiting for non-critical sectors of data and ECC." }, { "EventCode": "0x30036", @@ -187,17 +187,12 @@ { "EventCode": "0x3F044", "EventName": "PM_VSU2_ISSUE", - "BriefDescription": "VSU instructions issued to VSU pipe 2." + "BriefDescription": "VSU instruction issued to VSU pipe 2." }, { "EventCode": "0x30058", "EventName": "PM_TLBIE_FIN", - "BriefDescription": "TLBIE instructions finished in the LSU. Two TLBIEs can finish each cycle. All will be counted." - }, - { - "EventCode": "0x3D058", - "EventName": "PM_SCALAR_FSQRT_FDIV_ISSUE", - "BriefDescription": "Scalar versions of four floating point operations: fdiv,fsqrt (xvdivdp, xvdivsp, xvsqrtdp, xvsqrtsp)." + "BriefDescription": "TLBIE instruction finished in the LSU. Two TLBIEs can finish each cycle. All will be counted." }, { "EventCode": "0x30066", @@ -252,7 +247,7 @@ { "EventCode": "0x4E012", "EventName": "PM_EXEC_STALL_UNKNOWN", - "BriefDescription": "Cycles in which the oldest instruction in the pipeline completed without an ntf_type pulse. The ntf_pulse was missed by the ISU because the NTF finishes and completions came too close together." + "BriefDescription": "Cycles in which the oldest instruction in the pipeline completed without an ntf_type pulse. The ntf_pulse was missed by the ISU because the next-to-finish (NTF) instruction finishes and completions came too close together." }, { "EventCode": "0x4D020", @@ -267,12 +262,7 @@ { "EventCode": "0x45058", "EventName": "PM_IC_MISS_CMPL", - "BriefDescription": "Non-speculative icache miss, counted at completion." - }, - { - "EventCode": "0x4D050", - "EventName": "PM_VSU_NON_FLOP_CMPL", - "BriefDescription": "Non-floating point VSU instructions completed." + "BriefDescription": "Non-speculative instruction cache miss, counted at completion." }, { "EventCode": "0x4D052", only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/pmu-events/arch/powerpc/power10/pmc.json +++ linux-6.2.0/tools/perf/pmu-events/arch/powerpc/power10/pmc.json @@ -12,11 +12,11 @@ { "EventCode": "0x45052", "EventName": "PM_4FLOP_CMPL", - "BriefDescription": "Four floating point instructions completed (fadd, fmul, fsub, fcmp, fsel, fabs, fnabs, fres, fsqrte, fneg)." + "BriefDescription": "Four floating point instruction completed (fadd, fmul, fsub, fcmp, fsel, fabs, fnabs, fres, fsqrte, fneg)." }, { "EventCode": "0x4D054", "EventName": "PM_8FLOP_CMPL", - "BriefDescription": "Four Double Precision vector instructions completed." + "BriefDescription": "Four Double Precision vector instruction completed." } ] only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/pmu-events/arch/powerpc/power10/translation.json +++ linux-6.2.0/tools/perf/pmu-events/arch/powerpc/power10/translation.json @@ -5,11 +5,6 @@ "BriefDescription": "Marked Start probe nop (AND R0,R0,R0) completed." }, { - "EventCode": "0x20016", - "EventName": "PM_ST_FIN", - "BriefDescription": "Store finish count. Includes speculative activity." - }, - { "EventCode": "0x20018", "EventName": "PM_ST_FWD", "BriefDescription": "Store forwards that finished." @@ -17,7 +12,7 @@ { "EventCode": "0x2011C", "EventName": "PM_MRK_NTF_CYC", - "BriefDescription": "Cycles during which the marked instruction is the oldest in the pipeline (NTF or NTC)." + "BriefDescription": "Cycles in which the marked instruction is the oldest in the pipeline (next-to-finish or next-to-complete)." }, { "EventCode": "0x2E01C", @@ -37,7 +32,7 @@ { "EventCode": "0x200FE", "EventName": "PM_DATA_FROM_L2MISS", - "BriefDescription": "The processor's data cache was reloaded from a source other than the local core's L1 or L2 due to a demand miss." + "BriefDescription": "The processor's L1 data cache was reloaded from a source beyond the local core's L2 due to a demand miss." }, { "EventCode": "0x30010", @@ -52,6 +47,6 @@ { "EventCode": "0x4D05C", "EventName": "PM_DPP_FLOP_CMPL", - "BriefDescription": "Double-Precision or Quad-Precision instructions completed." + "BriefDescription": "Double-Precision or Quad-Precision instruction completed." } ] only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/tests/shell/stat_bpf_counters.sh +++ linux-6.2.0/tools/perf/tests/shell/stat_bpf_counters.sh @@ -22,10 +22,10 @@ } # skip if --bpf-counters is not supported -if ! perf stat --bpf-counters true > /dev/null 2>&1; then +if ! perf stat -e cycles --bpf-counters true > /dev/null 2>&1; then if [ "$1" = "-v" ]; then echo "Skipping: --bpf-counters not supported" - perf --no-pager stat --bpf-counters true || true + perf --no-pager stat -e cycles --bpf-counters true || true fi exit 2 fi only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/tests/shell/stat_bpf_counters_cgrp.sh +++ linux-6.2.0/tools/perf/tests/shell/stat_bpf_counters_cgrp.sh @@ -25,22 +25,22 @@ find_cgroups() { # try usual systemd slices first - if [ -d /sys/fs/cgroup/system.slice -a -d /sys/fs/cgroup/user.slice ]; then + if [ -d /sys/fs/cgroup/system.slice ] && [ -d /sys/fs/cgroup/user.slice ]; then test_cgroups="system.slice,user.slice" return fi # try root and self cgroups - local self_cgrp=$(grep perf_event /proc/self/cgroup | cut -d: -f3) - if [ -z ${self_cgrp} ]; then + find_cgroups_self_cgrp=$(grep perf_event /proc/self/cgroup | cut -d: -f3) + if [ -z ${find_cgroups_self_cgrp} ]; then # cgroup v2 doesn't specify perf_event - self_cgrp=$(grep ^0: /proc/self/cgroup | cut -d: -f3) + find_cgroups_self_cgrp=$(grep ^0: /proc/self/cgroup | cut -d: -f3) fi - if [ -z ${self_cgrp} ]; then + if [ -z ${find_cgroups_self_cgrp} ]; then test_cgroups="/" else - test_cgroups="/,${self_cgrp}" + test_cgroups="/,${find_cgroups_self_cgrp}" fi } @@ -48,13 +48,11 @@ # Just check if it runs without failure and has non-zero results. check_system_wide_counted() { - local output - - output=$(perf stat -a --bpf-counters --for-each-cgroup ${test_cgroups} -e cpu-clock -x, sleep 1 2>&1) - if echo ${output} | grep -q -F "&1) + if echo ${check_system_wide_counted_output} | grep -q -F "&1) - if echo ${output} | grep -q -F "&1) + if echo ${check_cpu_list_counted_output} | grep -q -F "has_children; } -static bool hist_browser__he_selection_unfolded(struct hist_browser *browser) -{ - return browser->he_selection ? browser->he_selection->unfolded : false; -} - static bool hist_browser__selection_unfolded(struct hist_browser *browser) { struct hist_entry *he = browser->he_selection; @@ -584,8 +579,8 @@ return n; } -static void __hist_entry__set_folding(struct hist_entry *he, - struct hist_browser *hb, bool unfold) +static void hist_entry__set_folding(struct hist_entry *he, + struct hist_browser *hb, bool unfold) { hist_entry__init_have_children(he); he->unfolded = unfold ? he->has_children : false; @@ -603,34 +598,12 @@ he->nr_rows = 0; } -static void hist_entry__set_folding(struct hist_entry *he, - struct hist_browser *browser, bool unfold) -{ - double percent; - - percent = hist_entry__get_percent_limit(he); - if (he->filtered || percent < browser->min_pcnt) - return; - - __hist_entry__set_folding(he, browser, unfold); - - if (!he->depth || unfold) - browser->nr_hierarchy_entries++; - if (he->leaf) - browser->nr_callchain_rows += he->nr_rows; - else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) { - browser->nr_hierarchy_entries++; - he->has_no_entry = true; - he->nr_rows = 1; - } else - he->has_no_entry = false; -} - static void __hist_browser__set_folding(struct hist_browser *browser, bool unfold) { struct rb_node *nd; struct hist_entry *he; + double percent; nd = rb_first_cached(&browser->hists->entries); while (nd) { @@ -640,6 +613,21 @@ nd = __rb_hierarchy_next(nd, HMD_FORCE_CHILD); hist_entry__set_folding(he, browser, unfold); + + percent = hist_entry__get_percent_limit(he); + if (he->filtered || percent < browser->min_pcnt) + continue; + + if (!he->depth || unfold) + browser->nr_hierarchy_entries++; + if (he->leaf) + browser->nr_callchain_rows += he->nr_rows; + else if (unfold && !hist_entry__has_hierarchy_children(he, browser->min_pcnt)) { + browser->nr_hierarchy_entries++; + he->has_no_entry = true; + he->nr_rows = 1; + } else + he->has_no_entry = false; } } @@ -659,8 +647,10 @@ if (!browser->he_selection) return; - hist_entry__set_folding(browser->he_selection, browser, unfold); - browser->b.nr_entries = hist_browser__nr_entries(browser); + if (unfold == browser->he_selection->unfolded) + return; + + hist_browser__toggle_fold(browser); } static void ui_browser__warn_lost_events(struct ui_browser *browser) @@ -732,8 +722,8 @@ hist_browser__set_folding(browser, true); break; case 'e': - /* Expand the selected entry. */ - hist_browser__set_folding_selected(browser, !hist_browser__he_selection_unfolded(browser)); + /* Toggle expand/collapse the selected entry. */ + hist_browser__toggle_fold(browser); break; case 'H': browser->show_headers = !browser->show_headers; @@ -1779,7 +1769,7 @@ hists_browser__scnprintf_hierarchy_headers(browser, headers, sizeof(headers)); - ui_browser__gotorc(&browser->b, 0, 0); + ui_browser__gotorc_title(&browser->b, 0, 0); ui_browser__set_color(&browser->b, HE_COLORSET_ROOT); ui_browser__write_nstring(&browser->b, headers, browser->b.width + 1); } only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/util/annotate.c +++ linux-6.2.0/tools/perf/util/annotate.c @@ -1756,8 +1756,11 @@ perf_exe(tpath, sizeof(tpath)); bfdf = bfd_openr(tpath, NULL); - assert(bfdf); - assert(bfd_check_format(bfdf, bfd_object)); + if (bfdf == NULL) + abort(); + + if (!bfd_check_format(bfdf, bfd_object)) + abort(); s = open_memstream(&buf, &buf_size); if (!s) { @@ -1805,7 +1808,8 @@ #else disassemble = disassembler(bfdf); #endif - assert(disassemble); + if (disassemble == NULL) + abort(); fflush(s); do { only in patch2: unchanged: --- linux-6.2.0.orig/tools/perf/util/header.c +++ linux-6.2.0/tools/perf/util/header.c @@ -4348,7 +4348,8 @@ union perf_event *event, struct evlist **pevlist) { - u32 i, ids, n_ids; + u32 i, n_ids; + u64 *ids; struct evsel *evsel; struct evlist *evlist = *pevlist; @@ -4364,9 +4365,8 @@ evlist__add(evlist, evsel); - ids = event->header.size; - ids -= (void *)&event->attr.id - (void *)event; - n_ids = ids / sizeof(u64); + n_ids = event->header.size - sizeof(event->header) - event->attr.attr.size; + n_ids = n_ids / sizeof(u64); /* * We don't have the cpu and thread maps on the header, so * for allocating the perf_sample_id table we fake 1 cpu and @@ -4375,8 +4375,9 @@ if (perf_evsel__alloc_id(&evsel->core, 1, n_ids)) return -ENOMEM; + ids = (void *)&event->attr.attr + event->attr.attr.size; for (i = 0; i < n_ids; i++) { - perf_evlist__id_add(&evlist->core, &evsel->core, 0, i, event->attr.id[i]); + perf_evlist__id_add(&evlist->core, &evsel->core, 0, i, ids[i]); } return 0; only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/memblock/tests/basic_api.c +++ linux-6.2.0/tools/testing/memblock/tests/basic_api.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later +#include "basic_api.h" #include #include -#include "basic_api.h" #define EXPECTED_MEMBLOCK_REGIONS 128 #define FUNC_ADD "memblock_add" only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/memblock/tests/common.h +++ linux-6.2.0/tools/testing/memblock/tests/common.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/radix-tree/multiorder.c +++ linux-6.2.0/tools/testing/radix-tree/multiorder.c @@ -159,7 +159,7 @@ item_kill_tree(xa); } -bool stop_iteration = false; +bool stop_iteration; static void *creator_func(void *ptr) { @@ -201,6 +201,7 @@ pthread_t worker_thread[num_threads]; int i; + stop_iteration = false; pthread_create(&worker_thread[0], NULL, &creator_func, xa); for (i = 1; i < num_threads; i++) pthread_create(&worker_thread[i], NULL, &iterator_func, xa); @@ -211,6 +212,61 @@ item_kill_tree(xa); } +static void *load_creator(void *ptr) +{ + /* 'order' is set up to ensure we have sibling entries */ + unsigned int order; + struct radix_tree_root *tree = ptr; + int i; + + rcu_register_thread(); + item_insert_order(tree, 3 << RADIX_TREE_MAP_SHIFT, 0); + item_insert_order(tree, 2 << RADIX_TREE_MAP_SHIFT, 0); + for (i = 0; i < 10000; i++) { + for (order = 1; order < RADIX_TREE_MAP_SHIFT; order++) { + unsigned long index = (3 << RADIX_TREE_MAP_SHIFT) - + (1 << order); + item_insert_order(tree, index, order); + item_delete_rcu(tree, index); + } + } + rcu_unregister_thread(); + + stop_iteration = true; + return NULL; +} + +static void *load_worker(void *ptr) +{ + unsigned long index = (3 << RADIX_TREE_MAP_SHIFT) - 1; + + rcu_register_thread(); + while (!stop_iteration) { + struct item *item = xa_load(ptr, index); + assert(!xa_is_internal(item)); + } + rcu_unregister_thread(); + + return NULL; +} + +static void load_race(struct xarray *xa) +{ + const int num_threads = sysconf(_SC_NPROCESSORS_ONLN) * 4; + pthread_t worker_thread[num_threads]; + int i; + + stop_iteration = false; + pthread_create(&worker_thread[0], NULL, &load_creator, xa); + for (i = 1; i < num_threads; i++) + pthread_create(&worker_thread[i], NULL, &load_worker, xa); + + for (i = 0; i < num_threads; i++) + pthread_join(worker_thread[i], NULL); + + item_kill_tree(xa); +} + static DEFINE_XARRAY(array); void multiorder_checks(void) @@ -218,12 +274,20 @@ multiorder_iteration(&array); multiorder_tagged_iteration(&array); multiorder_iteration_race(&array); + load_race(&array); radix_tree_cpu_dead(0); } -int __weak main(void) +int __weak main(int argc, char **argv) { + int opt; + + while ((opt = getopt(argc, argv, "ls:v")) != -1) { + if (opt == 'v') + test_verbose++; + } + rcu_register_thread(); radix_tree_init(); multiorder_checks(); only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/bpf/benchs/run_bench_rename.sh +++ linux-6.2.0/tools/testing/selftests/bpf/benchs/run_bench_rename.sh @@ -2,7 +2,7 @@ set -eufo pipefail -for i in base kprobe kretprobe rawtp fentry fexit fmodret +for i in base kprobe kretprobe rawtp fentry fexit do summary=$(sudo ./bench -w2 -d5 -a rename-$i | tail -n1 | cut -d'(' -f1 | cut -d' ' -f3-) printf "%-10s: %s\n" $i "$summary" only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/bpf/prog_tests/bpf_nf.c +++ linux-6.2.0/tools/testing/selftests/bpf/prog_tests/bpf_nf.c @@ -123,12 +123,13 @@ ASSERT_EQ(skel->data->test_snat_addr, 0, "Test for source natting"); ASSERT_EQ(skel->data->test_dnat_addr, 0, "Test for destination natting"); end: - if (srv_client_fd != -1) - close(srv_client_fd); if (client_fd != -1) close(client_fd); + if (srv_client_fd != -1) + close(srv_client_fd); if (srv_fd != -1) close(srv_fd); + snprintf(cmd, sizeof(cmd), iptables, "-D"); system(cmd); test_bpf_nf__destroy(skel); only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/bpf/prog_tests/kfunc_call.c +++ linux-6.2.0/tools/testing/selftests/bpf/prog_tests/kfunc_call.c @@ -171,8 +171,8 @@ case tc_test: topts.data_in = &pkt_v4; topts.data_size_in = sizeof(pkt_v4); - break; topts.repeat = 1; + break; } skel = kfunc_call_fail__open_opts(&opts); only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/ftrace/ftracetest +++ linux-6.2.0/tools/testing/selftests/ftrace/ftracetest @@ -30,6 +30,9 @@ # kselftest skip code is 4 err_skip=4 +# umount required +UMOUNT_DIR="" + # cgroup RT scheduling prevents chrt commands from succeeding, which # induces failures in test wakeup tests. Disable for the duration of # the tests. @@ -44,6 +47,9 @@ cleanup() { echo $sched_rt_runtime_orig > $sched_rt_runtime + if [ -n "${UMOUNT_DIR}" ]; then + umount ${UMOUNT_DIR} ||: + fi } errexit() { # message @@ -155,11 +161,13 @@ mount -t tracefs nodev /sys/kernel/tracing || errexit "Failed to mount /sys/kernel/tracing" TRACING_DIR="/sys/kernel/tracing" + UMOUNT_DIR=${TRACING_DIR} # If debugfs exists, then so does /sys/kernel/debug elif [ -d "/sys/kernel/debug" ]; then mount -t debugfs nodev /sys/kernel/debug || errexit "Failed to mount /sys/kernel/debug" TRACING_DIR="/sys/kernel/debug/tracing" + UMOUNT_DIR=${TRACING_DIR} else err_ret=$err_skip errexit "debugfs and tracefs are not configured in this kernel" only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc +++ linux-6.2.0/tools/testing/selftests/ftrace/test.d/instances/instance-event.tc @@ -39,7 +39,7 @@ instance_set() { while :; do - echo 1 > foo/events/sched/sched_switch + echo 1 > foo/events/sched/sched_switch/enable done 2> /dev/null } only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/futex/functional/futex_wait_timeout.c +++ linux-6.2.0/tools/testing/selftests/futex/functional/futex_wait_timeout.c @@ -24,6 +24,7 @@ static long timeout_ns = 100000; /* 100us default timeout */ static futex_t futex_pi; +static pthread_barrier_t barrier; void usage(char *prog) { @@ -48,6 +49,8 @@ if (ret != 0) error("futex_lock_pi failed\n", ret); + pthread_barrier_wait(&barrier); + /* Blocks forever */ ret = futex_wait(&lock, 0, NULL, 0); error("futex_wait failed\n", ret); @@ -130,6 +133,7 @@ basename(argv[0])); ksft_print_msg("\tArguments: timeout=%ldns\n", timeout_ns); + pthread_barrier_init(&barrier, NULL, 2); pthread_create(&thread, NULL, get_pi_lock, NULL); /* initialize relative timeout */ @@ -163,6 +167,9 @@ res = futex_wait_requeue_pi(&f1, f1, &futex_pi, &to, 0); test_timeout(res, &ret, "futex_wait_requeue_pi monotonic", ETIMEDOUT); + /* Wait until the other thread calls futex_lock_pi() */ + pthread_barrier_wait(&barrier); + pthread_barrier_destroy(&barrier); /* * FUTEX_LOCK_PI with CLOCK_REALTIME * Due to historical reasons, FUTEX_LOCK_PI supports only realtime only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/kselftest_deps.sh +++ linux-6.2.0/tools/testing/selftests/kselftest_deps.sh @@ -46,11 +46,11 @@ print_targets=0 while getopts "p" arg; do - case $arg in - p) + case $arg in + p) print_targets=1 shift;; - esac + esac done if [ $# -eq 0 ] @@ -92,6 +92,10 @@ # Get all TARGETS from selftests Makefile targets=$(grep -E "^TARGETS +|^TARGETS =" Makefile | cut -d "=" -f2) +# Initially, in LDLIBS related lines, the dep checker needs +# to ignore lines containing the following strings: +filter="\$(VAR_LDLIBS)\|pkg-config\|PKG_CONFIG\|IOURING_EXTRA_LIBS" + # Single test case if [ $# -eq 2 ] then @@ -100,6 +104,8 @@ l1_test $test l2_test $test l3_test $test + l4_test $test + l5_test $test print_results $1 $2 exit $? @@ -113,7 +119,7 @@ # Append space at the end of the list to append more tests. l1_tests=$(grep -r --include=Makefile "^LDLIBS" | \ - grep -v "VAR_LDLIBS" | awk -F: '{print $1}') + grep -v "$filter" | awk -F: '{print $1}' | uniq) # Level 2: LDLIBS set dynamically. # @@ -126,7 +132,7 @@ # Append space at the end of the list to append more tests. l2_tests=$(grep -r --include=Makefile ": LDLIBS" | \ - grep -v "VAR_LDLIBS" | awk -F: '{print $1}') + grep -v "$filter" | awk -F: '{print $1}' | uniq) # Level 3 # memfd and others use pkg-config to find mount and fuse libs @@ -138,11 +144,32 @@ # VAR_LDLIBS := $(shell pkg-config fuse --libs 2>/dev/null) l3_tests=$(grep -r --include=Makefile "^VAR_LDLIBS" | \ - grep -v "pkg-config" | awk -F: '{print $1}') + grep -v "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq) -#echo $l1_tests -#echo $l2_1_tests -#echo $l3_tests +# Level 4 +# some tests may fall back to default using `|| echo -l` +# if pkg-config doesn't find the libs, instead of using VAR_LDLIBS +# as per level 3 checks. +# e.g: +# netfilter/Makefile +# LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl) +l4_tests=$(grep -r --include=Makefile "^LDLIBS" | \ + grep "pkg-config\|PKG_CONFIG" | awk -F: '{print $1}' | uniq) + +# Level 5 +# some tests may use IOURING_EXTRA_LIBS to add extra libs to LDLIBS, +# which in turn may be defined in a sub-Makefile +# e.g.: +# mm/Makefile +# $(OUTPUT)/gup_longterm: LDLIBS += $(IOURING_EXTRA_LIBS) +l5_tests=$(grep -r --include=Makefile "LDLIBS +=.*\$(IOURING_EXTRA_LIBS)" | \ + awk -F: '{print $1}' | uniq) + +#echo l1_tests $l1_tests +#echo l2_tests $l2_tests +#echo l3_tests $l3_tests +#echo l4_tests $l4_tests +#echo l5_tests $l5_tests all_tests print_results $1 $2 @@ -164,24 +191,32 @@ for test in $l3_tests; do l3_test $test done + + for test in $l4_tests; do + l4_test $test + done + + for test in $l5_tests; do + l5_test $test + done } # Use same parsing used for l1_tests and pick libraries this time. l1_test() { test_libs=$(grep --include=Makefile "^LDLIBS" $test | \ - grep -v "VAR_LDLIBS" | \ + grep -v "$filter" | \ sed -e 's/\:/ /' | \ sed -e 's/+/ /' | cut -d "=" -f 2) check_libs $test $test_libs } -# Use same parsing used for l2__tests and pick libraries this time. +# Use same parsing used for l2_tests and pick libraries this time. l2_test() { test_libs=$(grep --include=Makefile ": LDLIBS" $test | \ - grep -v "VAR_LDLIBS" | \ + grep -v "$filter" | \ sed -e 's/\:/ /' | sed -e 's/+/ /' | \ cut -d "=" -f 2) @@ -196,6 +231,24 @@ check_libs $test $test_libs } + +l4_test() +{ + test_libs=$(grep --include=Makefile "^VAR_LDLIBS\|^LDLIBS" $test | \ + grep "\(pkg-config\|PKG_CONFIG\).*|| echo " | \ + sed -e 's/.*|| echo //' | sed -e 's/)$//') + + check_libs $test $test_libs +} + +l5_test() +{ + tests=$(find $(dirname "$test") -type f -name "*.mk") + test_libs=$(grep "^IOURING_EXTRA_LIBS +\?=" $tests | \ + cut -d "=" -f 2) + + check_libs $test $test_libs +} check_libs() { only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/kselftest_harness.h +++ linux-6.2.0/tools/testing/selftests/kselftest_harness.h @@ -937,7 +937,11 @@ fprintf(TH_LOG_STREAM, "# %s: Test terminated by timeout\n", t->name); } else if (WIFEXITED(status)) { - if (t->termsig != -1) { + if (WEXITSTATUS(status) == 255) { + /* SKIP */ + t->passed = 1; + t->skip = 1; + } else if (t->termsig != -1) { t->passed = 0; fprintf(TH_LOG_STREAM, "# %s: Test exited normally instead of by signal (code: %d)\n", @@ -949,11 +953,6 @@ case 0: t->passed = 1; break; - /* SKIP */ - case 255: - t->passed = 1; - t->skip = 1; - break; /* Other failure, assume step report. */ default: t->passed = 0; only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/netfilter/audit_logread.c +++ linux-6.2.0/tools/testing/selftests/netfilter/audit_logread.c @@ -0,0 +1,165 @@ +// SPDX-License-Identifier: GPL-2.0 + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int fd; + +#define MAX_AUDIT_MESSAGE_LENGTH 8970 +struct audit_message { + struct nlmsghdr nlh; + union { + struct audit_status s; + char data[MAX_AUDIT_MESSAGE_LENGTH]; + } u; +}; + +int audit_recv(int fd, struct audit_message *rep) +{ + struct sockaddr_nl addr; + socklen_t addrlen = sizeof(addr); + int ret; + + do { + ret = recvfrom(fd, rep, sizeof(*rep), 0, + (struct sockaddr *)&addr, &addrlen); + } while (ret < 0 && errno == EINTR); + + if (ret < 0 || + addrlen != sizeof(addr) || + addr.nl_pid != 0 || + rep->nlh.nlmsg_type == NLMSG_ERROR) /* short-cut for now */ + return -1; + + return ret; +} + +int audit_send(int fd, uint16_t type, uint32_t key, uint32_t val) +{ + static int seq = 0; + struct audit_message msg = { + .nlh = { + .nlmsg_len = NLMSG_SPACE(sizeof(msg.u.s)), + .nlmsg_type = type, + .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK, + .nlmsg_seq = ++seq, + }, + .u.s = { + .mask = key, + .enabled = key == AUDIT_STATUS_ENABLED ? val : 0, + .pid = key == AUDIT_STATUS_PID ? val : 0, + } + }; + struct sockaddr_nl addr = { + .nl_family = AF_NETLINK, + }; + int ret; + + do { + ret = sendto(fd, &msg, msg.nlh.nlmsg_len, 0, + (struct sockaddr *)&addr, sizeof(addr)); + } while (ret < 0 && errno == EINTR); + + if (ret != (int)msg.nlh.nlmsg_len) + return -1; + return 0; +} + +int audit_set(int fd, uint32_t key, uint32_t val) +{ + struct audit_message rep = { 0 }; + int ret; + + ret = audit_send(fd, AUDIT_SET, key, val); + if (ret) + return ret; + + ret = audit_recv(fd, &rep); + if (ret < 0) + return ret; + return 0; +} + +int readlog(int fd) +{ + struct audit_message rep = { 0 }; + int ret = audit_recv(fd, &rep); + const char *sep = ""; + char *k, *v; + + if (ret < 0) + return ret; + + if (rep.nlh.nlmsg_type != AUDIT_NETFILTER_CFG) + return 0; + + /* skip the initial "audit(...): " part */ + strtok(rep.u.data, " "); + + while ((k = strtok(NULL, "="))) { + v = strtok(NULL, " "); + + /* these vary and/or are uninteresting, ignore */ + if (!strcmp(k, "pid") || + !strcmp(k, "comm") || + !strcmp(k, "subj")) + continue; + + /* strip the varying sequence number */ + if (!strcmp(k, "table")) + *strchrnul(v, ':') = '\0'; + + printf("%s%s=%s", sep, k, v); + sep = " "; + } + if (*sep) { + printf("\n"); + fflush(stdout); + } + return 0; +} + +void cleanup(int sig) +{ + audit_set(fd, AUDIT_STATUS_ENABLED, 0); + close(fd); + if (sig) + exit(0); +} + +int main(int argc, char **argv) +{ + struct sigaction act = { + .sa_handler = cleanup, + }; + + fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_AUDIT); + if (fd < 0) { + perror("Can't open netlink socket"); + return -1; + } + + if (sigaction(SIGTERM, &act, NULL) < 0 || + sigaction(SIGINT, &act, NULL) < 0) { + perror("Can't set signal handler"); + close(fd); + return -1; + } + + audit_set(fd, AUDIT_STATUS_ENABLED, 1); + audit_set(fd, AUDIT_STATUS_PID, getpid()); + + while (1) + readlog(fd); +} only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/netfilter/config +++ linux-6.2.0/tools/testing/selftests/netfilter/config @@ -6,3 +6,4 @@ CONFIG_NFT_MASQ=m CONFIG_NFT_FLOW_OFFLOAD=m CONFIG_NF_CT_NETLINK=m +CONFIG_AUDIT=y only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/netfilter/nft_audit.sh +++ linux-6.2.0/tools/testing/selftests/netfilter/nft_audit.sh @@ -0,0 +1,193 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Check that audit logs generated for nft commands are as expected. + +SKIP_RC=4 +RC=0 + +nft --version >/dev/null 2>&1 || { + echo "SKIP: missing nft tool" + exit $SKIP_RC +} + +logfile=$(mktemp) +rulefile=$(mktemp) +echo "logging into $logfile" +./audit_logread >"$logfile" & +logread_pid=$! +trap 'kill $logread_pid; rm -f $logfile $rulefile' EXIT +exec 3<"$logfile" + +do_test() { # (cmd, log) + echo -n "testing for cmd: $1 ... " + cat <&3 >/dev/null + $1 >/dev/null || exit 1 + sleep 0.1 + res=$(diff -a -u <(echo "$2") - <&3) + [ $? -eq 0 ] && { echo "OK"; return; } + echo "FAIL" + grep -v '^\(---\|+++\|@@\)' <<< "$res" + ((RC--)) +} + +nft flush ruleset + +# adding tables, chains and rules + +for table in t1 t2; do + do_test "nft add table $table" \ + "table=$table family=2 entries=1 op=nft_register_table" + + do_test "nft add chain $table c1" \ + "table=$table family=2 entries=1 op=nft_register_chain" + + do_test "nft add chain $table c2; add chain $table c3" \ + "table=$table family=2 entries=2 op=nft_register_chain" + + cmd="add rule $table c1 counter" + + do_test "nft $cmd" \ + "table=$table family=2 entries=1 op=nft_register_rule" + + do_test "nft $cmd; $cmd" \ + "table=$table family=2 entries=2 op=nft_register_rule" + + cmd="" + sep="" + for chain in c2 c3; do + for i in {1..3}; do + cmd+="$sep add rule $table $chain counter" + sep=";" + done + done + do_test "nft $cmd" \ + "table=$table family=2 entries=6 op=nft_register_rule" +done + +for ((i = 0; i < 500; i++)); do + echo "add rule t2 c3 counter accept comment \"rule $i\"" +done >$rulefile +do_test "nft -f $rulefile" \ +'table=t2 family=2 entries=500 op=nft_register_rule' + +# adding sets and elements + +settype='type inet_service; counter' +setelem='{ 22, 80, 443 }' +setblock="{ $settype; elements = $setelem; }" +do_test "nft add set t1 s $setblock" \ +"table=t1 family=2 entries=4 op=nft_register_set" + +do_test "nft add set t1 s2 $setblock; add set t1 s3 { $settype; }" \ +"table=t1 family=2 entries=5 op=nft_register_set" + +do_test "nft add element t1 s3 $setelem" \ +"table=t1 family=2 entries=3 op=nft_register_setelem" + +# adding counters + +do_test 'nft add counter t1 c1' \ +'table=t1 family=2 entries=1 op=nft_register_obj' + +do_test 'nft add counter t2 c1; add counter t2 c2' \ +'table=t2 family=2 entries=2 op=nft_register_obj' + +# adding/updating quotas + +do_test 'nft add quota t1 q1 { 10 bytes }' \ +'table=t1 family=2 entries=1 op=nft_register_obj' + +do_test 'nft add quota t2 q1 { 10 bytes }; add quota t2 q2 { 10 bytes }' \ +'table=t2 family=2 entries=2 op=nft_register_obj' + +# changing the quota value triggers obj update path +do_test 'nft add quota t1 q1 { 20 bytes }' \ +'table=t1 family=2 entries=1 op=nft_register_obj' + +# resetting rules + +do_test 'nft reset rules t1 c2' \ +'table=t1 family=2 entries=3 op=nft_reset_rule' + +do_test 'nft reset rules table t1' \ +'table=t1 family=2 entries=3 op=nft_reset_rule +table=t1 family=2 entries=3 op=nft_reset_rule +table=t1 family=2 entries=3 op=nft_reset_rule' + +do_test 'nft reset rules t2 c3' \ +'table=t2 family=2 entries=189 op=nft_reset_rule +table=t2 family=2 entries=188 op=nft_reset_rule +table=t2 family=2 entries=126 op=nft_reset_rule' + +do_test 'nft reset rules t2' \ +'table=t2 family=2 entries=3 op=nft_reset_rule +table=t2 family=2 entries=3 op=nft_reset_rule +table=t2 family=2 entries=186 op=nft_reset_rule +table=t2 family=2 entries=188 op=nft_reset_rule +table=t2 family=2 entries=129 op=nft_reset_rule' + +do_test 'nft reset rules' \ +'table=t1 family=2 entries=3 op=nft_reset_rule +table=t1 family=2 entries=3 op=nft_reset_rule +table=t1 family=2 entries=3 op=nft_reset_rule +table=t2 family=2 entries=3 op=nft_reset_rule +table=t2 family=2 entries=3 op=nft_reset_rule +table=t2 family=2 entries=180 op=nft_reset_rule +table=t2 family=2 entries=188 op=nft_reset_rule +table=t2 family=2 entries=135 op=nft_reset_rule' + +# resetting sets and elements + +elem=(22 ,80 ,443) +relem="" +for i in {1..3}; do + relem+="${elem[((i - 1))]}" + do_test "nft reset element t1 s { $relem }" \ + "table=t1 family=2 entries=$i op=nft_reset_setelem" +done + +do_test 'nft reset set t1 s' \ +'table=t1 family=2 entries=3 op=nft_reset_setelem' + +# deleting rules + +readarray -t handles < <(nft -a list chain t1 c1 | \ + sed -n 's/.*counter.* handle \(.*\)$/\1/p') + +do_test "nft delete rule t1 c1 handle ${handles[0]}" \ +'table=t1 family=2 entries=1 op=nft_unregister_rule' + +cmd='delete rule t1 c1 handle' +do_test "nft $cmd ${handles[1]}; $cmd ${handles[2]}" \ +'table=t1 family=2 entries=2 op=nft_unregister_rule' + +do_test 'nft flush chain t1 c2' \ +'table=t1 family=2 entries=3 op=nft_unregister_rule' + +do_test 'nft flush table t2' \ +'table=t2 family=2 entries=509 op=nft_unregister_rule' + +# deleting chains + +do_test 'nft delete chain t2 c2' \ +'table=t2 family=2 entries=1 op=nft_unregister_chain' + +# deleting sets and elements + +do_test 'nft delete element t1 s { 22 }' \ +'table=t1 family=2 entries=1 op=nft_unregister_setelem' + +do_test 'nft delete element t1 s { 80, 443 }' \ +'table=t1 family=2 entries=2 op=nft_unregister_setelem' + +do_test 'nft flush set t1 s2' \ +'table=t1 family=2 entries=3 op=nft_unregister_setelem' + +do_test 'nft delete set t1 s2' \ +'table=t1 family=2 entries=1 op=nft_unregister_set' + +do_test 'nft delete set t1 s3' \ +'table=t1 family=2 entries=1 op=nft_unregister_set' + +exit $RC only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/nolibc/nolibc-test.c +++ linux-6.2.0/tools/testing/selftests/nolibc/nolibc-test.c @@ -637,6 +637,35 @@ { 0 } }; +int is_setting_valid(char *test) +{ + int idx, len, test_len, valid = 0; + char delimiter; + + if (!test) + return valid; + + test_len = strlen(test); + + for (idx = 0; test_names[idx].name; idx++) { + len = strlen(test_names[idx].name); + if (test_len < len) + continue; + + if (strncmp(test, test_names[idx].name, len) != 0) + continue; + + delimiter = test[len]; + if (delimiter != ':' && delimiter != ',' && delimiter != '\0') + continue; + + valid = 1; + break; + } + + return valid; +} + int main(int argc, char **argv, char **envp) { int min = 0; @@ -662,10 +691,10 @@ * syscall:5-15[:.*],stdlib:8-10 */ test = argv[1]; - if (!test) + if (!is_setting_valid(test)) test = getenv("NOLIBC_TEST"); - if (test) { + if (is_setting_valid(test)) { char *comma, *colon, *dash, *value; do { only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/powerpc/Makefile +++ linux-6.2.0/tools/testing/selftests/powerpc/Makefile @@ -45,28 +45,27 @@ include ../lib.mk override define RUN_TESTS - @for TARGET in $(SUB_DIRS); do \ + +@for TARGET in $(SUB_DIRS); do \ BUILD_TARGET=$(OUTPUT)/$$TARGET; \ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests;\ done; endef override define INSTALL_RULE - @for TARGET in $(SUB_DIRS); do \ + +@for TARGET in $(SUB_DIRS); do \ BUILD_TARGET=$(OUTPUT)/$$TARGET; \ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install;\ done; endef -override define EMIT_TESTS - @for TARGET in $(SUB_DIRS); do \ +emit_tests: + +@for TARGET in $(SUB_DIRS); do \ BUILD_TARGET=$(OUTPUT)/$$TARGET; \ - $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests;\ + $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET $@;\ done; -endef override define CLEAN - @for TARGET in $(SUB_DIRS); do \ + +@for TARGET in $(SUB_DIRS); do \ BUILD_TARGET=$(OUTPUT)/$$TARGET; \ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean; \ done; @@ -76,4 +75,4 @@ tags: find . -name '*.c' -o -name '*.h' | xargs ctags -.PHONY: tags $(SUB_DIRS) +.PHONY: tags $(SUB_DIRS) emit_tests only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/powerpc/pmu/Makefile +++ linux-6.2.0/tools/testing/selftests/powerpc/pmu/Makefile @@ -25,32 +25,36 @@ DEFAULT_RUN_TESTS := $(RUN_TESTS) override define RUN_TESTS $(DEFAULT_RUN_TESTS) - TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests - TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests - TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests + +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests + +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests + +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests endef -DEFAULT_EMIT_TESTS := $(EMIT_TESTS) -override define EMIT_TESTS - $(DEFAULT_EMIT_TESTS) - TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests - TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests - TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests -endef +emit_tests: + for TEST in $(TEST_GEN_PROGS); do \ + BASENAME_TEST=`basename $$TEST`; \ + echo "$(COLLECTION):$$BASENAME_TEST"; \ + done + +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests + +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests + +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests DEFAULT_INSTALL_RULE := $(INSTALL_RULE) override define INSTALL_RULE $(DEFAULT_INSTALL_RULE) - TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install - TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install - TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install + +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install + +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install + +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install endef -clean: +DEFAULT_CLEAN := $(CLEAN) +override define CLEAN + $(DEFAULT_CLEAN) $(RM) $(TEST_GEN_PROGS) $(OUTPUT)/loop.o - TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean - TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean - TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean + +TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean + +TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean + +TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean +endef ebb: TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all @@ -61,4 +65,4 @@ event_code_tests: TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all -.PHONY: all run_tests clean ebb sampling_tests event_code_tests +.PHONY: all run_tests ebb sampling_tests event_code_tests emit_tests only in patch2: unchanged: --- linux-6.2.0.orig/tools/testing/selftests/resctrl/Makefile +++ linux-6.2.0/tools/testing/selftests/resctrl/Makefile @@ -7,4 +7,4 @@ include ../lib.mk -$(OUTPUT)/resctrl_tests: $(wildcard *.c) +$(OUTPUT)/resctrl_tests: $(wildcard *.[ch]) only in patch2: unchanged: --- linux-6.2.0.orig/virt/kvm/vfio.c +++ linux-6.2.0/virt/kvm/vfio.c @@ -21,7 +21,7 @@ #include #endif -struct kvm_vfio_group { +struct kvm_vfio_file { struct list_head node; struct file *file; #ifdef CONFIG_SPAPR_TCE_IOMMU @@ -30,7 +30,7 @@ }; struct kvm_vfio { - struct list_head group_list; + struct list_head file_list; struct mutex lock; bool noncoherent; }; @@ -98,34 +98,35 @@ } static void kvm_spapr_tce_release_vfio_group(struct kvm *kvm, - struct kvm_vfio_group *kvg) + struct kvm_vfio_file *kvf) { - if (WARN_ON_ONCE(!kvg->iommu_group)) + if (WARN_ON_ONCE(!kvf->iommu_group)) return; - kvm_spapr_tce_release_iommu_group(kvm, kvg->iommu_group); - iommu_group_put(kvg->iommu_group); - kvg->iommu_group = NULL; + kvm_spapr_tce_release_iommu_group(kvm, kvf->iommu_group); + iommu_group_put(kvf->iommu_group); + kvf->iommu_group = NULL; } #endif /* - * Groups can use the same or different IOMMU domains. If the same then - * adding a new group may change the coherency of groups we've previously - * been told about. We don't want to care about any of that so we retest - * each group and bail as soon as we find one that's noncoherent. This - * means we only ever [un]register_noncoherent_dma once for the whole device. + * Groups/devices can use the same or different IOMMU domains. If the same + * then adding a new group/device may change the coherency of groups/devices + * we've previously been told about. We don't want to care about any of + * that so we retest each group/device and bail as soon as we find one that's + * noncoherent. This means we only ever [un]register_noncoherent_dma once + * for the whole device. */ static void kvm_vfio_update_coherency(struct kvm_device *dev) { struct kvm_vfio *kv = dev->private; bool noncoherent = false; - struct kvm_vfio_group *kvg; + struct kvm_vfio_file *kvf; mutex_lock(&kv->lock); - list_for_each_entry(kvg, &kv->group_list, node) { - if (!kvm_vfio_file_enforced_coherent(kvg->file)) { + list_for_each_entry(kvf, &kv->file_list, node) { + if (!kvm_vfio_file_enforced_coherent(kvf->file)) { noncoherent = true; break; } @@ -143,10 +144,10 @@ mutex_unlock(&kv->lock); } -static int kvm_vfio_group_add(struct kvm_device *dev, unsigned int fd) +static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd) { struct kvm_vfio *kv = dev->private; - struct kvm_vfio_group *kvg; + struct kvm_vfio_file *kvf; struct file *filp; int ret; @@ -162,27 +163,27 @@ mutex_lock(&kv->lock); - list_for_each_entry(kvg, &kv->group_list, node) { - if (kvg->file == filp) { + list_for_each_entry(kvf, &kv->file_list, node) { + if (kvf->file == filp) { ret = -EEXIST; goto err_unlock; } } - kvg = kzalloc(sizeof(*kvg), GFP_KERNEL_ACCOUNT); - if (!kvg) { + kvf = kzalloc(sizeof(*kvf), GFP_KERNEL_ACCOUNT); + if (!kvf) { ret = -ENOMEM; goto err_unlock; } - kvg->file = filp; - list_add_tail(&kvg->node, &kv->group_list); + kvf->file = filp; + list_add_tail(&kvf->node, &kv->file_list); kvm_arch_start_assignment(dev->kvm); + kvm_vfio_file_set_kvm(kvf->file, dev->kvm); mutex_unlock(&kv->lock); - kvm_vfio_file_set_kvm(kvg->file, dev->kvm); kvm_vfio_update_coherency(dev); return 0; @@ -193,10 +194,10 @@ return ret; } -static int kvm_vfio_group_del(struct kvm_device *dev, unsigned int fd) +static int kvm_vfio_file_del(struct kvm_device *dev, unsigned int fd) { struct kvm_vfio *kv = dev->private; - struct kvm_vfio_group *kvg; + struct kvm_vfio_file *kvf; struct fd f; int ret; @@ -208,18 +209,18 @@ mutex_lock(&kv->lock); - list_for_each_entry(kvg, &kv->group_list, node) { - if (kvg->file != f.file) + list_for_each_entry(kvf, &kv->file_list, node) { + if (kvf->file != f.file) continue; - list_del(&kvg->node); + list_del(&kvf->node); kvm_arch_end_assignment(dev->kvm); #ifdef CONFIG_SPAPR_TCE_IOMMU - kvm_spapr_tce_release_vfio_group(dev->kvm, kvg); + kvm_spapr_tce_release_vfio_group(dev->kvm, kvf); #endif - kvm_vfio_file_set_kvm(kvg->file, NULL); - fput(kvg->file); - kfree(kvg); + kvm_vfio_file_set_kvm(kvf->file, NULL); + fput(kvf->file); + kfree(kvf); ret = 0; break; } @@ -234,12 +235,12 @@ } #ifdef CONFIG_SPAPR_TCE_IOMMU -static int kvm_vfio_group_set_spapr_tce(struct kvm_device *dev, - void __user *arg) +static int kvm_vfio_file_set_spapr_tce(struct kvm_device *dev, + void __user *arg) { struct kvm_vfio_spapr_tce param; struct kvm_vfio *kv = dev->private; - struct kvm_vfio_group *kvg; + struct kvm_vfio_file *kvf; struct fd f; int ret; @@ -254,20 +255,20 @@ mutex_lock(&kv->lock); - list_for_each_entry(kvg, &kv->group_list, node) { - if (kvg->file != f.file) + list_for_each_entry(kvf, &kv->file_list, node) { + if (kvf->file != f.file) continue; - if (!kvg->iommu_group) { - kvg->iommu_group = kvm_vfio_file_iommu_group(kvg->file); - if (WARN_ON_ONCE(!kvg->iommu_group)) { + if (!kvf->iommu_group) { + kvf->iommu_group = kvm_vfio_file_iommu_group(kvf->file); + if (WARN_ON_ONCE(!kvf->iommu_group)) { ret = -EIO; goto err_fdput; } } ret = kvm_spapr_tce_attach_iommu_group(dev->kvm, param.tablefd, - kvg->iommu_group); + kvf->iommu_group); break; } @@ -278,8 +279,8 @@ } #endif -static int kvm_vfio_set_group(struct kvm_device *dev, long attr, - void __user *arg) +static int kvm_vfio_set_file(struct kvm_device *dev, long attr, + void __user *arg) { int32_t __user *argp = arg; int32_t fd; @@ -288,16 +289,16 @@ case KVM_DEV_VFIO_GROUP_ADD: if (get_user(fd, argp)) return -EFAULT; - return kvm_vfio_group_add(dev, fd); + return kvm_vfio_file_add(dev, fd); case KVM_DEV_VFIO_GROUP_DEL: if (get_user(fd, argp)) return -EFAULT; - return kvm_vfio_group_del(dev, fd); + return kvm_vfio_file_del(dev, fd); #ifdef CONFIG_SPAPR_TCE_IOMMU case KVM_DEV_VFIO_GROUP_SET_SPAPR_TCE: - return kvm_vfio_group_set_spapr_tce(dev, arg); + return kvm_vfio_file_set_spapr_tce(dev, arg); #endif } @@ -309,8 +310,8 @@ { switch (attr->group) { case KVM_DEV_VFIO_GROUP: - return kvm_vfio_set_group(dev, attr->attr, - u64_to_user_ptr(attr->addr)); + return kvm_vfio_set_file(dev, attr->attr, + u64_to_user_ptr(attr->addr)); } return -ENXIO; @@ -339,16 +340,16 @@ static void kvm_vfio_release(struct kvm_device *dev) { struct kvm_vfio *kv = dev->private; - struct kvm_vfio_group *kvg, *tmp; + struct kvm_vfio_file *kvf, *tmp; - list_for_each_entry_safe(kvg, tmp, &kv->group_list, node) { + list_for_each_entry_safe(kvf, tmp, &kv->file_list, node) { #ifdef CONFIG_SPAPR_TCE_IOMMU - kvm_spapr_tce_release_vfio_group(dev->kvm, kvg); + kvm_spapr_tce_release_vfio_group(dev->kvm, kvf); #endif - kvm_vfio_file_set_kvm(kvg->file, NULL); - fput(kvg->file); - list_del(&kvg->node); - kfree(kvg); + kvm_vfio_file_set_kvm(kvf->file, NULL); + fput(kvf->file); + list_del(&kvf->node); + kfree(kvf); kvm_arch_end_assignment(dev->kvm); } @@ -382,7 +383,7 @@ if (!kv) return -ENOMEM; - INIT_LIST_HEAD(&kv->group_list); + INIT_LIST_HEAD(&kv->file_list); mutex_init(&kv->lock); dev->private = kv;