]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.16
authorSasha Levin <sashal@kernel.org>
Sat, 5 Mar 2022 20:55:47 +0000 (15:55 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 5 Mar 2022 20:55:47 +0000 (15:55 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
46 files changed:
queue-5.16/arm-dts-switch-timer-config-to-common-devkit8000-dev.patch [new file with mode: 0644]
queue-5.16/arm-dts-use-32kihz-oscillator-on-devkit8000.patch [new file with mode: 0644]
queue-5.16/arm-tegra-move-panels-to-aux-bus.patch [new file with mode: 0644]
queue-5.16/arm64-dts-imx8mm-fix-vpu-hanging.patch [new file with mode: 0644]
queue-5.16/arm64-dts-juno-remove-gicv2m-dma-range.patch [new file with mode: 0644]
queue-5.16/arm64-dts-rockchip-drop-pclk_xpcs-from-gmac0-on-rk35.patch [new file with mode: 0644]
queue-5.16/arm64-dts-rockchip-fix-quartz64-a-ddr-regulator-volt.patch [new file with mode: 0644]
queue-5.16/bluetooth-fix-bt_skb_sendmmsg-not-allocating-partial.patch [new file with mode: 0644]
queue-5.16/can-etas_es58x-change-opened_channel_cnt-s-type-from.patch [new file with mode: 0644]
queue-5.16/drm-amdgpu-fix-suspend-resume-hang-regression.patch [new file with mode: 0644]
queue-5.16/drm-bridge-ti-sn65dsi86-properly-undo-autosuspend.patch [new file with mode: 0644]
queue-5.16/drm-i915-guc-slpc-correct-the-param-count-for-unset-.patch [new file with mode: 0644]
queue-5.16/e1000e-fix-possible-hw-unit-hang-after-an-s0ix-exit.patch [new file with mode: 0644]
queue-5.16/iavf-add-trace-while-removing-device.patch [new file with mode: 0644]
queue-5.16/iavf-add-waiting-so-the-port-is-initialized-in-remov.patch [new file with mode: 0644]
queue-5.16/iavf-fix-__iavf_resetting-state-usage.patch [new file with mode: 0644]
queue-5.16/iavf-fix-init-state-closure-on-remove.patch [new file with mode: 0644]
queue-5.16/iavf-fix-locking-for-virtchnl_op_get_offload_vlan_v2.patch [new file with mode: 0644]
queue-5.16/iavf-fix-race-in-init-state.patch [new file with mode: 0644]
queue-5.16/iavf-rework-mutexes-for-better-synchronisation.patch [new file with mode: 0644]
queue-5.16/ibmvnic-allow-queueing-resets-during-probe.patch [new file with mode: 0644]
queue-5.16/ibmvnic-clear-fop-when-retrying-probe.patch [new file with mode: 0644]
queue-5.16/ibmvnic-complete-init_done-on-transport-events.patch [new file with mode: 0644]
queue-5.16/ibmvnic-define-flush_reset_queue-helper.patch [new file with mode: 0644]
queue-5.16/ibmvnic-init-init_done_rc-earlier.patch [new file with mode: 0644]
queue-5.16/ibmvnic-initialize-rc-before-completing-wait.patch [new file with mode: 0644]
queue-5.16/ibmvnic-update-driver-return-codes.patch [new file with mode: 0644]
queue-5.16/iommu-amd-fix-i-o-page-table-memory-leak.patch [new file with mode: 0644]
queue-5.16/iommu-amd-simplify-pagetable-freeing.patch [new file with mode: 0644]
queue-5.16/iommu-amd-use-put_pages_list.patch [new file with mode: 0644]
queue-5.16/mips-ralink-mt7621-do-memory-detection-on-kseg1.patch [new file with mode: 0644]
queue-5.16/mips-ralink-mt7621-use-bitwise-not-instead-of-logica.patch [new file with mode: 0644]
queue-5.16/net-chelsio-cxgb3-check-the-return-value-of-pci_find.patch [new file with mode: 0644]
queue-5.16/net-dcb-disable-softirqs-in-dcbnl_flush_dev.patch [new file with mode: 0644]
queue-5.16/net-sparx5-fix-add-vlan-when-invalid-operation.patch [new file with mode: 0644]
queue-5.16/net-stmmac-enhance-xdp-zc-driver-level-switching-per.patch [new file with mode: 0644]
queue-5.16/net-stmmac-only-enable-dma-interrupts-when-ready.patch [new file with mode: 0644]
queue-5.16/netfilter-nf_tables-prefer-kfree_rcu-ptr-rcu-variant.patch [new file with mode: 0644]
queue-5.16/nl80211-handle-nla_memdup-failures-in-handle_nan_fil.patch [new file with mode: 0644]
queue-5.16/ptp-ocp-add-ptp_ocp_adjtime_coarse-for-large-adjustm.patch [new file with mode: 0644]
queue-5.16/selftests-mlxsw-resource_scale-fix-return-value.patch [new file with mode: 0644]
queue-5.16/series
queue-5.16/soc-fsl-guts-add-a-missing-memory-allocation-failure.patch [new file with mode: 0644]
queue-5.16/soc-fsl-guts-revert-commit-3c0d64e867ed.patch [new file with mode: 0644]
queue-5.16/soc-fsl-qe-check-of-ioremap-return-value.patch [new file with mode: 0644]
queue-5.16/soc-imx-gpcv2-fix-clock-disabling-imbalance-in-error.patch [new file with mode: 0644]

diff --git a/queue-5.16/arm-dts-switch-timer-config-to-common-devkit8000-dev.patch b/queue-5.16/arm-dts-switch-timer-config-to-common-devkit8000-dev.patch
new file mode 100644 (file)
index 0000000..485ffd2
--- /dev/null
@@ -0,0 +1,109 @@
+From 6f349e33ce2921776a4a4305397d74ab05a2bfcb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jan 2022 20:11:38 +0100
+Subject: ARM: dts: switch timer config to common devkit8000 devicetree
+
+From: Anthoine Bourgeois <anthoine.bourgeois@gmail.com>
+
+[ Upstream commit 64324ef337d0caa5798fa8fa3f6bbfbd3245868a ]
+
+This patch allow lcd43 and lcd70 flavors to benefit from timer
+evolution.
+
+Fixes: e428e250fde6 ("ARM: dts: Configure system timers for omap3")
+Signed-off-by: Anthoine Bourgeois <anthoine.bourgeois@gmail.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../arm/boot/dts/omap3-devkit8000-common.dtsi | 33 +++++++++++++++++++
+ arch/arm/boot/dts/omap3-devkit8000.dts        | 33 -------------------
+ 2 files changed, 33 insertions(+), 33 deletions(-)
+
+diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+index 5e55198e4576..f5197bb31ed8 100644
+--- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
++++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+@@ -158,6 +158,39 @@
+       status = "disabled";
+ };
++/* Unusable as clocksource because of unreliable oscillator */
++&counter32k {
++      status = "disabled";
++};
++
++/* Unusable as clockevent because if unreliable oscillator, allow to idle */
++&timer1_target {
++      /delete-property/ti,no-reset-on-init;
++      /delete-property/ti,no-idle;
++      timer@0 {
++              /delete-property/ti,timer-alwon;
++      };
++};
++
++/* Preferred always-on timer for clocksource */
++&timer12_target {
++      ti,no-reset-on-init;
++      ti,no-idle;
++      timer@0 {
++              /* Always clocked by secure_32k_fck */
++      };
++};
++
++/* Preferred timer for clockevent */
++&timer2_target {
++      ti,no-reset-on-init;
++      ti,no-idle;
++      timer@0 {
++              assigned-clocks = <&gpt2_fck>;
++              assigned-clock-parents = <&sys_ck>;
++      };
++};
++
+ &twl_gpio {
+       ti,use-leds;
+       /*
+diff --git a/arch/arm/boot/dts/omap3-devkit8000.dts b/arch/arm/boot/dts/omap3-devkit8000.dts
+index c2995a280729..162d0726b008 100644
+--- a/arch/arm/boot/dts/omap3-devkit8000.dts
++++ b/arch/arm/boot/dts/omap3-devkit8000.dts
+@@ -14,36 +14,3 @@
+               display2 = &tv0;
+       };
+ };
+-
+-/* Unusable as clocksource because of unreliable oscillator */
+-&counter32k {
+-      status = "disabled";
+-};
+-
+-/* Unusable as clockevent because if unreliable oscillator, allow to idle */
+-&timer1_target {
+-      /delete-property/ti,no-reset-on-init;
+-      /delete-property/ti,no-idle;
+-      timer@0 {
+-              /delete-property/ti,timer-alwon;
+-      };
+-};
+-
+-/* Preferred always-on timer for clocksource */
+-&timer12_target {
+-      ti,no-reset-on-init;
+-      ti,no-idle;
+-      timer@0 {
+-              /* Always clocked by secure_32k_fck */
+-      };
+-};
+-
+-/* Preferred timer for clockevent */
+-&timer2_target {
+-      ti,no-reset-on-init;
+-      ti,no-idle;
+-      timer@0 {
+-              assigned-clocks = <&gpt2_fck>;
+-              assigned-clock-parents = <&sys_ck>;
+-      };
+-};
+-- 
+2.34.1
+
diff --git a/queue-5.16/arm-dts-use-32kihz-oscillator-on-devkit8000.patch b/queue-5.16/arm-dts-use-32kihz-oscillator-on-devkit8000.patch
new file mode 100644 (file)
index 0000000..45a863b
--- /dev/null
@@ -0,0 +1,88 @@
+From 61077c5b779d97f87bb7479bfb12974d305e8bc9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jan 2022 20:11:39 +0100
+Subject: ARM: dts: Use 32KiHz oscillator on devkit8000
+
+From: Anthoine Bourgeois <anthoine.bourgeois@gmail.com>
+
+[ Upstream commit 8840f5460a23759403f1f2860429dcbcc2f04a65 ]
+
+Devkit8000 board seems to always used 32k_counter as clocksource.
+Restore this behavior.
+
+If clocksource is back to 32k_counter, timer12 is now the clockevent
+source (as before) and timer2 is not longer needed here.
+
+This commit fixes the same issue observed with commit 23885389dbbb
+("ARM: dts: Fix timer regression for beagleboard revision c") when sleep
+is blocked until hitting keys over serial console.
+
+Fixes: aba1ad05da08 ("clocksource/drivers/timer-ti-dm: Add clockevent and clocksource support")
+Fixes: e428e250fde6 ("ARM: dts: Configure system timers for omap3")
+Signed-off-by: Anthoine Bourgeois <anthoine.bourgeois@gmail.com>
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/omap3-devkit8000-common.dtsi | 17 +----------------
+ drivers/clocksource/timer-ti-dm-systimer.c     |  3 +--
+ 2 files changed, 2 insertions(+), 18 deletions(-)
+
+diff --git a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+index f5197bb31ed8..54cd37336be7 100644
+--- a/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
++++ b/arch/arm/boot/dts/omap3-devkit8000-common.dtsi
+@@ -158,11 +158,6 @@
+       status = "disabled";
+ };
+-/* Unusable as clocksource because of unreliable oscillator */
+-&counter32k {
+-      status = "disabled";
+-};
+-
+ /* Unusable as clockevent because if unreliable oscillator, allow to idle */
+ &timer1_target {
+       /delete-property/ti,no-reset-on-init;
+@@ -172,7 +167,7 @@
+       };
+ };
+-/* Preferred always-on timer for clocksource */
++/* Preferred timer for clockevent */
+ &timer12_target {
+       ti,no-reset-on-init;
+       ti,no-idle;
+@@ -181,16 +176,6 @@
+       };
+ };
+-/* Preferred timer for clockevent */
+-&timer2_target {
+-      ti,no-reset-on-init;
+-      ti,no-idle;
+-      timer@0 {
+-              assigned-clocks = <&gpt2_fck>;
+-              assigned-clock-parents = <&sys_ck>;
+-      };
+-};
+-
+ &twl_gpio {
+       ti,use-leds;
+       /*
+diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c
+index 5c40ca1d4740..1fccb457fcc5 100644
+--- a/drivers/clocksource/timer-ti-dm-systimer.c
++++ b/drivers/clocksource/timer-ti-dm-systimer.c
+@@ -241,8 +241,7 @@ static void __init dmtimer_systimer_assign_alwon(void)
+       bool quirk_unreliable_oscillator = false;
+       /* Quirk unreliable 32 KiHz oscillator with incomplete dts */
+-      if (of_machine_is_compatible("ti,omap3-beagle-ab4") ||
+-          of_machine_is_compatible("timll,omap3-devkit8000")) {
++      if (of_machine_is_compatible("ti,omap3-beagle-ab4")) {
+               quirk_unreliable_oscillator = true;
+               counter_32k = -ENODEV;
+       }
+-- 
+2.34.1
+
diff --git a/queue-5.16/arm-tegra-move-panels-to-aux-bus.patch b/queue-5.16/arm-tegra-move-panels-to-aux-bus.patch
new file mode 100644 (file)
index 0000000..d22bce4
--- /dev/null
@@ -0,0 +1,112 @@
+From 2fb2e0a2be5a86af006852750ecfdcb65cac5cb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Dec 2021 11:32:39 +0100
+Subject: ARM: tegra: Move panels to AUX bus
+
+From: Thierry Reding <treding@nvidia.com>
+
+[ Upstream commit 8d3b01e0d4bb54368d73d0984466d72c2eeeac74 ]
+
+Move the eDP panel on Venice 2 and Nyan boards into the corresponding
+AUX bus device tree node. This allows us to avoid a nasty circular
+dependency that would otherwise be created between the DPAUX and panel
+nodes via the DDC/I2C phandle.
+
+Fixes: eb481f9ac95c ("ARM: tegra: add Acer Chromebook 13 device tree")
+Fixes: 59fe02cb079f ("ARM: tegra: Add DTS for the nyan-blaze board")
+Fixes: 40e231c770a4 ("ARM: tegra: Enable eDP for Venice2")
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/tegra124-nyan-big.dts   | 15 +++++++++------
+ arch/arm/boot/dts/tegra124-nyan-blaze.dts | 15 +++++++++------
+ arch/arm/boot/dts/tegra124-venice2.dts    | 14 +++++++-------
+ 3 files changed, 25 insertions(+), 19 deletions(-)
+
+diff --git a/arch/arm/boot/dts/tegra124-nyan-big.dts b/arch/arm/boot/dts/tegra124-nyan-big.dts
+index 1d2aac2cb6d0..fdc1d64dfff9 100644
+--- a/arch/arm/boot/dts/tegra124-nyan-big.dts
++++ b/arch/arm/boot/dts/tegra124-nyan-big.dts
+@@ -13,12 +13,15 @@
+                    "google,nyan-big-rev1", "google,nyan-big-rev0",
+                    "google,nyan-big", "google,nyan", "nvidia,tegra124";
+-      panel: panel {
+-              compatible = "auo,b133xtn01";
+-
+-              power-supply = <&vdd_3v3_panel>;
+-              backlight = <&backlight>;
+-              ddc-i2c-bus = <&dpaux>;
++      host1x@50000000 {
++              dpaux@545c0000 {
++                      aux-bus {
++                              panel: panel {
++                                      compatible = "auo,b133xtn01";
++                                      backlight = <&backlight>;
++                              };
++                      };
++              };
+       };
+       mmc@700b0400 { /* SD Card on this bus */
+diff --git a/arch/arm/boot/dts/tegra124-nyan-blaze.dts b/arch/arm/boot/dts/tegra124-nyan-blaze.dts
+index 677babde6460..abdf4456826f 100644
+--- a/arch/arm/boot/dts/tegra124-nyan-blaze.dts
++++ b/arch/arm/boot/dts/tegra124-nyan-blaze.dts
+@@ -15,12 +15,15 @@
+                    "google,nyan-blaze-rev0", "google,nyan-blaze",
+                    "google,nyan", "nvidia,tegra124";
+-      panel: panel {
+-              compatible = "samsung,ltn140at29-301";
+-
+-              power-supply = <&vdd_3v3_panel>;
+-              backlight = <&backlight>;
+-              ddc-i2c-bus = <&dpaux>;
++      host1x@50000000 {
++              dpaux@545c0000 {
++                      aux-bus {
++                              panel: panel {
++                                      compatible = "samsung,ltn140at29-301";
++                                      backlight = <&backlight>;
++                              };
++                      };
++              };
+       };
+       sound {
+diff --git a/arch/arm/boot/dts/tegra124-venice2.dts b/arch/arm/boot/dts/tegra124-venice2.dts
+index e6b54ac1ebd1..84e2d24065e9 100644
+--- a/arch/arm/boot/dts/tegra124-venice2.dts
++++ b/arch/arm/boot/dts/tegra124-venice2.dts
+@@ -48,6 +48,13 @@
+               dpaux@545c0000 {
+                       vdd-supply = <&vdd_3v3_panel>;
+                       status = "okay";
++
++                      aux-bus {
++                              panel: panel {
++                                      compatible = "lg,lp129qe";
++                                      backlight = <&backlight>;
++                              };
++                      };
+               };
+       };
+@@ -1079,13 +1086,6 @@
+               };
+       };
+-      panel: panel {
+-              compatible = "lg,lp129qe";
+-              power-supply = <&vdd_3v3_panel>;
+-              backlight = <&backlight>;
+-              ddc-i2c-bus = <&dpaux>;
+-      };
+-
+       vdd_mux: regulator@0 {
+               compatible = "regulator-fixed";
+               regulator-name = "+VDD_MUX";
+-- 
+2.34.1
+
diff --git a/queue-5.16/arm64-dts-imx8mm-fix-vpu-hanging.patch b/queue-5.16/arm64-dts-imx8mm-fix-vpu-hanging.patch
new file mode 100644 (file)
index 0000000..8a538f8
--- /dev/null
@@ -0,0 +1,37 @@
+From f234fb54ef2de87445571761d231af85c6c06807 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jan 2022 11:11:25 -0600
+Subject: arm64: dts: imx8mm: Fix VPU Hanging
+
+From: Adam Ford <aford173@gmail.com>
+
+[ Upstream commit ef3075d6638d3d5353a97fcc7bb0338fc85675f5 ]
+
+The vpumix power domain has a reset assigned to it, however
+when used, it causes a system hang.  Testing has shown that
+it does not appear to be needed anywhere.
+
+Fixes: d39d4bb15310 ("arm64: dts: imx8mm: add GPC node")
+Signed-off-by: Adam Ford <aford173@gmail.com>
+Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mm.dtsi | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm64/boot/dts/freescale/imx8mm.dtsi b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+index c2f3f118f82e..f13d31ebfcbd 100644
+--- a/arch/arm64/boot/dts/freescale/imx8mm.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mm.dtsi
+@@ -681,7 +681,6 @@
+                                               clocks = <&clk IMX8MM_CLK_VPU_DEC_ROOT>;
+                                               assigned-clocks = <&clk IMX8MM_CLK_VPU_BUS>;
+                                               assigned-clock-parents = <&clk IMX8MM_SYS_PLL1_800M>;
+-                                              resets = <&src IMX8MQ_RESET_VPU_RESET>;
+                                       };
+                                       pgc_vpu_g1: power-domain@7 {
+-- 
+2.34.1
+
diff --git a/queue-5.16/arm64-dts-juno-remove-gicv2m-dma-range.patch b/queue-5.16/arm64-dts-juno-remove-gicv2m-dma-range.patch
new file mode 100644 (file)
index 0000000..2067299
--- /dev/null
@@ -0,0 +1,49 @@
+From 06e1c23b052f352842554a016c55db9a1737bbe8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 24 Jan 2022 17:57:01 +0000
+Subject: arm64: dts: juno: Remove GICv2m dma-range
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit 31eeb6b09f4053f32a30ce9fbcdfca31f713028d ]
+
+Although it is painstakingly honest to describe all 3 PCI windows in
+"dma-ranges", it misses the the subtle distinction that the window for
+the GICv2m range is normally programmed for Device memory attributes
+rather than Normal Cacheable like the DRAM windows. Since MMU-401 only
+offers stage 2 translation, this means that when the PCI SMMU is
+enabled, accesses through that IPA range unexpectedly lose coherency if
+mapped as cacheable at the SMMU, due to the attribute combining rules.
+Since an extra 256KB is neither here nor there when we still have 10GB
+worth of usable address space, rather than attempting to describe and
+cope with this detail let's just remove the offending range. If the SMMU
+is not used then it makes no difference anyway.
+
+Link: https://lore.kernel.org/r/856c3f7192c6c3ce545ba67462f2ce9c86ed6b0c.1643046936.git.robin.murphy@arm.com
+Fixes: 4ac4d146cb63 ("arm64: dts: juno: Describe PCI dma-ranges")
+Reported-by: Anders Roxell <anders.roxell@linaro.org>
+Acked-by: Liviu Dudau <liviu.dudau@arm.com>
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/arm/juno-base.dtsi | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi
+index 6288e104a089..a2635b14da30 100644
+--- a/arch/arm64/boot/dts/arm/juno-base.dtsi
++++ b/arch/arm64/boot/dts/arm/juno-base.dtsi
+@@ -543,8 +543,7 @@
+                        <0x02000000 0x00 0x50000000 0x00 0x50000000 0x0 0x08000000>,
+                        <0x42000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>;
+               /* Standard AXI Translation entries as programmed by EDK2 */
+-              dma-ranges = <0x02000000 0x0 0x2c1c0000 0x0 0x2c1c0000 0x0 0x00040000>,
+-                           <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>,
++              dma-ranges = <0x02000000 0x0 0x80000000 0x0 0x80000000 0x0 0x80000000>,
+                            <0x43000000 0x8 0x00000000 0x8 0x00000000 0x2 0x00000000>;
+               #interrupt-cells = <1>;
+               interrupt-map-mask = <0 0 0 7>;
+-- 
+2.34.1
+
diff --git a/queue-5.16/arm64-dts-rockchip-drop-pclk_xpcs-from-gmac0-on-rk35.patch b/queue-5.16/arm64-dts-rockchip-drop-pclk_xpcs-from-gmac0-on-rk35.patch
new file mode 100644 (file)
index 0000000..b5a7e0d
--- /dev/null
@@ -0,0 +1,64 @@
+From 4458a534ef37cb25041df6bdd34201e39e8b678f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 23 Jan 2022 14:35:10 +0100
+Subject: arm64: dts: rockchip: drop pclk_xpcs from gmac0 on rk3568
+
+From: Frank Wunderlich <frank-w@public-files.de>
+
+[ Upstream commit 85a8bccfa945680dc561f06b65ea01341d2033fc ]
+
+pclk_xpcs is not supported by mainline driver and breaks dtbs_check
+
+following warnings occour, and many more
+
+rk3568-evb1-v10.dt.yaml: ethernet@fe2a0000: clocks:
+    [[15, 386], [15, 389], [15, 389], [15, 184], [15, 180], [15, 181],
+    [15, 389], [15, 185], [15, 172]] is too long
+       From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
+rk3568-evb1-v10.dt.yaml: ethernet@fe2a0000: clock-names:
+    ['stmmaceth', 'mac_clk_rx', 'mac_clk_tx', 'clk_mac_refout', 'aclk_mac',
+    'pclk_mac', 'clk_mac_speed', 'ptp_ref', 'pclk_xpcs'] is too long
+       From schema: Documentation/devicetree/bindings/net/snps,dwmac.yaml
+
+after removing it, the clock and other warnings are gone.
+
+pclk_xpcs on gmac is used to support QSGMII, but this requires a driver
+supporting it.
+Once xpcs support is introduced, the clock can be added to the
+documentation and both controllers.
+
+Fixes: b8d41e5053cd ("arm64: dts: rockchip: add gmac0 node to rk3568")
+Co-developed-by: Peter Geis <pgwipeout@gmail.com>
+Signed-off-by: Peter Geis <pgwipeout@gmail.com>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Acked-by: Michael Riesch <michael.riesch@wolfvision.net>
+Link: https://lore.kernel.org/r/20220123133510.135651-1-linux@fw-web.de
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3568.dtsi | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+index 2fd313a295f8..d91df1cde736 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi
++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
+@@ -32,13 +32,11 @@
+               clocks = <&cru SCLK_GMAC0>, <&cru SCLK_GMAC0_RX_TX>,
+                        <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_MAC0_REFOUT>,
+                        <&cru ACLK_GMAC0>, <&cru PCLK_GMAC0>,
+-                       <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>,
+-                       <&cru PCLK_XPCS>;
++                       <&cru SCLK_GMAC0_RX_TX>, <&cru CLK_GMAC0_PTP_REF>;
+               clock-names = "stmmaceth", "mac_clk_rx",
+                             "mac_clk_tx", "clk_mac_refout",
+                             "aclk_mac", "pclk_mac",
+-                            "clk_mac_speed", "ptp_ref",
+-                            "pclk_xpcs";
++                            "clk_mac_speed", "ptp_ref";
+               resets = <&cru SRST_A_GMAC0>;
+               reset-names = "stmmaceth";
+               rockchip,grf = <&grf>;
+-- 
+2.34.1
+
diff --git a/queue-5.16/arm64-dts-rockchip-fix-quartz64-a-ddr-regulator-volt.patch b/queue-5.16/arm64-dts-rockchip-fix-quartz64-a-ddr-regulator-volt.patch
new file mode 100644 (file)
index 0000000..d044e8c
--- /dev/null
@@ -0,0 +1,41 @@
+From 79a124d5500cb9b3a89c99b7d5794e140a68ac70 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Jan 2022 19:38:05 -0500
+Subject: arm64: dts: rockchip: fix Quartz64-A ddr regulator voltage
+
+From: Peter Geis <pgwipeout@gmail.com>
+
+[ Upstream commit ad02776cf8d083e28b1ca4d93d8b1949668c27cc ]
+
+The Quartz64 Model A uses a voltage divider to ensure ddr voltage is
+within specification from the default regulator configuration.
+Adjusting this voltage is detrimental, and currently causes the ddr
+voltage to be about 0.8v.
+
+Remove the min and max voltage setpoints for the ddr regulator.
+
+Fixes: b33a22a1e7c4 ("arm64: dts: rockchip: add basic dts for Pine64 Quartz64-A")
+Signed-off-by: Peter Geis <pgwipeout@gmail.com>
+Link: https://lore.kernel.org/r/20220128003809.3291407-2-pgwipeout@gmail.com
+Signed-off-by: Heiko Stuebner <heiko@sntech.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+index 4d4b2a301b1a..f6290538c8a4 100644
+--- a/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
++++ b/arch/arm64/boot/dts/rockchip/rk3566-quartz64-a.dts
+@@ -285,8 +285,6 @@
+                       vcc_ddr: DCDC_REG3 {
+                               regulator-always-on;
+                               regulator-boot-on;
+-                              regulator-min-microvolt = <1100000>;
+-                              regulator-max-microvolt = <1100000>;
+                               regulator-initial-mode = <0x2>;
+                               regulator-name = "vcc_ddr";
+                               regulator-state-mem {
+-- 
+2.34.1
+
diff --git a/queue-5.16/bluetooth-fix-bt_skb_sendmmsg-not-allocating-partial.patch b/queue-5.16/bluetooth-fix-bt_skb_sendmmsg-not-allocating-partial.patch
new file mode 100644 (file)
index 0000000..5865140
--- /dev/null
@@ -0,0 +1,42 @@
+From 976b37e2a5885863e25eb71ebf8f67bf272a3b0f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 14 Feb 2022 17:59:38 -0800
+Subject: Bluetooth: Fix bt_skb_sendmmsg not allocating partial chunks
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 29fb608396d6a62c1b85acc421ad7a4399085b9f ]
+
+Since bt_skb_sendmmsg can be used with the likes of SOCK_STREAM it
+shall return the partial chunks it could allocate instead of freeing
+everything as otherwise it can cause problems like bellow.
+
+Fixes: 81be03e026dc ("Bluetooth: RFCOMM: Replace use of memcpy_from_msg with bt_skb_sendmmsg")
+Reported-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Link: https://lore.kernel.org/r/d7206e12-1b99-c3be-84f4-df22af427ef5@molgen.mpg.de
+BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215594
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Tested-by: Paul Menzel <pmenzel@molgen.mpg.de> (Nokia N9 (MeeGo/Harmattan)
+Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/bluetooth/bluetooth.h | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
+index 3271870fd85e..a1093994e5e4 100644
+--- a/include/net/bluetooth/bluetooth.h
++++ b/include/net/bluetooth/bluetooth.h
+@@ -497,8 +497,7 @@ static inline struct sk_buff *bt_skb_sendmmsg(struct sock *sk,
+               tmp = bt_skb_sendmsg(sk, msg, len, mtu, headroom, tailroom);
+               if (IS_ERR(tmp)) {
+-                      kfree_skb(skb);
+-                      return tmp;
++                      return skb;
+               }
+               len -= tmp->len;
+-- 
+2.34.1
+
diff --git a/queue-5.16/can-etas_es58x-change-opened_channel_cnt-s-type-from.patch b/queue-5.16/can-etas_es58x-change-opened_channel_cnt-s-type-from.patch
new file mode 100644 (file)
index 0000000..8384e20
--- /dev/null
@@ -0,0 +1,145 @@
+From 1885746ec2ea63d5ee6970657c878610417c8531 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 12 Feb 2022 20:27:13 +0900
+Subject: can: etas_es58x: change opened_channel_cnt's type from atomic_t to u8
+
+From: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+
+[ Upstream commit f4896248e9025ff744b4147e6758274a1cb8cbae ]
+
+The driver uses an atomic_t variable: struct
+es58x_device::opened_channel_cnt to keep track of the number of opened
+channels in order to only allocate memory for the URBs when this count
+changes from zero to one.
+
+While the intent was to prevent race conditions, the choice of an
+atomic_t turns out to be a bad idea for several reasons:
+
+- implementation is incorrect and fails to decrement
+  opened_channel_cnt when the URB allocation fails as reported in
+  [1].
+
+- even if opened_channel_cnt were to be correctly decremented,
+  atomic_t is insufficient to cover edge cases: there can be a race
+  condition in which 1/ a first process fails to allocate URBs
+  memory 2/ a second process enters es58x_open() before the first
+  process does its cleanup and decrements opened_channed_cnt. In
+  which case, the second process would successfully return despite
+  the URBs memory not being allocated.
+
+- actually, any kind of locking mechanism was useless here because
+  it is redundant with the network stack big kernel lock
+  (a.k.a. rtnl_lock) which is being hold by all the callers of
+  net_device_ops:ndo_open() and net_device_ops:ndo_close(). c.f. the
+  ASSERST_RTNL() calls in __dev_open() [2] and __dev_close_many()
+  [3].
+
+The atmomic_t is thus replaced by a simple u8 type and the logic to
+increment and decrement es58x_device:opened_channel_cnt is simplified
+accordingly fixing the bug reported in [1]. We do not check again for
+ASSERST_RTNL() as this is already done by the callers.
+
+[1] https://lore.kernel.org/linux-can/20220201140351.GA2548@kili/T/#u
+[2] https://elixir.bootlin.com/linux/v5.16/source/net/core/dev.c#L1463
+[3] https://elixir.bootlin.com/linux/v5.16/source/net/core/dev.c#L1541
+
+Fixes: 8537257874e9 ("can: etas_es58x: add core support for ETAS ES58X CAN USB interfaces")
+Link: https://lore.kernel.org/all/20220212112713.577957-1-mailhol.vincent@wanadoo.fr
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
+Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/can/usb/etas_es58x/es58x_core.c | 9 +++++----
+ drivers/net/can/usb/etas_es58x/es58x_core.h | 8 +++++---
+ 2 files changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c
+index fb07c33ba0c3..78d0a5947ba1 100644
+--- a/drivers/net/can/usb/etas_es58x/es58x_core.c
++++ b/drivers/net/can/usb/etas_es58x/es58x_core.c
+@@ -1787,7 +1787,7 @@ static int es58x_open(struct net_device *netdev)
+       struct es58x_device *es58x_dev = es58x_priv(netdev)->es58x_dev;
+       int ret;
+-      if (atomic_inc_return(&es58x_dev->opened_channel_cnt) == 1) {
++      if (!es58x_dev->opened_channel_cnt) {
+               ret = es58x_alloc_rx_urbs(es58x_dev);
+               if (ret)
+                       return ret;
+@@ -1805,12 +1805,13 @@ static int es58x_open(struct net_device *netdev)
+       if (ret)
+               goto free_urbs;
++      es58x_dev->opened_channel_cnt++;
+       netif_start_queue(netdev);
+       return ret;
+  free_urbs:
+-      if (atomic_dec_and_test(&es58x_dev->opened_channel_cnt))
++      if (!es58x_dev->opened_channel_cnt)
+               es58x_free_urbs(es58x_dev);
+       netdev_err(netdev, "%s: Could not open the network device: %pe\n",
+                  __func__, ERR_PTR(ret));
+@@ -1845,7 +1846,8 @@ static int es58x_stop(struct net_device *netdev)
+       es58x_flush_pending_tx_msg(netdev);
+-      if (atomic_dec_and_test(&es58x_dev->opened_channel_cnt))
++      es58x_dev->opened_channel_cnt--;
++      if (!es58x_dev->opened_channel_cnt)
+               es58x_free_urbs(es58x_dev);
+       return 0;
+@@ -2214,7 +2216,6 @@ static struct es58x_device *es58x_init_es58x_dev(struct usb_interface *intf,
+       init_usb_anchor(&es58x_dev->tx_urbs_idle);
+       init_usb_anchor(&es58x_dev->tx_urbs_busy);
+       atomic_set(&es58x_dev->tx_urbs_idle_cnt, 0);
+-      atomic_set(&es58x_dev->opened_channel_cnt, 0);
+       usb_set_intfdata(intf, es58x_dev);
+       es58x_dev->rx_pipe = usb_rcvbulkpipe(es58x_dev->udev,
+diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.h b/drivers/net/can/usb/etas_es58x/es58x_core.h
+index 826a15871573..e5033cb5e695 100644
+--- a/drivers/net/can/usb/etas_es58x/es58x_core.h
++++ b/drivers/net/can/usb/etas_es58x/es58x_core.h
+@@ -373,8 +373,6 @@ struct es58x_operators {
+  *    queue wake/stop logic should prevent this URB from getting
+  *    empty. Please refer to es58x_get_tx_urb() for more details.
+  * @tx_urbs_idle_cnt: number of urbs in @tx_urbs_idle.
+- * @opened_channel_cnt: number of channels opened (c.f. es58x_open()
+- *    and es58x_stop()).
+  * @ktime_req_ns: kernel timestamp when es58x_set_realtime_diff_ns()
+  *    was called.
+  * @realtime_diff_ns: difference in nanoseconds between the clocks of
+@@ -384,6 +382,10 @@ struct es58x_operators {
+  *    in RX branches.
+  * @rx_max_packet_size: Maximum length of bulk-in URB.
+  * @num_can_ch: Number of CAN channel (i.e. number of elements of @netdev).
++ * @opened_channel_cnt: number of channels opened. Free of race
++ *    conditions because its two users (net_device_ops:ndo_open()
++ *    and net_device_ops:ndo_close()) guarantee that the network
++ *    stack big kernel lock (a.k.a. rtnl_mutex) is being hold.
+  * @rx_cmd_buf_len: Length of @rx_cmd_buf.
+  * @rx_cmd_buf: The device might split the URB commands in an
+  *    arbitrary amount of pieces. This buffer is used to concatenate
+@@ -406,7 +408,6 @@ struct es58x_device {
+       struct usb_anchor tx_urbs_busy;
+       struct usb_anchor tx_urbs_idle;
+       atomic_t tx_urbs_idle_cnt;
+-      atomic_t opened_channel_cnt;
+       u64 ktime_req_ns;
+       s64 realtime_diff_ns;
+@@ -415,6 +416,7 @@ struct es58x_device {
+       u16 rx_max_packet_size;
+       u8 num_can_ch;
++      u8 opened_channel_cnt;
+       u16 rx_cmd_buf_len;
+       union es58x_urb_cmd rx_cmd_buf;
+-- 
+2.34.1
+
diff --git a/queue-5.16/drm-amdgpu-fix-suspend-resume-hang-regression.patch b/queue-5.16/drm-amdgpu-fix-suspend-resume-hang-regression.patch
new file mode 100644 (file)
index 0000000..63c2d12
--- /dev/null
@@ -0,0 +1,44 @@
+From 5bb330da4ac107341315142178a975fc3953f3ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Mar 2022 14:11:59 +0800
+Subject: drm/amdgpu: fix suspend/resume hang regression
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Qiang Yu <qiang.yu@amd.com>
+
+[ Upstream commit f1ef17011c765495c876fa75435e59eecfdc1ee4 ]
+
+Regression has been reported that suspend/resume may hang with
+the previous vm ready check commit.
+
+So bring back the evicted list check as a temp fix.
+
+Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1922
+Fixes: c1a66c3bc425 ("drm/amdgpu: check vm ready by amdgpu_vm->evicting flag")
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Signed-off-by: Qiang Yu <qiang.yu@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index bc8d83698880..e73c09d05b6e 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -777,7 +777,8 @@ bool amdgpu_vm_ready(struct amdgpu_vm *vm)
+       amdgpu_vm_eviction_lock(vm);
+       ret = !vm->evicting;
+       amdgpu_vm_eviction_unlock(vm);
+-      return ret;
++
++      return ret && list_empty(&vm->evicted);
+ }
+ /**
+-- 
+2.34.1
+
diff --git a/queue-5.16/drm-bridge-ti-sn65dsi86-properly-undo-autosuspend.patch b/queue-5.16/drm-bridge-ti-sn65dsi86-properly-undo-autosuspend.patch
new file mode 100644 (file)
index 0000000..ada39a3
--- /dev/null
@@ -0,0 +1,54 @@
+From 7b75869723751933faead20e628c433346bcef41 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Feb 2022 14:18:43 -0800
+Subject: drm/bridge: ti-sn65dsi86: Properly undo autosuspend
+
+From: Douglas Anderson <dianders@chromium.org>
+
+[ Upstream commit 26d3474348293dc752c55fe6d41282199f73714c ]
+
+The PM Runtime docs say:
+  Drivers in ->remove() callback should undo the runtime PM changes done
+  in ->probe(). Usually this means calling pm_runtime_disable(),
+  pm_runtime_dont_use_autosuspend() etc.
+
+We weren't doing that for autosuspend. Let's do it.
+
+Fixes: 9bede63127c6 ("drm/bridge: ti-sn65dsi86: Use pm_runtime autosuspend")
+Signed-off-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220222141838.1.If784ba19e875e8ded4ec4931601ce6d255845245@changeid
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/bridge/ti-sn65dsi86.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+index 83d06c16d4d7..b7f74c146dee 100644
+--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c
++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c
+@@ -1474,6 +1474,7 @@ static inline void ti_sn_gpio_unregister(void) {}
+ static void ti_sn65dsi86_runtime_disable(void *data)
+ {
++      pm_runtime_dont_use_autosuspend(data);
+       pm_runtime_disable(data);
+ }
+@@ -1533,11 +1534,11 @@ static int ti_sn65dsi86_probe(struct i2c_client *client,
+                                    "failed to get reference clock\n");
+       pm_runtime_enable(dev);
++      pm_runtime_set_autosuspend_delay(pdata->dev, 500);
++      pm_runtime_use_autosuspend(pdata->dev);
+       ret = devm_add_action_or_reset(dev, ti_sn65dsi86_runtime_disable, dev);
+       if (ret)
+               return ret;
+-      pm_runtime_set_autosuspend_delay(pdata->dev, 500);
+-      pm_runtime_use_autosuspend(pdata->dev);
+       ti_sn65dsi86_debugfs_init(pdata);
+-- 
+2.34.1
+
diff --git a/queue-5.16/drm-i915-guc-slpc-correct-the-param-count-for-unset-.patch b/queue-5.16/drm-i915-guc-slpc-correct-the-param-count-for-unset-.patch
new file mode 100644 (file)
index 0000000..5ae7305
--- /dev/null
@@ -0,0 +1,42 @@
+From e7c44e365b06eb6dc329bc235a5c92f729d284d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 16 Feb 2022 10:15:04 -0800
+Subject: drm/i915/guc/slpc: Correct the param count for unset param
+
+From: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
+
+[ Upstream commit 1b279f6ad467535c3b8a66b4edefaca2cdd5bdc3 ]
+
+SLPC unset param H2G only needs one parameter - the id of the
+param.
+
+Fixes: 025cb07bebfa ("drm/i915/guc/slpc: Cache platform frequency limits")
+
+Suggested-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
+Signed-off-by: Vinay Belgaumkar <vinay.belgaumkar@intel.com>
+Reviewed-by: Umesh Nerlige Ramappa <umesh.nerlige.ramappa@intel.com>
+Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20220216181504.7155-1-vinay.belgaumkar@intel.com
+(cherry picked from commit 9648f1c3739505557d94ff749a4f32192ea81fe3)
+Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+index 65a3e7fdb2b2..95ff630157b9 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_slpc.c
+@@ -133,7 +133,7 @@ static int guc_action_slpc_unset_param(struct intel_guc *guc, u8 id)
+ {
+       u32 request[] = {
+               GUC_ACTION_HOST2GUC_PC_SLPC_REQUEST,
+-              SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 2),
++              SLPC_EVENT(SLPC_EVENT_PARAMETER_UNSET, 1),
+               id,
+       };
+-- 
+2.34.1
+
diff --git a/queue-5.16/e1000e-fix-possible-hw-unit-hang-after-an-s0ix-exit.patch b/queue-5.16/e1000e-fix-possible-hw-unit-hang-after-an-s0ix-exit.patch
new file mode 100644 (file)
index 0000000..2dba1e4
--- /dev/null
@@ -0,0 +1,124 @@
+From 4c3a8889de12355d19058fc38b0067b81f1bdee3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Jan 2022 19:31:23 +0200
+Subject: e1000e: Fix possible HW unit hang after an s0ix exit
+
+From: Sasha Neftin <sasha.neftin@intel.com>
+
+[ Upstream commit 1866aa0d0d6492bc2f8d22d0df49abaccf50cddd ]
+
+Disable the OEM bit/Gig Disable/restart AN impact and disable the PHY
+LAN connected device (LCD) reset during power management flows. This
+fixes possible HW unit hangs on the s0ix exit on some corporate ADL
+platforms.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=214821
+Fixes: 3e55d231716e ("e1000e: Add handshake with the CSME to support S0ix")
+Suggested-by: Dima Ruinskiy <dima.ruinskiy@intel.com>
+Suggested-by: Nir Efrati <nir.efrati@intel.com>
+Signed-off-by: Sasha Neftin <sasha.neftin@intel.com>
+Tested-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/e1000e/hw.h      |  1 +
+ drivers/net/ethernet/intel/e1000e/ich8lan.c |  4 ++++
+ drivers/net/ethernet/intel/e1000e/ich8lan.h |  1 +
+ drivers/net/ethernet/intel/e1000e/netdev.c  | 26 +++++++++++++++++++++
+ 4 files changed, 32 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h
+index bcf680e83811..13382df2f2ef 100644
+--- a/drivers/net/ethernet/intel/e1000e/hw.h
++++ b/drivers/net/ethernet/intel/e1000e/hw.h
+@@ -630,6 +630,7 @@ struct e1000_phy_info {
+       bool disable_polarity_correction;
+       bool is_mdix;
+       bool polarity_correction;
++      bool reset_disable;
+       bool speed_downgraded;
+       bool autoneg_wait_to_complete;
+ };
+diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
+index a3e42d06c63e..d60e2016d03c 100644
+--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
+@@ -2050,6 +2050,10 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
+       bool blocked = false;
+       int i = 0;
++      /* Check the PHY (LCD) reset flag */
++      if (hw->phy.reset_disable)
++              return true;
++
+       while ((blocked = !(er32(FWSM) & E1000_ICH_FWSM_RSPCIPHY)) &&
+              (i++ < 30))
+               usleep_range(10000, 11000);
+diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h
+index 2504b11c3169..638a3ddd7ada 100644
+--- a/drivers/net/ethernet/intel/e1000e/ich8lan.h
++++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h
+@@ -271,6 +271,7 @@
+ #define I217_CGFREG_ENABLE_MTA_RESET  0x0002
+ #define I217_MEMPWR                   PHY_REG(772, 26)
+ #define I217_MEMPWR_DISABLE_SMB_RELEASE       0x0010
++#define I217_MEMPWR_MOEM              0x1000
+ /* Receive Address Initial CRC Calculation */
+ #define E1000_PCH_RAICC(_n)   (0x05F50 + ((_n) * 4))
+diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
+index c063128ed1df..f2db4ff0003f 100644
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -6991,8 +6991,21 @@ static __maybe_unused int e1000e_pm_suspend(struct device *dev)
+       struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
+       struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct pci_dev *pdev = to_pci_dev(dev);
++      struct e1000_hw *hw = &adapter->hw;
++      u16 phy_data;
+       int rc;
++      if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
++          hw->mac.type >= e1000_pch_adp) {
++              /* Mask OEM Bits / Gig Disable / Restart AN (772_26[12] = 1) */
++              e1e_rphy(hw, I217_MEMPWR, &phy_data);
++              phy_data |= I217_MEMPWR_MOEM;
++              e1e_wphy(hw, I217_MEMPWR, phy_data);
++
++              /* Disable LCD reset */
++              hw->phy.reset_disable = true;
++      }
++
+       e1000e_flush_lpic(pdev);
+       e1000e_pm_freeze(dev);
+@@ -7014,6 +7027,8 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev)
+       struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
+       struct e1000_adapter *adapter = netdev_priv(netdev);
+       struct pci_dev *pdev = to_pci_dev(dev);
++      struct e1000_hw *hw = &adapter->hw;
++      u16 phy_data;
+       int rc;
+       /* Introduce S0ix implementation */
+@@ -7024,6 +7039,17 @@ static __maybe_unused int e1000e_pm_resume(struct device *dev)
+       if (rc)
+               return rc;
++      if (er32(FWSM) & E1000_ICH_FWSM_FW_VALID &&
++          hw->mac.type >= e1000_pch_adp) {
++              /* Unmask OEM Bits / Gig Disable / Restart AN 772_26[12] = 0 */
++              e1e_rphy(hw, I217_MEMPWR, &phy_data);
++              phy_data &= ~I217_MEMPWR_MOEM;
++              e1e_wphy(hw, I217_MEMPWR, phy_data);
++
++              /* Enable LCD reset */
++              hw->phy.reset_disable = false;
++      }
++
+       return e1000e_pm_thaw(dev);
+ }
+-- 
+2.34.1
+
diff --git a/queue-5.16/iavf-add-trace-while-removing-device.patch b/queue-5.16/iavf-add-trace-while-removing-device.patch
new file mode 100644 (file)
index 0000000..4934f53
--- /dev/null
@@ -0,0 +1,40 @@
+From 31531faa59684b9869ef5b39c00dd9730e0d1f2f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Jun 2021 15:43:48 +0200
+Subject: iavf: Add trace while removing device
+
+From: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+
+[ Upstream commit bdb9e5c7aec73a7b8b5acab37587b6de1203e68d ]
+
+Add kernel trace that device was removed.
+Currently there is no such information.
+I.e. Host admin removes a PCI device from a VM,
+than on VM shall be info about the event.
+
+This patch adds info log to iavf_remove function.
+
+Signed-off-by: Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>
+Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 5ff6d0de654e..fff9e9c7f76e 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -4005,6 +4005,7 @@ static void iavf_remove(struct pci_dev *pdev)
+       if (iavf_lock_timeout(&adapter->crit_lock, 5000))
+               dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n", __FUNCTION__);
++      dev_info(&adapter->pdev->dev, "Removing device\n");
+       /* Shut down all the garbage mashers on the detention level */
+       iavf_change_state(adapter, __IAVF_REMOVE);
+       adapter->aq_required = 0;
+-- 
+2.34.1
+
diff --git a/queue-5.16/iavf-add-waiting-so-the-port-is-initialized-in-remov.patch b/queue-5.16/iavf-add-waiting-so-the-port-is-initialized-in-remov.patch
new file mode 100644 (file)
index 0000000..252e507
--- /dev/null
@@ -0,0 +1,91 @@
+From 9ccd78004b57c3dede3fc56df9ca14144c4a5c24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Feb 2022 13:36:56 +0100
+Subject: iavf: Add waiting so the port is initialized in remove
+
+From: Slawomir Laba <slawomirx.laba@intel.com>
+
+[ Upstream commit 974578017fc1fdd06cea8afb9dfa32602e8529ed ]
+
+There exist races when port is being configured and remove is
+triggered.
+
+unregister_netdev is not and can't be called under crit_lock
+mutex since it is calling ndo_stop -> iavf_close which requires
+this lock. Depending on init state the netdev could be still
+unregistered so unregister_netdev never cleans up, when shortly
+after that the device could become registered.
+
+Make iavf_remove wait until port finishes initialization.
+All critical state changes are atomic (under crit_lock).
+Crashes that come from iavf_reset_interrupt_capability and
+iavf_free_traffic_irqs should now be solved in a graceful
+manner.
+
+Fixes: 605ca7c5c6707 ("iavf: Fix kernel BUG in free_msi_irqs")
+Signed-off-by: Slawomir Laba <slawomirx.laba@intel.com>
+Signed-off-by: Phani Burra <phani.r.burra@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 27 ++++++++++++---------
+ 1 file changed, 16 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index ab7cce78988a..d5055a49ae12 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -3981,7 +3981,6 @@ static int __maybe_unused iavf_resume(struct device *dev_d)
+ static void iavf_remove(struct pci_dev *pdev)
+ {
+       struct iavf_adapter *adapter = iavf_pdev_to_adapter(pdev);
+-      enum iavf_state_t prev_state = adapter->last_state;
+       struct net_device *netdev = adapter->netdev;
+       struct iavf_fdir_fltr *fdir, *fdirtmp;
+       struct iavf_vlan_filter *vlf, *vlftmp;
+@@ -3991,6 +3990,22 @@ static void iavf_remove(struct pci_dev *pdev)
+       struct iavf_hw *hw = &adapter->hw;
+       int err;
++      /* Wait until port initialization is complete.
++       * There are flows where register/unregister netdev may race.
++       */
++      while (1) {
++              mutex_lock(&adapter->crit_lock);
++              if (adapter->state == __IAVF_RUNNING ||
++                  adapter->state == __IAVF_DOWN) {
++                      mutex_unlock(&adapter->crit_lock);
++                      break;
++              }
++
++              mutex_unlock(&adapter->crit_lock);
++              usleep_range(500, 1000);
++      }
++      cancel_delayed_work_sync(&adapter->watchdog_task);
++
+       if (adapter->netdev_registered) {
+               unregister_netdev(netdev);
+               adapter->netdev_registered = false;
+@@ -4028,16 +4043,6 @@ static void iavf_remove(struct pci_dev *pdev)
+       iavf_free_all_rx_resources(adapter);
+       iavf_free_misc_irq(adapter);
+-      /* In case we enter iavf_remove from erroneous state, free traffic irqs
+-       * here, so as to not cause a kernel crash, when calling
+-       * iavf_reset_interrupt_capability.
+-       */
+-      if ((adapter->last_state == __IAVF_RESETTING &&
+-           prev_state != __IAVF_DOWN) ||
+-          (adapter->last_state == __IAVF_RUNNING &&
+-           !(netdev->flags & IFF_UP)))
+-              iavf_free_traffic_irqs(adapter);
+-
+       iavf_reset_interrupt_capability(adapter);
+       iavf_free_q_vectors(adapter);
+-- 
+2.34.1
+
diff --git a/queue-5.16/iavf-fix-__iavf_resetting-state-usage.patch b/queue-5.16/iavf-fix-__iavf_resetting-state-usage.patch
new file mode 100644 (file)
index 0000000..41e0e31
--- /dev/null
@@ -0,0 +1,75 @@
+From 99370296907366839eaca8f96dff68d036a1df4f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Feb 2022 13:38:55 +0100
+Subject: iavf: Fix __IAVF_RESETTING state usage
+
+From: Slawomir Laba <slawomirx.laba@intel.com>
+
+[ Upstream commit 14756b2ae265d526b8356e86729090b01778fdf6 ]
+
+The setup of __IAVF_RESETTING state in watchdog task had no
+effect and could lead to slow resets in the driver as
+the task for __IAVF_RESETTING state only requeues watchdog.
+Till now the __IAVF_RESETTING was interpreted by reset task
+as running state which could lead to errors with allocating
+and resources disposal.
+
+Make watchdog_task queue the reset task when it's necessary.
+Do not update the state to __IAVF_RESETTING so the reset task
+knows exactly what is the current state of the adapter.
+
+Fixes: 898ef1cb1cb2 ("iavf: Combine init and watchdog state machines")
+Signed-off-by: Slawomir Laba <slawomirx.laba@intel.com>
+Signed-off-by: Phani Burra <phani.r.burra@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 9ed02a8ca7a3..138db07bdfa8 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -1073,8 +1073,7 @@ void iavf_down(struct iavf_adapter *adapter)
+               rss->state = IAVF_ADV_RSS_DEL_REQUEST;
+       spin_unlock_bh(&adapter->adv_rss_lock);
+-      if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) &&
+-          adapter->state != __IAVF_RESETTING) {
++      if (!(adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)) {
+               /* cancel any current operation */
+               adapter->current_op = VIRTCHNL_OP_UNKNOWN;
+               /* Schedule operations to close down the HW. Don't wait
+@@ -1992,11 +1991,12 @@ static void iavf_watchdog_task(struct work_struct *work)
+       if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
+               iavf_change_state(adapter, __IAVF_COMM_FAILED);
+-      if (adapter->flags & IAVF_FLAG_RESET_NEEDED &&
+-          adapter->state != __IAVF_RESETTING) {
+-              iavf_change_state(adapter, __IAVF_RESETTING);
++      if (adapter->flags & IAVF_FLAG_RESET_NEEDED) {
+               adapter->aq_required = 0;
+               adapter->current_op = VIRTCHNL_OP_UNKNOWN;
++              mutex_unlock(&adapter->crit_lock);
++              queue_work(iavf_wq, &adapter->reset_task);
++              return;
+       }
+       switch (adapter->state) {
+@@ -2289,8 +2289,7 @@ static void iavf_reset_task(struct work_struct *work)
+        * ndo_open() returning, so we can't assume it means all our open
+        * tasks have finished, since we're not holding the rtnl_lock here.
+        */
+-      running = ((adapter->state == __IAVF_RUNNING) ||
+-                 (adapter->state == __IAVF_RESETTING));
++      running = adapter->state == __IAVF_RUNNING;
+       if (running) {
+               netdev->flags &= ~IFF_UP;
+-- 
+2.34.1
+
diff --git a/queue-5.16/iavf-fix-init-state-closure-on-remove.patch b/queue-5.16/iavf-fix-init-state-closure-on-remove.patch
new file mode 100644 (file)
index 0000000..28139c9
--- /dev/null
@@ -0,0 +1,120 @@
+From b5ee8c62e24fc6ddbec4fbbe5e7964968d6fc37c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Feb 2022 13:37:10 +0100
+Subject: iavf: Fix init state closure on remove
+
+From: Slawomir Laba <slawomirx.laba@intel.com>
+
+[ Upstream commit 3ccd54ef44ebfa0792c5441b6d9c86618f3378d1 ]
+
+When init states of the adapter work, the errors like lack
+of communication with the PF might hop in. If such events
+occur the driver restores previous states in order to retry
+initialization in a proper way. When remove task kicks in,
+this situation could lead to races with unregistering the
+netdevice as well as resources cleanup. With the commit
+introducing the waiting in remove for init to complete,
+this problem turns into an endless waiting if init never
+recovers from errors.
+
+Introduce __IAVF_IN_REMOVE_TASK bit to indicate that the
+remove thread has started.
+
+Make __IAVF_COMM_FAILED adapter state respect the
+__IAVF_IN_REMOVE_TASK bit and set the __IAVF_INIT_FAILED
+state and return without any action instead of trying to
+recover.
+
+Make __IAVF_INIT_FAILED adapter state respect the
+__IAVF_IN_REMOVE_TASK bit and return without any further
+actions.
+
+Make the loop in the remove handler break when adapter has
+__IAVF_INIT_FAILED state set.
+
+Fixes: 898ef1cb1cb2 ("iavf: Combine init and watchdog state machines")
+Signed-off-by: Slawomir Laba <slawomirx.laba@intel.com>
+Signed-off-by: Phani Burra <phani.r.burra@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h      |  4 ++++
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 24 ++++++++++++++++++++-
+ 2 files changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 21e0f3361560..ffc61993019b 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -188,6 +188,10 @@ enum iavf_state_t {
+       __IAVF_RUNNING,         /* opened, working */
+ };
++enum iavf_critical_section_t {
++      __IAVF_IN_REMOVE_TASK,  /* device being removed */
++};
++
+ #define IAVF_CLOUD_FIELD_OMAC         0x01
+ #define IAVF_CLOUD_FIELD_IMAC         0x02
+ #define IAVF_CLOUD_FIELD_IVLAN        0x04
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index d5055a49ae12..2a9044c8396f 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -2019,6 +2019,15 @@ static void iavf_watchdog_task(struct work_struct *work)
+                                  msecs_to_jiffies(1));
+               return;
+       case __IAVF_INIT_FAILED:
++              if (test_bit(__IAVF_IN_REMOVE_TASK,
++                           &adapter->crit_section)) {
++                      /* Do not update the state and do not reschedule
++                       * watchdog task, iavf_remove should handle this state
++                       * as it can loop forever
++                       */
++                      mutex_unlock(&adapter->crit_lock);
++                      return;
++              }
+               if (++adapter->aq_wait_count > IAVF_AQ_MAX_ERR) {
+                       dev_err(&adapter->pdev->dev,
+                               "Failed to communicate with PF; waiting before retry\n");
+@@ -2035,6 +2044,17 @@ static void iavf_watchdog_task(struct work_struct *work)
+               queue_delayed_work(iavf_wq, &adapter->watchdog_task, HZ);
+               return;
+       case __IAVF_COMM_FAILED:
++              if (test_bit(__IAVF_IN_REMOVE_TASK,
++                           &adapter->crit_section)) {
++                      /* Set state to __IAVF_INIT_FAILED and perform remove
++                       * steps. Remove IAVF_FLAG_PF_COMMS_FAILED so the task
++                       * doesn't bring the state back to __IAVF_COMM_FAILED.
++                       */
++                      iavf_change_state(adapter, __IAVF_INIT_FAILED);
++                      adapter->flags &= ~IAVF_FLAG_PF_COMMS_FAILED;
++                      mutex_unlock(&adapter->crit_lock);
++                      return;
++              }
+               reg_val = rd32(hw, IAVF_VFGEN_RSTAT) &
+                         IAVF_VFGEN_RSTAT_VFR_STATE_MASK;
+               if (reg_val == VIRTCHNL_VFR_VFACTIVE ||
+@@ -3990,13 +4010,15 @@ static void iavf_remove(struct pci_dev *pdev)
+       struct iavf_hw *hw = &adapter->hw;
+       int err;
++      set_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section);
+       /* Wait until port initialization is complete.
+        * There are flows where register/unregister netdev may race.
+        */
+       while (1) {
+               mutex_lock(&adapter->crit_lock);
+               if (adapter->state == __IAVF_RUNNING ||
+-                  adapter->state == __IAVF_DOWN) {
++                  adapter->state == __IAVF_DOWN ||
++                  adapter->state == __IAVF_INIT_FAILED) {
+                       mutex_unlock(&adapter->crit_lock);
+                       break;
+               }
+-- 
+2.34.1
+
diff --git a/queue-5.16/iavf-fix-locking-for-virtchnl_op_get_offload_vlan_v2.patch b/queue-5.16/iavf-fix-locking-for-virtchnl_op_get_offload_vlan_v2.patch
new file mode 100644 (file)
index 0000000..4681844
--- /dev/null
@@ -0,0 +1,123 @@
+From 4ed13bc6fb5640e254709a62b47d3bc20a2ed796 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Feb 2022 13:37:50 +0100
+Subject: iavf: Fix locking for VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS
+
+From: Slawomir Laba <slawomirx.laba@intel.com>
+
+[ Upstream commit 0579fafd37fb7efe091f0e6c8ccf968864f40f3e ]
+
+iavf_virtchnl_completion is called under crit_lock but when
+the code for VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS is called,
+this lock is released in order to obtain rtnl_lock to avoid
+ABBA deadlock with unregister_netdev.
+
+Along with the new way iavf_remove behaves, there exist
+many risks related to the lock release and attmepts to regrab
+it. The driver faces crashes related to races between
+unregister_netdev and netdev_update_features. Yet another
+risk is that the driver could already obtain the crit_lock
+in order to destroy it and iavf_virtchnl_completion could
+crash or block forever.
+
+Make iavf_virtchnl_completion never relock crit_lock in it's
+call paths.
+
+Extract rtnl_lock locking logic to the driver for
+unregister_netdev in order to set the netdev_registered flag
+inside the lock.
+
+Introduce a new flag that will inform adminq_task to perform
+the code from VIRTCHNL_OP_GET_OFFLOAD_VLAN_V2_CAPS right after
+it finishes processing messages. Guard this code with remove
+flags so it's never called when the driver is in remove state.
+
+Fixes: 5951a2b9812d ("iavf: Fix VLAN feature flags after VFR")
+Signed-off-by: Slawomir Laba <slawomirx.laba@intel.com>
+Signed-off-by: Phani Burra <phani.r.burra@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h          |  1 +
+ drivers/net/ethernet/intel/iavf/iavf_main.c     | 16 +++++++++++++++-
+ drivers/net/ethernet/intel/iavf/iavf_virtchnl.c | 14 +-------------
+ 3 files changed, 17 insertions(+), 14 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index ffc61993019b..9a122aea6979 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -274,6 +274,7 @@ struct iavf_adapter {
+ #define IAVF_FLAG_LEGACY_RX                   BIT(15)
+ #define IAVF_FLAG_REINIT_ITR_NEEDED           BIT(16)
+ #define IAVF_FLAG_QUEUES_DISABLED             BIT(17)
++#define IAVF_FLAG_SETUP_NETDEV_FEATURES               BIT(18)
+ /* duplicates for common code */
+ #define IAVF_FLAG_DCB_ENABLED                 0
+       /* flags for admin queue service task */
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 2a9044c8396f..1af3fe427543 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -2465,6 +2465,18 @@ static void iavf_adminq_task(struct work_struct *work)
+       } while (pending);
+       mutex_unlock(&adapter->crit_lock);
++      if ((adapter->flags & IAVF_FLAG_SETUP_NETDEV_FEATURES)) {
++              if (adapter->netdev_registered ||
++                  !test_bit(__IAVF_IN_REMOVE_TASK, &adapter->crit_section)) {
++                      struct net_device *netdev = adapter->netdev;
++
++                      rtnl_lock();
++                      netdev_update_features(netdev);
++                      rtnl_unlock();
++              }
++
++              adapter->flags &= ~IAVF_FLAG_SETUP_NETDEV_FEATURES;
++      }
+       if ((adapter->flags &
+            (IAVF_FLAG_RESET_PENDING | IAVF_FLAG_RESET_NEEDED)) ||
+           adapter->state == __IAVF_RESETTING)
+@@ -4029,8 +4041,10 @@ static void iavf_remove(struct pci_dev *pdev)
+       cancel_delayed_work_sync(&adapter->watchdog_task);
+       if (adapter->netdev_registered) {
+-              unregister_netdev(netdev);
++              rtnl_lock();
++              unregister_netdevice(netdev);
+               adapter->netdev_registered = false;
++              rtnl_unlock();
+       }
+       if (CLIENT_ALLOWED(adapter)) {
+               err = iavf_lan_del_device(adapter);
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+index d60bf7c21200..d3da65d24bd6 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
+@@ -1752,19 +1752,7 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
+               spin_unlock_bh(&adapter->mac_vlan_list_lock);
+               iavf_process_config(adapter);
+-
+-              /* unlock crit_lock before acquiring rtnl_lock as other
+-               * processes holding rtnl_lock could be waiting for the same
+-               * crit_lock
+-               */
+-              mutex_unlock(&adapter->crit_lock);
+-              rtnl_lock();
+-              netdev_update_features(adapter->netdev);
+-              rtnl_unlock();
+-              if (iavf_lock_timeout(&adapter->crit_lock, 10000))
+-                      dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n",
+-                               __FUNCTION__);
+-
++              adapter->flags |= IAVF_FLAG_SETUP_NETDEV_FEATURES;
+               }
+               break;
+       case VIRTCHNL_OP_ENABLE_QUEUES:
+-- 
+2.34.1
+
diff --git a/queue-5.16/iavf-fix-race-in-init-state.patch b/queue-5.16/iavf-fix-race-in-init-state.patch
new file mode 100644 (file)
index 0000000..348a073
--- /dev/null
@@ -0,0 +1,51 @@
+From e890ce16df6f8ce37e95dc56b74ff4da0c1aaaaf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Feb 2022 13:38:01 +0100
+Subject: iavf: Fix race in init state
+
+From: Slawomir Laba <slawomirx.laba@intel.com>
+
+[ Upstream commit a472eb5cbaebb5774672c565e024336c039e9128 ]
+
+When iavf_init_version_check sends VIRTCHNL_OP_GET_VF_RESOURCES
+message, the driver will wait for the response after requeueing
+the watchdog task in iavf_init_get_resources call stack. The
+logic is implemented this way that iavf_init_get_resources has
+to be called in order to allocate adapter->vf_res. It is polling
+for the AQ response in iavf_get_vf_config function. Expect a
+call trace from kernel when adminq_task worker handles this
+message first. adapter->vf_res will be NULL in
+iavf_virtchnl_completion.
+
+Make the watchdog task not queue the adminq_task if the init
+process is not finished yet.
+
+Fixes: 898ef1cb1cb2 ("iavf: Combine init and watchdog state machines")
+Signed-off-by: Slawomir Laba <slawomirx.laba@intel.com>
+Signed-off-by: Phani Burra <phani.r.burra@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index 1af3fe427543..9ed02a8ca7a3 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -2124,7 +2124,8 @@ static void iavf_watchdog_task(struct work_struct *work)
+       schedule_delayed_work(&adapter->client_task, msecs_to_jiffies(5));
+       mutex_unlock(&adapter->crit_lock);
+ restart_watchdog:
+-      queue_work(iavf_wq, &adapter->adminq_task);
++      if (adapter->state >= __IAVF_DOWN)
++              queue_work(iavf_wq, &adapter->adminq_task);
+       if (adapter->aq_required)
+               queue_delayed_work(iavf_wq, &adapter->watchdog_task,
+                                  msecs_to_jiffies(20));
+-- 
+2.34.1
+
diff --git a/queue-5.16/iavf-rework-mutexes-for-better-synchronisation.patch b/queue-5.16/iavf-rework-mutexes-for-better-synchronisation.patch
new file mode 100644 (file)
index 0000000..d7b6875
--- /dev/null
@@ -0,0 +1,220 @@
+From aa8fabb6d326832ab5aebcc9186aa22245552065 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 23 Feb 2022 13:35:49 +0100
+Subject: iavf: Rework mutexes for better synchronisation
+
+From: Slawomir Laba <slawomirx.laba@intel.com>
+
+[ Upstream commit fc2e6b3b132a907378f6af08356b105a4139c4fb ]
+
+The driver used to crash in multiple spots when put to stress testing
+of the init, reset and remove paths.
+
+The user would experience call traces or hangs when creating,
+resetting, removing VFs. Depending on the machines, the call traces
+are happening in random spots, like reset restoring resources racing
+with driver remove.
+
+Make adapter->crit_lock mutex a mandatory lock for guarding the
+operations performed on all workqueues and functions dealing with
+resource allocation and disposal.
+
+Make __IAVF_REMOVE a final state of the driver respected by
+workqueues that shall not requeue, when they fail to obtain the
+crit_lock.
+
+Make the IRQ handler not to queue the new work for adminq_task
+when the __IAVF_REMOVE state is set.
+
+Fixes: 5ac49f3c2702 ("iavf: use mutexes for locking of critical sections")
+Signed-off-by: Slawomir Laba <slawomirx.laba@intel.com>
+Signed-off-by: Phani Burra <phani.r.burra@intel.com>
+Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
+Signed-off-by: Mateusz Palczewski <mateusz.palczewski@intel.com>
+Tested-by: Konrad Jankowski <konrad0.jankowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/iavf/iavf.h      |  1 -
+ drivers/net/ethernet/intel/iavf/iavf_main.c | 66 +++++++++++----------
+ 2 files changed, 36 insertions(+), 31 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
+index 3789269ce741..21e0f3361560 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf.h
++++ b/drivers/net/ethernet/intel/iavf/iavf.h
+@@ -233,7 +233,6 @@ struct iavf_adapter {
+       struct list_head mac_filter_list;
+       struct mutex crit_lock;
+       struct mutex client_lock;
+-      struct mutex remove_lock;
+       /* Lock to protect accesses to MAC and VLAN lists */
+       spinlock_t mac_vlan_list_lock;
+       char misc_vector_name[IFNAMSIZ + 9];
+diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
+index fff9e9c7f76e..ab7cce78988a 100644
+--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
++++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
+@@ -302,8 +302,9 @@ static irqreturn_t iavf_msix_aq(int irq, void *data)
+       rd32(hw, IAVF_VFINT_ICR01);
+       rd32(hw, IAVF_VFINT_ICR0_ENA1);
+-      /* schedule work on the private workqueue */
+-      queue_work(iavf_wq, &adapter->adminq_task);
++      if (adapter->state != __IAVF_REMOVE)
++              /* schedule work on the private workqueue */
++              queue_work(iavf_wq, &adapter->adminq_task);
+       return IRQ_HANDLED;
+ }
+@@ -1981,8 +1982,12 @@ static void iavf_watchdog_task(struct work_struct *work)
+       struct iavf_hw *hw = &adapter->hw;
+       u32 reg_val;
+-      if (!mutex_trylock(&adapter->crit_lock))
++      if (!mutex_trylock(&adapter->crit_lock)) {
++              if (adapter->state == __IAVF_REMOVE)
++                      return;
++
+               goto restart_watchdog;
++      }
+       if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
+               iavf_change_state(adapter, __IAVF_COMM_FAILED);
+@@ -2193,13 +2198,13 @@ static void iavf_reset_task(struct work_struct *work)
+       /* When device is being removed it doesn't make sense to run the reset
+        * task, just return in such a case.
+        */
+-      if (mutex_is_locked(&adapter->remove_lock))
+-              return;
++      if (!mutex_trylock(&adapter->crit_lock)) {
++              if (adapter->state != __IAVF_REMOVE)
++                      queue_work(iavf_wq, &adapter->reset_task);
+-      if (iavf_lock_timeout(&adapter->crit_lock, 200)) {
+-              schedule_work(&adapter->reset_task);
+               return;
+       }
++
+       while (!mutex_trylock(&adapter->client_lock))
+               usleep_range(500, 1000);
+       if (CLIENT_ENABLED(adapter)) {
+@@ -2412,13 +2417,19 @@ static void iavf_adminq_task(struct work_struct *work)
+       if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED)
+               goto out;
++      if (!mutex_trylock(&adapter->crit_lock)) {
++              if (adapter->state == __IAVF_REMOVE)
++                      return;
++
++              queue_work(iavf_wq, &adapter->adminq_task);
++              goto out;
++      }
++
+       event.buf_len = IAVF_MAX_AQ_BUF_SIZE;
+       event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL);
+       if (!event.msg_buf)
+               goto out;
+-      if (iavf_lock_timeout(&adapter->crit_lock, 200))
+-              goto freedom;
+       do {
+               ret = iavf_clean_arq_element(hw, &event, &pending);
+               v_op = (enum virtchnl_ops)le32_to_cpu(event.desc.cookie_high);
+@@ -3386,11 +3397,12 @@ static int iavf_close(struct net_device *netdev)
+       struct iavf_adapter *adapter = netdev_priv(netdev);
+       int status;
+-      if (adapter->state <= __IAVF_DOWN_PENDING)
+-              return 0;
++      mutex_lock(&adapter->crit_lock);
+-      while (!mutex_trylock(&adapter->crit_lock))
+-              usleep_range(500, 1000);
++      if (adapter->state <= __IAVF_DOWN_PENDING) {
++              mutex_unlock(&adapter->crit_lock);
++              return 0;
++      }
+       set_bit(__IAVF_VSI_DOWN, adapter->vsi.state);
+       if (CLIENT_ENABLED(adapter))
+@@ -3854,7 +3866,6 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+        */
+       mutex_init(&adapter->crit_lock);
+       mutex_init(&adapter->client_lock);
+-      mutex_init(&adapter->remove_lock);
+       mutex_init(&hw->aq.asq_mutex);
+       mutex_init(&hw->aq.arq_mutex);
+@@ -3979,11 +3990,7 @@ static void iavf_remove(struct pci_dev *pdev)
+       struct iavf_cloud_filter *cf, *cftmp;
+       struct iavf_hw *hw = &adapter->hw;
+       int err;
+-      /* Indicate we are in remove and not to run reset_task */
+-      mutex_lock(&adapter->remove_lock);
+-      cancel_work_sync(&adapter->reset_task);
+-      cancel_delayed_work_sync(&adapter->watchdog_task);
+-      cancel_delayed_work_sync(&adapter->client_task);
++
+       if (adapter->netdev_registered) {
+               unregister_netdev(netdev);
+               adapter->netdev_registered = false;
+@@ -3995,6 +4002,10 @@ static void iavf_remove(struct pci_dev *pdev)
+                                err);
+       }
++      mutex_lock(&adapter->crit_lock);
++      dev_info(&adapter->pdev->dev, "Remove device\n");
++      iavf_change_state(adapter, __IAVF_REMOVE);
++
+       iavf_request_reset(adapter);
+       msleep(50);
+       /* If the FW isn't responding, kick it once, but only once. */
+@@ -4002,18 +4013,19 @@ static void iavf_remove(struct pci_dev *pdev)
+               iavf_request_reset(adapter);
+               msleep(50);
+       }
+-      if (iavf_lock_timeout(&adapter->crit_lock, 5000))
+-              dev_warn(&adapter->pdev->dev, "failed to acquire crit_lock in %s\n", __FUNCTION__);
+-      dev_info(&adapter->pdev->dev, "Removing device\n");
++      iavf_misc_irq_disable(adapter);
+       /* Shut down all the garbage mashers on the detention level */
+-      iavf_change_state(adapter, __IAVF_REMOVE);
++      cancel_work_sync(&adapter->reset_task);
++      cancel_delayed_work_sync(&adapter->watchdog_task);
++      cancel_work_sync(&adapter->adminq_task);
++      cancel_delayed_work_sync(&adapter->client_task);
++
+       adapter->aq_required = 0;
+       adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED;
+       iavf_free_all_tx_resources(adapter);
+       iavf_free_all_rx_resources(adapter);
+-      iavf_misc_irq_disable(adapter);
+       iavf_free_misc_irq(adapter);
+       /* In case we enter iavf_remove from erroneous state, free traffic irqs
+@@ -4029,10 +4041,6 @@ static void iavf_remove(struct pci_dev *pdev)
+       iavf_reset_interrupt_capability(adapter);
+       iavf_free_q_vectors(adapter);
+-      cancel_delayed_work_sync(&adapter->watchdog_task);
+-
+-      cancel_work_sync(&adapter->adminq_task);
+-
+       iavf_free_rss(adapter);
+       if (hw->aq.asq.count)
+@@ -4044,8 +4052,6 @@ static void iavf_remove(struct pci_dev *pdev)
+       mutex_destroy(&adapter->client_lock);
+       mutex_unlock(&adapter->crit_lock);
+       mutex_destroy(&adapter->crit_lock);
+-      mutex_unlock(&adapter->remove_lock);
+-      mutex_destroy(&adapter->remove_lock);
+       iounmap(hw->hw_addr);
+       pci_release_regions(pdev);
+-- 
+2.34.1
+
diff --git a/queue-5.16/ibmvnic-allow-queueing-resets-during-probe.patch b/queue-5.16/ibmvnic-allow-queueing-resets-during-probe.patch
new file mode 100644 (file)
index 0000000..0c5138f
--- /dev/null
@@ -0,0 +1,274 @@
+From 8dda9af1e93ced0c920755ad32d2e6c93ea00be8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Feb 2022 22:23:58 -0800
+Subject: ibmvnic: Allow queueing resets during probe
+
+From: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+
+[ Upstream commit fd98693cb0721317f27341951593712c580c36a1 ]
+
+We currently don't allow queuing resets when adapter is in VNIC_PROBING
+state - instead we throw away the reset and return EBUSY. The reasoning
+is probably that during ibmvnic_probe() the ibmvnic_adapter itself is
+being initialized so performing a reset during this time can lead us to
+accessing fields in the ibmvnic_adapter that are not fully initialized.
+A review of the code shows that all the adapter state neede to process a
+reset is initialized before registering the CRQ so that should no longer
+be a concern.
+
+Further the expectation is that if we do get a reset (transport event)
+during probe, the do..while() loop in ibmvnic_probe() will handle this
+by reinitializing the CRQ.
+
+While that is true to some extent, it is possible that the reset might
+occur _after_ the CRQ is registered and CRQ_INIT message was exchanged
+but _before_ the adapter state is set to VNIC_PROBED. As mentioned above,
+such a reset will be thrown away. While the client assumes that the
+adapter is functional, the vnic server will wait for the client to reinit
+the adapter. This disconnect between the two leaves the adapter down
+needing manual intervention.
+
+Because ibmvnic_probe() has other work to do after initializing the CRQ
+(such as registering the netdev at a minimum) and because the reset event
+can occur at any instant after the CRQ is initialized, there will always
+be a window between initializing the CRQ and considering the adapter
+ready for resets (ie state == PROBED).
+
+So rather than discarding resets during this window, allow queueing them
+- but only process them after the adapter is fully initialized.
+
+To do this, introduce a new completion state ->probe_done and have the
+reset worker thread wait on this before processing resets.
+
+This change brings up two new situations in or just after ibmvnic_probe().
+First after one or more resets were queued, we encounter an error and
+decide to retry the initialization.  At that point the queued resets are
+no longer relevant since we could be talking to a new vnic server. So we
+must purge/flush the queued resets before restarting the initialization.
+As a side note, since we are still in the probing stage and we have not
+registered the netdev, it will not be CHANGE_PARAM reset.
+
+Second this change opens up a potential race between the worker thread
+in __ibmvnic_reset(), the tasklet and the ibmvnic_open() due to the
+following sequence of events:
+
+       1. Register CRQ
+       2. Get transport event before CRQ_INIT completes.
+       3. Tasklet schedules reset:
+               a) add rwi to list
+               b) schedule_work() to start worker thread which runs
+                  and waits for ->probe_done.
+       4. ibmvnic_probe() decides to retry, purges rwi_list
+       5. Re-register crq and this time rest of probe succeeds - register
+          netdev and complete(->probe_done).
+       6. Worker thread resumes in __ibmvnic_reset() from 3b.
+       7. Worker thread sets ->resetting bit
+       8. ibmvnic_open() comes in, notices ->resetting bit, sets state
+          to IBMVNIC_OPEN and returns early expecting worker thread to
+          finish the open.
+       9. Worker thread finds rwi_list empty and returns without
+          opening the interface.
+
+If this happens, the ->ndo_open() call is effectively lost and the
+interface remains down. To address this, ensure that ->rwi_list is
+not empty before setting the ->resetting  bit. See also comments in
+__ibmvnic_reset().
+
+Fixes: 6a2fb0e99f9c ("ibmvnic: driver initialization for kdump/kexec")
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 107 ++++++++++++++++++++++++++---
+ drivers/net/ethernet/ibm/ibmvnic.h |   1 +
+ 2 files changed, 98 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 679257d3a3c6..a8b65c072f64 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -2618,23 +2618,82 @@ static int do_passive_init(struct ibmvnic_adapter *adapter)
+ static void __ibmvnic_reset(struct work_struct *work)
+ {
+       struct ibmvnic_adapter *adapter;
+-      bool saved_state = false;
++      unsigned int timeout = 5000;
+       struct ibmvnic_rwi *tmprwi;
++      bool saved_state = false;
+       struct ibmvnic_rwi *rwi;
+       unsigned long flags;
+-      u32 reset_state;
++      struct device *dev;
++      bool need_reset;
+       int num_fails = 0;
++      u32 reset_state;
+       int rc = 0;
+       adapter = container_of(work, struct ibmvnic_adapter, ibmvnic_reset);
++              dev = &adapter->vdev->dev;
+-      if (test_and_set_bit_lock(0, &adapter->resetting)) {
++      /* Wait for ibmvnic_probe() to complete. If probe is taking too long
++       * or if another reset is in progress, defer work for now. If probe
++       * eventually fails it will flush and terminate our work.
++       *
++       * Three possibilities here:
++       * 1. Adpater being removed  - just return
++       * 2. Timed out on probe or another reset in progress - delay the work
++       * 3. Completed probe - perform any resets in queue
++       */
++      if (adapter->state == VNIC_PROBING &&
++          !wait_for_completion_timeout(&adapter->probe_done, timeout)) {
++              dev_err(dev, "Reset thread timed out on probe");
+               queue_delayed_work(system_long_wq,
+                                  &adapter->ibmvnic_delayed_reset,
+                                  IBMVNIC_RESET_DELAY);
+               return;
+       }
++      /* adapter is done with probe (i.e state is never VNIC_PROBING now) */
++      if (adapter->state == VNIC_REMOVING)
++              return;
++
++      /* ->rwi_list is stable now (no one else is removing entries) */
++
++      /* ibmvnic_probe() may have purged the reset queue after we were
++       * scheduled to process a reset so there maybe no resets to process.
++       * Before setting the ->resetting bit though, we have to make sure
++       * that there is infact a reset to process. Otherwise we may race
++       * with ibmvnic_open() and end up leaving the vnic down:
++       *
++       *      __ibmvnic_reset()           ibmvnic_open()
++       *      -----------------           --------------
++       *
++       *  set ->resetting bit
++       *                              find ->resetting bit is set
++       *                              set ->state to IBMVNIC_OPEN (i.e
++       *                              assume reset will open device)
++       *                              return
++       *  find reset queue empty
++       *  return
++       *
++       *      Neither performed vnic login/open and vnic stays down
++       *
++       * If we hold the lock and conditionally set the bit, either we
++       * or ibmvnic_open() will complete the open.
++       */
++      need_reset = false;
++      spin_lock(&adapter->rwi_lock);
++      if (!list_empty(&adapter->rwi_list)) {
++              if (test_and_set_bit_lock(0, &adapter->resetting)) {
++                      queue_delayed_work(system_long_wq,
++                                         &adapter->ibmvnic_delayed_reset,
++                                         IBMVNIC_RESET_DELAY);
++              } else {
++                      need_reset = true;
++              }
++      }
++      spin_unlock(&adapter->rwi_lock);
++
++      if (!need_reset)
++              return;
++
+       rwi = get_next_rwi(adapter);
+       while (rwi) {
+               spin_lock_irqsave(&adapter->state_lock, flags);
+@@ -2786,13 +2845,6 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
+               goto err;
+       }
+-      if (adapter->state == VNIC_PROBING) {
+-              netdev_warn(netdev, "Adapter reset during probe\n");
+-              adapter->init_done_rc = -EAGAIN;
+-              ret = EAGAIN;
+-              goto err;
+-      }
+-
+       list_for_each_entry(tmp, &adapter->rwi_list, list) {
+               if (tmp->reset_reason == reason) {
+                       netdev_dbg(netdev, "Skipping matching reset, reason=%s\n",
+@@ -5761,6 +5813,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
+       struct ibmvnic_adapter *adapter;
+       struct net_device *netdev;
+       unsigned char *mac_addr_p;
++      unsigned long flags;
+       bool init_success;
+       int rc;
+@@ -5805,6 +5858,7 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
+       spin_lock_init(&adapter->rwi_lock);
+       spin_lock_init(&adapter->state_lock);
+       mutex_init(&adapter->fw_lock);
++      init_completion(&adapter->probe_done);
+       init_completion(&adapter->init_done);
+       init_completion(&adapter->fw_done);
+       init_completion(&adapter->reset_done);
+@@ -5822,6 +5876,26 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
+                */
+               adapter->failover_pending = false;
++              /* If we had already initialized CRQ, we may have one or
++               * more resets queued already. Discard those and release
++               * the CRQ before initializing the CRQ again.
++               */
++              release_crq_queue(adapter);
++
++              /* Since we are still in PROBING state, __ibmvnic_reset()
++               * will not access the ->rwi_list and since we released CRQ,
++               * we won't get _new_ transport events. But there maybe an
++               * ongoing ibmvnic_reset() call. So serialize access to
++               * rwi_list. If we win the race, ibvmnic_reset() could add
++               * a reset after we purged but thats ok - we just may end
++               * up with an extra reset (i.e similar to having two or more
++               * resets in the queue at once).
++               * CHECK.
++               */
++              spin_lock_irqsave(&adapter->rwi_lock, flags);
++              flush_reset_queue(adapter);
++              spin_unlock_irqrestore(&adapter->rwi_lock, flags);
++
+               rc = init_crq_queue(adapter);
+               if (rc) {
+                       dev_err(&dev->dev, "Couldn't initialize crq. rc=%d\n",
+@@ -5873,6 +5947,8 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
+       }
+       dev_info(&dev->dev, "ibmvnic registered\n");
++      complete(&adapter->probe_done);
++
+       return 0;
+ ibmvnic_register_fail:
+@@ -5887,6 +5963,17 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
+ ibmvnic_init_fail:
+       release_sub_crqs(adapter, 1);
+       release_crq_queue(adapter);
++
++      /* cleanup worker thread after releasing CRQ so we don't get
++       * transport events (i.e new work items for the worker thread).
++       */
++      adapter->state = VNIC_REMOVING;
++      complete(&adapter->probe_done);
++      flush_work(&adapter->ibmvnic_reset);
++      flush_delayed_work(&adapter->ibmvnic_delayed_reset);
++
++      flush_reset_queue(adapter);
++
+       mutex_destroy(&adapter->fw_lock);
+       free_netdev(netdev);
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.h b/drivers/net/ethernet/ibm/ibmvnic.h
+index b8e42f67d897..549a9b7b1a70 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.h
++++ b/drivers/net/ethernet/ibm/ibmvnic.h
+@@ -933,6 +933,7 @@ struct ibmvnic_adapter {
+       struct ibmvnic_tx_pool *tx_pool;
+       struct ibmvnic_tx_pool *tso_pool;
++      struct completion probe_done;
+       struct completion init_done;
+       int init_done_rc;
+-- 
+2.34.1
+
diff --git a/queue-5.16/ibmvnic-clear-fop-when-retrying-probe.patch b/queue-5.16/ibmvnic-clear-fop-when-retrying-probe.patch
new file mode 100644 (file)
index 0000000..a41c44d
--- /dev/null
@@ -0,0 +1,46 @@
+From 2451f3416710e850ea0b6de71393b7a7cba2f02e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Feb 2022 22:23:57 -0800
+Subject: ibmvnic: clear fop when retrying probe
+
+From: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+
+[ Upstream commit f628ad531b4f34fdba0984255b4a2850dd369513 ]
+
+Clear ->failover_pending flag that may have been set in the previous
+pass of registering CRQ. If we don't clear, a subsequent ibmvnic_open()
+call would be misled into thinking a failover is pending and assuming
+that the reset worker thread would open the adapter. If this pass of
+registering the CRQ succeeds (i.e there is no transport event), there
+wouldn't be a reset worker thread.
+
+This would leave the adapter unconfigured and require manual intervention
+to bring it up during boot.
+
+Fixes: 5a18e1e0c193 ("ibmvnic: Fix failover case for non-redundant configuration")
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 26ea1f32281f..679257d3a3c6 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -5817,6 +5817,11 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
+       do {
+               reinit_init_done(adapter);
++              /* clear any failovers we got in the previous pass
++               * since we are reinitializing the CRQ
++               */
++              adapter->failover_pending = false;
++
+               rc = init_crq_queue(adapter);
+               if (rc) {
+                       dev_err(&dev->dev, "Couldn't initialize crq. rc=%d\n",
+-- 
+2.34.1
+
diff --git a/queue-5.16/ibmvnic-complete-init_done-on-transport-events.patch b/queue-5.16/ibmvnic-complete-init_done-on-transport-events.patch
new file mode 100644 (file)
index 0000000..b2dc06f
--- /dev/null
@@ -0,0 +1,42 @@
+From a4db48354e5a7a137f12185261d3caf27e0da6c9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Feb 2022 22:23:54 -0800
+Subject: ibmvnic: complete init_done on transport events
+
+From: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+
+[ Upstream commit 36491f2df9ad2501e5a4ec25d3d95d72bafd2781 ]
+
+If we get a transport event, set the error and mark the init as
+complete so the attempt to send crq-init or login fail sooner
+rather than wait for the timeout.
+
+Fixes: bbd669a868bb ("ibmvnic: Fix completion structure initialization")
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 5c8264e3979a..16e772f80ec5 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -5352,6 +5352,13 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
+                       adapter->fw_done_rc = -EIO;
+                       complete(&adapter->fw_done);
+               }
++
++              /* if we got here during crq-init, retry crq-init */
++              if (!completion_done(&adapter->init_done)) {
++                      adapter->init_done_rc = -EAGAIN;
++                      complete(&adapter->init_done);
++              }
++
+               if (!completion_done(&adapter->stats_done))
+                       complete(&adapter->stats_done);
+               if (test_bit(0, &adapter->resetting))
+-- 
+2.34.1
+
diff --git a/queue-5.16/ibmvnic-define-flush_reset_queue-helper.patch b/queue-5.16/ibmvnic-define-flush_reset_queue-helper.patch
new file mode 100644 (file)
index 0000000..784e54f
--- /dev/null
@@ -0,0 +1,68 @@
+From 46cbdf8227c219ca051270e873f38443f974e17a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Feb 2022 22:23:53 -0800
+Subject: ibmvnic: define flush_reset_queue helper
+
+From: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+
+[ Upstream commit 83da53f7e4bd86dca4b2edc1e2bb324fb3c033a1 ]
+
+Define and use a helper to flush the reset queue.
+
+Fixes: 2770a7984db5 ("ibmvnic: Introduce hard reset recovery")
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 24 ++++++++++++++++--------
+ 1 file changed, 16 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 945a84c2134f..5c8264e3979a 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -2731,12 +2731,23 @@ static void __ibmvnic_delayed_reset(struct work_struct *work)
+       __ibmvnic_reset(&adapter->ibmvnic_reset);
+ }
++static void flush_reset_queue(struct ibmvnic_adapter *adapter)
++{
++      struct list_head *entry, *tmp_entry;
++
++      if (!list_empty(&adapter->rwi_list)) {
++              list_for_each_safe(entry, tmp_entry, &adapter->rwi_list) {
++                      list_del(entry);
++                      kfree(list_entry(entry, struct ibmvnic_rwi, list));
++              }
++      }
++}
++
+ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
+                        enum ibmvnic_reset_reason reason)
+ {
+-      struct list_head *entry, *tmp_entry;
+-      struct ibmvnic_rwi *rwi, *tmp;
+       struct net_device *netdev = adapter->netdev;
++      struct ibmvnic_rwi *rwi, *tmp;
+       unsigned long flags;
+       int ret;
+@@ -2779,12 +2790,9 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter,
+       /* if we just received a transport event,
+        * flush reset queue and process this reset
+        */
+-      if (adapter->force_reset_recovery && !list_empty(&adapter->rwi_list)) {
+-              list_for_each_safe(entry, tmp_entry, &adapter->rwi_list) {
+-                      list_del(entry);
+-                      kfree(list_entry(entry, struct ibmvnic_rwi, list));
+-              }
+-      }
++      if (adapter->force_reset_recovery)
++              flush_reset_queue(adapter);
++
+       rwi->reset_reason = reason;
+       list_add_tail(&rwi->list, &adapter->rwi_list);
+       netdev_dbg(adapter->netdev, "Scheduling reset (reason %s)\n",
+-- 
+2.34.1
+
diff --git a/queue-5.16/ibmvnic-init-init_done_rc-earlier.patch b/queue-5.16/ibmvnic-init-init_done_rc-earlier.patch
new file mode 100644 (file)
index 0000000..626ef88
--- /dev/null
@@ -0,0 +1,110 @@
+From c6d999a4962f162f0de1b18f7f35c1be5b86fdb5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Feb 2022 22:23:56 -0800
+Subject: ibmvnic: init init_done_rc earlier
+
+From: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+
+[ Upstream commit ae16bf15374d8b055e040ac6f3f1147ab1c9bb7d ]
+
+We currently initialize the ->init_done completion/return code fields
+before issuing a CRQ_INIT command. But if we get a transport event soon
+after registering the CRQ the taskslet may already have recorded the
+completion and error code. If we initialize here, we might overwrite/
+lose that and end up issuing the CRQ_INIT only to timeout later.
+
+If that timeout happens during probe, we will leave the adapter in the
+DOWN state rather than retrying to register/init the CRQ.
+
+Initialize the completion before registering the CRQ so we don't lose
+the notification.
+
+Fixes: 032c5e82847a ("Driver for IBM System i/p VNIC protocol")
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 26 +++++++++++++++++++++-----
+ 1 file changed, 21 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 7bd0ad590898..26ea1f32281f 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -2212,6 +2212,19 @@ static const char *reset_reason_to_string(enum ibmvnic_reset_reason reason)
+       return "UNKNOWN";
+ }
++/*
++ * Initialize the init_done completion and return code values. We
++ * can get a transport event just after registering the CRQ and the
++ * tasklet will use this to communicate the transport event. To ensure
++ * we don't miss the notification/error, initialize these _before_
++ * regisering the CRQ.
++ */
++static inline void reinit_init_done(struct ibmvnic_adapter *adapter)
++{
++      reinit_completion(&adapter->init_done);
++      adapter->init_done_rc = 0;
++}
++
+ /*
+  * do_reset returns zero if we are able to keep processing reset events, or
+  * non-zero if we hit a fatal error and must halt.
+@@ -2318,6 +2331,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
+                */
+               adapter->state = VNIC_PROBED;
++              reinit_init_done(adapter);
++
+               if (adapter->reset_reason == VNIC_RESET_CHANGE_PARAM) {
+                       rc = init_crq_queue(adapter);
+               } else if (adapter->reset_reason == VNIC_RESET_MOBILITY) {
+@@ -2461,7 +2476,8 @@ static int do_hard_reset(struct ibmvnic_adapter *adapter,
+        */
+       adapter->state = VNIC_PROBED;
+-      reinit_completion(&adapter->init_done);
++      reinit_init_done(adapter);
++
+       rc = init_crq_queue(adapter);
+       if (rc) {
+               netdev_err(adapter->netdev,
+@@ -5685,10 +5701,6 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
+       adapter->from_passive_init = false;
+-      if (reset)
+-              reinit_completion(&adapter->init_done);
+-
+-      adapter->init_done_rc = 0;
+       rc = ibmvnic_send_crq_init(adapter);
+       if (rc) {
+               dev_err(dev, "Send crq init failed with error %d\n", rc);
+@@ -5702,12 +5714,14 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
+       if (adapter->init_done_rc) {
+               release_crq_queue(adapter);
++              dev_err(dev, "CRQ-init failed, %d\n", adapter->init_done_rc);
+               return adapter->init_done_rc;
+       }
+       if (adapter->from_passive_init) {
+               adapter->state = VNIC_OPEN;
+               adapter->from_passive_init = false;
++              dev_err(dev, "CRQ-init failed, passive-init\n");
+               return -EINVAL;
+       }
+@@ -5801,6 +5815,8 @@ static int ibmvnic_probe(struct vio_dev *dev, const struct vio_device_id *id)
+       init_success = false;
+       do {
++              reinit_init_done(adapter);
++
+               rc = init_crq_queue(adapter);
+               if (rc) {
+                       dev_err(&dev->dev, "Couldn't initialize crq. rc=%d\n",
+-- 
+2.34.1
+
diff --git a/queue-5.16/ibmvnic-initialize-rc-before-completing-wait.patch b/queue-5.16/ibmvnic-initialize-rc-before-completing-wait.patch
new file mode 100644 (file)
index 0000000..ecf2f3d
--- /dev/null
@@ -0,0 +1,39 @@
+From 54950130f768f2d2a0977e6f4f4b0257580ebbb6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Feb 2022 22:23:52 -0800
+Subject: ibmvnic: initialize rc before completing wait
+
+From: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+
+[ Upstream commit 765559b10ce514eb1576595834f23cdc92125fee ]
+
+We should initialize ->init_done_rc before calling complete(). Otherwise
+the waiting thread may see ->init_done_rc as 0 before we have updated it
+and may assume that the CRQ was successful.
+
+Fixes: 6b278c0cb378 ("ibmvnic delay complete()")
+Signed-off-by: Sukadev Bhattiprolu <sukadev@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 996da870dafe..945a84c2134f 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -5319,9 +5319,9 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
+                       }
+                       if (!completion_done(&adapter->init_done)) {
+-                              complete(&adapter->init_done);
+                               if (!adapter->init_done_rc)
+                                       adapter->init_done_rc = -EAGAIN;
++                              complete(&adapter->init_done);
+                       }
+                       break;
+-- 
+2.34.1
+
diff --git a/queue-5.16/ibmvnic-update-driver-return-codes.patch b/queue-5.16/ibmvnic-update-driver-return-codes.patch
new file mode 100644 (file)
index 0000000..5ed4500
--- /dev/null
@@ -0,0 +1,268 @@
+From 0bc96584ee434c4a72e533f64309a5ffebbef2d1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Dec 2021 00:17:47 -0500
+Subject: ibmvnic: Update driver return codes
+
+From: Dany Madden <drt@linux.ibm.com>
+
+[ Upstream commit b6ee566cf3940883d67c0d142fae8d410e975f47 ]
+
+Update return codes to be more informative.
+
+Signed-off-by: Jacob Root <otis@otisroot.com>
+Signed-off-by: Dany Madden <drt@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/ibm/ibmvnic.c | 64 ++++++++++++++++--------------
+ 1 file changed, 34 insertions(+), 30 deletions(-)
+
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c
+index 16e772f80ec5..7bd0ad590898 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -309,7 +309,7 @@ static int alloc_long_term_buff(struct ibmvnic_adapter *adapter,
+       if (adapter->fw_done_rc) {
+               dev_err(dev, "Couldn't map LTB, rc = %d\n",
+                       adapter->fw_done_rc);
+-              rc = -1;
++              rc = -EIO;
+               goto out;
+       }
+       rc = 0;
+@@ -541,13 +541,15 @@ static int init_stats_token(struct ibmvnic_adapter *adapter)
+ {
+       struct device *dev = &adapter->vdev->dev;
+       dma_addr_t stok;
++      int rc;
+       stok = dma_map_single(dev, &adapter->stats,
+                             sizeof(struct ibmvnic_statistics),
+                             DMA_FROM_DEVICE);
+-      if (dma_mapping_error(dev, stok)) {
+-              dev_err(dev, "Couldn't map stats buffer\n");
+-              return -1;
++      rc = dma_mapping_error(dev, stok);
++      if (rc) {
++              dev_err(dev, "Couldn't map stats buffer, rc = %d\n", rc);
++              return rc;
+       }
+       adapter->stats_token = stok;
+@@ -656,7 +658,7 @@ static int init_rx_pools(struct net_device *netdev)
+       u64 num_pools;
+       u64 pool_size;          /* # of buffers in one pool */
+       u64 buff_size;
+-      int i, j;
++      int i, j, rc;
+       pool_size = adapter->req_rx_add_entries_per_subcrq;
+       num_pools = adapter->req_rx_queues;
+@@ -675,7 +677,7 @@ static int init_rx_pools(struct net_device *netdev)
+                                  GFP_KERNEL);
+       if (!adapter->rx_pool) {
+               dev_err(dev, "Failed to allocate rx pools\n");
+-              return -1;
++              return -ENOMEM;
+       }
+       /* Set num_active_rx_pools early. If we fail below after partial
+@@ -698,6 +700,7 @@ static int init_rx_pools(struct net_device *netdev)
+                                           GFP_KERNEL);
+               if (!rx_pool->free_map) {
+                       dev_err(dev, "Couldn't alloc free_map %d\n", i);
++                      rc = -ENOMEM;
+                       goto out_release;
+               }
+@@ -706,6 +709,7 @@ static int init_rx_pools(struct net_device *netdev)
+                                          GFP_KERNEL);
+               if (!rx_pool->rx_buff) {
+                       dev_err(dev, "Couldn't alloc rx buffers\n");
++                      rc = -ENOMEM;
+                       goto out_release;
+               }
+       }
+@@ -719,8 +723,9 @@ static int init_rx_pools(struct net_device *netdev)
+               dev_dbg(dev, "Updating LTB for rx pool %d [%d, %d]\n",
+                       i, rx_pool->size, rx_pool->buff_size);
+-              if (alloc_long_term_buff(adapter, &rx_pool->long_term_buff,
+-                                       rx_pool->size * rx_pool->buff_size))
++              rc = alloc_long_term_buff(adapter, &rx_pool->long_term_buff,
++                                        rx_pool->size * rx_pool->buff_size);
++              if (rc)
+                       goto out;
+               for (j = 0; j < rx_pool->size; ++j) {
+@@ -757,7 +762,7 @@ static int init_rx_pools(struct net_device *netdev)
+       /* We failed to allocate one or more LTBs or map them on the VIOS.
+        * Hold onto the pools and any LTBs that we did allocate/map.
+        */
+-      return -1;
++      return rc;
+ }
+ static void release_vpd_data(struct ibmvnic_adapter *adapter)
+@@ -818,13 +823,13 @@ static int init_one_tx_pool(struct net_device *netdev,
+                                  sizeof(struct ibmvnic_tx_buff),
+                                  GFP_KERNEL);
+       if (!tx_pool->tx_buff)
+-              return -1;
++              return -ENOMEM;
+       tx_pool->free_map = kcalloc(pool_size, sizeof(int), GFP_KERNEL);
+       if (!tx_pool->free_map) {
+               kfree(tx_pool->tx_buff);
+               tx_pool->tx_buff = NULL;
+-              return -1;
++              return -ENOMEM;
+       }
+       for (i = 0; i < pool_size; i++)
+@@ -915,7 +920,7 @@ static int init_tx_pools(struct net_device *netdev)
+       adapter->tx_pool = kcalloc(num_pools,
+                                  sizeof(struct ibmvnic_tx_pool), GFP_KERNEL);
+       if (!adapter->tx_pool)
+-              return -1;
++              return -ENOMEM;
+       adapter->tso_pool = kcalloc(num_pools,
+                                   sizeof(struct ibmvnic_tx_pool), GFP_KERNEL);
+@@ -925,7 +930,7 @@ static int init_tx_pools(struct net_device *netdev)
+       if (!adapter->tso_pool) {
+               kfree(adapter->tx_pool);
+               adapter->tx_pool = NULL;
+-              return -1;
++              return -ENOMEM;
+       }
+       /* Set num_active_tx_pools early. If we fail below after partial
+@@ -1114,7 +1119,7 @@ static int ibmvnic_login(struct net_device *netdev)
+               retry = false;
+               if (retry_count > retries) {
+                       netdev_warn(netdev, "Login attempts exceeded\n");
+-                      return -1;
++                      return -EACCES;
+               }
+               adapter->init_done_rc = 0;
+@@ -1155,25 +1160,26 @@ static int ibmvnic_login(struct net_device *netdev)
+                                                        timeout)) {
+                               netdev_warn(netdev,
+                                           "Capabilities query timed out\n");
+-                              return -1;
++                              return -ETIMEDOUT;
+                       }
+                       rc = init_sub_crqs(adapter);
+                       if (rc) {
+                               netdev_warn(netdev,
+                                           "SCRQ initialization failed\n");
+-                              return -1;
++                              return rc;
+                       }
+                       rc = init_sub_crq_irqs(adapter);
+                       if (rc) {
+                               netdev_warn(netdev,
+                                           "SCRQ irq initialization failed\n");
+-                              return -1;
++                              return rc;
+                       }
+               } else if (adapter->init_done_rc) {
+-                      netdev_warn(netdev, "Adapter login failed\n");
+-                      return -1;
++                      netdev_warn(netdev, "Adapter login failed, init_done_rc = %d\n",
++                                  adapter->init_done_rc);
++                      return -EIO;
+               }
+       } while (retry);
+@@ -1232,7 +1238,7 @@ static int set_link_state(struct ibmvnic_adapter *adapter, u8 link_state)
+               if (!wait_for_completion_timeout(&adapter->init_done,
+                                                timeout)) {
+                       netdev_err(netdev, "timeout setting link state\n");
+-                      return -1;
++                      return -ETIMEDOUT;
+               }
+               if (adapter->init_done_rc == PARTIALSUCCESS) {
+@@ -2293,7 +2299,7 @@ static int do_reset(struct ibmvnic_adapter *adapter,
+                               /* If someone else changed the adapter state
+                                * when we dropped the rtnl, fail the reset
+                                */
+-                              rc = -1;
++                              rc = -EAGAIN;
+                               goto out;
+                       }
+                       adapter->state = VNIC_CLOSED;
+@@ -2335,10 +2341,8 @@ static int do_reset(struct ibmvnic_adapter *adapter,
+               }
+               rc = ibmvnic_reset_init(adapter, true);
+-              if (rc) {
+-                      rc = IBMVNIC_INIT_FAILED;
++              if (rc)
+                       goto out;
+-              }
+               /* If the adapter was in PROBE or DOWN state prior to the reset,
+                * exit here.
+@@ -3787,7 +3791,7 @@ static int init_sub_crqs(struct ibmvnic_adapter *adapter)
+       allqueues = kcalloc(total_queues, sizeof(*allqueues), GFP_KERNEL);
+       if (!allqueues)
+-              return -1;
++              return -ENOMEM;
+       for (i = 0; i < total_queues; i++) {
+               allqueues[i] = init_sub_crq_queue(adapter);
+@@ -3856,7 +3860,7 @@ static int init_sub_crqs(struct ibmvnic_adapter *adapter)
+       for (i = 0; i < registered_queues; i++)
+               release_sub_crq_queue(adapter, allqueues[i], 1);
+       kfree(allqueues);
+-      return -1;
++      return -ENOMEM;
+ }
+ static void send_request_cap(struct ibmvnic_adapter *adapter, int retry)
+@@ -4235,7 +4239,7 @@ static int send_login(struct ibmvnic_adapter *adapter)
+       if (!adapter->tx_scrq || !adapter->rx_scrq) {
+               netdev_err(adapter->netdev,
+                          "RX or TX queues are not allocated, device login failed\n");
+-              return -1;
++              return -ENOMEM;
+       }
+       release_login_buffer(adapter);
+@@ -4355,7 +4359,7 @@ static int send_login(struct ibmvnic_adapter *adapter)
+       kfree(login_buffer);
+       adapter->login_buf = NULL;
+ buf_alloc_failed:
+-      return -1;
++      return -ENOMEM;
+ }
+ static int send_request_map(struct ibmvnic_adapter *adapter, dma_addr_t addr,
+@@ -5693,7 +5697,7 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
+       if (!wait_for_completion_timeout(&adapter->init_done, timeout)) {
+               dev_err(dev, "Initialization sequence timed out\n");
+-              return -1;
++              return -ETIMEDOUT;
+       }
+       if (adapter->init_done_rc) {
+@@ -5704,7 +5708,7 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset)
+       if (adapter->from_passive_init) {
+               adapter->state = VNIC_OPEN;
+               adapter->from_passive_init = false;
+-              return -1;
++              return -EINVAL;
+       }
+       if (reset &&
+-- 
+2.34.1
+
diff --git a/queue-5.16/iommu-amd-fix-i-o-page-table-memory-leak.patch b/queue-5.16/iommu-amd-fix-i-o-page-table-memory-leak.patch
new file mode 100644 (file)
index 0000000..ab29f79
--- /dev/null
@@ -0,0 +1,61 @@
+From 17bba395b5754c254a6fda3a6973b2f35f6e4a46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 10 Feb 2022 09:47:45 -0600
+Subject: iommu/amd: Fix I/O page table memory leak
+
+From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+
+[ Upstream commit 6b0b2d9a6a308bcd9300c2d83000a82812c56cea ]
+
+The current logic updates the I/O page table mode for the domain
+before calling the logic to free memory used for the page table.
+This results in IOMMU page table memory leak, and can be observed
+when launching VM w/ pass-through devices.
+
+Fix by freeing the memory used for page table before updating the mode.
+
+Cc: Joerg Roedel <joro@8bytes.org>
+Reported-by: Daniel Jordan <daniel.m.jordan@oracle.com>
+Tested-by: Daniel Jordan <daniel.m.jordan@oracle.com>
+Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
+Fixes: e42ba0633064 ("iommu/amd: Restructure code for freeing page table")
+Link: https://lore.kernel.org/all/20220118194720.urjgi73b7c3tq2o6@oracle.com/
+Link: https://lore.kernel.org/r/20220210154745.11524-1-suravee.suthikulpanit@amd.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/io_pgtable.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c
+index b1bf4125b0f7..6608d1717574 100644
+--- a/drivers/iommu/amd/io_pgtable.c
++++ b/drivers/iommu/amd/io_pgtable.c
+@@ -492,18 +492,18 @@ static void v1_free_pgtable(struct io_pgtable *iop)
+       dom = container_of(pgtable, struct protection_domain, iop);
+-      /* Update data structure */
+-      amd_iommu_domain_clr_pt_root(dom);
+-
+-      /* Make changes visible to IOMMUs */
+-      amd_iommu_domain_update(dom);
+-
+       /* Page-table is not visible to IOMMU anymore, so free it */
+       BUG_ON(pgtable->mode < PAGE_MODE_NONE ||
+              pgtable->mode > PAGE_MODE_6_LEVEL);
+       free_sub_pt(pgtable->root, pgtable->mode, &freelist);
++      /* Update data structure */
++      amd_iommu_domain_clr_pt_root(dom);
++
++      /* Make changes visible to IOMMUs */
++      amd_iommu_domain_update(dom);
++
+       put_pages_list(&freelist);
+ }
+-- 
+2.34.1
+
diff --git a/queue-5.16/iommu-amd-simplify-pagetable-freeing.patch b/queue-5.16/iommu-amd-simplify-pagetable-freeing.patch
new file mode 100644 (file)
index 0000000..20deda4
--- /dev/null
@@ -0,0 +1,169 @@
+From da8f8eb5547bbcc236d36afd7cd01f49ad5d2c42 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Dec 2021 15:30:58 +0000
+Subject: iommu/amd: Simplify pagetable freeing
+
+From: Robin Murphy <robin.murphy@arm.com>
+
+[ Upstream commit 6b3106e9ba2de7320a71291cedcefdcf1195ad58 ]
+
+For reasons unclear, pagetable freeing is an effectively recursive
+method implemented via an elaborate system of templated functions that
+turns out to account for 25% of the object file size. Implementing it
+using regular straightforward recursion makes the code simpler, and
+seems like a good thing to do before we work on it further. As part of
+that, also fix the types to avoid all the needless casting back and
+forth which just gets in the way.
+
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/d3d00c9f3fa0df4756b867072c201e6e82f9ce39.1639753638.git.robin.murphy@arm.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/io_pgtable.c | 82 ++++++++++++++--------------------
+ 1 file changed, 34 insertions(+), 48 deletions(-)
+
+diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c
+index 182c93a43efd..4165e1372b6e 100644
+--- a/drivers/iommu/amd/io_pgtable.c
++++ b/drivers/iommu/amd/io_pgtable.c
+@@ -84,49 +84,45 @@ static void free_page_list(struct page *freelist)
+       }
+ }
+-static struct page *free_pt_page(unsigned long pt, struct page *freelist)
++static struct page *free_pt_page(u64 *pt, struct page *freelist)
+ {
+-      struct page *p = virt_to_page((void *)pt);
++      struct page *p = virt_to_page(pt);
+       p->freelist = freelist;
+       return p;
+ }
+-#define DEFINE_FREE_PT_FN(LVL, FN)                                            \
+-static struct page *free_pt_##LVL (unsigned long __pt, struct page *freelist) \
+-{                                                                             \
+-      unsigned long p;                                                        \
+-      u64 *pt;                                                                \
+-      int i;                                                                  \
+-                                                                              \
+-      pt = (u64 *)__pt;                                                       \
+-                                                                              \
+-      for (i = 0; i < 512; ++i) {                                             \
+-              /* PTE present? */                                              \
+-              if (!IOMMU_PTE_PRESENT(pt[i]))                                  \
+-                      continue;                                               \
+-                                                                              \
+-              /* Large PTE? */                                                \
+-              if (PM_PTE_LEVEL(pt[i]) == 0 ||                                 \
+-                  PM_PTE_LEVEL(pt[i]) == 7)                                   \
+-                      continue;                                               \
+-                                                                              \
+-              p = (unsigned long)IOMMU_PTE_PAGE(pt[i]);                       \
+-              freelist = FN(p, freelist);                                     \
+-      }                                                                       \
+-                                                                              \
+-      return free_pt_page((unsigned long)pt, freelist);                       \
+-}
++static struct page *free_pt_lvl(u64 *pt, struct page *freelist, int lvl)
++{
++      u64 *p;
++      int i;
++
++      for (i = 0; i < 512; ++i) {
++              /* PTE present? */
++              if (!IOMMU_PTE_PRESENT(pt[i]))
++                      continue;
+-DEFINE_FREE_PT_FN(l2, free_pt_page)
+-DEFINE_FREE_PT_FN(l3, free_pt_l2)
+-DEFINE_FREE_PT_FN(l4, free_pt_l3)
+-DEFINE_FREE_PT_FN(l5, free_pt_l4)
+-DEFINE_FREE_PT_FN(l6, free_pt_l5)
++              /* Large PTE? */
++              if (PM_PTE_LEVEL(pt[i]) == 0 ||
++                  PM_PTE_LEVEL(pt[i]) == 7)
++                      continue;
+-static struct page *free_sub_pt(unsigned long root, int mode,
+-                              struct page *freelist)
++              /*
++               * Free the next level. No need to look at l1 tables here since
++               * they can only contain leaf PTEs; just free them directly.
++               */
++              p = IOMMU_PTE_PAGE(pt[i]);
++              if (lvl > 2)
++                      freelist = free_pt_lvl(p, freelist, lvl - 1);
++              else
++                      freelist = free_pt_page(p, freelist);
++      }
++
++      return free_pt_page(pt, freelist);
++}
++
++static struct page *free_sub_pt(u64 *root, int mode, struct page *freelist)
+ {
+       switch (mode) {
+       case PAGE_MODE_NONE:
+@@ -136,19 +132,11 @@ static struct page *free_sub_pt(unsigned long root, int mode,
+               freelist = free_pt_page(root, freelist);
+               break;
+       case PAGE_MODE_2_LEVEL:
+-              freelist = free_pt_l2(root, freelist);
+-              break;
+       case PAGE_MODE_3_LEVEL:
+-              freelist = free_pt_l3(root, freelist);
+-              break;
+       case PAGE_MODE_4_LEVEL:
+-              freelist = free_pt_l4(root, freelist);
+-              break;
+       case PAGE_MODE_5_LEVEL:
+-              freelist = free_pt_l5(root, freelist);
+-              break;
+       case PAGE_MODE_6_LEVEL:
+-              freelist = free_pt_l6(root, freelist);
++              free_pt_lvl(root, freelist, mode);
+               break;
+       default:
+               BUG();
+@@ -364,7 +352,7 @@ static u64 *fetch_pte(struct amd_io_pgtable *pgtable,
+ static struct page *free_clear_pte(u64 *pte, u64 pteval, struct page *freelist)
+ {
+-      unsigned long pt;
++      u64 *pt;
+       int mode;
+       while (cmpxchg64(pte, pteval, 0) != pteval) {
+@@ -375,7 +363,7 @@ static struct page *free_clear_pte(u64 *pte, u64 pteval, struct page *freelist)
+       if (!IOMMU_PTE_PRESENT(pteval))
+               return freelist;
+-      pt   = (unsigned long)IOMMU_PTE_PAGE(pteval);
++      pt   = IOMMU_PTE_PAGE(pteval);
+       mode = IOMMU_PTE_MODE(pteval);
+       return free_sub_pt(pt, mode, freelist);
+@@ -512,7 +500,6 @@ static void v1_free_pgtable(struct io_pgtable *iop)
+       struct amd_io_pgtable *pgtable = container_of(iop, struct amd_io_pgtable, iop);
+       struct protection_domain *dom;
+       struct page *freelist = NULL;
+-      unsigned long root;
+       if (pgtable->mode == PAGE_MODE_NONE)
+               return;
+@@ -529,8 +516,7 @@ static void v1_free_pgtable(struct io_pgtable *iop)
+       BUG_ON(pgtable->mode < PAGE_MODE_NONE ||
+              pgtable->mode > PAGE_MODE_6_LEVEL);
+-      root = (unsigned long)pgtable->root;
+-      freelist = free_sub_pt(root, pgtable->mode, freelist);
++      freelist = free_sub_pt(pgtable->root, pgtable->mode, freelist);
+       free_page_list(freelist);
+ }
+-- 
+2.34.1
+
diff --git a/queue-5.16/iommu-amd-use-put_pages_list.patch b/queue-5.16/iommu-amd-use-put_pages_list.patch
new file mode 100644 (file)
index 0000000..cd226f6
--- /dev/null
@@ -0,0 +1,173 @@
+From 42cf2683550e58b3529f00d834e1a700c8962994 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 17 Dec 2021 15:30:59 +0000
+Subject: iommu/amd: Use put_pages_list
+
+From: Matthew Wilcox (Oracle) <willy@infradead.org>
+
+[ Upstream commit ce00eece6909c266da123fd147172d745a4f14a0 ]
+
+page->freelist is for the use of slab.  We already have the ability
+to free a list of pages in the core mm, but it requires the use of a
+list_head and for the pages to be chained together through page->lru.
+Switch the AMD IOMMU code over to using free_pages_list().
+
+Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+[rm: split from original patch, cosmetic tweaks]
+Signed-off-by: Robin Murphy <robin.murphy@arm.com>
+Link: https://lore.kernel.org/r/73af128f651aaa1f38f69e586c66765a88ad2de0.1639753638.git.robin.murphy@arm.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/amd/io_pgtable.c | 50 ++++++++++++----------------------
+ 1 file changed, 18 insertions(+), 32 deletions(-)
+
+diff --git a/drivers/iommu/amd/io_pgtable.c b/drivers/iommu/amd/io_pgtable.c
+index 4165e1372b6e..b1bf4125b0f7 100644
+--- a/drivers/iommu/amd/io_pgtable.c
++++ b/drivers/iommu/amd/io_pgtable.c
+@@ -74,26 +74,14 @@ static u64 *first_pte_l7(u64 *pte, unsigned long *page_size,
+  *
+  ****************************************************************************/
+-static void free_page_list(struct page *freelist)
+-{
+-      while (freelist != NULL) {
+-              unsigned long p = (unsigned long)page_address(freelist);
+-
+-              freelist = freelist->freelist;
+-              free_page(p);
+-      }
+-}
+-
+-static struct page *free_pt_page(u64 *pt, struct page *freelist)
++static void free_pt_page(u64 *pt, struct list_head *freelist)
+ {
+       struct page *p = virt_to_page(pt);
+-      p->freelist = freelist;
+-
+-      return p;
++      list_add_tail(&p->lru, freelist);
+ }
+-static struct page *free_pt_lvl(u64 *pt, struct page *freelist, int lvl)
++static void free_pt_lvl(u64 *pt, struct list_head *freelist, int lvl)
+ {
+       u64 *p;
+       int i;
+@@ -114,22 +102,22 @@ static struct page *free_pt_lvl(u64 *pt, struct page *freelist, int lvl)
+                */
+               p = IOMMU_PTE_PAGE(pt[i]);
+               if (lvl > 2)
+-                      freelist = free_pt_lvl(p, freelist, lvl - 1);
++                      free_pt_lvl(p, freelist, lvl - 1);
+               else
+-                      freelist = free_pt_page(p, freelist);
++                      free_pt_page(p, freelist);
+       }
+-      return free_pt_page(pt, freelist);
++      free_pt_page(pt, freelist);
+ }
+-static struct page *free_sub_pt(u64 *root, int mode, struct page *freelist)
++static void free_sub_pt(u64 *root, int mode, struct list_head *freelist)
+ {
+       switch (mode) {
+       case PAGE_MODE_NONE:
+       case PAGE_MODE_7_LEVEL:
+               break;
+       case PAGE_MODE_1_LEVEL:
+-              freelist = free_pt_page(root, freelist);
++              free_pt_page(root, freelist);
+               break;
+       case PAGE_MODE_2_LEVEL:
+       case PAGE_MODE_3_LEVEL:
+@@ -141,8 +129,6 @@ static struct page *free_sub_pt(u64 *root, int mode, struct page *freelist)
+       default:
+               BUG();
+       }
+-
+-      return freelist;
+ }
+ void amd_iommu_domain_set_pgtable(struct protection_domain *domain,
+@@ -350,7 +336,7 @@ static u64 *fetch_pte(struct amd_io_pgtable *pgtable,
+       return pte;
+ }
+-static struct page *free_clear_pte(u64 *pte, u64 pteval, struct page *freelist)
++static void free_clear_pte(u64 *pte, u64 pteval, struct list_head *freelist)
+ {
+       u64 *pt;
+       int mode;
+@@ -361,12 +347,12 @@ static struct page *free_clear_pte(u64 *pte, u64 pteval, struct page *freelist)
+       }
+       if (!IOMMU_PTE_PRESENT(pteval))
+-              return freelist;
++              return;
+       pt   = IOMMU_PTE_PAGE(pteval);
+       mode = IOMMU_PTE_MODE(pteval);
+-      return free_sub_pt(pt, mode, freelist);
++      free_sub_pt(pt, mode, freelist);
+ }
+ /*
+@@ -380,7 +366,7 @@ static int iommu_v1_map_page(struct io_pgtable_ops *ops, unsigned long iova,
+                         phys_addr_t paddr, size_t size, int prot, gfp_t gfp)
+ {
+       struct protection_domain *dom = io_pgtable_ops_to_domain(ops);
+-      struct page *freelist = NULL;
++      LIST_HEAD(freelist);
+       bool updated = false;
+       u64 __pte, *pte;
+       int ret, i, count;
+@@ -400,9 +386,9 @@ static int iommu_v1_map_page(struct io_pgtable_ops *ops, unsigned long iova,
+               goto out;
+       for (i = 0; i < count; ++i)
+-              freelist = free_clear_pte(&pte[i], pte[i], freelist);
++              free_clear_pte(&pte[i], pte[i], &freelist);
+-      if (freelist != NULL)
++      if (!list_empty(&freelist))
+               updated = true;
+       if (count > 1) {
+@@ -437,7 +423,7 @@ static int iommu_v1_map_page(struct io_pgtable_ops *ops, unsigned long iova,
+       }
+       /* Everything flushed out, free pages now */
+-      free_page_list(freelist);
++      put_pages_list(&freelist);
+       return ret;
+ }
+@@ -499,7 +485,7 @@ static void v1_free_pgtable(struct io_pgtable *iop)
+ {
+       struct amd_io_pgtable *pgtable = container_of(iop, struct amd_io_pgtable, iop);
+       struct protection_domain *dom;
+-      struct page *freelist = NULL;
++      LIST_HEAD(freelist);
+       if (pgtable->mode == PAGE_MODE_NONE)
+               return;
+@@ -516,9 +502,9 @@ static void v1_free_pgtable(struct io_pgtable *iop)
+       BUG_ON(pgtable->mode < PAGE_MODE_NONE ||
+              pgtable->mode > PAGE_MODE_6_LEVEL);
+-      freelist = free_sub_pt(pgtable->root, pgtable->mode, freelist);
++      free_sub_pt(pgtable->root, pgtable->mode, &freelist);
+-      free_page_list(freelist);
++      put_pages_list(&freelist);
+ }
+ static struct io_pgtable *v1_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
+-- 
+2.34.1
+
diff --git a/queue-5.16/mips-ralink-mt7621-do-memory-detection-on-kseg1.patch b/queue-5.16/mips-ralink-mt7621-do-memory-detection-on-kseg1.patch
new file mode 100644 (file)
index 0000000..08aef2d
--- /dev/null
@@ -0,0 +1,95 @@
+From 916192e06e8e114c5173b101cf321101d81fa8a9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 11 Feb 2022 08:13:44 +0800
+Subject: MIPS: ralink: mt7621: do memory detection on KSEG1
+
+From: Chuanhong Guo <gch981213@gmail.com>
+
+[ Upstream commit cc19db8b312a6c75645645f5cc1b45166b109006 ]
+
+It's reported that current memory detection code occasionally detects
+larger memory under some bootloaders.
+Current memory detection code tests whether address space wraps around
+on KSEG0, which is unreliable because it's cached.
+
+Rewrite memory size detection to perform the same test on KSEG1 instead.
+While at it, this patch also does the following two things:
+1. use a fixed pattern instead of a random function pointer as the magic
+   value.
+2. add an additional memory write and a second comparison as part of the
+   test to prevent possible smaller memory detection result due to
+   leftover values in memory.
+
+Fixes: 139c949f7f0a MIPS: ("ralink: mt7621: add memory detection support")
+Reported-by: Rui Salvaterra <rsalvaterra@gmail.com>
+Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
+Tested-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Tested-by: Rui Salvaterra <rsalvaterra@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/ralink/mt7621.c | 36 +++++++++++++++++++++++-------------
+ 1 file changed, 23 insertions(+), 13 deletions(-)
+
+diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
+index bd71f5b14238..fd9a872d5713 100644
+--- a/arch/mips/ralink/mt7621.c
++++ b/arch/mips/ralink/mt7621.c
+@@ -20,31 +20,41 @@
+ #include "common.h"
+-static void *detect_magic __initdata = detect_memory_region;
++#define MT7621_MEM_TEST_PATTERN         0xaa5555aa
++
++static u32 detect_magic __initdata;
+ phys_addr_t mips_cpc_default_phys_base(void)
+ {
+       panic("Cannot detect cpc address");
+ }
++static bool __init mt7621_addr_wraparound_test(phys_addr_t size)
++{
++      void *dm = (void *)KSEG1ADDR(&detect_magic);
++
++      if (CPHYSADDR(dm + size) >= MT7621_LOWMEM_MAX_SIZE)
++              return true;
++      __raw_writel(MT7621_MEM_TEST_PATTERN, dm);
++      if (__raw_readl(dm) != __raw_readl(dm + size))
++              return false;
++      __raw_writel(!MT7621_MEM_TEST_PATTERN, dm);
++      return __raw_readl(dm) == __raw_readl(dm + size);
++}
++
+ static void __init mt7621_memory_detect(void)
+ {
+-      void *dm = &detect_magic;
+       phys_addr_t size;
+-      for (size = 32 * SZ_1M; size < 256 * SZ_1M; size <<= 1) {
+-              if (!__builtin_memcmp(dm, dm + size, sizeof(detect_magic)))
+-                      break;
++      for (size = 32 * SZ_1M; size <= 256 * SZ_1M; size <<= 1) {
++              if (mt7621_addr_wraparound_test(size)) {
++                      memblock_add(MT7621_LOWMEM_BASE, size);
++                      return;
++              }
+       }
+-      if ((size == 256 * SZ_1M) &&
+-          (CPHYSADDR(dm + size) < MT7621_LOWMEM_MAX_SIZE) &&
+-          __builtin_memcmp(dm, dm + size, sizeof(detect_magic))) {
+-              memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
+-              memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
+-      } else {
+-              memblock_add(MT7621_LOWMEM_BASE, size);
+-      }
++      memblock_add(MT7621_LOWMEM_BASE, MT7621_LOWMEM_MAX_SIZE);
++      memblock_add(MT7621_HIGHMEM_BASE, MT7621_HIGHMEM_SIZE);
+ }
+ void __init ralink_of_remap(void)
+-- 
+2.34.1
+
diff --git a/queue-5.16/mips-ralink-mt7621-use-bitwise-not-instead-of-logica.patch b/queue-5.16/mips-ralink-mt7621-use-bitwise-not-instead-of-logica.patch
new file mode 100644 (file)
index 0000000..5601d85
--- /dev/null
@@ -0,0 +1,38 @@
+From 9d933ab70e2c0d56f1d4ccf3317453642c8cc784 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Feb 2022 17:15:07 -0800
+Subject: MIPS: ralink: mt7621: use bitwise NOT instead of logical
+
+From: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+
+[ Upstream commit 5d8965704fe5662e2e4a7e4424a2cbe53e182670 ]
+
+It was the intention to reverse the bits, not make them all zero by
+using logical NOT operator.
+
+Fixes: cc19db8b312a ("MIPS: ralink: mt7621: do memory detection on KSEG1")
+Suggested-by: Chuanhong Guo <gch981213@gmail.com>
+Signed-off-by: Ilya Lipnitskiy <ilya.lipnitskiy@gmail.com>
+Reviewed-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
+Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/mips/ralink/mt7621.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c
+index fd9a872d5713..4c8378661219 100644
+--- a/arch/mips/ralink/mt7621.c
++++ b/arch/mips/ralink/mt7621.c
+@@ -38,7 +38,7 @@ static bool __init mt7621_addr_wraparound_test(phys_addr_t size)
+       __raw_writel(MT7621_MEM_TEST_PATTERN, dm);
+       if (__raw_readl(dm) != __raw_readl(dm + size))
+               return false;
+-      __raw_writel(!MT7621_MEM_TEST_PATTERN, dm);
++      __raw_writel(~MT7621_MEM_TEST_PATTERN, dm);
+       return __raw_readl(dm) == __raw_readl(dm + size);
+ }
+-- 
+2.34.1
+
diff --git a/queue-5.16/net-chelsio-cxgb3-check-the-return-value-of-pci_find.patch b/queue-5.16/net-chelsio-cxgb3-check-the-return-value-of-pci_find.patch
new file mode 100644 (file)
index 0000000..9f1916c
--- /dev/null
@@ -0,0 +1,37 @@
+From 2f521aadaaaca07cd1143861d0ae29b3efaa0144 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Feb 2022 04:37:27 -0800
+Subject: net: chelsio: cxgb3: check the return value of pci_find_capability()
+
+From: Jia-Ju Bai <baijiaju1990@gmail.com>
+
+[ Upstream commit 767b9825ed1765894e569a3d698749d40d83762a ]
+
+The function pci_find_capability() in t3_prep_adapter() can fail, so its
+return value should be checked.
+
+Fixes: 4d22de3e6cc4 ("Add support for the latest 1G/10G Chelsio adapter, T3")
+Reported-by: TOTE Robot <oslab@tsinghua.edu.cn>
+Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/chelsio/cxgb3/t3_hw.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
+index da41eee2f25c..a06003bfa04b 100644
+--- a/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
++++ b/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c
+@@ -3613,6 +3613,8 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
+           MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
+       adapter->params.pci.vpd_cap_addr =
+           pci_find_capability(adapter->pdev, PCI_CAP_ID_VPD);
++      if (!adapter->params.pci.vpd_cap_addr)
++              return -ENODEV;
+       ret = get_vpd_params(adapter, &adapter->params.vpd);
+       if (ret < 0)
+               return ret;
+-- 
+2.34.1
+
diff --git a/queue-5.16/net-dcb-disable-softirqs-in-dcbnl_flush_dev.patch b/queue-5.16/net-dcb-disable-softirqs-in-dcbnl_flush_dev.patch
new file mode 100644 (file)
index 0000000..f94cae3
--- /dev/null
@@ -0,0 +1,62 @@
+From c18d886459e3b77da5a853535c93ab7500f58124 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 21:39:39 +0200
+Subject: net: dcb: disable softirqs in dcbnl_flush_dev()
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit 10b6bb62ae1a49ee818fc479cf57b8900176773e ]
+
+Ido Schimmel points out that since commit 52cff74eef5d ("dcbnl : Disable
+software interrupts before taking dcb_lock"), the DCB API can be called
+by drivers from softirq context.
+
+One such in-tree example is the chelsio cxgb4 driver:
+dcb_rpl
+-> cxgb4_dcb_handle_fw_update
+   -> dcb_ieee_setapp
+
+If the firmware for this driver happened to send an event which resulted
+in a call to dcb_ieee_setapp() at the exact same time as another
+DCB-enabled interface was unregistering on the same CPU, the softirq
+would deadlock, because the interrupted process was already holding the
+dcb_lock in dcbnl_flush_dev().
+
+Fix this unlikely event by using spin_lock_bh() in dcbnl_flush_dev() as
+in the rest of the dcbnl code.
+
+Fixes: 91b0383fef06 ("net: dcb: flush lingering app table entries for unregistered devices")
+Reported-by: Ido Schimmel <idosch@idosch.org>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://lore.kernel.org/r/20220302193939.1368823-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/dcb/dcbnl.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
+index 36c91273daac..dc4fb699b56c 100644
+--- a/net/dcb/dcbnl.c
++++ b/net/dcb/dcbnl.c
+@@ -2077,7 +2077,7 @@ static void dcbnl_flush_dev(struct net_device *dev)
+ {
+       struct dcb_app_type *itr, *tmp;
+-      spin_lock(&dcb_lock);
++      spin_lock_bh(&dcb_lock);
+       list_for_each_entry_safe(itr, tmp, &dcb_app_list, list) {
+               if (itr->ifindex == dev->ifindex) {
+@@ -2086,7 +2086,7 @@ static void dcbnl_flush_dev(struct net_device *dev)
+               }
+       }
+-      spin_unlock(&dcb_lock);
++      spin_unlock_bh(&dcb_lock);
+ }
+ static int dcbnl_netdevice_event(struct notifier_block *nb,
+-- 
+2.34.1
+
diff --git a/queue-5.16/net-sparx5-fix-add-vlan-when-invalid-operation.patch b/queue-5.16/net-sparx5-fix-add-vlan-when-invalid-operation.patch
new file mode 100644 (file)
index 0000000..36e41e6
--- /dev/null
@@ -0,0 +1,64 @@
+From 114e9646f14fb5067363c0a83daf8314e103ee84 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 25 Feb 2022 11:15:16 +0100
+Subject: net: sparx5: Fix add vlan when invalid operation
+
+From: Casper Andersson <casper.casan@gmail.com>
+
+[ Upstream commit b3a34dc362c03215031b268fcc0b988e69490231 ]
+
+Check if operation is valid before changing any
+settings in hardware. Otherwise it results in
+changes being made despite it not being a valid
+operation.
+
+Fixes: 78eab33bb68b ("net: sparx5: add vlan support")
+
+Signed-off-by: Casper Andersson <casper.casan@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../ethernet/microchip/sparx5/sparx5_vlan.c   | 20 +++++++++----------
+ 1 file changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c b/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
+index 4ce490a25f33..8e56ffa1c4f7 100644
+--- a/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
++++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vlan.c
+@@ -58,16 +58,6 @@ int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid,
+       struct sparx5 *sparx5 = port->sparx5;
+       int ret;
+-      /* Make the port a member of the VLAN */
+-      set_bit(port->portno, sparx5->vlan_mask[vid]);
+-      ret = sparx5_vlant_set_mask(sparx5, vid);
+-      if (ret)
+-              return ret;
+-
+-      /* Default ingress vlan classification */
+-      if (pvid)
+-              port->pvid = vid;
+-
+       /* Untagged egress vlan classification */
+       if (untagged && port->vid != vid) {
+               if (port->vid) {
+@@ -79,6 +69,16 @@ int sparx5_vlan_vid_add(struct sparx5_port *port, u16 vid, bool pvid,
+               port->vid = vid;
+       }
++      /* Make the port a member of the VLAN */
++      set_bit(port->portno, sparx5->vlan_mask[vid]);
++      ret = sparx5_vlant_set_mask(sparx5, vid);
++      if (ret)
++              return ret;
++
++      /* Default ingress vlan classification */
++      if (pvid)
++              port->pvid = vid;
++
+       sparx5_vlan_port_apply(sparx5, port);
+       return 0;
+-- 
+2.34.1
+
diff --git a/queue-5.16/net-stmmac-enhance-xdp-zc-driver-level-switching-per.patch b/queue-5.16/net-stmmac-enhance-xdp-zc-driver-level-switching-per.patch
new file mode 100644 (file)
index 0000000..67f735e
--- /dev/null
@@ -0,0 +1,255 @@
+From 721322b751f39f2843d35dec7a80001d5cc446b6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 11 Nov 2021 22:39:49 +0800
+Subject: net: stmmac: enhance XDP ZC driver level switching performance
+
+From: Ong Boon Leong <boon.leong.ong@intel.com>
+
+[ Upstream commit ac746c8520d9d056b6963ecca8ff1da9929d02f1 ]
+
+The previous stmmac_xdp_set_prog() implementation uses stmmac_release()
+and stmmac_open() which tear down the PHY device and causes undesirable
+autonegotiation which causes a delay whenever AFXDP ZC is setup.
+
+This patch introduces two new functions that just sufficiently tear
+down DMA descriptors, buffer, NAPI process, and IRQs and reestablish
+them accordingly in both stmmac_xdp_release() and stammac_xdp_open().
+
+As the results of this enhancement, we get rid of transient state
+introduced by the link auto-negotiation:
+
+$ ./xdpsock -i eth0 -t -z
+
+ sock0@eth0:0 txonly xdp-drv
+                   pps            pkts           1.00
+rx                 0              0
+tx                 634444         634560
+
+ sock0@eth0:0 txonly xdp-drv
+                   pps            pkts           1.00
+rx                 0              0
+tx                 632330         1267072
+
+ sock0@eth0:0 txonly xdp-drv
+                   pps            pkts           1.00
+rx                 0              0
+tx                 632438         1899584
+
+ sock0@eth0:0 txonly xdp-drv
+                   pps            pkts           1.00
+rx                 0              0
+tx                 632502         2532160
+
+Reported-by: Kurt Kanzenbach <kurt@linutronix.de>
+Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com>
+Tested-by: Kurt Kanzenbach <kurt@linutronix.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac.h  |   4 +-
+ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 137 +++++++++++++++++-
+ .../net/ethernet/stmicro/stmmac/stmmac_xdp.c  |   4 +-
+ 3 files changed, 139 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+index 873b9e3e5da2..05b5371ca036 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+@@ -334,8 +334,8 @@ void stmmac_set_ethtool_ops(struct net_device *netdev);
+ int stmmac_init_tstamp_counter(struct stmmac_priv *priv, u32 systime_flags);
+ void stmmac_ptp_register(struct stmmac_priv *priv);
+ void stmmac_ptp_unregister(struct stmmac_priv *priv);
+-int stmmac_open(struct net_device *dev);
+-int stmmac_release(struct net_device *dev);
++int stmmac_xdp_open(struct net_device *dev);
++void stmmac_xdp_release(struct net_device *dev);
+ int stmmac_resume(struct device *dev);
+ int stmmac_suspend(struct device *dev);
+ int stmmac_dvr_remove(struct device *dev);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 240dffe20fc3..2b3752bd1ac9 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -3679,7 +3679,7 @@ static int stmmac_request_irq(struct net_device *dev)
+  *  0 on success and an appropriate (-)ve integer as defined in errno.h
+  *  file on failure.
+  */
+-int stmmac_open(struct net_device *dev)
++static int stmmac_open(struct net_device *dev)
+ {
+       struct stmmac_priv *priv = netdev_priv(dev);
+       int mode = priv->plat->phy_interface;
+@@ -3803,7 +3803,7 @@ static void stmmac_fpe_stop_wq(struct stmmac_priv *priv)
+  *  Description:
+  *  This is the stop entry point of the driver.
+  */
+-int stmmac_release(struct net_device *dev)
++static int stmmac_release(struct net_device *dev)
+ {
+       struct stmmac_priv *priv = netdev_priv(dev);
+       u32 chan;
+@@ -6473,6 +6473,139 @@ void stmmac_enable_tx_queue(struct stmmac_priv *priv, u32 queue)
+       spin_unlock_irqrestore(&ch->lock, flags);
+ }
++void stmmac_xdp_release(struct net_device *dev)
++{
++      struct stmmac_priv *priv = netdev_priv(dev);
++      u32 chan;
++
++      /* Disable NAPI process */
++      stmmac_disable_all_queues(priv);
++
++      for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
++              hrtimer_cancel(&priv->tx_queue[chan].txtimer);
++
++      /* Free the IRQ lines */
++      stmmac_free_irq(dev, REQ_IRQ_ERR_ALL, 0);
++
++      /* Stop TX/RX DMA channels */
++      stmmac_stop_all_dma(priv);
++
++      /* Release and free the Rx/Tx resources */
++      free_dma_desc_resources(priv);
++
++      /* Disable the MAC Rx/Tx */
++      stmmac_mac_set(priv, priv->ioaddr, false);
++
++      /* set trans_start so we don't get spurious
++       * watchdogs during reset
++       */
++      netif_trans_update(dev);
++      netif_carrier_off(dev);
++}
++
++int stmmac_xdp_open(struct net_device *dev)
++{
++      struct stmmac_priv *priv = netdev_priv(dev);
++      u32 rx_cnt = priv->plat->rx_queues_to_use;
++      u32 tx_cnt = priv->plat->tx_queues_to_use;
++      u32 dma_csr_ch = max(rx_cnt, tx_cnt);
++      struct stmmac_rx_queue *rx_q;
++      struct stmmac_tx_queue *tx_q;
++      u32 buf_size;
++      bool sph_en;
++      u32 chan;
++      int ret;
++
++      ret = alloc_dma_desc_resources(priv);
++      if (ret < 0) {
++              netdev_err(dev, "%s: DMA descriptors allocation failed\n",
++                         __func__);
++              goto dma_desc_error;
++      }
++
++      ret = init_dma_desc_rings(dev, GFP_KERNEL);
++      if (ret < 0) {
++              netdev_err(dev, "%s: DMA descriptors initialization failed\n",
++                         __func__);
++              goto init_error;
++      }
++
++      /* DMA CSR Channel configuration */
++      for (chan = 0; chan < dma_csr_ch; chan++)
++              stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
++
++      /* Adjust Split header */
++      sph_en = (priv->hw->rx_csum > 0) && priv->sph;
++
++      /* DMA RX Channel Configuration */
++      for (chan = 0; chan < rx_cnt; chan++) {
++              rx_q = &priv->rx_queue[chan];
++
++              stmmac_init_rx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
++                                  rx_q->dma_rx_phy, chan);
++
++              rx_q->rx_tail_addr = rx_q->dma_rx_phy +
++                                   (rx_q->buf_alloc_num *
++                                    sizeof(struct dma_desc));
++              stmmac_set_rx_tail_ptr(priv, priv->ioaddr,
++                                     rx_q->rx_tail_addr, chan);
++
++              if (rx_q->xsk_pool && rx_q->buf_alloc_num) {
++                      buf_size = xsk_pool_get_rx_frame_size(rx_q->xsk_pool);
++                      stmmac_set_dma_bfsize(priv, priv->ioaddr,
++                                            buf_size,
++                                            rx_q->queue_index);
++              } else {
++                      stmmac_set_dma_bfsize(priv, priv->ioaddr,
++                                            priv->dma_buf_sz,
++                                            rx_q->queue_index);
++              }
++
++              stmmac_enable_sph(priv, priv->ioaddr, sph_en, chan);
++      }
++
++      /* DMA TX Channel Configuration */
++      for (chan = 0; chan < tx_cnt; chan++) {
++              tx_q = &priv->tx_queue[chan];
++
++              stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
++                                  tx_q->dma_tx_phy, chan);
++
++              tx_q->tx_tail_addr = tx_q->dma_tx_phy;
++              stmmac_set_tx_tail_ptr(priv, priv->ioaddr,
++                                     tx_q->tx_tail_addr, chan);
++      }
++
++      /* Enable the MAC Rx/Tx */
++      stmmac_mac_set(priv, priv->ioaddr, true);
++
++      /* Start Rx & Tx DMA Channels */
++      stmmac_start_all_dma(priv);
++
++      stmmac_init_coalesce(priv);
++
++      ret = stmmac_request_irq(dev);
++      if (ret)
++              goto irq_error;
++
++      /* Enable NAPI process*/
++      stmmac_enable_all_queues(priv);
++      netif_carrier_on(dev);
++      netif_tx_start_all_queues(dev);
++
++      return 0;
++
++irq_error:
++      for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
++              hrtimer_cancel(&priv->tx_queue[chan].txtimer);
++
++      stmmac_hw_teardown(dev);
++init_error:
++      free_dma_desc_resources(priv);
++dma_desc_error:
++      return ret;
++}
++
+ int stmmac_xsk_wakeup(struct net_device *dev, u32 queue, u32 flags)
+ {
+       struct stmmac_priv *priv = netdev_priv(dev);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
+index 2a616c6f7cd0..9d4d8c3dad0a 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_xdp.c
+@@ -119,7 +119,7 @@ int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog,
+       need_update = !!priv->xdp_prog != !!prog;
+       if (if_running && need_update)
+-              stmmac_release(dev);
++              stmmac_xdp_release(dev);
+       old_prog = xchg(&priv->xdp_prog, prog);
+       if (old_prog)
+@@ -129,7 +129,7 @@ int stmmac_xdp_set_prog(struct stmmac_priv *priv, struct bpf_prog *prog,
+       priv->sph = priv->sph_cap && !stmmac_xdp_is_enabled(priv);
+       if (if_running && need_update)
+-              stmmac_open(dev);
++              stmmac_xdp_open(dev);
+       return 0;
+ }
+-- 
+2.34.1
+
diff --git a/queue-5.16/net-stmmac-only-enable-dma-interrupts-when-ready.patch b/queue-5.16/net-stmmac-only-enable-dma-interrupts-when-ready.patch
new file mode 100644 (file)
index 0000000..ff23140
--- /dev/null
@@ -0,0 +1,111 @@
+From d18a70db2c7ba7da108f9c33b9b11d7cbb195bd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Feb 2022 12:38:29 +0100
+Subject: net: stmmac: only enable DMA interrupts when ready
+
+From: Vincent Whitchurch <vincent.whitchurch@axis.com>
+
+[ Upstream commit 087a7b944c5db409f7c1a68bf4896c56ba54eaff ]
+
+In this driver's ->ndo_open() callback, it enables DMA interrupts,
+starts the DMA channels, then requests interrupts with request_irq(),
+and then finally enables napi.
+
+If RX DMA interrupts are received before napi is enabled, no processing
+is done because napi_schedule_prep() will return false.  If the network
+has a lot of broadcast/multicast traffic, then the RX ring could fill up
+completely before napi is enabled.  When this happens, no further RX
+interrupts will be delivered, and the driver will fail to receive any
+packets.
+
+Fix this by only enabling DMA interrupts after all other initialization
+is complete.
+
+Fixes: 523f11b5d4fd72efb ("net: stmmac: move hardware setup for stmmac_open to new function")
+Reported-by: Lars Persson <larper@axis.com>
+Signed-off-by: Vincent Whitchurch <vincent.whitchurch@axis.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/stmicro/stmmac/stmmac_main.c | 28 +++++++++++++++++--
+ 1 file changed, 26 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 2b3752bd1ac9..8610e4d28e85 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2272,6 +2272,23 @@ static void stmmac_stop_tx_dma(struct stmmac_priv *priv, u32 chan)
+       stmmac_stop_tx(priv, priv->ioaddr, chan);
+ }
++static void stmmac_enable_all_dma_irq(struct stmmac_priv *priv)
++{
++      u32 rx_channels_count = priv->plat->rx_queues_to_use;
++      u32 tx_channels_count = priv->plat->tx_queues_to_use;
++      u32 dma_csr_ch = max(rx_channels_count, tx_channels_count);
++      u32 chan;
++
++      for (chan = 0; chan < dma_csr_ch; chan++) {
++              struct stmmac_channel *ch = &priv->channel[chan];
++              unsigned long flags;
++
++              spin_lock_irqsave(&ch->lock, flags);
++              stmmac_enable_dma_irq(priv, priv->ioaddr, chan, 1, 1);
++              spin_unlock_irqrestore(&ch->lock, flags);
++      }
++}
++
+ /**
+  * stmmac_start_all_dma - start all RX and TX DMA channels
+  * @priv: driver private structure
+@@ -2911,8 +2928,10 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
+               stmmac_axi(priv, priv->ioaddr, priv->plat->axi);
+       /* DMA CSR Channel configuration */
+-      for (chan = 0; chan < dma_csr_ch; chan++)
++      for (chan = 0; chan < dma_csr_ch; chan++) {
+               stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
++              stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 1, 1);
++      }
+       /* DMA RX Channel Configuration */
+       for (chan = 0; chan < rx_channels_count; chan++) {
+@@ -3768,6 +3787,7 @@ static int stmmac_open(struct net_device *dev)
+       stmmac_enable_all_queues(priv);
+       netif_tx_start_all_queues(priv->dev);
++      stmmac_enable_all_dma_irq(priv);
+       return 0;
+@@ -6531,8 +6551,10 @@ int stmmac_xdp_open(struct net_device *dev)
+       }
+       /* DMA CSR Channel configuration */
+-      for (chan = 0; chan < dma_csr_ch; chan++)
++      for (chan = 0; chan < dma_csr_ch; chan++) {
+               stmmac_init_chan(priv, priv->ioaddr, priv->plat->dma_cfg, chan);
++              stmmac_disable_dma_irq(priv, priv->ioaddr, chan, 1, 1);
++      }
+       /* Adjust Split header */
+       sph_en = (priv->hw->rx_csum > 0) && priv->sph;
+@@ -6592,6 +6614,7 @@ int stmmac_xdp_open(struct net_device *dev)
+       stmmac_enable_all_queues(priv);
+       netif_carrier_on(dev);
+       netif_tx_start_all_queues(dev);
++      stmmac_enable_all_dma_irq(priv);
+       return 0;
+@@ -7470,6 +7493,7 @@ int stmmac_resume(struct device *dev)
+       stmmac_restore_hw_vlan_rx_fltr(priv, ndev, priv->hw);
+       stmmac_enable_all_queues(priv);
++      stmmac_enable_all_dma_irq(priv);
+       mutex_unlock(&priv->lock);
+       rtnl_unlock();
+-- 
+2.34.1
+
diff --git a/queue-5.16/netfilter-nf_tables-prefer-kfree_rcu-ptr-rcu-variant.patch b/queue-5.16/netfilter-nf_tables-prefer-kfree_rcu-ptr-rcu-variant.patch
new file mode 100644 (file)
index 0000000..2fa0c8d
--- /dev/null
@@ -0,0 +1,53 @@
+From 733f87d56b9a367d15a7d964b23dbe840d01c1c7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 22 Feb 2022 10:13:31 -0800
+Subject: netfilter: nf_tables: prefer kfree_rcu(ptr, rcu) variant
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit ae089831ff28a115908b8d796f667c2dadef1637 ]
+
+While kfree_rcu(ptr) _is_ supported, it has some limitations.
+
+Given that 99.99% of kfree_rcu() users [1] use the legacy
+two parameters variant, and @catchall objects do have an rcu head,
+simply use it.
+
+Choice of kfree_rcu(ptr) variant was probably not intentional.
+
+[1] including calls from net/netfilter/nf_tables_api.c
+
+Fixes: aaa31047a6d2 ("netfilter: nftables: add catch-all set element support")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index a65b530975f5..2b2e0210a7f9 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -4486,7 +4486,7 @@ static void nft_set_catchall_destroy(const struct nft_ctx *ctx,
+       list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
+               list_del_rcu(&catchall->list);
+               nft_set_elem_destroy(set, catchall->elem, true);
+-              kfree_rcu(catchall);
++              kfree_rcu(catchall, rcu);
+       }
+ }
+@@ -5653,7 +5653,7 @@ static void nft_setelem_catchall_remove(const struct net *net,
+       list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
+               if (catchall->elem == elem->priv) {
+                       list_del_rcu(&catchall->list);
+-                      kfree_rcu(catchall);
++                      kfree_rcu(catchall, rcu);
+                       break;
+               }
+       }
+-- 
+2.34.1
+
diff --git a/queue-5.16/nl80211-handle-nla_memdup-failures-in-handle_nan_fil.patch b/queue-5.16/nl80211-handle-nla_memdup-failures-in-handle_nan_fil.patch
new file mode 100644 (file)
index 0000000..c7fe08d
--- /dev/null
@@ -0,0 +1,54 @@
+From 44331e751c3907fe89f2c201f5ea59a56acd9f3f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Mar 2022 18:00:20 +0800
+Subject: nl80211: Handle nla_memdup failures in handle_nan_filter
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit 6ad27f522cb3b210476daf63ce6ddb6568c0508b ]
+
+As there's potential for failure of the nla_memdup(),
+check the return value.
+
+Fixes: a442b761b24b ("cfg80211: add add_nan_func / del_nan_func")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Link: https://lore.kernel.org/r/20220301100020.3801187-1-jiasheng@iscas.ac.cn
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/wireless/nl80211.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
+index a27b3b5fa210..f73251828782 100644
+--- a/net/wireless/nl80211.c
++++ b/net/wireless/nl80211.c
+@@ -13379,6 +13379,9 @@ static int handle_nan_filter(struct nlattr *attr_filter,
+       i = 0;
+       nla_for_each_nested(attr, attr_filter, rem) {
+               filter[i].filter = nla_memdup(attr, GFP_KERNEL);
++              if (!filter[i].filter)
++                      goto err;
++
+               filter[i].len = nla_len(attr);
+               i++;
+       }
+@@ -13391,6 +13394,15 @@ static int handle_nan_filter(struct nlattr *attr_filter,
+       }
+       return 0;
++
++err:
++      i = 0;
++      nla_for_each_nested(attr, attr_filter, rem) {
++              kfree(filter[i].filter);
++              i++;
++      }
++      kfree(filter);
++      return -ENOMEM;
+ }
+ static int nl80211_nan_add_func(struct sk_buff *skb,
+-- 
+2.34.1
+
diff --git a/queue-5.16/ptp-ocp-add-ptp_ocp_adjtime_coarse-for-large-adjustm.patch b/queue-5.16/ptp-ocp-add-ptp_ocp_adjtime_coarse-for-large-adjustm.patch
new file mode 100644 (file)
index 0000000..f057eb7
--- /dev/null
@@ -0,0 +1,91 @@
+From ff38defe5e96242ec919416054973ec803a864dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 28 Feb 2022 12:39:57 -0800
+Subject: ptp: ocp: Add ptp_ocp_adjtime_coarse for large adjustments
+
+From: Jonathan Lemon <jonathan.lemon@gmail.com>
+
+[ Upstream commit 90f8f4c0e3cebd541deaa45cf0e470bb9810dd4f ]
+
+In ("ptp: ocp: Have FPGA fold in ns adjustment for adjtime."), the
+ns adjustment was written to the FPGA register, so the clock could
+accurately perform adjustments.
+
+However, the adjtime() call passes in a s64, while the clock adjustment
+registers use a s32.  When trying to perform adjustments with a large
+value (37 sec), things fail.
+
+Examine the incoming delta, and if larger than 1 sec, use the original
+(coarse) adjustment method.  If smaller than 1 sec, then allow the
+FPGA to fold in the changes over a 1 second window.
+
+Fixes: 6d59d4fa1789 ("ptp: ocp: Have FPGA fold in ns adjustment for adjtime.")
+Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
+Acked-by: Richard Cochran <richardcochran@gmail.com>
+Link: https://lore.kernel.org/r/20220228203957.367371-1-jonathan.lemon@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ptp/ptp_ocp.c | 25 +++++++++++++++++++++++--
+ 1 file changed, 23 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c
+index 0f1b5a7d2a89..17ad5f0d13b2 100644
+--- a/drivers/ptp/ptp_ocp.c
++++ b/drivers/ptp/ptp_ocp.c
+@@ -607,7 +607,7 @@ ptp_ocp_settime(struct ptp_clock_info *ptp_info, const struct timespec64 *ts)
+ }
+ static void
+-__ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
++__ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u32 adj_val)
+ {
+       u32 select, ctrl;
+@@ -615,7 +615,7 @@ __ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
+       iowrite32(OCP_SELECT_CLK_REG, &bp->reg->select);
+       iowrite32(adj_val, &bp->reg->offset_ns);
+-      iowrite32(adj_val & 0x7f, &bp->reg->offset_window_ns);
++      iowrite32(NSEC_PER_SEC, &bp->reg->offset_window_ns);
+       ctrl = OCP_CTRL_ADJUST_OFFSET | OCP_CTRL_ENABLE;
+       iowrite32(ctrl, &bp->reg->ctrl);
+@@ -624,6 +624,22 @@ __ptp_ocp_adjtime_locked(struct ptp_ocp *bp, u64 adj_val)
+       iowrite32(select >> 16, &bp->reg->select);
+ }
++static void
++ptp_ocp_adjtime_coarse(struct ptp_ocp *bp, u64 delta_ns)
++{
++      struct timespec64 ts;
++      unsigned long flags;
++      int err;
++
++      spin_lock_irqsave(&bp->lock, flags);
++      err = __ptp_ocp_gettime_locked(bp, &ts, NULL);
++      if (likely(!err)) {
++              timespec64_add_ns(&ts, delta_ns);
++              __ptp_ocp_settime_locked(bp, &ts);
++      }
++      spin_unlock_irqrestore(&bp->lock, flags);
++}
++
+ static int
+ ptp_ocp_adjtime(struct ptp_clock_info *ptp_info, s64 delta_ns)
+ {
+@@ -631,6 +647,11 @@ ptp_ocp_adjtime(struct ptp_clock_info *ptp_info, s64 delta_ns)
+       unsigned long flags;
+       u32 adj_ns, sign;
++      if (delta_ns > NSEC_PER_SEC || -delta_ns > NSEC_PER_SEC) {
++              ptp_ocp_adjtime_coarse(bp, delta_ns);
++              return 0;
++      }
++
+       sign = delta_ns < 0 ? BIT(31) : 0;
+       adj_ns = sign ? -delta_ns : delta_ns;
+-- 
+2.34.1
+
diff --git a/queue-5.16/selftests-mlxsw-resource_scale-fix-return-value.patch b/queue-5.16/selftests-mlxsw-resource_scale-fix-return-value.patch
new file mode 100644 (file)
index 0000000..70a6fcc
--- /dev/null
@@ -0,0 +1,57 @@
+From 5457c795f1823dbffe1a4a9321a33d6761b4b4b7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Mar 2022 18:14:47 +0200
+Subject: selftests: mlxsw: resource_scale: Fix return value
+
+From: Amit Cohen <amcohen@nvidia.com>
+
+[ Upstream commit 196f9bc050cbc5085b4cbb61cce2efe380bc66d0 ]
+
+The test runs several test cases and is supposed to return an error in
+case at least one of them failed.
+
+Currently, the check of the return value of each test case is in the
+wrong place, which can result in the wrong return value. For example:
+
+ # TESTS='tc_police' ./resource_scale.sh
+ TEST: 'tc_police' [default] 968                                     [FAIL]
+         tc police offload count failed
+ Error: mlxsw_spectrum: Failed to allocate policer index.
+ We have an error talking to the kernel
+ Command failed /tmp/tmp.i7Oc5HwmXY:969
+ TEST: 'tc_police' [default] overflow 969                            [ OK ]
+ ...
+ TEST: 'tc_police' [ipv4_max] overflow 969                           [ OK ]
+
+ $ echo $?
+ 0
+
+Fix this by moving the check to be done after each test case.
+
+Fixes: 059b18e21c63 ("selftests: mlxsw: Return correct error code in resource scale test")
+Signed-off-by: Amit Cohen <amcohen@nvidia.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../selftests/drivers/net/mlxsw/spectrum/resource_scale.sh      | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh b/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh
+index bcb110e830ce..dea33dc93790 100755
+--- a/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh
++++ b/tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh
+@@ -50,8 +50,8 @@ for current_test in ${TESTS:-$ALL_TESTS}; do
+                       else
+                               log_test "'$current_test' [$profile] overflow $target"
+                       fi
++                      RET_FIN=$(( RET_FIN || RET ))
+               done
+-              RET_FIN=$(( RET_FIN || RET ))
+       done
+ done
+ current_test=""
+-- 
+2.34.1
+
index fa3909a987fd48beb1c90bcf726b48bd51504c32..adf1eff10fcb9d927a24114355322ff0e2848d93 100644 (file)
@@ -116,3 +116,48 @@ ibmvnic-free-reset-work-item-when-flushing.patch
 memfd-fix-f_seal_write-after-shmem-huge-page-allocated.patch
 s390-setup-preserve-memory-at-oldmem_base-and-oldmem_size.patch
 s390-extable-fix-exception-table-sorting.patch
+arm64-dts-rockchip-drop-pclk_xpcs-from-gmac0-on-rk35.patch
+arm64-dts-juno-remove-gicv2m-dma-range.patch
+arm64-dts-rockchip-fix-quartz64-a-ddr-regulator-volt.patch
+arm64-dts-imx8mm-fix-vpu-hanging.patch
+iommu-amd-simplify-pagetable-freeing.patch
+iommu-amd-use-put_pages_list.patch
+iommu-amd-fix-i-o-page-table-memory-leak.patch
+mips-ralink-mt7621-do-memory-detection-on-kseg1.patch
+arm-dts-switch-timer-config-to-common-devkit8000-dev.patch
+arm-dts-use-32kihz-oscillator-on-devkit8000.patch
+soc-fsl-guts-revert-commit-3c0d64e867ed.patch
+soc-fsl-guts-add-a-missing-memory-allocation-failure.patch
+soc-fsl-qe-check-of-ioremap-return-value.patch
+soc-imx-gpcv2-fix-clock-disabling-imbalance-in-error.patch
+netfilter-nf_tables-prefer-kfree_rcu-ptr-rcu-variant.patch
+arm-tegra-move-panels-to-aux-bus.patch
+bluetooth-fix-bt_skb_sendmmsg-not-allocating-partial.patch
+can-etas_es58x-change-opened_channel_cnt-s-type-from.patch
+net-stmmac-enhance-xdp-zc-driver-level-switching-per.patch
+net-stmmac-only-enable-dma-interrupts-when-ready.patch
+ibmvnic-initialize-rc-before-completing-wait.patch
+ibmvnic-define-flush_reset_queue-helper.patch
+ibmvnic-complete-init_done-on-transport-events.patch
+ibmvnic-update-driver-return-codes.patch
+ibmvnic-init-init_done_rc-earlier.patch
+ibmvnic-clear-fop-when-retrying-probe.patch
+ibmvnic-allow-queueing-resets-during-probe.patch
+net-chelsio-cxgb3-check-the-return-value-of-pci_find.patch
+net-sparx5-fix-add-vlan-when-invalid-operation.patch
+iavf-add-trace-while-removing-device.patch
+iavf-rework-mutexes-for-better-synchronisation.patch
+iavf-add-waiting-so-the-port-is-initialized-in-remov.patch
+iavf-fix-init-state-closure-on-remove.patch
+iavf-fix-locking-for-virtchnl_op_get_offload_vlan_v2.patch
+iavf-fix-race-in-init-state.patch
+iavf-fix-__iavf_resetting-state-usage.patch
+drm-i915-guc-slpc-correct-the-param-count-for-unset-.patch
+drm-bridge-ti-sn65dsi86-properly-undo-autosuspend.patch
+e1000e-fix-possible-hw-unit-hang-after-an-s0ix-exit.patch
+mips-ralink-mt7621-use-bitwise-not-instead-of-logica.patch
+nl80211-handle-nla_memdup-failures-in-handle_nan_fil.patch
+ptp-ocp-add-ptp_ocp_adjtime_coarse-for-large-adjustm.patch
+drm-amdgpu-fix-suspend-resume-hang-regression.patch
+net-dcb-disable-softirqs-in-dcbnl_flush_dev.patch
+selftests-mlxsw-resource_scale-fix-return-value.patch
diff --git a/queue-5.16/soc-fsl-guts-add-a-missing-memory-allocation-failure.patch b/queue-5.16/soc-fsl-guts-add-a-missing-memory-allocation-failure.patch
new file mode 100644 (file)
index 0000000..5b46ecc
--- /dev/null
@@ -0,0 +1,49 @@
+From 4693252150fc3c82d81c55a99788e49835c1743b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Nov 2021 21:00:33 +0100
+Subject: soc: fsl: guts: Add a missing memory allocation failure check
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit b9abe942cda43a1d46a0fd96efb54f1aa909f757 ]
+
+If 'devm_kstrdup()' fails, we should return -ENOMEM.
+
+While at it, move the 'of_node_put()' call in the error handling path and
+after the 'machine' has been copied.
+Better safe than sorry.
+
+Fixes: a6fc3b698130 ("soc: fsl: add GUTS driver for QorIQ platforms")
+Depends-on: fddacc7ff4dd ("soc: fsl: guts: Revert commit 3c0d64e867ed")
+Suggested-by: Tyrel Datwyler <tyreld@linux.ibm.com>
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/guts.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
+index af7741eafc57..5ed2fc1c53a0 100644
+--- a/drivers/soc/fsl/guts.c
++++ b/drivers/soc/fsl/guts.c
+@@ -158,9 +158,14 @@ static int fsl_guts_probe(struct platform_device *pdev)
+       root = of_find_node_by_path("/");
+       if (of_property_read_string(root, "model", &machine))
+               of_property_read_string_index(root, "compatible", 0, &machine);
+-      of_node_put(root);
+-      if (machine)
++      if (machine) {
+               soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
++              if (!soc_dev_attr.machine) {
++                      of_node_put(root);
++                      return -ENOMEM;
++              }
++      }
++      of_node_put(root);
+       svr = fsl_guts_get_svr();
+       soc_die = fsl_soc_die_match(svr, fsl_soc_die);
+-- 
+2.34.1
+
diff --git a/queue-5.16/soc-fsl-guts-revert-commit-3c0d64e867ed.patch b/queue-5.16/soc-fsl-guts-revert-commit-3c0d64e867ed.patch
new file mode 100644 (file)
index 0000000..74afe39
--- /dev/null
@@ -0,0 +1,66 @@
+From 899a1d20a75fb5d0791c36baae3b7636339e90dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 3 Nov 2021 21:00:17 +0100
+Subject: soc: fsl: guts: Revert commit 3c0d64e867ed
+
+From: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+
+[ Upstream commit b113737cf12964a20cc3ba1ddabe6229099661c6 ]
+
+This reverts commit 3c0d64e867ed
+("soc: fsl: guts: reuse machine name from device tree").
+
+A following patch will fix the missing memory allocation failure check
+instead.
+
+Suggested-by: Tyrel Datwyler <tyreld@linux.ibm.com>
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/guts.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c
+index 072473a16f4d..af7741eafc57 100644
+--- a/drivers/soc/fsl/guts.c
++++ b/drivers/soc/fsl/guts.c
+@@ -28,7 +28,6 @@ struct fsl_soc_die_attr {
+ static struct guts *guts;
+ static struct soc_device_attribute soc_dev_attr;
+ static struct soc_device *soc_dev;
+-static struct device_node *root;
+ /* SoC die attribute definition for QorIQ platform */
+@@ -138,7 +137,7 @@ static u32 fsl_guts_get_svr(void)
+ static int fsl_guts_probe(struct platform_device *pdev)
+ {
+-      struct device_node *np = pdev->dev.of_node;
++      struct device_node *root, *np = pdev->dev.of_node;
+       struct device *dev = &pdev->dev;
+       const struct fsl_soc_die_attr *soc_die;
+       const char *machine;
+@@ -159,8 +158,9 @@ static int fsl_guts_probe(struct platform_device *pdev)
+       root = of_find_node_by_path("/");
+       if (of_property_read_string(root, "model", &machine))
+               of_property_read_string_index(root, "compatible", 0, &machine);
++      of_node_put(root);
+       if (machine)
+-              soc_dev_attr.machine = machine;
++              soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL);
+       svr = fsl_guts_get_svr();
+       soc_die = fsl_soc_die_match(svr, fsl_soc_die);
+@@ -195,7 +195,6 @@ static int fsl_guts_probe(struct platform_device *pdev)
+ static int fsl_guts_remove(struct platform_device *dev)
+ {
+       soc_device_unregister(soc_dev);
+-      of_node_put(root);
+       return 0;
+ }
+-- 
+2.34.1
+
diff --git a/queue-5.16/soc-fsl-qe-check-of-ioremap-return-value.patch b/queue-5.16/soc-fsl-qe-check-of-ioremap-return-value.patch
new file mode 100644 (file)
index 0000000..39c5461
--- /dev/null
@@ -0,0 +1,43 @@
+From 7bb0e835e01e327a37d1f46cf24095b8a97518ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 30 Dec 2021 09:45:43 +0800
+Subject: soc: fsl: qe: Check of ioremap return value
+
+From: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+
+[ Upstream commit a222fd8541394b36b13c89d1698d9530afd59a9c ]
+
+As the possible failure of the ioremap(), the par_io could be NULL.
+Therefore it should be better to check it and return error in order to
+guarantee the success of the initiation.
+But, I also notice that all the caller like mpc85xx_qe_par_io_init() in
+`arch/powerpc/platforms/85xx/common.c` don't check the return value of
+the par_io_init().
+Actually, par_io_init() needs to check to handle the potential error.
+I will submit another patch to fix that.
+Anyway, par_io_init() itsely should be fixed.
+
+Fixes: 7aa1aa6ecec2 ("QE: Move QE from arch/powerpc to drivers/soc")
+Signed-off-by: Jiasheng Jiang <jiasheng@iscas.ac.cn>
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/fsl/qe/qe_io.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/soc/fsl/qe/qe_io.c b/drivers/soc/fsl/qe/qe_io.c
+index e277c827bdf3..a5e2d0e5ab51 100644
+--- a/drivers/soc/fsl/qe/qe_io.c
++++ b/drivers/soc/fsl/qe/qe_io.c
+@@ -35,6 +35,8 @@ int par_io_init(struct device_node *np)
+       if (ret)
+               return ret;
+       par_io = ioremap(res.start, resource_size(&res));
++      if (!par_io)
++              return -ENOMEM;
+       if (!of_property_read_u32(np, "num-ports", &num_ports))
+               num_par_io_ports = num_ports;
+-- 
+2.34.1
+
diff --git a/queue-5.16/soc-imx-gpcv2-fix-clock-disabling-imbalance-in-error.patch b/queue-5.16/soc-imx-gpcv2-fix-clock-disabling-imbalance-in-error.patch
new file mode 100644 (file)
index 0000000..c26da41
--- /dev/null
@@ -0,0 +1,41 @@
+From 851466a38cf93dd073dfe79b166fb7e3249843a3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 18 Feb 2022 23:57:20 +0200
+Subject: soc: imx: gpcv2: Fix clock disabling imbalance in error path
+
+From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+[ Upstream commit fa231bef3b34f1670b240409c11e59a3ce095e6d ]
+
+The imx_pgc_power_down() starts by enabling the domain clocks, and thus
+disables them in the error path. Commit 18c98573a4cf ("soc: imx: gpcv2:
+add domain option to keep domain clocks enabled") made the clock enable
+conditional, but forgot to add the same condition to the error path.
+This can result in a clock enable/disable imbalance. Fix it.
+
+Fixes: 18c98573a4cf ("soc: imx: gpcv2: add domain option to keep domain clocks enabled")
+Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/imx/gpcv2.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
+index 8176380b02e6..4415f07e1fa9 100644
+--- a/drivers/soc/imx/gpcv2.c
++++ b/drivers/soc/imx/gpcv2.c
+@@ -382,7 +382,8 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd)
+       return 0;
+ out_clk_disable:
+-      clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
++      if (!domain->keep_clocks)
++              clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
+       return ret;
+ }
+-- 
+2.34.1
+