From 14ccdb534eae3b649ca5219c1873a79cbfd43ebd Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sun, 2 Oct 2022 13:51:54 -0400 Subject: [PATCH] Fixes for 5.19 Signed-off-by: Sasha Levin --- ...dts-am33xx-fix-mmchs0-dma-properties.patch | 39 + ...arm-dts-am5748-keep-usb4_tm-disabled.patch | 68 + ...-qcom-sm8350-fix-ufs-phy-serdes-size.patch | 38 + ...-fix-refcount-issue-with-of_node_put.patch | 44 + ...soc-tas2770-reinit-regcache-on-reset.patch | 50 + ...emove-the-set_rate_parent-flag-for-q.patch | 49 + queue-5.19/clk-imx93-drop-of_match_ptr.patch | 44 + ...-rely-on-node-name-for-correct-pll-s.patch | 82 + ...fs-fix-clk_cfg-array-bounds-violatio.patch | 93 + ...fs-make-the-rtc-s-ahb-clock-critical.patch | 46 + ...g-unlock-on-ethofld-desc-collect-fai.patch | 121 ++ ...se-__kernel_write-on-kmap_local_page.patch | 160 ++ .../drm-bridge-lt8912b-add-vsync-hsync.patch | 66 + ...e-lt8912b-fix-corrupted-image-output.patch | 47 + ...-bridge-lt8912b-set-hdmi-or-dvi-mode.patch | 38 + ..._limit_reasons-are-only-available-fo.patch | 74 + ...heck-for-pwm-support-on-non-a8k-plat.patch | 60 + ...hange-batched-tx-descriptor-cleaning.patch | 304 +++ ...er-of-2-ring-size-restriction-for-af.patch | 79 + ...4-fix-return-value-check-in-mip4_pro.patch | 37 + ...2_platform_dca_cap-31-0-from-the-gue.patch | 40 + ..._eth_soc-fix-mask-of-rx_dma_get_spor.patch | 41 + ...qmp-sgmii-non-wakeup-source-resume-f.patch | 62 + ...ix-an-is_err-vs-null-bug-in-mlxbf_gi.patch | 39 + ...fix-tagged-vlan-refusal-while-under-.patch | 83 + ...rn-for-phy_up-state-in-mdio_bus_phy_.patch | 63 + ...-fix-possible-refcount-leak-in-tcf_c.patch | 47 + ...-up-down-serdes-in-stmmac_open-relea.patch | 130 ++ ...clear-and-ioc_pr_release-ioctls-for-.patch | 63 + ...ts-break-out-tracepoint-and-printing.patch | 1790 +++++++++++++++++ ...s-remove-not-supported-hybrid-cache-.patch | 236 +++ ...s-fix-perf-list-can-not-display-the-.patch | 101 + ...st-case-87-perf-record-tests-for-hyb.patch | 56 + ...d-fail-the-test-if-the-errs-counter-.patch | 65 + ...ix-the-imx8mp-pcie-phy-perst-support.patch | 44 + ...e-analogix-dp-add-panel-prepare-unpr.patch | 88 + ...e-if-conditions-of-in-test_extra_fil.patch | 37 + queue-5.19/series | 48 + ...nxi-sram-actually-claim-sram-regions.patch | 40 + ...sram-fix-debugfs-info-for-a64-sram-c.patch | 40 + ...m-fix-probe-function-ordering-issues.patch | 74 + ...revent-the-driver-from-being-unbound.patch | 53 + ...fix-memory-leak-in-usbnet_disconnect.patch | 56 + ...cvf-fix-the-calculation-of-queuepair.patch | 49 + ...-to-support-non-power-of-two-num-que.patch | 103 + ...-fix-warn_on_once-in-virtio_queue_rq.patch | 149 ++ .../wifi-cfg80211-fix-mcs-divisor-value.patch | 51 + ...x-memory-corruption-in-minstrel_ht_u.patch | 122 ++ ...-fix-regression-with-non-qos-drivers.patch | 65 + 49 files changed, 5374 insertions(+) create mode 100644 queue-5.19/arm-dts-am33xx-fix-mmchs0-dma-properties.patch create mode 100644 queue-5.19/arm-dts-am5748-keep-usb4_tm-disabled.patch create mode 100644 queue-5.19/arm64-dts-qcom-sm8350-fix-ufs-phy-serdes-size.patch create mode 100644 queue-5.19/asoc-imx-card-fix-refcount-issue-with-of_node_put.patch create mode 100644 queue-5.19/asoc-tas2770-reinit-regcache-on-reset.patch create mode 100644 queue-5.19/clk-imx-imx6sx-remove-the-set_rate_parent-flag-for-q.patch create mode 100644 queue-5.19/clk-imx93-drop-of_match_ptr.patch create mode 100644 queue-5.19/clk-iproc-do-not-rely-on-node-name-for-correct-pll-s.patch create mode 100644 queue-5.19/clk-microchip-mpfs-fix-clk_cfg-array-bounds-violatio.patch create mode 100644 queue-5.19/clk-microchip-mpfs-make-the-rtc-s-ahb-clock-critical.patch create mode 100644 queue-5.19/cxgb4-fix-missing-unlock-on-ethofld-desc-collect-fai.patch create mode 100644 queue-5.19/don-t-use-__kernel_write-on-kmap_local_page.patch create mode 100644 queue-5.19/drm-bridge-lt8912b-add-vsync-hsync.patch create mode 100644 queue-5.19/drm-bridge-lt8912b-fix-corrupted-image-output.patch create mode 100644 queue-5.19/drm-bridge-lt8912b-set-hdmi-or-dvi-mode.patch create mode 100644 queue-5.19/drm-i915-gt-perf_limit_reasons-are-only-available-fo.patch create mode 100644 queue-5.19/gpio-mvebu-fix-check-for-pwm-support-on-non-a8k-plat.patch create mode 100644 queue-5.19/ice-xsk-change-batched-tx-descriptor-cleaning.patch create mode 100644 queue-5.19/ice-xsk-drop-power-of-2-ring-size-restriction-for-af.patch create mode 100644 queue-5.19/input-melfas_mip4-fix-return-value-check-in-mip4_pro.patch create mode 100644 queue-5.19/kvm-x86-hide-ia32_platform_dca_cap-31-0-from-the-gue.patch create mode 100644 queue-5.19/net-ethernet-mtk_eth_soc-fix-mask-of-rx_dma_get_spor.patch create mode 100644 queue-5.19/net-macb-fix-zynqmp-sgmii-non-wakeup-source-resume-f.patch create mode 100644 queue-5.19/net-mlxbf_gige-fix-an-is_err-vs-null-bug-in-mlxbf_gi.patch create mode 100644 queue-5.19/net-mscc-ocelot-fix-tagged-vlan-refusal-while-under-.patch create mode 100644 queue-5.19/net-phy-don-t-warn-for-phy_up-state-in-mdio_bus_phy_.patch create mode 100644 queue-5.19/net-sched-act_ct-fix-possible-refcount-leak-in-tcf_c.patch create mode 100644 queue-5.19/net-stmmac-power-up-down-serdes-in-stmmac_open-relea.patch create mode 100644 queue-5.19/nvme-fix-ioc_pr_clear-and-ioc_pr_release-ioctls-for-.patch create mode 100644 queue-5.19/perf-parse-events-break-out-tracepoint-and-printing.patch create mode 100644 queue-5.19/perf-parse-events-remove-not-supported-hybrid-cache-.patch create mode 100644 queue-5.19/perf-print-events-fix-perf-list-can-not-display-the-.patch create mode 100644 queue-5.19/perf-test-fix-test-case-87-perf-record-tests-for-hyb.patch create mode 100644 queue-5.19/perf-tests-record-fail-the-test-if-the-errs-counter-.patch create mode 100644 queue-5.19/reset-imx7-fix-the-imx8mp-pcie-phy-perst-support.patch create mode 100644 queue-5.19/revert-drm-bridge-analogix-dp-add-panel-prepare-unpr.patch create mode 100644 queue-5.19/selftests-fix-the-if-conditions-of-in-test_extra_fil.patch create mode 100644 queue-5.19/soc-sunxi-sram-actually-claim-sram-regions.patch create mode 100644 queue-5.19/soc-sunxi-sram-fix-debugfs-info-for-a64-sram-c.patch create mode 100644 queue-5.19/soc-sunxi-sram-fix-probe-function-ordering-issues.patch create mode 100644 queue-5.19/soc-sunxi-sram-prevent-the-driver-from-being-unbound.patch create mode 100644 queue-5.19/usbnet-fix-memory-leak-in-usbnet_disconnect.patch create mode 100644 queue-5.19/vdpa-ifcvf-fix-the-calculation-of-queuepair.patch create mode 100644 queue-5.19/vdpa-mlx5-fix-mq-to-support-non-power-of-two-num-que.patch create mode 100644 queue-5.19/virtio-blk-fix-warn_on_once-in-virtio_queue_rq.patch create mode 100644 queue-5.19/wifi-cfg80211-fix-mcs-divisor-value.patch create mode 100644 queue-5.19/wifi-mac80211-fix-memory-corruption-in-minstrel_ht_u.patch create mode 100644 queue-5.19/wifi-mac80211-fix-regression-with-non-qos-drivers.patch diff --git a/queue-5.19/arm-dts-am33xx-fix-mmchs0-dma-properties.patch b/queue-5.19/arm-dts-am33xx-fix-mmchs0-dma-properties.patch new file mode 100644 index 00000000000..5d569d0d9a7 --- /dev/null +++ b/queue-5.19/arm-dts-am33xx-fix-mmchs0-dma-properties.patch @@ -0,0 +1,39 @@ +From e10d6ffb0aa8944422e52adb0afc7b5e6393d3fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Jun 2022 05:41:46 -0700 +Subject: ARM: dts: am33xx: Fix MMCHS0 dma properties + +From: YuTong Chang + +[ Upstream commit 2eb502f496f7764027b7958d4e74356fed918059 ] + +According to technical manual(table 11-24), the DMA of MMCHS0 should be +direct mapped. + +Fixes: b5e509066074 ("ARM: DTS: am33xx: Use the new DT bindings for the eDMA3") +Signed-off-by: YuTong Chang +Message-Id: <20220620124146.5330-1-mtwget@gmail.com> +Acked-by: Krzysztof Kozlowski +Signed-off-by: Tony Lindgren +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/am33xx-l4.dtsi | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi +index 7da42a5b959c..7e50fe633d8a 100644 +--- a/arch/arm/boot/dts/am33xx-l4.dtsi ++++ b/arch/arm/boot/dts/am33xx-l4.dtsi +@@ -1502,8 +1502,7 @@ + mmc1: mmc@0 { + compatible = "ti,am335-sdhci"; + ti,needs-special-reset; +- dmas = <&edma_xbar 24 0 0 +- &edma_xbar 25 0 0>; ++ dmas = <&edma 24 0>, <&edma 25 0>; + dma-names = "tx", "rx"; + interrupts = <64>; + reg = <0x0 0x1000>; +-- +2.35.1 + diff --git a/queue-5.19/arm-dts-am5748-keep-usb4_tm-disabled.patch b/queue-5.19/arm-dts-am5748-keep-usb4_tm-disabled.patch new file mode 100644 index 00000000000..18f57387516 --- /dev/null +++ b/queue-5.19/arm-dts-am5748-keep-usb4_tm-disabled.patch @@ -0,0 +1,68 @@ +From 7ea878619f50157bbb40a3d4406d40fbc0722b65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Aug 2022 09:27:42 +0200 +Subject: ARM: dts: am5748: keep usb4_tm disabled + +From: Romain Naour + +[ Upstream commit 6a6d9ecff14a2a46c1deeffa3eb3825349639bdd ] + +Commit bcbb63b80284 ("ARM: dts: dra7: Separate AM57 dtsi files") +disabled usb4_tm for am5748 devices since USB4 IP is not present +in this SoC. + +The commit log explained the difference between AM5 and DRA7 families: + +AM5 and DRA7 SoC families have different set of modules in them so the +SoC sepecific dtsi files need to be separated. + +e.g. Some of the major differences between AM576 and DRA76 + + DRA76x AM576x + +USB3 x +USB4 x +ATL x +VCP x +MLB x +ISS x +PRU-ICSS1 x +PRU-ICSS2 x + +Then commit 176f26bcd41a ("ARM: dts: Add support for dra762 abz +package") removed usb4_tm part from am5748.dtsi and introcuded new +ti-sysc errors in dmesg: + +ti-sysc 48940000.target-module: clock get error for fck: -2 +ti-sysc: probe of 48940000.target-module failed with error -2 + +Fixes: 176f26bcd41a ("ARM: dts: Add support for dra762 abz package") + +Signed-off-by: Romain Naour +Signed-off-by: Romain Naour +Message-Id: <20220823072742.351368-1-romain.naour@smile.fr> +Reviewed-by: Roger Quadros +Signed-off-by: Tony Lindgren +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/am5748.dtsi | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm/boot/dts/am5748.dtsi b/arch/arm/boot/dts/am5748.dtsi +index c260aa1a85bd..a1f029e9d1f3 100644 +--- a/arch/arm/boot/dts/am5748.dtsi ++++ b/arch/arm/boot/dts/am5748.dtsi +@@ -25,6 +25,10 @@ + status = "disabled"; + }; + ++&usb4_tm { ++ status = "disabled"; ++}; ++ + &atl_tm { + status = "disabled"; + }; +-- +2.35.1 + diff --git a/queue-5.19/arm64-dts-qcom-sm8350-fix-ufs-phy-serdes-size.patch b/queue-5.19/arm64-dts-qcom-sm8350-fix-ufs-phy-serdes-size.patch new file mode 100644 index 00000000000..ca4da62624e --- /dev/null +++ b/queue-5.19/arm64-dts-qcom-sm8350-fix-ufs-phy-serdes-size.patch @@ -0,0 +1,38 @@ +From 579553f3ba02a8703964adde942b166ceb9623a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Sep 2022 11:36:03 +0200 +Subject: arm64: dts: qcom: sm8350: fix UFS PHY serdes size + +From: Johan Hovold + +[ Upstream commit 40e9541959100e017533e18e44d07eed44f91dc5 ] + +The size of the UFS PHY serdes register region is 0x1c4 and the +corresponding 'reg' property should specifically not include the +adjacent regions that are defined in the child node (e.g. tx and rx). + +Fixes: 59c7cf814783 ("arm64: dts: qcom: sm8350: Add UFS nodes") +Signed-off-by: Johan Hovold +Signed-off-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20220916093603.24263-1-johan+linaro@kernel.org +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8350.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi +index 3293f76478df..0e5a4fbb5eb1 100644 +--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi +@@ -2128,7 +2128,7 @@ + + ufs_mem_phy: phy@1d87000 { + compatible = "qcom,sm8350-qmp-ufs-phy"; +- reg = <0 0x01d87000 0 0xe10>; ++ reg = <0 0x01d87000 0 0x1c4>; + #address-cells = <2>; + #size-cells = <2>; + ranges; +-- +2.35.1 + diff --git a/queue-5.19/asoc-imx-card-fix-refcount-issue-with-of_node_put.patch b/queue-5.19/asoc-imx-card-fix-refcount-issue-with-of_node_put.patch new file mode 100644 index 00000000000..081f0ea12ea --- /dev/null +++ b/queue-5.19/asoc-imx-card-fix-refcount-issue-with-of_node_put.patch @@ -0,0 +1,44 @@ +From 638d3203de61befe2a0d901dcf27cbc10c10a38a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 13 Sep 2022 17:00:01 +0800 +Subject: ASoC: imx-card: Fix refcount issue with of_node_put + +From: Shengjiu Wang + +[ Upstream commit d56ba9a04d7548d4149c46ec86a0e3cc41a70f4a ] + +imx_card_parse_of will search all the node with loop, +if there is defer probe happen in the middle of loop, +the previous released codec node will be released +twice, then cause refcount issue. + +Here assign NULL to pointer of released nodes to fix +the issue. + +Fixes: aa736700f42f ("ASoC: imx-card: Add imx-card machine driver") +Signed-off-by: Shengjiu Wang +Link: https://lore.kernel.org/r/1663059601-29259-1-git-send-email-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/imx-card.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c +index 4a8609b0d700..5153af3281d2 100644 +--- a/sound/soc/fsl/imx-card.c ++++ b/sound/soc/fsl/imx-card.c +@@ -698,6 +698,10 @@ static int imx_card_parse_of(struct imx_card_data *data) + of_node_put(cpu); + of_node_put(codec); + of_node_put(platform); ++ ++ cpu = NULL; ++ codec = NULL; ++ platform = NULL; + } + + return 0; +-- +2.35.1 + diff --git a/queue-5.19/asoc-tas2770-reinit-regcache-on-reset.patch b/queue-5.19/asoc-tas2770-reinit-regcache-on-reset.patch new file mode 100644 index 00000000000..df2115f2542 --- /dev/null +++ b/queue-5.19/asoc-tas2770-reinit-regcache-on-reset.patch @@ -0,0 +1,50 @@ +From 5e518dc0aff5239e6ede53ab9bcbae54fbeb12ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Sep 2022 19:34:53 +0200 +Subject: ASoC: tas2770: Reinit regcache on reset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Martin Povišer + +[ Upstream commit 0a0342ede303fc420f3a388e1ae82da3ae8ff6bd ] + +On probe of the ASoC component, the device is reset but the regcache is +retained. This means the regcache gets out of sync if the codec is +rebound to a sound card for a second time. Fix it by reinitializing the +regcache to defaults after the device is reset. + +Fixes: b0bcbe615756 ("ASoC: tas2770: Fix calling reset in probe") +Signed-off-by: Martin Povišer +Link: https://lore.kernel.org/r/20220919173453.84292-1-povik+lin@cutebit.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/tas2770.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/codecs/tas2770.c b/sound/soc/codecs/tas2770.c +index 9ea2aca65e89..e02ad765351b 100644 +--- a/sound/soc/codecs/tas2770.c ++++ b/sound/soc/codecs/tas2770.c +@@ -495,6 +495,8 @@ static struct snd_soc_dai_driver tas2770_dai_driver[] = { + }, + }; + ++static const struct regmap_config tas2770_i2c_regmap; ++ + static int tas2770_codec_probe(struct snd_soc_component *component) + { + struct tas2770_priv *tas2770 = +@@ -508,6 +510,7 @@ static int tas2770_codec_probe(struct snd_soc_component *component) + } + + tas2770_reset(tas2770); ++ regmap_reinit_cache(tas2770->regmap, &tas2770_i2c_regmap); + + return 0; + } +-- +2.35.1 + diff --git a/queue-5.19/clk-imx-imx6sx-remove-the-set_rate_parent-flag-for-q.patch b/queue-5.19/clk-imx-imx6sx-remove-the-set_rate_parent-flag-for-q.patch new file mode 100644 index 00000000000..31c9e1dfc08 --- /dev/null +++ b/queue-5.19/clk-imx-imx6sx-remove-the-set_rate_parent-flag-for-q.patch @@ -0,0 +1,49 @@ +From dcbfbd95b2ca32266290ade8b2cd85f2169e4e82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Sep 2022 10:09:59 -0500 +Subject: clk: imx: imx6sx: remove the SET_RATE_PARENT flag for QSPI clocks + +From: Han Xu + +[ Upstream commit b1ff1bfe81e763420afd5f3f25f0b3cbfd97055c ] + +There is no dedicate parent clock for QSPI so SET_RATE_PARENT flag +should not be used. For instance, the default parent clock for QSPI is +pll2_bus, which is also the parent clock for quite a few modules, such +as MMDC, once GPMI NAND set clock rate for EDO5 mode can cause system +hang due to pll2_bus rate changed. + +Fixes: f1541e15e38e ("clk: imx6sx: Switch to clk_hw based API") +Signed-off-by: Han Xu +Link: https://lore.kernel.org/r/20220915150959.3646702-1-han.xu@nxp.com +Tested-by: Fabio Estevam +Reviewed-by: Abel Vesa +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx6sx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c +index fc1bd23d4583..598f3cf4eba4 100644 +--- a/drivers/clk/imx/clk-imx6sx.c ++++ b/drivers/clk/imx/clk-imx6sx.c +@@ -280,13 +280,13 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) + hws[IMX6SX_CLK_SSI3_SEL] = imx_clk_hw_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + hws[IMX6SX_CLK_SSI2_SEL] = imx_clk_hw_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); + hws[IMX6SX_CLK_SSI1_SEL] = imx_clk_hw_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); +- hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT); ++ hws[IMX6SX_CLK_QSPI1_SEL] = imx_clk_hw_mux("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels)); + hws[IMX6SX_CLK_PERCLK_SEL] = imx_clk_hw_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); + hws[IMX6SX_CLK_VID_SEL] = imx_clk_hw_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels)); + hws[IMX6SX_CLK_ESAI_SEL] = imx_clk_hw_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); + hws[IMX6SX_CLK_CAN_SEL] = imx_clk_hw_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); + hws[IMX6SX_CLK_UART_SEL] = imx_clk_hw_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); +- hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT); ++ hws[IMX6SX_CLK_QSPI2_SEL] = imx_clk_hw_mux("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels)); + hws[IMX6SX_CLK_SPDIF_SEL] = imx_clk_hw_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); + hws[IMX6SX_CLK_AUDIO_SEL] = imx_clk_hw_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); + hws[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_hw_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels)); +-- +2.35.1 + diff --git a/queue-5.19/clk-imx93-drop-of_match_ptr.patch b/queue-5.19/clk-imx93-drop-of_match_ptr.patch new file mode 100644 index 00000000000..06315cfad85 --- /dev/null +++ b/queue-5.19/clk-imx93-drop-of_match_ptr.patch @@ -0,0 +1,44 @@ +From feab25fe1722b94aff9d52ae1677d37db79c4253 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Aug 2022 11:31:31 +0800 +Subject: clk: imx93: drop of_match_ptr + +From: Peng Fan + +[ Upstream commit daaa2fbe678efdaced53d1c635f4d326751addf8 ] + +There is build warning when CONFIG_OF is not selected. +>> drivers/clk/imx/clk-imx93.c:324:34: warning: 'imx93_clk_of_match' +>> defined but not used [-Wunused-const-variable=] + 324 | static const struct of_device_id imx93_clk_of_match[] = { + | ^~~~~~~~~~~~~~~~~~ + +The driver only support DT table, no sense to use of_match_ptr. + +Fixes: 24defbe194b6 ("clk: imx: add i.MX93 clk") +Reported-by: kernel test robot +Signed-off-by: Peng Fan +Link: https://lore.kernel.org/r/20220830033137.4149542-3-peng.fan@oss.nxp.com +Reviewed-by: Abel Vesa +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/imx/clk-imx93.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/imx/clk-imx93.c b/drivers/clk/imx/clk-imx93.c +index f5c9fa40491c..dcc41d178238 100644 +--- a/drivers/clk/imx/clk-imx93.c ++++ b/drivers/clk/imx/clk-imx93.c +@@ -332,7 +332,7 @@ static struct platform_driver imx93_clk_driver = { + .driver = { + .name = "imx93-ccm", + .suppress_bind_attrs = true, +- .of_match_table = of_match_ptr(imx93_clk_of_match), ++ .of_match_table = imx93_clk_of_match, + }, + }; + module_platform_driver(imx93_clk_driver); +-- +2.35.1 + diff --git a/queue-5.19/clk-iproc-do-not-rely-on-node-name-for-correct-pll-s.patch b/queue-5.19/clk-iproc-do-not-rely-on-node-name-for-correct-pll-s.patch new file mode 100644 index 00000000000..eb1eb278ee2 --- /dev/null +++ b/queue-5.19/clk-iproc-do-not-rely-on-node-name-for-correct-pll-s.patch @@ -0,0 +1,82 @@ +From 3d49a6ae18988c75b3122550e116289d7b5f9442 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Sep 2022 09:15:03 -0700 +Subject: clk: iproc: Do not rely on node name for correct PLL setup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Florian Fainelli + +[ Upstream commit 1b24a132eba7a1c19475ba2510ec1c00af3ff914 ] + +After commit 31fd9b79dc58 ("ARM: dts: BCM5301X: update CRU block +description") a warning from clk-iproc-pll.c was generated due to a +duplicate PLL name as well as the console stopped working. Upon closer +inspection it became clear that iproc_pll_clk_setup() used the Device +Tree node unit name as an unique identifier as well as a parent name to +parent all clocks under the PLL. + +BCM5301X was the first platform on which that got noticed because of the +DT node unit name renaming but the same assumptions hold true for any +user of the iproc_pll_clk_setup() function. + +The first 'clock-output-names' property is always guaranteed to be +unique as well as providing the actual desired PLL clock name, so we +utilize that to register the PLL and as a parent name of all children +clock. + +Fixes: 5fe225c105fd ("clk: iproc: add initial common clock support") +Signed-off-by: Florian Fainelli +Acked-by: Rafał Miłecki +Link: https://lore.kernel.org/r/20220905161504.1526-1-f.fainelli@gmail.com +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/bcm/clk-iproc-pll.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c +index 33da30f99c79..d39c44b61c52 100644 +--- a/drivers/clk/bcm/clk-iproc-pll.c ++++ b/drivers/clk/bcm/clk-iproc-pll.c +@@ -736,6 +736,7 @@ void iproc_pll_clk_setup(struct device_node *node, + const char *parent_name; + struct iproc_clk *iclk_array; + struct clk_hw_onecell_data *clk_data; ++ const char *clk_name; + + if (WARN_ON(!pll_ctrl) || WARN_ON(!clk_ctrl)) + return; +@@ -783,7 +784,12 @@ void iproc_pll_clk_setup(struct device_node *node, + iclk = &iclk_array[0]; + iclk->pll = pll; + +- init.name = node->name; ++ ret = of_property_read_string_index(node, "clock-output-names", ++ 0, &clk_name); ++ if (WARN_ON(ret)) ++ goto err_pll_register; ++ ++ init.name = clk_name; + init.ops = &iproc_pll_ops; + init.flags = 0; + parent_name = of_clk_get_parent_name(node, 0); +@@ -803,13 +809,11 @@ void iproc_pll_clk_setup(struct device_node *node, + goto err_pll_register; + + clk_data->hws[0] = &iclk->hw; ++ parent_name = clk_name; + + /* now initialize and register all leaf clocks */ + for (i = 1; i < num_clks; i++) { +- const char *clk_name; +- + memset(&init, 0, sizeof(init)); +- parent_name = node->name; + + ret = of_property_read_string_index(node, "clock-output-names", + i, &clk_name); +-- +2.35.1 + diff --git a/queue-5.19/clk-microchip-mpfs-fix-clk_cfg-array-bounds-violatio.patch b/queue-5.19/clk-microchip-mpfs-fix-clk_cfg-array-bounds-violatio.patch new file mode 100644 index 00000000000..013201d0223 --- /dev/null +++ b/queue-5.19/clk-microchip-mpfs-fix-clk_cfg-array-bounds-violatio.patch @@ -0,0 +1,93 @@ +From 09deaaada2e6dbe0bebf671b34b7ea18c7ce3ddc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Sep 2022 13:31:10 +0100 +Subject: clk: microchip: mpfs: fix clk_cfg array bounds violation + +From: Conor Dooley + +[ Upstream commit 5da39ac5d648cdbfdfa8bea0e0cde279ded5c7c2 ] + +There is an array bounds violation present during clock registration, +triggered by current code by only specific toolchains. This seems to +fail gracefully in v6.0-rc1, using a toolchain build from the riscv- +gnu-toolchain repo and with clang-15, and life carries on. While +converting the driver to use standard clock structs/ops, kernel panics +were seen during boot when built with clang-15: + +[ 0.581754] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000b1 +[ 0.591520] Oops [#1] +[ 0.594045] Modules linked in: +[ 0.597435] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.0.0-rc1-00011-g8e1459cf4eca #1 +[ 0.606188] Hardware name: Microchip PolarFire-SoC Icicle Kit (DT) +[ 0.613012] epc : __clk_register+0x4a6/0x85c +[ 0.617759] ra : __clk_register+0x49e/0x85c +[ 0.622489] epc : ffffffff803faf7c ra : ffffffff803faf74 sp : ffffffc80400b720 +[ 0.630466] gp : ffffffff810e93f8 tp : ffffffe77fe60000 t0 : ffffffe77ffb3800 +[ 0.638443] t1 : 000000000000000a t2 : ffffffffffffffff s0 : ffffffc80400b7c0 +[ 0.646420] s1 : 0000000000000001 a0 : 0000000000000001 a1 : 0000000000000000 +[ 0.654396] a2 : 0000000000000001 a3 : 0000000000000000 a4 : 0000000000000000 +[ 0.662373] a5 : ffffffff803a5810 a6 : 0000000200000022 a7 : 0000000000000006 +[ 0.670350] s2 : ffffffff81099d48 s3 : ffffffff80d6e28e s4 : 0000000000000028 +[ 0.678327] s5 : ffffffff810ed3c8 s6 : ffffffff810ed3d0 s7 : ffffffe77ffbc100 +[ 0.686304] s8 : ffffffe77ffb1540 s9 : ffffffe77ffb1540 s10: 0000000000000008 +[ 0.694281] s11: 0000000000000000 t3 : 00000000000000c6 t4 : 0000000000000007 +[ 0.702258] t5 : ffffffff810c78c0 t6 : ffffffe77ff88cd0 +[ 0.708125] status: 0000000200000120 badaddr: 00000000000000b1 cause: 000000000000000d +[ 0.716869] [] devm_clk_hw_register+0x62/0xaa +[ 0.723420] [] mpfs_clk_probe+0x1e0/0x244 + +In v6.0-rc1 and later, this issue is visible without the follow on +patches doing the conversion using toolchains provided by our Yocto +meta layer too. + +It fails on "clk_periph_timer" - which uses a different parent, that it +tries to find using the macro: +\#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].cfg.hw) + +If parent is RTCREF, so the macro becomes: &mpfs_cfg_clks[33].cfg.hw +which is well beyond the end of the array. Amazingly, builds with GCC +11.1 see no problem here, booting correctly and hooking the parent up +etc. Builds with clang-15 do not, with the above panic. + +Change the macro to use specific offsets depending on the parent rather +than the dt-binding's clock IDs. + +Fixes: 1c6a7ea32b8c ("clk: microchip: mpfs: add RTCREF clock control") +CC: Nathan Chancellor +Signed-off-by: Conor Dooley +Reviewed-by: Claudiu Beznea +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20220909123123.2699583-2-conor.dooley@microchip.com +Signed-off-by: Sasha Levin +--- + drivers/clk/microchip/clk-mpfs.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c +index 070c3b896559..f0f9c9a1cc48 100644 +--- a/drivers/clk/microchip/clk-mpfs.c ++++ b/drivers/clk/microchip/clk-mpfs.c +@@ -239,6 +239,11 @@ static const struct clk_ops mpfs_clk_cfg_ops = { + .hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \ + } + ++#define CLK_CPU_OFFSET 0u ++#define CLK_AXI_OFFSET 1u ++#define CLK_AHB_OFFSET 2u ++#define CLK_RTCREF_OFFSET 3u ++ + static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = { + CLK_CFG(CLK_CPU, "clk_cpu", "clk_msspll", 0, 2, mpfs_div_cpu_axi_table, 0, + REG_CLOCK_CONFIG_CR), +@@ -362,7 +367,7 @@ static const struct clk_ops mpfs_periph_clk_ops = { + _flags), \ + } + +-#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT].hw) ++#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].hw) + + /* + * Critical clocks: +-- +2.35.1 + diff --git a/queue-5.19/clk-microchip-mpfs-make-the-rtc-s-ahb-clock-critical.patch b/queue-5.19/clk-microchip-mpfs-make-the-rtc-s-ahb-clock-critical.patch new file mode 100644 index 00000000000..a21a2a0446f --- /dev/null +++ b/queue-5.19/clk-microchip-mpfs-make-the-rtc-s-ahb-clock-critical.patch @@ -0,0 +1,46 @@ +From c112c1c905cb06ba3e548d6e253e7b941870cd5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 9 Sep 2022 13:31:11 +0100 +Subject: clk: microchip: mpfs: make the rtc's ahb clock critical + +From: Conor Dooley + +[ Upstream commit 05d27090b6dc88bce71a608d1271536e582b73d1 ] + +The onboard RTC's AHB bus clock must be kept running as the RTC will +stop & lose track of time if the AHB interface clock is disabled. + +Fixes: 635e5e73370e ("clk: microchip: Add driver for Microchip PolarFire SoC") +Signed-off-by: Conor Dooley +Signed-off-by: Claudiu Beznea +Link: https://lore.kernel.org/r/20220909123123.2699583-3-conor.dooley@microchip.com +Signed-off-by: Sasha Levin +--- + drivers/clk/microchip/clk-mpfs.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/microchip/clk-mpfs.c b/drivers/clk/microchip/clk-mpfs.c +index f0f9c9a1cc48..b6b89413e090 100644 +--- a/drivers/clk/microchip/clk-mpfs.c ++++ b/drivers/clk/microchip/clk-mpfs.c +@@ -375,6 +375,8 @@ static const struct clk_ops mpfs_periph_clk_ops = { + * trap handler + * - CLK_MMUART0: reserved by the hss + * - CLK_DDRC: provides clock to the ddr subsystem ++ * - CLK_RTC: the onboard RTC's AHB bus clock must be kept running as the rtc will stop ++ * if the AHB interface clock is disabled + * - CLK_FICx: these provide the processor side clocks to the "FIC" (Fabric InterConnect) + * clock domain crossers which provide the interface to the FPGA fabric. Disabling them + * causes the FPGA fabric to go into reset. +@@ -399,7 +401,7 @@ static struct mpfs_periph_hw_clock mpfs_periph_clks[] = { + CLK_PERIPH(CLK_CAN0, "clk_periph_can0", PARENT_CLK(AHB), 14, 0), + CLK_PERIPH(CLK_CAN1, "clk_periph_can1", PARENT_CLK(AHB), 15, 0), + CLK_PERIPH(CLK_USB, "clk_periph_usb", PARENT_CLK(AHB), 16, 0), +- CLK_PERIPH(CLK_RTC, "clk_periph_rtc", PARENT_CLK(AHB), 18, 0), ++ CLK_PERIPH(CLK_RTC, "clk_periph_rtc", PARENT_CLK(AHB), 18, CLK_IS_CRITICAL), + CLK_PERIPH(CLK_QSPI, "clk_periph_qspi", PARENT_CLK(AHB), 19, 0), + CLK_PERIPH(CLK_GPIO0, "clk_periph_gpio0", PARENT_CLK(AHB), 20, 0), + CLK_PERIPH(CLK_GPIO1, "clk_periph_gpio1", PARENT_CLK(AHB), 21, 0), +-- +2.35.1 + diff --git a/queue-5.19/cxgb4-fix-missing-unlock-on-ethofld-desc-collect-fai.patch b/queue-5.19/cxgb4-fix-missing-unlock-on-ethofld-desc-collect-fai.patch new file mode 100644 index 00000000000..22d4a0367db --- /dev/null +++ b/queue-5.19/cxgb4-fix-missing-unlock-on-ethofld-desc-collect-fai.patch @@ -0,0 +1,121 @@ +From 51af011630be456ba629b6ab7381a14bff48c55c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Sep 2022 14:51:08 -0300 +Subject: cxgb4: fix missing unlock on ETHOFLD desc collect fail path + +From: Rafael Mendonca + +[ Upstream commit c635ebe8d911a93bd849a9419b01a58783de76f1 ] + +The label passed to the QDESC_GET for the ETHOFLD TXQ, RXQ, and FLQ, is the +'out' one, which skips the 'out_unlock' label, and thus doesn't unlock the +'uld_mutex' before returning. Additionally, since commit 5148e5950c67 +("cxgb4: add EOTID tracking and software context dump"), the access to +these ETHOFLD hardware queues should be protected by the 'mqprio_mutex' +instead. + +Fixes: 2d0cb84dd973 ("cxgb4: add ETHOFLD hardware queue support") +Fixes: 5148e5950c67 ("cxgb4: add EOTID tracking and software context dump") +Signed-off-by: Rafael Mendonca +Reviewed-by: Rahul Lakkireddy +Link: https://lore.kernel.org/r/20220922175109.764898-1-rafaelmendsr@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/ethernet/chelsio/cxgb4/cudbg_lib.c | 28 +++++++++++++------ + 1 file changed, 19 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c +index a7f291c89702..557c591a6ce3 100644 +--- a/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c ++++ b/drivers/net/ethernet/chelsio/cxgb4/cudbg_lib.c +@@ -14,6 +14,7 @@ + #include "cudbg_entity.h" + #include "cudbg_lib.h" + #include "cudbg_zlib.h" ++#include "cxgb4_tc_mqprio.h" + + static const u32 t6_tp_pio_array[][IREG_NUM_ELEM] = { + {0x7e40, 0x7e44, 0x020, 28}, /* t6_tp_pio_regs_20_to_3b */ +@@ -3458,7 +3459,7 @@ int cudbg_collect_qdesc(struct cudbg_init *pdbg_init, + for (i = 0; i < utxq->ntxq; i++) + QDESC_GET_TXQ(&utxq->uldtxq[i].q, + cudbg_uld_txq_to_qtype(j), +- out_unlock); ++ out_unlock_uld); + } + } + +@@ -3475,7 +3476,7 @@ int cudbg_collect_qdesc(struct cudbg_init *pdbg_init, + for (i = 0; i < urxq->nrxq; i++) + QDESC_GET_RXQ(&urxq->uldrxq[i].rspq, + cudbg_uld_rxq_to_qtype(j), +- out_unlock); ++ out_unlock_uld); + } + + /* ULD FLQ */ +@@ -3487,7 +3488,7 @@ int cudbg_collect_qdesc(struct cudbg_init *pdbg_init, + for (i = 0; i < urxq->nrxq; i++) + QDESC_GET_FLQ(&urxq->uldrxq[i].fl, + cudbg_uld_flq_to_qtype(j), +- out_unlock); ++ out_unlock_uld); + } + + /* ULD CIQ */ +@@ -3500,29 +3501,34 @@ int cudbg_collect_qdesc(struct cudbg_init *pdbg_init, + for (i = 0; i < urxq->nciq; i++) + QDESC_GET_RXQ(&urxq->uldrxq[base + i].rspq, + cudbg_uld_ciq_to_qtype(j), +- out_unlock); ++ out_unlock_uld); + } + } ++ mutex_unlock(&uld_mutex); ++ ++ if (!padap->tc_mqprio) ++ goto out; + ++ mutex_lock(&padap->tc_mqprio->mqprio_mutex); + /* ETHOFLD TXQ */ + if (s->eohw_txq) + for (i = 0; i < s->eoqsets; i++) + QDESC_GET_TXQ(&s->eohw_txq[i].q, +- CUDBG_QTYPE_ETHOFLD_TXQ, out); ++ CUDBG_QTYPE_ETHOFLD_TXQ, out_unlock_mqprio); + + /* ETHOFLD RXQ and FLQ */ + if (s->eohw_rxq) { + for (i = 0; i < s->eoqsets; i++) + QDESC_GET_RXQ(&s->eohw_rxq[i].rspq, +- CUDBG_QTYPE_ETHOFLD_RXQ, out); ++ CUDBG_QTYPE_ETHOFLD_RXQ, out_unlock_mqprio); + + for (i = 0; i < s->eoqsets; i++) + QDESC_GET_FLQ(&s->eohw_rxq[i].fl, +- CUDBG_QTYPE_ETHOFLD_FLQ, out); ++ CUDBG_QTYPE_ETHOFLD_FLQ, out_unlock_mqprio); + } + +-out_unlock: +- mutex_unlock(&uld_mutex); ++out_unlock_mqprio: ++ mutex_unlock(&padap->tc_mqprio->mqprio_mutex); + + out: + qdesc_info->qdesc_entry_size = sizeof(*qdesc_entry); +@@ -3559,6 +3565,10 @@ int cudbg_collect_qdesc(struct cudbg_init *pdbg_init, + #undef QDESC_GET + + return rc; ++ ++out_unlock_uld: ++ mutex_unlock(&uld_mutex); ++ goto out; + } + + int cudbg_collect_flash(struct cudbg_init *pdbg_init, +-- +2.35.1 + diff --git a/queue-5.19/don-t-use-__kernel_write-on-kmap_local_page.patch b/queue-5.19/don-t-use-__kernel_write-on-kmap_local_page.patch new file mode 100644 index 00000000000..43ad2e6c475 --- /dev/null +++ b/queue-5.19/don-t-use-__kernel_write-on-kmap_local_page.patch @@ -0,0 +1,160 @@ +From bbb6fad0e391971325367d5ceb857b80f754c626 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 26 Sep 2022 11:59:14 -0400 +Subject: don't use __kernel_write() on kmap_local_page() + +From: Al Viro + +[ Upstream commit 06bbaa6dc53cb72040db952053432541acb9adc7 ] + +passing kmap_local_page() result to __kernel_write() is unsafe - +random ->write_iter() might (and 9p one does) get unhappy when +passed ITER_KVEC with pointer that came from kmap_local_page(). + +Fix by providing a variant of __kernel_write() that takes an iov_iter +from caller (__kernel_write() becomes a trivial wrapper) and adding +dump_emit_page() that parallels dump_emit(), except that instead of +__kernel_write() it uses __kernel_write_iter() with ITER_BVEC source. + +Fixes: 3159ed57792b "fs/coredump: use kmap_local_page()" +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/coredump.c | 38 +++++++++++++++++++++++++++++++++----- + fs/internal.h | 3 +++ + fs/read_write.c | 22 ++++++++++++++-------- + 3 files changed, 50 insertions(+), 13 deletions(-) + +diff --git a/fs/coredump.c b/fs/coredump.c +index ebc43f960b64..f1355e52614a 100644 +--- a/fs/coredump.c ++++ b/fs/coredump.c +@@ -832,6 +832,38 @@ static int __dump_skip(struct coredump_params *cprm, size_t nr) + } + } + ++static int dump_emit_page(struct coredump_params *cprm, struct page *page) ++{ ++ struct bio_vec bvec = { ++ .bv_page = page, ++ .bv_offset = 0, ++ .bv_len = PAGE_SIZE, ++ }; ++ struct iov_iter iter; ++ struct file *file = cprm->file; ++ loff_t pos = file->f_pos; ++ ssize_t n; ++ ++ if (cprm->to_skip) { ++ if (!__dump_skip(cprm, cprm->to_skip)) ++ return 0; ++ cprm->to_skip = 0; ++ } ++ if (cprm->written + PAGE_SIZE > cprm->limit) ++ return 0; ++ if (dump_interrupted()) ++ return 0; ++ iov_iter_bvec(&iter, WRITE, &bvec, 1, PAGE_SIZE); ++ n = __kernel_write_iter(cprm->file, &iter, &pos); ++ if (n != PAGE_SIZE) ++ return 0; ++ file->f_pos = pos; ++ cprm->written += PAGE_SIZE; ++ cprm->pos += PAGE_SIZE; ++ ++ return 1; ++} ++ + int dump_emit(struct coredump_params *cprm, const void *addr, int nr) + { + if (cprm->to_skip) { +@@ -863,7 +895,6 @@ int dump_user_range(struct coredump_params *cprm, unsigned long start, + + for (addr = start; addr < start + len; addr += PAGE_SIZE) { + struct page *page; +- int stop; + + /* + * To avoid having to allocate page tables for virtual address +@@ -874,10 +905,7 @@ int dump_user_range(struct coredump_params *cprm, unsigned long start, + */ + page = get_dump_page(addr); + if (page) { +- void *kaddr = kmap_local_page(page); +- +- stop = !dump_emit(cprm, kaddr, PAGE_SIZE); +- kunmap_local(kaddr); ++ int stop = !dump_emit_page(cprm, page); + put_page(page); + if (stop) + return 0; +diff --git a/fs/internal.h b/fs/internal.h +index 87e96b9024ce..3e206d3e317c 100644 +--- a/fs/internal.h ++++ b/fs/internal.h +@@ -16,6 +16,7 @@ struct shrink_control; + struct fs_context; + struct user_namespace; + struct pipe_inode_info; ++struct iov_iter; + + /* + * block/bdev.c +@@ -221,3 +222,5 @@ ssize_t do_getxattr(struct user_namespace *mnt_userns, + int setxattr_copy(const char __user *name, struct xattr_ctx *ctx); + int do_setxattr(struct user_namespace *mnt_userns, struct dentry *dentry, + struct xattr_ctx *ctx); ++ ++ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *pos); +diff --git a/fs/read_write.c b/fs/read_write.c +index 397da0236607..a0a3d35e2c0f 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -509,14 +509,9 @@ static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t + } + + /* caller is responsible for file_start_write/file_end_write */ +-ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) ++ssize_t __kernel_write_iter(struct file *file, struct iov_iter *from, loff_t *pos) + { +- struct kvec iov = { +- .iov_base = (void *)buf, +- .iov_len = min_t(size_t, count, MAX_RW_COUNT), +- }; + struct kiocb kiocb; +- struct iov_iter iter; + ssize_t ret; + + if (WARN_ON_ONCE(!(file->f_mode & FMODE_WRITE))) +@@ -532,8 +527,7 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t + + init_sync_kiocb(&kiocb, file); + kiocb.ki_pos = pos ? *pos : 0; +- iov_iter_kvec(&iter, WRITE, &iov, 1, iov.iov_len); +- ret = file->f_op->write_iter(&kiocb, &iter); ++ ret = file->f_op->write_iter(&kiocb, from); + if (ret > 0) { + if (pos) + *pos = kiocb.ki_pos; +@@ -543,6 +537,18 @@ ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t + inc_syscw(current); + return ret; + } ++ ++/* caller is responsible for file_start_write/file_end_write */ ++ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) ++{ ++ struct kvec iov = { ++ .iov_base = (void *)buf, ++ .iov_len = min_t(size_t, count, MAX_RW_COUNT), ++ }; ++ struct iov_iter iter; ++ iov_iter_kvec(&iter, WRITE, &iov, 1, iov.iov_len); ++ return __kernel_write_iter(file, &iter, pos); ++} + /* + * This "EXPORT_SYMBOL_GPL()" is more of a "EXPORT_SYMBOL_DONTUSE()", + * but autofs is one of the few internal kernel users that actually +-- +2.35.1 + diff --git a/queue-5.19/drm-bridge-lt8912b-add-vsync-hsync.patch b/queue-5.19/drm-bridge-lt8912b-add-vsync-hsync.patch new file mode 100644 index 00000000000..4ff34de6050 --- /dev/null +++ b/queue-5.19/drm-bridge-lt8912b-add-vsync-hsync.patch @@ -0,0 +1,66 @@ +From 78816e7f3538520c61b98669c3f78842ae277a72 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Sep 2022 14:43:03 +0200 +Subject: drm/bridge: lt8912b: add vsync hsync + +From: Philippe Schenker + +[ Upstream commit da73a94fa282f78d485bd0aab36c8ac15b6f792c ] + +Currently the bridge driver does not take care whether or not the display +needs positive/negative vertical/horizontal syncs. Pass these two flags +to the bridge from the EDID that was read out from the display. + +Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge") +Signed-off-by: Philippe Schenker +Acked-by: Adrien Grassein +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20220922124306.34729-2-dev@pschenker.ch +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/lontium-lt8912b.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c +index c642d1e02b2f..e011a2763621 100644 +--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c ++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c +@@ -266,7 +266,7 @@ static int lt8912_video_setup(struct lt8912 *lt) + u32 hactive, h_total, hpw, hfp, hbp; + u32 vactive, v_total, vpw, vfp, vbp; + u8 settle = 0x08; +- int ret; ++ int ret, hsync_activehigh, vsync_activehigh; + + if (!lt) + return -EINVAL; +@@ -276,12 +276,14 @@ static int lt8912_video_setup(struct lt8912 *lt) + hpw = lt->mode.hsync_len; + hbp = lt->mode.hback_porch; + h_total = hactive + hfp + hpw + hbp; ++ hsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_HSYNC_HIGH; + + vactive = lt->mode.vactive; + vfp = lt->mode.vfront_porch; + vpw = lt->mode.vsync_len; + vbp = lt->mode.vback_porch; + v_total = vactive + vfp + vpw + vbp; ++ vsync_activehigh = lt->mode.flags & DISPLAY_FLAGS_VSYNC_HIGH; + + if (vactive <= 600) + settle = 0x04; +@@ -315,6 +317,11 @@ static int lt8912_video_setup(struct lt8912 *lt) + ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3e, hfp & 0xff); + ret |= regmap_write(lt->regmap[I2C_CEC_DSI], 0x3f, hfp >> 8); + ++ ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(0), ++ vsync_activehigh ? BIT(0) : 0); ++ ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(1), ++ hsync_activehigh ? BIT(1) : 0); ++ + return ret; + } + +-- +2.35.1 + diff --git a/queue-5.19/drm-bridge-lt8912b-fix-corrupted-image-output.patch b/queue-5.19/drm-bridge-lt8912b-fix-corrupted-image-output.patch new file mode 100644 index 00000000000..dff469468c5 --- /dev/null +++ b/queue-5.19/drm-bridge-lt8912b-fix-corrupted-image-output.patch @@ -0,0 +1,47 @@ +From 3857d44f2cca3c658cda52e087acfd6f1873eec4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Sep 2022 14:43:05 +0200 +Subject: drm/bridge: lt8912b: fix corrupted image output + +From: Francesco Dolcini + +[ Upstream commit 051ad2788d35ca07aec8402542e5d38429f2426a ] + +Correct I2C address for the register list in lt8912_write_lvds_config(), +these registers are on the first I2C address (0x48), the current +function is just writing garbage to the wrong registers and this creates +multiple issues (artifacts and output completely corrupted) on some HDMI +displays. + +Correct I2C address comes from Lontium documentation and it is the one +used on other out-of-tree LT8912B drivers [1]. + +[1] https://github.com/boundarydevices/linux/blob/boundary-imx_5.10.x_2.0.0/drivers/video/lt8912.c#L296 + +Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge") +Signed-off-by: Francesco Dolcini +Signed-off-by: Philippe Schenker +Acked-by: Adrien Grassein +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20220922124306.34729-4-dev@pschenker.ch +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/lontium-lt8912b.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c +index bab3772c8407..167cd7d85dbb 100644 +--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c ++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c +@@ -186,7 +186,7 @@ static int lt8912_write_lvds_config(struct lt8912 *lt) + {0x03, 0xff}, + }; + +- return regmap_multi_reg_write(lt->regmap[I2C_CEC_DSI], seq, ARRAY_SIZE(seq)); ++ return regmap_multi_reg_write(lt->regmap[I2C_MAIN], seq, ARRAY_SIZE(seq)); + }; + + static inline struct lt8912 *bridge_to_lt8912(struct drm_bridge *b) +-- +2.35.1 + diff --git a/queue-5.19/drm-bridge-lt8912b-set-hdmi-or-dvi-mode.patch b/queue-5.19/drm-bridge-lt8912b-set-hdmi-or-dvi-mode.patch new file mode 100644 index 00000000000..cf3e1e612e8 --- /dev/null +++ b/queue-5.19/drm-bridge-lt8912b-set-hdmi-or-dvi-mode.patch @@ -0,0 +1,38 @@ +From 6fd13acc9b389b3311cde40eb0740983dcd64f7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Sep 2022 14:43:04 +0200 +Subject: drm/bridge: lt8912b: set hdmi or dvi mode + +From: Philippe Schenker + +[ Upstream commit 6dd1de12e1243f2013e4fabf31e99e63b1a860d0 ] + +The Lontium LT8912 does have a setting for DVI or HDMI. This patch reads +from EDID what the display needs and sets it accordingly. + +Fixes: 30e2ae943c26 ("drm/bridge: Introduce LT8912B DSI to HDMI bridge") +Signed-off-by: Philippe Schenker +Acked-by: Adrien Grassein +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/20220922124306.34729-3-dev@pschenker.ch +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/lontium-lt8912b.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/bridge/lontium-lt8912b.c b/drivers/gpu/drm/bridge/lontium-lt8912b.c +index e011a2763621..bab3772c8407 100644 +--- a/drivers/gpu/drm/bridge/lontium-lt8912b.c ++++ b/drivers/gpu/drm/bridge/lontium-lt8912b.c +@@ -321,6 +321,8 @@ static int lt8912_video_setup(struct lt8912 *lt) + vsync_activehigh ? BIT(0) : 0); + ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xab, BIT(1), + hsync_activehigh ? BIT(1) : 0); ++ ret |= regmap_update_bits(lt->regmap[I2C_MAIN], 0xb2, BIT(0), ++ lt->connector.display_info.is_hdmi ? BIT(0) : 0); + + return ret; + } +-- +2.35.1 + diff --git a/queue-5.19/drm-i915-gt-perf_limit_reasons-are-only-available-fo.patch b/queue-5.19/drm-i915-gt-perf_limit_reasons-are-only-available-fo.patch new file mode 100644 index 00000000000..2130d459560 --- /dev/null +++ b/queue-5.19/drm-i915-gt-perf_limit_reasons-are-only-available-fo.patch @@ -0,0 +1,74 @@ +From 2482242d5abe4452394e4569a2eb8dbc97b9894a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Sep 2022 12:02:12 -0700 +Subject: drm/i915/gt: Perf_limit_reasons are only available for Gen11+ + +From: Ashutosh Dixit + +[ Upstream commit 7738be973fc4e2ba22154fafd3a5d7b9666f9abf ] + +Register GT0_PERF_LIMIT_REASONS (0x1381a8) is available only for +Gen11+. Therefore ensure perf_limit_reasons sysfs files are created only +for Gen11+. Otherwise on Gen < 5 accessing these files results in the +following oops: + +<1> [88.829420] BUG: unable to handle page fault for address: ffffc90000bb81a8 +<1> [88.829438] #PF: supervisor read access in kernel mode +<1> [88.829447] #PF: error_code(0x0000) - not-present page + +This patch is a backport of the drm-tip commit 0d2d201095e9 +("drm/i915: Perf_limit_reasons are only available for Gen11+") to +drm-intel-fixes. The backport is not identical to the original, it only +includes the sysfs portions of if. The debugfs portion is not available +in drm-intel-fixes so has not been backported. + +Bspec: 20008 +Bug: https://gitlab.freedesktop.org/drm/intel/-/issues/6863 +Fixes: fa68bff7cf27 ("drm/i915/gt: Add sysfs throttle frequency interfaces") +Signed-off-by: Ashutosh Dixit +Reviewed-by: Rodrigo Vivi +Signed-off-by: Rodrigo Vivi +Link: https://patchwork.freedesktop.org/patch/msgid/20220919162401.2077713-1-ashutosh.dixit@intel.com +(backported from commit 0d2d201095e9f141d6a9fb44320afce761f8b5c2) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c +index f76b6cf8040e..b8cb58e2819a 100644 +--- a/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c ++++ b/drivers/gpu/drm/i915/gt/intel_gt_sysfs_pm.c +@@ -544,8 +544,7 @@ static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_ratl, RATL_MASK); + static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_vr_thermalert, VR_THERMALERT_MASK); + static INTEL_GT_RPS_BOOL_ATTR_RO(throttle_reason_vr_tdc, VR_TDC_MASK); + +-static const struct attribute *freq_attrs[] = { +- &dev_attr_punit_req_freq_mhz.attr, ++static const struct attribute *throttle_reason_attrs[] = { + &attr_throttle_reason_status.attr, + &attr_throttle_reason_pl1.attr, + &attr_throttle_reason_pl2.attr, +@@ -594,9 +593,17 @@ void intel_gt_sysfs_pm_init(struct intel_gt *gt, struct kobject *kobj) + if (!is_object_gt(kobj)) + return; + +- ret = sysfs_create_files(kobj, freq_attrs); ++ ret = sysfs_create_file(kobj, &dev_attr_punit_req_freq_mhz.attr); + if (ret) + drm_warn(>->i915->drm, +- "failed to create gt%u throttle sysfs files (%pe)", ++ "failed to create gt%u punit_req_freq_mhz sysfs (%pe)", + gt->info.id, ERR_PTR(ret)); ++ ++ if (GRAPHICS_VER(gt->i915) >= 11) { ++ ret = sysfs_create_files(kobj, throttle_reason_attrs); ++ if (ret) ++ drm_warn(>->i915->drm, ++ "failed to create gt%u throttle sysfs files (%pe)", ++ gt->info.id, ERR_PTR(ret)); ++ } + } +-- +2.35.1 + diff --git a/queue-5.19/gpio-mvebu-fix-check-for-pwm-support-on-non-a8k-plat.patch b/queue-5.19/gpio-mvebu-fix-check-for-pwm-support-on-non-a8k-plat.patch new file mode 100644 index 00000000000..c5321abeb38 --- /dev/null +++ b/queue-5.19/gpio-mvebu-fix-check-for-pwm-support-on-non-a8k-plat.patch @@ -0,0 +1,60 @@ +From 94385f9f0eca46a41b9879a77bb8e2f11e9581b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Jul 2022 20:33:25 +0200 +Subject: gpio: mvebu: Fix check for pwm support on non-A8K platforms +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Pali Rohár + +[ Upstream commit 4335417da2b8d6d9b2d4411b5f9e248e5bb2d380 ] + +pwm support incompatible with Armada 80x0/70x0 API is not only in +Armada 370, but also in Armada XP, 38x and 39x. So basically every non-A8K +platform. Fix check for pwm support appropriately. + +Fixes: 85b7d8abfec7 ("gpio: mvebu: add pwm support for Armada 8K/7K") +Signed-off-by: Pali Rohár +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-mvebu.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c +index 2db19cd640a4..de1e7a1a76f2 100644 +--- a/drivers/gpio/gpio-mvebu.c ++++ b/drivers/gpio/gpio-mvebu.c +@@ -793,8 +793,12 @@ static int mvebu_pwm_probe(struct platform_device *pdev, + u32 offset; + u32 set; + +- if (of_device_is_compatible(mvchip->chip.of_node, +- "marvell,armada-370-gpio")) { ++ if (mvchip->soc_variant == MVEBU_GPIO_SOC_VARIANT_A8K) { ++ int ret = of_property_read_u32(dev->of_node, ++ "marvell,pwm-offset", &offset); ++ if (ret < 0) ++ return 0; ++ } else { + /* + * There are only two sets of PWM configuration registers for + * all the GPIO lines on those SoCs which this driver reserves +@@ -804,13 +808,6 @@ static int mvebu_pwm_probe(struct platform_device *pdev, + if (!platform_get_resource_byname(pdev, IORESOURCE_MEM, "pwm")) + return 0; + offset = 0; +- } else if (mvchip->soc_variant == MVEBU_GPIO_SOC_VARIANT_A8K) { +- int ret = of_property_read_u32(dev->of_node, +- "marvell,pwm-offset", &offset); +- if (ret < 0) +- return 0; +- } else { +- return 0; + } + + if (IS_ERR(mvchip->clk)) +-- +2.35.1 + diff --git a/queue-5.19/ice-xsk-change-batched-tx-descriptor-cleaning.patch b/queue-5.19/ice-xsk-change-batched-tx-descriptor-cleaning.patch new file mode 100644 index 00000000000..636ad63048f --- /dev/null +++ b/queue-5.19/ice-xsk-change-batched-tx-descriptor-cleaning.patch @@ -0,0 +1,304 @@ +From 296a51992871862e86b93ffee214c0275fc3e833 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Sep 2022 12:40:39 +0200 +Subject: ice: xsk: change batched Tx descriptor cleaning + +From: Maciej Fijalkowski + +[ Upstream commit 29322791bc8b4f42fc65734840826e3ddc30921e ] + +AF_XDP Tx descriptor cleaning in ice driver currently works in a "lazy" +way - descriptors are not cleaned immediately after send. We rather hold +on with cleaning until we see that free space in ring drops below +particular threshold. This was supposed to reduce the amount of +unnecessary work related to cleaning and instead of keeping the ring +empty, ring was rather saturated. + +In AF_XDP realm cleaning Tx descriptors implies producing them to CQ. +This is a way of letting know user space that particular descriptor has +been sent, as John points out in [0]. + +We tried to implement serial descriptor cleaning which would be used in +conjunction with batched cleaning but it made code base more convoluted +and probably harder to maintain in future. Therefore we step away from +batched cleaning in a current form in favor of an approach where we set +RS bit on every last descriptor from a batch and clean always at the +beginning of ice_xmit_zc(). + +This means that we give up a bit of Tx performance, but this doesn't +hurt l2fwd scenario which is way more meaningful than txonly as this can +be treaten as AF_XDP based packet generator. l2fwd is not hurt due to +the fact that Tx side is much faster than Rx and Rx is the one that has +to catch Tx up. + +FWIW Tx descriptors are still produced in a batched way. + +[0]: https://lore.kernel.org/bpf/62b0a20232920_3573208ab@john.notmuch/ + +Fixes: 126cdfe1007a ("ice: xsk: Improve AF_XDP ZC Tx and use batching API") +Signed-off-by: Maciej Fijalkowski +Tested-by: George Kuruvinakunnel +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_txrx.c | 2 +- + drivers/net/ethernet/intel/ice/ice_xsk.c | 143 +++++++++------------- + drivers/net/ethernet/intel/ice/ice_xsk.h | 7 +- + 3 files changed, 64 insertions(+), 88 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c +index 97453d1dfafe..dd2285d4bef4 100644 +--- a/drivers/net/ethernet/intel/ice/ice_txrx.c ++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c +@@ -1467,7 +1467,7 @@ int ice_napi_poll(struct napi_struct *napi, int budget) + bool wd; + + if (tx_ring->xsk_pool) +- wd = ice_xmit_zc(tx_ring, ICE_DESC_UNUSED(tx_ring), budget); ++ wd = ice_xmit_zc(tx_ring); + else if (ice_ring_is_xdp(tx_ring)) + wd = true; + else +diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c +index 03ce85f6e6df..8833b66b4e54 100644 +--- a/drivers/net/ethernet/intel/ice/ice_xsk.c ++++ b/drivers/net/ethernet/intel/ice/ice_xsk.c +@@ -788,69 +788,57 @@ ice_clean_xdp_tx_buf(struct ice_tx_ring *xdp_ring, struct ice_tx_buf *tx_buf) + } + + /** +- * ice_clean_xdp_irq_zc - Reclaim resources after transmit completes on XDP ring +- * @xdp_ring: XDP ring to clean +- * @napi_budget: amount of descriptors that NAPI allows us to clean +- * +- * Returns count of cleaned descriptors ++ * ice_clean_xdp_irq_zc - produce AF_XDP descriptors to CQ ++ * @xdp_ring: XDP Tx ring + */ +-static u16 ice_clean_xdp_irq_zc(struct ice_tx_ring *xdp_ring, int napi_budget) ++static void ice_clean_xdp_irq_zc(struct ice_tx_ring *xdp_ring) + { +- u16 tx_thresh = ICE_RING_QUARTER(xdp_ring); +- int budget = napi_budget / tx_thresh; +- u16 next_dd = xdp_ring->next_dd; +- u16 ntc, cleared_dds = 0; +- +- do { +- struct ice_tx_desc *next_dd_desc; +- u16 desc_cnt = xdp_ring->count; +- struct ice_tx_buf *tx_buf; +- u32 xsk_frames; +- u16 i; +- +- next_dd_desc = ICE_TX_DESC(xdp_ring, next_dd); +- if (!(next_dd_desc->cmd_type_offset_bsz & +- cpu_to_le64(ICE_TX_DESC_DTYPE_DESC_DONE))) +- break; ++ u16 ntc = xdp_ring->next_to_clean; ++ struct ice_tx_desc *tx_desc; ++ u16 cnt = xdp_ring->count; ++ struct ice_tx_buf *tx_buf; ++ u16 xsk_frames = 0; ++ u16 last_rs; ++ int i; + +- cleared_dds++; +- xsk_frames = 0; +- if (likely(!xdp_ring->xdp_tx_active)) { +- xsk_frames = tx_thresh; +- goto skip; +- } ++ last_rs = xdp_ring->next_to_use ? xdp_ring->next_to_use - 1 : cnt - 1; ++ tx_desc = ICE_TX_DESC(xdp_ring, last_rs); ++ if ((tx_desc->cmd_type_offset_bsz & ++ cpu_to_le64(ICE_TX_DESC_DTYPE_DESC_DONE))) { ++ if (last_rs >= ntc) ++ xsk_frames = last_rs - ntc + 1; ++ else ++ xsk_frames = last_rs + cnt - ntc + 1; ++ } + +- ntc = xdp_ring->next_to_clean; ++ if (!xsk_frames) ++ return; + +- for (i = 0; i < tx_thresh; i++) { +- tx_buf = &xdp_ring->tx_buf[ntc]; ++ if (likely(!xdp_ring->xdp_tx_active)) ++ goto skip; + +- if (tx_buf->raw_buf) { +- ice_clean_xdp_tx_buf(xdp_ring, tx_buf); +- tx_buf->raw_buf = NULL; +- } else { +- xsk_frames++; +- } ++ ntc = xdp_ring->next_to_clean; ++ for (i = 0; i < xsk_frames; i++) { ++ tx_buf = &xdp_ring->tx_buf[ntc]; + +- ntc++; +- if (ntc >= xdp_ring->count) +- ntc = 0; ++ if (tx_buf->raw_buf) { ++ ice_clean_xdp_tx_buf(xdp_ring, tx_buf); ++ tx_buf->raw_buf = NULL; ++ } else { ++ xsk_frames++; + } ++ ++ ntc++; ++ if (ntc >= xdp_ring->count) ++ ntc = 0; ++ } + skip: +- xdp_ring->next_to_clean += tx_thresh; +- if (xdp_ring->next_to_clean >= desc_cnt) +- xdp_ring->next_to_clean -= desc_cnt; +- if (xsk_frames) +- xsk_tx_completed(xdp_ring->xsk_pool, xsk_frames); +- next_dd_desc->cmd_type_offset_bsz = 0; +- next_dd = next_dd + tx_thresh; +- if (next_dd >= desc_cnt) +- next_dd = tx_thresh - 1; +- } while (--budget); +- +- xdp_ring->next_dd = next_dd; +- +- return cleared_dds * tx_thresh; ++ tx_desc->cmd_type_offset_bsz = 0; ++ xdp_ring->next_to_clean += xsk_frames; ++ if (xdp_ring->next_to_clean >= cnt) ++ xdp_ring->next_to_clean -= cnt; ++ if (xsk_frames) ++ xsk_tx_completed(xdp_ring->xsk_pool, xsk_frames); + } + + /** +@@ -885,7 +873,6 @@ static void ice_xmit_pkt(struct ice_tx_ring *xdp_ring, struct xdp_desc *desc, + static void ice_xmit_pkt_batch(struct ice_tx_ring *xdp_ring, struct xdp_desc *descs, + unsigned int *total_bytes) + { +- u16 tx_thresh = ICE_RING_QUARTER(xdp_ring); + u16 ntu = xdp_ring->next_to_use; + struct ice_tx_desc *tx_desc; + u32 i; +@@ -905,13 +892,6 @@ static void ice_xmit_pkt_batch(struct ice_tx_ring *xdp_ring, struct xdp_desc *de + } + + xdp_ring->next_to_use = ntu; +- +- if (xdp_ring->next_to_use > xdp_ring->next_rs) { +- tx_desc = ICE_TX_DESC(xdp_ring, xdp_ring->next_rs); +- tx_desc->cmd_type_offset_bsz |= +- cpu_to_le64(ICE_TX_DESC_CMD_RS << ICE_TXD_QW1_CMD_S); +- xdp_ring->next_rs += tx_thresh; +- } + } + + /** +@@ -924,7 +904,6 @@ static void ice_xmit_pkt_batch(struct ice_tx_ring *xdp_ring, struct xdp_desc *de + static void ice_fill_tx_hw_ring(struct ice_tx_ring *xdp_ring, struct xdp_desc *descs, + u32 nb_pkts, unsigned int *total_bytes) + { +- u16 tx_thresh = ICE_RING_QUARTER(xdp_ring); + u32 batched, leftover, i; + + batched = ALIGN_DOWN(nb_pkts, PKTS_PER_BATCH); +@@ -933,54 +912,54 @@ static void ice_fill_tx_hw_ring(struct ice_tx_ring *xdp_ring, struct xdp_desc *d + ice_xmit_pkt_batch(xdp_ring, &descs[i], total_bytes); + for (; i < batched + leftover; i++) + ice_xmit_pkt(xdp_ring, &descs[i], total_bytes); ++} + +- if (xdp_ring->next_to_use > xdp_ring->next_rs) { +- struct ice_tx_desc *tx_desc; ++/** ++ * ice_set_rs_bit - set RS bit on last produced descriptor (one behind current NTU) ++ * @xdp_ring: XDP ring to produce the HW Tx descriptors on ++ */ ++static void ice_set_rs_bit(struct ice_tx_ring *xdp_ring) ++{ ++ u16 ntu = xdp_ring->next_to_use ? xdp_ring->next_to_use - 1 : xdp_ring->count - 1; ++ struct ice_tx_desc *tx_desc; + +- tx_desc = ICE_TX_DESC(xdp_ring, xdp_ring->next_rs); +- tx_desc->cmd_type_offset_bsz |= +- cpu_to_le64(ICE_TX_DESC_CMD_RS << ICE_TXD_QW1_CMD_S); +- xdp_ring->next_rs += tx_thresh; +- } ++ tx_desc = ICE_TX_DESC(xdp_ring, ntu); ++ tx_desc->cmd_type_offset_bsz |= ++ cpu_to_le64(ICE_TX_DESC_CMD_RS << ICE_TXD_QW1_CMD_S); + } + + /** + * ice_xmit_zc - take entries from XSK Tx ring and place them onto HW Tx ring + * @xdp_ring: XDP ring to produce the HW Tx descriptors on +- * @budget: number of free descriptors on HW Tx ring that can be used +- * @napi_budget: amount of descriptors that NAPI allows us to clean + * + * Returns true if there is no more work that needs to be done, false otherwise + */ +-bool ice_xmit_zc(struct ice_tx_ring *xdp_ring, u32 budget, int napi_budget) ++bool ice_xmit_zc(struct ice_tx_ring *xdp_ring) + { + struct xdp_desc *descs = xdp_ring->xsk_pool->tx_descs; +- u16 tx_thresh = ICE_RING_QUARTER(xdp_ring); + u32 nb_pkts, nb_processed = 0; + unsigned int total_bytes = 0; ++ int budget; ++ ++ ice_clean_xdp_irq_zc(xdp_ring); + +- if (budget < tx_thresh) +- budget += ice_clean_xdp_irq_zc(xdp_ring, napi_budget); ++ budget = ICE_DESC_UNUSED(xdp_ring); ++ budget = min_t(u16, budget, ICE_RING_QUARTER(xdp_ring)); + + nb_pkts = xsk_tx_peek_release_desc_batch(xdp_ring->xsk_pool, budget); + if (!nb_pkts) + return true; + + if (xdp_ring->next_to_use + nb_pkts >= xdp_ring->count) { +- struct ice_tx_desc *tx_desc; +- + nb_processed = xdp_ring->count - xdp_ring->next_to_use; + ice_fill_tx_hw_ring(xdp_ring, descs, nb_processed, &total_bytes); +- tx_desc = ICE_TX_DESC(xdp_ring, xdp_ring->next_rs); +- tx_desc->cmd_type_offset_bsz |= +- cpu_to_le64(ICE_TX_DESC_CMD_RS << ICE_TXD_QW1_CMD_S); +- xdp_ring->next_rs = tx_thresh - 1; + xdp_ring->next_to_use = 0; + } + + ice_fill_tx_hw_ring(xdp_ring, &descs[nb_processed], nb_pkts - nb_processed, + &total_bytes); + ++ ice_set_rs_bit(xdp_ring); + ice_xdp_ring_update_tail(xdp_ring); + ice_update_tx_ring_stats(xdp_ring, nb_pkts, total_bytes); + +diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.h b/drivers/net/ethernet/intel/ice/ice_xsk.h +index 4edbe81eb646..6fa181f080ef 100644 +--- a/drivers/net/ethernet/intel/ice/ice_xsk.h ++++ b/drivers/net/ethernet/intel/ice/ice_xsk.h +@@ -26,13 +26,10 @@ bool ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring, u16 count); + bool ice_xsk_any_rx_ring_ena(struct ice_vsi *vsi); + void ice_xsk_clean_rx_ring(struct ice_rx_ring *rx_ring); + void ice_xsk_clean_xdp_ring(struct ice_tx_ring *xdp_ring); +-bool ice_xmit_zc(struct ice_tx_ring *xdp_ring, u32 budget, int napi_budget); ++bool ice_xmit_zc(struct ice_tx_ring *xdp_ring); + int ice_realloc_zc_buf(struct ice_vsi *vsi, bool zc); + #else +-static inline bool +-ice_xmit_zc(struct ice_tx_ring __always_unused *xdp_ring, +- u32 __always_unused budget, +- int __always_unused napi_budget) ++static inline bool ice_xmit_zc(struct ice_tx_ring __always_unused *xdp_ring) + { + return false; + } +-- +2.35.1 + diff --git a/queue-5.19/ice-xsk-drop-power-of-2-ring-size-restriction-for-af.patch b/queue-5.19/ice-xsk-drop-power-of-2-ring-size-restriction-for-af.patch new file mode 100644 index 00000000000..842fe2d8c51 --- /dev/null +++ b/queue-5.19/ice-xsk-drop-power-of-2-ring-size-restriction-for-af.patch @@ -0,0 +1,79 @@ +From b1287dd68c7951b4880ded64862e1716fbf90df1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Sep 2022 12:40:40 +0200 +Subject: ice: xsk: drop power of 2 ring size restriction for AF_XDP + +From: Maciej Fijalkowski + +[ Upstream commit b3056ae2b57858b02b376b3fed6077040caf14b4 ] + +We had multiple customers in the past months that reported commit +296f13ff3854 ("ice: xsk: Force rings to be sized to power of 2") +makes them unable to use ring size of 8160 in conjunction with AF_XDP. +Remove this restriction. + +Fixes: 296f13ff3854 ("ice: xsk: Force rings to be sized to power of 2") +CC: Alasdair McWilliam +Signed-off-by: Maciej Fijalkowski +Tested-by: George Kuruvinakunnel +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_xsk.c | 20 +++++++------------- + 1 file changed, 7 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c +index 8833b66b4e54..056c904b83cc 100644 +--- a/drivers/net/ethernet/intel/ice/ice_xsk.c ++++ b/drivers/net/ethernet/intel/ice/ice_xsk.c +@@ -392,13 +392,6 @@ int ice_xsk_pool_setup(struct ice_vsi *vsi, struct xsk_buff_pool *pool, u16 qid) + goto failure; + } + +- if (!is_power_of_2(vsi->rx_rings[qid]->count) || +- !is_power_of_2(vsi->tx_rings[qid]->count)) { +- netdev_err(vsi->netdev, "Please align ring sizes to power of 2\n"); +- pool_failure = -EINVAL; +- goto failure; +- } +- + if_running = netif_running(vsi->netdev) && ice_is_xdp_ena_vsi(vsi); + + if (if_running) { +@@ -534,11 +527,10 @@ static bool __ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring, u16 count) + bool ice_alloc_rx_bufs_zc(struct ice_rx_ring *rx_ring, u16 count) + { + u16 rx_thresh = ICE_RING_QUARTER(rx_ring); +- u16 batched, leftover, i, tail_bumps; ++ u16 leftover, i, tail_bumps; + +- batched = ALIGN_DOWN(count, rx_thresh); +- tail_bumps = batched / rx_thresh; +- leftover = count & (rx_thresh - 1); ++ tail_bumps = count / rx_thresh; ++ leftover = count - (tail_bumps * rx_thresh); + + for (i = 0; i < tail_bumps; i++) + if (!__ice_alloc_rx_bufs_zc(rx_ring, rx_thresh)) +@@ -1037,14 +1029,16 @@ bool ice_xsk_any_rx_ring_ena(struct ice_vsi *vsi) + */ + void ice_xsk_clean_rx_ring(struct ice_rx_ring *rx_ring) + { +- u16 count_mask = rx_ring->count - 1; + u16 ntc = rx_ring->next_to_clean; + u16 ntu = rx_ring->next_to_use; + +- for ( ; ntc != ntu; ntc = (ntc + 1) & count_mask) { ++ while (ntc != ntu) { + struct xdp_buff *xdp = *ice_xdp_buf(rx_ring, ntc); + + xsk_buff_free(xdp); ++ ntc++; ++ if (ntc >= rx_ring->count) ++ ntc = 0; + } + } + +-- +2.35.1 + diff --git a/queue-5.19/input-melfas_mip4-fix-return-value-check-in-mip4_pro.patch b/queue-5.19/input-melfas_mip4-fix-return-value-check-in-mip4_pro.patch new file mode 100644 index 00000000000..f788ebb7a4c --- /dev/null +++ b/queue-5.19/input-melfas_mip4-fix-return-value-check-in-mip4_pro.patch @@ -0,0 +1,37 @@ +From 66092630107c983b98459f718d755a9e62b1bf68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 24 Sep 2022 11:07:15 +0800 +Subject: Input: melfas_mip4 - fix return value check in mip4_probe() + +From: Yang Yingliang + +[ Upstream commit a54dc27bd25f20ee3ea2009584b3166d25178243 ] + +devm_gpiod_get_optional() may return ERR_PTR(-EPROBE_DEFER), +add a minus sign to fix it. + +Fixes: 6ccb1d8f78bd ("Input: add MELFAS MIP4 Touchscreen driver") +Signed-off-by: Yang Yingliang +Link: https://lore.kernel.org/r/20220924030715.1653538-1-yangyingliang@huawei.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Sasha Levin +--- + drivers/input/touchscreen/melfas_mip4.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c +index 2745bf1aee38..83f4be05e27b 100644 +--- a/drivers/input/touchscreen/melfas_mip4.c ++++ b/drivers/input/touchscreen/melfas_mip4.c +@@ -1453,7 +1453,7 @@ static int mip4_probe(struct i2c_client *client, const struct i2c_device_id *id) + "ce", GPIOD_OUT_LOW); + if (IS_ERR(ts->gpio_ce)) { + error = PTR_ERR(ts->gpio_ce); +- if (error != EPROBE_DEFER) ++ if (error != -EPROBE_DEFER) + dev_err(&client->dev, + "Failed to get gpio: %d\n", error); + return error; +-- +2.35.1 + diff --git a/queue-5.19/kvm-x86-hide-ia32_platform_dca_cap-31-0-from-the-gue.patch b/queue-5.19/kvm-x86-hide-ia32_platform_dca_cap-31-0-from-the-gue.patch new file mode 100644 index 00000000000..fe99f33bf7f --- /dev/null +++ b/queue-5.19/kvm-x86-hide-ia32_platform_dca_cap-31-0-from-the-gue.patch @@ -0,0 +1,40 @@ +From 827f850631dc39a7aea68c52fe0d64123ac81167 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Sep 2022 16:18:54 -0700 +Subject: KVM: x86: Hide IA32_PLATFORM_DCA_CAP[31:0] from the guest + +From: Jim Mattson + +[ Upstream commit aae2e72229cdb21f90df2dbe4244c977e5d3265b ] + +The only thing reported by CPUID.9 is the value of +IA32_PLATFORM_DCA_CAP[31:0] in EAX. This MSR doesn't even exist in the +guest, since CPUID.1:ECX.DCA[bit 18] is clear in the guest. + +Clear CPUID.9 in KVM_GET_SUPPORTED_CPUID. + +Fixes: 24c82e576b78 ("KVM: Sanitize cpuid") +Signed-off-by: Jim Mattson +Message-Id: <20220922231854.249383-1-jmattson@google.com> +Signed-off-by: Paolo Bonzini +Signed-off-by: Sasha Levin +--- + arch/x86/kvm/cpuid.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c +index 3ab498165639..cb14441cee37 100644 +--- a/arch/x86/kvm/cpuid.c ++++ b/arch/x86/kvm/cpuid.c +@@ -870,8 +870,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function) + entry->edx = 0; + } + break; +- case 9: +- break; + case 0xa: { /* Architectural Performance Monitoring */ + struct x86_pmu_capability cap; + union cpuid10_eax eax; +-- +2.35.1 + diff --git a/queue-5.19/net-ethernet-mtk_eth_soc-fix-mask-of-rx_dma_get_spor.patch b/queue-5.19/net-ethernet-mtk_eth_soc-fix-mask-of-rx_dma_get_spor.patch new file mode 100644 index 00000000000..45537818001 --- /dev/null +++ b/queue-5.19/net-ethernet-mtk_eth_soc-fix-mask-of-rx_dma_get_spor.patch @@ -0,0 +1,41 @@ +From cef396fb50fde98ec11f41b8b068d5dad362feed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 16:30:02 +0100 +Subject: net: ethernet: mtk_eth_soc: fix mask of RX_DMA_GET_SPORT{,_V2} + +From: Daniel Golle + +[ Upstream commit c9da02bfb1112461e048d3b736afb1873f6f4ccf ] + +The bitmasks applied in RX_DMA_GET_SPORT and RX_DMA_GET_SPORT_V2 macros +were swapped. Fix that. + +Reported-by: Chen Minqiang +Fixes: 160d3a9b192985 ("net: ethernet: mtk_eth_soc: introduce MTK_NETSYS_V2 support") +Acked-by: Lorenzo Bianconi +Signed-off-by: Daniel Golle +Link: https://lore.kernel.org/r/YzMW+mg9UsaCdKRQ@makrotopia.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +index 98d6a6d047e3..c1fe1a2cb746 100644 +--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h ++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h +@@ -312,8 +312,8 @@ + #define MTK_RXD5_PPE_CPU_REASON GENMASK(22, 18) + #define MTK_RXD5_SRC_PORT GENMASK(29, 26) + +-#define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0xf) +-#define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0x7) ++#define RX_DMA_GET_SPORT(x) (((x) >> 19) & 0x7) ++#define RX_DMA_GET_SPORT_V2(x) (((x) >> 26) & 0xf) + + /* PDMA V2 descriptor rxd3 */ + #define RX_DMA_VTAG_V2 BIT(0) +-- +2.35.1 + diff --git a/queue-5.19/net-macb-fix-zynqmp-sgmii-non-wakeup-source-resume-f.patch b/queue-5.19/net-macb-fix-zynqmp-sgmii-non-wakeup-source-resume-f.patch new file mode 100644 index 00000000000..ce2a5d084bc --- /dev/null +++ b/queue-5.19/net-macb-fix-zynqmp-sgmii-non-wakeup-source-resume-f.patch @@ -0,0 +1,62 @@ +From f628388172818793eab881b054ca7751d9fc68ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Sep 2022 19:06:10 +0530 +Subject: net: macb: Fix ZynqMP SGMII non-wakeup source resume failure + +From: Radhey Shyam Pandey + +[ Upstream commit f22bd29ba19a43e758b192429613e04aa7abb70d ] + +When GEM is in SGMII mode and disabled as a wakeup source, the power +management controller can power down the entire full power domain(FPD) +if none of the FPD devices are in use. + +Incase of FPD off, there are below ethernet link up issues on non-wakeup +suspend/resume. To fix it add phy_exit() in suspend and phy_init() in the +resume path which reinitializes PS GTR SGMII lanes. + +$ echo +20 > /sys/class/rtc/rtc0/wakealarm +$ echo mem > /sys/power/state + +After resume: + +$ ifconfig eth0 up +xilinx-psgtr fd400000.phy: lane 0 (type 10, protocol 5): PLL lock timeout +phy phy-fd400000.phy.0: phy poweron failed --> -110 +xilinx-psgtr fd400000.phy: lane 0 (type 10, protocol 5): PLL lock timeout +SIOCSIFFLAGS: Connection timed out +phy phy-fd400000.phy.0: phy poweron failed --> -110 + +Fixes: 8b73fa3ae02b ("net: macb: Added ZynqMP-specific initialization") +Signed-off-by: Radhey Shyam Pandey +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/cadence/macb_main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index d89098f4ede8..e9aa41949a4b 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -5092,6 +5092,7 @@ static int __maybe_unused macb_suspend(struct device *dev) + if (!(bp->wol & MACB_WOL_ENABLED)) { + rtnl_lock(); + phylink_stop(bp->phylink); ++ phy_exit(bp->sgmii_phy); + rtnl_unlock(); + spin_lock_irqsave(&bp->lock, flags); + macb_reset_hw(bp); +@@ -5181,6 +5182,9 @@ static int __maybe_unused macb_resume(struct device *dev) + macb_set_rx_mode(netdev); + macb_restore_features(bp); + rtnl_lock(); ++ if (!device_may_wakeup(&bp->dev->dev)) ++ phy_init(bp->sgmii_phy); ++ + phylink_start(bp->phylink); + rtnl_unlock(); + +-- +2.35.1 + diff --git a/queue-5.19/net-mlxbf_gige-fix-an-is_err-vs-null-bug-in-mlxbf_gi.patch b/queue-5.19/net-mlxbf_gige-fix-an-is_err-vs-null-bug-in-mlxbf_gi.patch new file mode 100644 index 00000000000..ff2d82d0d20 --- /dev/null +++ b/queue-5.19/net-mlxbf_gige-fix-an-is_err-vs-null-bug-in-mlxbf_gi.patch @@ -0,0 +1,39 @@ +From 13d1197739e4f9f29cb03e3ba1024aa7ddc2aff5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Sep 2022 02:36:40 +0000 +Subject: net/mlxbf_gige: Fix an IS_ERR() vs NULL bug in mlxbf_gige_mdio_probe + +From: Peng Wu + +[ Upstream commit 4774db8dfc6a2e6649920ebb2fc8e2f062c2080d ] + +The devm_ioremap() function returns NULL on error, it doesn't return +error pointers. + +Fixes: 3a1a274e933f ("mlxbf_gige: compute MDIO period based on i1clk") +Signed-off-by: Peng Wu +Link: https://lore.kernel.org/r/20220923023640.116057-1-wupeng58@huawei.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c +index 4aeb927c3715..aa780b1614a3 100644 +--- a/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c ++++ b/drivers/net/ethernet/mellanox/mlxbf_gige/mlxbf_gige_mdio.c +@@ -246,8 +246,8 @@ int mlxbf_gige_mdio_probe(struct platform_device *pdev, struct mlxbf_gige *priv) + } + + priv->clk_io = devm_ioremap(dev, res->start, resource_size(res)); +- if (IS_ERR(priv->clk_io)) +- return PTR_ERR(priv->clk_io); ++ if (!priv->clk_io) ++ return -ENOMEM; + + mlxbf_gige_mdio_cfg(priv); + +-- +2.35.1 + diff --git a/queue-5.19/net-mscc-ocelot-fix-tagged-vlan-refusal-while-under-.patch b/queue-5.19/net-mscc-ocelot-fix-tagged-vlan-refusal-while-under-.patch new file mode 100644 index 00000000000..8e77d4bb8b7 --- /dev/null +++ b/queue-5.19/net-mscc-ocelot-fix-tagged-vlan-refusal-while-under-.patch @@ -0,0 +1,83 @@ +From 0ddff6a150f6ade4dcf05ed74ed14056ec9db3dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 15:20:42 +0300 +Subject: net: mscc: ocelot: fix tagged VLAN refusal while under a VLAN-unaware + bridge + +From: Vladimir Oltean + +[ Upstream commit 276d37eb449133bc22872b8f0a6f878e120deeff ] + +Currently the following set of commands fails: + +$ ip link add br0 type bridge # vlan_filtering 0 +$ ip link set swp0 master br0 +$ bridge vlan +port vlan-id +swp0 1 PVID Egress Untagged +$ bridge vlan add dev swp0 vid 10 +Error: mscc_ocelot_switch_lib: Port with more than one egress-untagged VLAN cannot have egress-tagged VLANs. + +Dumping ocelot->vlans, one can see that the 2 egress-untagged VLANs on swp0 are +vid 1 (the bridge PVID) and vid 4094, a PVID used privately by the driver for +VLAN-unaware bridging. So this is why bridge vid 10 is refused, despite +'bridge vlan' showing a single egress untagged VLAN. + +As mentioned in the comment added, having this private VLAN does not impose +restrictions to the hardware configuration, yet it is a bookkeeping problem. + +There are 2 possible solutions. + +One is to make the functions that operate on VLAN-unaware pvids: +- ocelot_add_vlan_unaware_pvid() +- ocelot_del_vlan_unaware_pvid() +- ocelot_port_setup_dsa_8021q_cpu() +- ocelot_port_teardown_dsa_8021q_cpu() +call something different than ocelot_vlan_member_(add|del)(), the latter being +the real problem, because it allocates a struct ocelot_bridge_vlan *vlan which +it adds to ocelot->vlans. We don't really *need* the private VLANs in +ocelot->vlans, it's just that we have the extra convenience of having the +vlan->portmask cached in software (whereas without these structures, we'd have +to create a raw ocelot_vlant_rmw_mask() procedure which reads back the current +port mask from hardware). + +The other solution is to filter out the private VLANs from +ocelot_port_num_untagged_vlans(), since they aren't what callers care about. +We only need to do this to the mentioned function and not to +ocelot_port_num_tagged_vlans(), because private VLANs are never egress-tagged. + +Nothing else seems to be broken in either solution, but the first one requires +more rework which will conflict with the net-next change 36a0bf443585 ("net: +mscc: ocelot: set up tag_8021q CPU ports independent of user port affinity"), +and I'd like to avoid that. So go with the other one. + +Fixes: 54c319846086 ("net: mscc: ocelot: enforce FDB isolation when VLAN-unaware") +Signed-off-by: Vladimir Oltean +Link: https://lore.kernel.org/r/20220927122042.1100231-1-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mscc/ocelot.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c +index 68991b021c56..c250ad6dc956 100644 +--- a/drivers/net/ethernet/mscc/ocelot.c ++++ b/drivers/net/ethernet/mscc/ocelot.c +@@ -290,6 +290,13 @@ static int ocelot_port_num_untagged_vlans(struct ocelot *ocelot, int port) + if (!(vlan->portmask & BIT(port))) + continue; + ++ /* Ignore the VLAN added by ocelot_add_vlan_unaware_pvid(), ++ * because this is never active in hardware at the same time as ++ * the bridge VLANs, which only matter in VLAN-aware mode. ++ */ ++ if (vlan->vid >= OCELOT_RSV_VLAN_RANGE_START) ++ continue; ++ + if (vlan->untagged & BIT(port)) + num_untagged++; + } +-- +2.35.1 + diff --git a/queue-5.19/net-phy-don-t-warn-for-phy_up-state-in-mdio_bus_phy_.patch b/queue-5.19/net-phy-don-t-warn-for-phy_up-state-in-mdio_bus_phy_.patch new file mode 100644 index 00000000000..f5bfaea3e5f --- /dev/null +++ b/queue-5.19/net-phy-don-t-warn-for-phy_up-state-in-mdio_bus_phy_.patch @@ -0,0 +1,63 @@ +From d5d5902b31101076a1e35308d915abce6c808bac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Sep 2022 06:09:52 +0200 +Subject: net: phy: Don't WARN for PHY_UP state in mdio_bus_phy_resume() + +From: Lukas Wunner + +[ Upstream commit ea64cdfad124922c931633e39287c5a31a9b14a1 ] + +Commit 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume() +state") introduced a WARN() on resume from system sleep if a PHY is not +in PHY_HALTED state. + +Commit 6dbe852c379f ("net: phy: Don't WARN for PHY_READY state in +mdio_bus_phy_resume()") added an exemption for PHY_READY state from +the WARN(). + +It turns out PHY_UP state needs to be exempted as well because the +following may happen on suspend: + + mdio_bus_phy_suspend() + phy_stop_machine() + phydev->state = PHY_UP # if (phydev->state >= PHY_UP) + +Fixes: 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume() state") +Reported-by: Marek Szyprowski +Tested-by: Marek Szyprowski +Link: https://lore.kernel.org/netdev/2b1a1588-505e-dff3-301d-bfc1fb14d685@samsung.com/ +Signed-off-by: Lukas Wunner +Acked-by: Florian Fainelli +Cc: Xiaolei Wang +Link: https://lore.kernel.org/r/8128fdb51eeebc9efbf3776a4097363a1317aaf1.1663905575.git.lukas@wunner.de +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/phy/phy_device.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c +index f90a21781d8d..adc9d97cbb88 100644 +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -316,11 +316,13 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev) + + phydev->suspended_by_mdio_bus = 0; + +- /* If we manged to get here with the PHY state machine in a state neither +- * PHY_HALTED nor PHY_READY this is an indication that something went wrong +- * and we should most likely be using MAC managed PM and we are not. ++ /* If we managed to get here with the PHY state machine in a state ++ * neither PHY_HALTED, PHY_READY nor PHY_UP, this is an indication ++ * that something went wrong and we should most likely be using ++ * MAC managed PM, but we are not. + */ +- WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY); ++ WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY && ++ phydev->state != PHY_UP); + + ret = phy_init_hw(phydev); + if (ret < 0) +-- +2.35.1 + diff --git a/queue-5.19/net-sched-act_ct-fix-possible-refcount-leak-in-tcf_c.patch b/queue-5.19/net-sched-act_ct-fix-possible-refcount-leak-in-tcf_c.patch new file mode 100644 index 00000000000..f00fd60f95a --- /dev/null +++ b/queue-5.19/net-sched-act_ct-fix-possible-refcount-leak-in-tcf_c.patch @@ -0,0 +1,47 @@ +From f241f40b72fd649f34f8b7232385263990ee47f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Sep 2022 10:00:46 +0800 +Subject: net: sched: act_ct: fix possible refcount leak in tcf_ct_init() + +From: Hangyu Hua + +[ Upstream commit 6e23ec0ba92d426c77a73a9ccab16346e5e0ef49 ] + +nf_ct_put need to be called to put the refcount got by tcf_ct_fill_params +to avoid possible refcount leak when tcf_ct_flow_table_get fails. + +Fixes: c34b961a2492 ("net/sched: act_ct: Create nf flow table per zone") +Signed-off-by: Hangyu Hua +Link: https://lore.kernel.org/r/20220923020046.8021-1-hbh25y@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sched/act_ct.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c +index e013253b10d1..4d44a1bf4a04 100644 +--- a/net/sched/act_ct.c ++++ b/net/sched/act_ct.c +@@ -1393,7 +1393,7 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla, + + err = tcf_ct_flow_table_get(params); + if (err) +- goto cleanup; ++ goto cleanup_params; + + spin_lock_bh(&c->tcf_lock); + goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch); +@@ -1408,6 +1408,9 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla, + + return res; + ++cleanup_params: ++ if (params->tmpl) ++ nf_ct_put(params->tmpl); + cleanup: + if (goto_ch) + tcf_chain_put_by_act(goto_ch); +-- +2.35.1 + diff --git a/queue-5.19/net-stmmac-power-up-down-serdes-in-stmmac_open-relea.patch b/queue-5.19/net-stmmac-power-up-down-serdes-in-stmmac_open-relea.patch new file mode 100644 index 00000000000..712c9766e56 --- /dev/null +++ b/queue-5.19/net-stmmac-power-up-down-serdes-in-stmmac_open-relea.patch @@ -0,0 +1,130 @@ +From dee91ab757964ac15f2f1e37d15df87e08d430a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Sep 2022 13:04:48 +0800 +Subject: net: stmmac: power up/down serdes in stmmac_open/release + +From: Junxiao Chang + +[ Upstream commit 49725ffc15fc4e9fae68c55b691fd25168cbe5c1 ] + +This commit fixes DMA engine reset timeout issue in suspend/resume +with ADLink I-Pi SMARC Plus board which dmesg shows: +... +[ 54.678271] PM: suspend exit +[ 54.754066] intel-eth-pci 0000:00:1d.2 enp0s29f2: PHY [stmmac-3:01] driver [Maxlinear Ethernet GPY215B] (irq=POLL) +[ 54.755808] intel-eth-pci 0000:00:1d.2 enp0s29f2: Register MEM_TYPE_PAGE_POOL RxQ-0 +... +[ 54.780482] intel-eth-pci 0000:00:1d.2 enp0s29f2: Register MEM_TYPE_PAGE_POOL RxQ-7 +[ 55.784098] intel-eth-pci 0000:00:1d.2: Failed to reset the dma +[ 55.784111] intel-eth-pci 0000:00:1d.2 enp0s29f2: stmmac_hw_setup: DMA engine initialization failed +[ 55.784115] intel-eth-pci 0000:00:1d.2 enp0s29f2: stmmac_open: Hw setup failed +... + +The issue is related with serdes which impacts clock. There is +serdes in ADLink I-Pi SMARC board ethernet controller. Please refer to +commit b9663b7ca6ff78 ("net: stmmac: Enable SERDES power up/down sequence") +for detial. When issue is reproduced, DMA engine clock is not ready +because serdes is not powered up. + +To reproduce DMA engine reset timeout issue with hardware which has +serdes in GBE controller, install Ubuntu. In Ubuntu GUI, click +"Power Off/Log Out" -> "Suspend" menu, it disables network interface, +then goes to sleep mode. When it wakes up, it enables network +interface again. Stmmac driver is called in this way: + +1. stmmac_release: Stop network interface. In this function, it + disables DMA engine and network interface; +2. stmmac_suspend: It is called in kernel suspend flow. But because + network interface has been disabled(netif_running(ndev) is + false), it does nothing and returns directly; +3. System goes into S3 or S0ix state. Some time later, system is + waken up by keyboard or mouse; +4. stmmac_resume: It does nothing because network interface has + been disabled; +5. stmmac_open: It is called to enable network interace again. DMA + engine is initialized in this API, but serdes is not power on so + there will be DMA engine reset timeout issue. + +Similarly, serdes powerdown should be added in stmmac_release. +Network interface might be disabled by cmd "ifconfig eth0 down", +DMA engine, phy and mac have been disabled in ndo_stop callback, +serdes should be powered down as well. It doesn't make sense that +serdes is on while other components have been turned off. + +If ethernet interface is in enabled state(netif_running(ndev) is true) +before suspend/resume, the issue couldn't be reproduced because serdes +could be powered up in stmmac_resume. + +Because serdes_powerup is added in stmmac_open, it doesn't need to be +called in probe function. + +Fixes: b9663b7ca6ff78 ("net: stmmac: Enable SERDES power up/down sequence") +Signed-off-by: Junxiao Chang +Reviewed-by: Voon Weifeng +Tested-by: Jimmy JS Chen +Tested-by: Looi, Hong Aun +Link: https://lore.kernel.org/r/20220923050448.1220250-1-junxiao.chang@intel.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/ethernet/stmicro/stmmac/stmmac_main.c | 23 +++++++++++-------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 78f11dabca05..8d9272f01e31 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -3704,6 +3704,15 @@ static int stmmac_open(struct net_device *dev) + goto init_error; + } + ++ if (priv->plat->serdes_powerup) { ++ ret = priv->plat->serdes_powerup(dev, priv->plat->bsp_priv); ++ if (ret < 0) { ++ netdev_err(priv->dev, "%s: Serdes powerup failed\n", ++ __func__); ++ goto init_error; ++ } ++ } ++ + ret = stmmac_hw_setup(dev, true); + if (ret < 0) { + netdev_err(priv->dev, "%s: Hw setup failed\n", __func__); +@@ -3793,6 +3802,10 @@ static int stmmac_release(struct net_device *dev) + /* Disable the MAC Rx/Tx */ + stmmac_mac_set(priv, priv->ioaddr, false); + ++ /* Powerdown Serdes if there is */ ++ if (priv->plat->serdes_powerdown) ++ priv->plat->serdes_powerdown(dev, priv->plat->bsp_priv); ++ + netif_carrier_off(dev); + + stmmac_release_ptp(priv); +@@ -7158,14 +7171,6 @@ int stmmac_dvr_probe(struct device *device, + goto error_netdev_register; + } + +- if (priv->plat->serdes_powerup) { +- ret = priv->plat->serdes_powerup(ndev, +- priv->plat->bsp_priv); +- +- if (ret < 0) +- goto error_serdes_powerup; +- } +- + #ifdef CONFIG_DEBUG_FS + stmmac_init_fs(ndev); + #endif +@@ -7180,8 +7185,6 @@ int stmmac_dvr_probe(struct device *device, + + return ret; + +-error_serdes_powerup: +- unregister_netdev(ndev); + error_netdev_register: + phylink_destroy(priv->phylink); + error_xpcs_setup: +-- +2.35.1 + diff --git a/queue-5.19/nvme-fix-ioc_pr_clear-and-ioc_pr_release-ioctls-for-.patch b/queue-5.19/nvme-fix-ioc_pr_clear-and-ioc_pr_release-ioctls-for-.patch new file mode 100644 index 00000000000..4afa33b4c24 --- /dev/null +++ b/queue-5.19/nvme-fix-ioc_pr_clear-and-ioc_pr_release-ioctls-for-.patch @@ -0,0 +1,63 @@ +From 7c002dcfb951f2c4d3fed273d45086531059e2c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Sep 2022 21:49:09 -0700 +Subject: nvme: Fix IOC_PR_CLEAR and IOC_PR_RELEASE ioctls for nvme devices + +From: Michael Kelley + +[ Upstream commit c292a337d0e45a292c301e3cd51c35aa0ae91e95 ] + +The IOC_PR_CLEAR and IOC_PR_RELEASE ioctls are +non-functional on NVMe devices because the nvme_pr_clear() +and nvme_pr_release() functions set the IEKEY field incorrectly. +The IEKEY field should be set only when the key is zero (i.e, +not specified). The current code does it backwards. + +Furthermore, the NVMe spec describes the persistent +reservation "clear" function as an option on the reservation +release command. The current implementation of nvme_pr_clear() +erroneously uses the reservation register command. + +Fix these errors. Note that NVMe version 1.3 and later specify +that setting the IEKEY field will return an error of Invalid +Field in Command. The fix will set IEKEY when the key is zero, +which is appropriate as these ioctls consider a zero key to +be "unspecified", and the intention of the spec change is +to require a valid key. + +Tested on a version 1.4 PCI NVMe device in an Azure VM. + +Fixes: 1673f1f08c88 ("nvme: move block_device_operations and ns/ctrl freeing to common code") +Fixes: 1d277a637a71 ("NVMe: Add persistent reservation ops") +Signed-off-by: Michael Kelley +Signed-off-by: Christoph Hellwig +Signed-off-by: Sasha Levin +--- + drivers/nvme/host/core.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c +index 6d76fc608b74..326ad33537ed 100644 +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -2069,14 +2069,14 @@ static int nvme_pr_preempt(struct block_device *bdev, u64 old, u64 new, + + static int nvme_pr_clear(struct block_device *bdev, u64 key) + { +- u32 cdw10 = 1 | (key ? 1 << 3 : 0); ++ u32 cdw10 = 1 | (key ? 0 : 1 << 3); + +- return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_register); ++ return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release); + } + + static int nvme_pr_release(struct block_device *bdev, u64 key, enum pr_type type) + { +- u32 cdw10 = nvme_pr_type(type) << 8 | (key ? 1 << 3 : 0); ++ u32 cdw10 = nvme_pr_type(type) << 8 | (key ? 0 : 1 << 3); + + return nvme_pr_command(bdev, cdw10, key, 0, nvme_cmd_resv_release); + } +-- +2.35.1 + diff --git a/queue-5.19/perf-parse-events-break-out-tracepoint-and-printing.patch b/queue-5.19/perf-parse-events-break-out-tracepoint-and-printing.patch new file mode 100644 index 00000000000..d83e55cda6c --- /dev/null +++ b/queue-5.19/perf-parse-events-break-out-tracepoint-and-printing.patch @@ -0,0 +1,1790 @@ +From a25650f8fe8b8590684391276eb3a366c5d07d63 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Jul 2022 13:42:17 -0700 +Subject: perf parse-events: Break out tracepoint and printing + +From: Ian Rogers + +[ Upstream commit 9b7c7728f4e4ba8dd75269fb111fa187faa018c6 ] + +Move print_*_events functions out of parse-events.c into a new +print-events.c. Move tracepoint code into tracepoint.c or +trace-event-info.c (sole user). This reduces the dependencies of +parse-events.c and makes it more amenable to being a library in the +future. + +Remove some unnecessary definitions from parse-events.h. Fix a +checkpatch.pl warning on using unsigned rather than unsigned int. Fix +some line length warnings too. + +Signed-off-by: Ian Rogers +Cc: Alexander Shishkin +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Mark Rutland +Cc: Namhyung Kim +Cc: Peter Zijlstra +Cc: Stephane Eranian +Link: https://lore.kernel.org/r/20220729204217.250166-3-irogers@google.com +[ Add include linux/stddef.h before perf_events.h for systems where __always_inline isn't pulled in before used, such as older Alpine Linux ] +Signed-off-by: Arnaldo Carvalho de Melo +Stable-dep-of: 71c86cda750b ("perf parse-events: Remove "not supported" hybrid cache events") +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-list.c | 2 +- + tools/perf/builtin-lock.c | 1 + + tools/perf/builtin-timechart.c | 1 + + tools/perf/builtin-trace.c | 1 + + tools/perf/util/Build | 2 + + tools/perf/util/parse-events.c | 713 +---------------------------- + tools/perf/util/parse-events.h | 31 -- + tools/perf/util/print-events.c | 572 +++++++++++++++++++++++ + tools/perf/util/print-events.h | 22 + + tools/perf/util/trace-event-info.c | 96 ++++ + tools/perf/util/tracepoint.c | 63 +++ + tools/perf/util/tracepoint.h | 25 + + 12 files changed, 791 insertions(+), 738 deletions(-) + create mode 100644 tools/perf/util/print-events.c + create mode 100644 tools/perf/util/print-events.h + create mode 100644 tools/perf/util/tracepoint.c + create mode 100644 tools/perf/util/tracepoint.h + +diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c +index 468958154ed9..744dd3520584 100644 +--- a/tools/perf/builtin-list.c ++++ b/tools/perf/builtin-list.c +@@ -10,7 +10,7 @@ + */ + #include "builtin.h" + +-#include "util/parse-events.h" ++#include "util/print-events.h" + #include "util/pmu.h" + #include "util/pmu-hybrid.h" + #include "util/debug.h" +diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c +index 23a33ac15e68..dcc079a80585 100644 +--- a/tools/perf/builtin-lock.c ++++ b/tools/perf/builtin-lock.c +@@ -13,6 +13,7 @@ + #include + #include + #include "util/trace-event.h" ++#include "util/tracepoint.h" + + #include "util/debug.h" + #include "util/session.h" +diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c +index afce731cec16..e2e9ad929baf 100644 +--- a/tools/perf/builtin-timechart.c ++++ b/tools/perf/builtin-timechart.c +@@ -36,6 +36,7 @@ + #include "util/data.h" + #include "util/debug.h" + #include "util/string2.h" ++#include "util/tracepoint.h" + #include + + #ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE +diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c +index f075cf37a65e..1e1f10a1971d 100644 +--- a/tools/perf/builtin-trace.c ++++ b/tools/perf/builtin-trace.c +@@ -53,6 +53,7 @@ + #include "trace-event.h" + #include "util/parse-events.h" + #include "util/bpf-loader.h" ++#include "util/tracepoint.h" + #include "callchain.h" + #include "print_binary.h" + #include "string2.h" +diff --git a/tools/perf/util/Build b/tools/perf/util/Build +index a51267d88ca9..038e4cf8f488 100644 +--- a/tools/perf/util/Build ++++ b/tools/perf/util/Build +@@ -26,6 +26,8 @@ perf-y += mmap.o + perf-y += memswap.o + perf-y += parse-events.o + perf-y += parse-events-hybrid.o ++perf-y += print-events.o ++perf-y += tracepoint.o + perf-y += perf_regs.o + perf-y += path.o + perf-y += print_binary.o +diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c +index 700c95eafd62..3acf7452572c 100644 +--- a/tools/perf/util/parse-events.c ++++ b/tools/perf/util/parse-events.c +@@ -5,18 +5,12 @@ + #include + #include + #include +-#include +-#include +-#include + #include + #include "term.h" +-#include "build-id.h" + #include "evlist.h" + #include "evsel.h" +-#include + #include + #include "parse-events.h" +-#include + #include "string2.h" + #include "strlist.h" + #include "bpf-loader.h" +@@ -27,20 +21,22 @@ + #define YY_EXTRA_TYPE void* + #include "parse-events-flex.h" + #include "pmu.h" +-#include "thread_map.h" +-#include "probe-file.h" + #include "asm/bug.h" + #include "util/parse-branch-options.h" +-#include "metricgroup.h" + #include "util/evsel_config.h" + #include "util/event.h" +-#include "util/pfm.h" ++#include "perf.h" + #include "util/parse-events-hybrid.h" + #include "util/pmu-hybrid.h" +-#include "perf.h" ++#include "tracepoint.h" + + #define MAX_NAME_LEN 100 + ++struct perf_pmu_event_symbol { ++ char *symbol; ++ enum perf_pmu_event_symbol_type type; ++}; ++ + #ifdef PARSER_DEBUG + extern int parse_events_debug; + #endif +@@ -154,21 +150,6 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { + }, + }; + +-struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = { +- [PERF_TOOL_DURATION_TIME] = { +- .symbol = "duration_time", +- .alias = "", +- }, +- [PERF_TOOL_USER_TIME] = { +- .symbol = "user_time", +- .alias = "", +- }, +- [PERF_TOOL_SYSTEM_TIME] = { +- .symbol = "system_time", +- .alias = "", +- }, +-}; +- + #define __PERF_EVENT_FIELD(config, name) \ + ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) + +@@ -177,121 +158,6 @@ struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = { + #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) + #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) + +-#define for_each_subsystem(sys_dir, sys_dirent) \ +- while ((sys_dirent = readdir(sys_dir)) != NULL) \ +- if (sys_dirent->d_type == DT_DIR && \ +- (strcmp(sys_dirent->d_name, ".")) && \ +- (strcmp(sys_dirent->d_name, ".."))) +- +-static int tp_event_has_id(const char *dir_path, struct dirent *evt_dir) +-{ +- char evt_path[MAXPATHLEN]; +- int fd; +- +- snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, evt_dir->d_name); +- fd = open(evt_path, O_RDONLY); +- if (fd < 0) +- return -EINVAL; +- close(fd); +- +- return 0; +-} +- +-#define for_each_event(dir_path, evt_dir, evt_dirent) \ +- while ((evt_dirent = readdir(evt_dir)) != NULL) \ +- if (evt_dirent->d_type == DT_DIR && \ +- (strcmp(evt_dirent->d_name, ".")) && \ +- (strcmp(evt_dirent->d_name, "..")) && \ +- (!tp_event_has_id(dir_path, evt_dirent))) +- +-#define MAX_EVENT_LENGTH 512 +- +-struct tracepoint_path *tracepoint_id_to_path(u64 config) +-{ +- struct tracepoint_path *path = NULL; +- DIR *sys_dir, *evt_dir; +- struct dirent *sys_dirent, *evt_dirent; +- char id_buf[24]; +- int fd; +- u64 id; +- char evt_path[MAXPATHLEN]; +- char *dir_path; +- +- sys_dir = tracing_events__opendir(); +- if (!sys_dir) +- return NULL; +- +- for_each_subsystem(sys_dir, sys_dirent) { +- dir_path = get_events_file(sys_dirent->d_name); +- if (!dir_path) +- continue; +- evt_dir = opendir(dir_path); +- if (!evt_dir) +- goto next; +- +- for_each_event(dir_path, evt_dir, evt_dirent) { +- +- scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, +- evt_dirent->d_name); +- fd = open(evt_path, O_RDONLY); +- if (fd < 0) +- continue; +- if (read(fd, id_buf, sizeof(id_buf)) < 0) { +- close(fd); +- continue; +- } +- close(fd); +- id = atoll(id_buf); +- if (id == config) { +- put_events_file(dir_path); +- closedir(evt_dir); +- closedir(sys_dir); +- path = zalloc(sizeof(*path)); +- if (!path) +- return NULL; +- if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { +- free(path); +- return NULL; +- } +- if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { +- zfree(&path->system); +- free(path); +- return NULL; +- } +- return path; +- } +- } +- closedir(evt_dir); +-next: +- put_events_file(dir_path); +- } +- +- closedir(sys_dir); +- return NULL; +-} +- +-struct tracepoint_path *tracepoint_name_to_path(const char *name) +-{ +- struct tracepoint_path *path = zalloc(sizeof(*path)); +- char *str = strchr(name, ':'); +- +- if (path == NULL || str == NULL) { +- free(path); +- return NULL; +- } +- +- path->system = strndup(name, str - name); +- path->name = strdup(str+1); +- +- if (path->system == NULL || path->name == NULL) { +- zfree(&path->system); +- zfree(&path->name); +- zfree(&path); +- } +- +- return path; +-} +- + const char *event_type(int type) + { + switch (type) { +@@ -2674,571 +2540,6 @@ int exclude_perf(const struct option *opt, + NULL); + } + +-static const char * const event_type_descriptors[] = { +- "Hardware event", +- "Software event", +- "Tracepoint event", +- "Hardware cache event", +- "Raw hardware event descriptor", +- "Hardware breakpoint", +-}; +- +-static int cmp_string(const void *a, const void *b) +-{ +- const char * const *as = a; +- const char * const *bs = b; +- +- return strcmp(*as, *bs); +-} +- +-/* +- * Print the events from /tracing/events +- */ +- +-void print_tracepoint_events(const char *subsys_glob, const char *event_glob, +- bool name_only) +-{ +- DIR *sys_dir, *evt_dir; +- struct dirent *sys_dirent, *evt_dirent; +- char evt_path[MAXPATHLEN]; +- char *dir_path; +- char **evt_list = NULL; +- unsigned int evt_i = 0, evt_num = 0; +- bool evt_num_known = false; +- +-restart: +- sys_dir = tracing_events__opendir(); +- if (!sys_dir) +- return; +- +- if (evt_num_known) { +- evt_list = zalloc(sizeof(char *) * evt_num); +- if (!evt_list) +- goto out_close_sys_dir; +- } +- +- for_each_subsystem(sys_dir, sys_dirent) { +- if (subsys_glob != NULL && +- !strglobmatch(sys_dirent->d_name, subsys_glob)) +- continue; +- +- dir_path = get_events_file(sys_dirent->d_name); +- if (!dir_path) +- continue; +- evt_dir = opendir(dir_path); +- if (!evt_dir) +- goto next; +- +- for_each_event(dir_path, evt_dir, evt_dirent) { +- if (event_glob != NULL && +- !strglobmatch(evt_dirent->d_name, event_glob)) +- continue; +- +- if (!evt_num_known) { +- evt_num++; +- continue; +- } +- +- snprintf(evt_path, MAXPATHLEN, "%s:%s", +- sys_dirent->d_name, evt_dirent->d_name); +- +- evt_list[evt_i] = strdup(evt_path); +- if (evt_list[evt_i] == NULL) { +- put_events_file(dir_path); +- goto out_close_evt_dir; +- } +- evt_i++; +- } +- closedir(evt_dir); +-next: +- put_events_file(dir_path); +- } +- closedir(sys_dir); +- +- if (!evt_num_known) { +- evt_num_known = true; +- goto restart; +- } +- qsort(evt_list, evt_num, sizeof(char *), cmp_string); +- evt_i = 0; +- while (evt_i < evt_num) { +- if (name_only) { +- printf("%s ", evt_list[evt_i++]); +- continue; +- } +- printf(" %-50s [%s]\n", evt_list[evt_i++], +- event_type_descriptors[PERF_TYPE_TRACEPOINT]); +- } +- if (evt_num && pager_in_use()) +- printf("\n"); +- +-out_free: +- evt_num = evt_i; +- for (evt_i = 0; evt_i < evt_num; evt_i++) +- zfree(&evt_list[evt_i]); +- zfree(&evt_list); +- return; +- +-out_close_evt_dir: +- closedir(evt_dir); +-out_close_sys_dir: +- closedir(sys_dir); +- +- printf("FATAL: not enough memory to print %s\n", +- event_type_descriptors[PERF_TYPE_TRACEPOINT]); +- if (evt_list) +- goto out_free; +-} +- +-/* +- * Check whether event is in /tracing/events +- */ +- +-int is_valid_tracepoint(const char *event_string) +-{ +- DIR *sys_dir, *evt_dir; +- struct dirent *sys_dirent, *evt_dirent; +- char evt_path[MAXPATHLEN]; +- char *dir_path; +- +- sys_dir = tracing_events__opendir(); +- if (!sys_dir) +- return 0; +- +- for_each_subsystem(sys_dir, sys_dirent) { +- dir_path = get_events_file(sys_dirent->d_name); +- if (!dir_path) +- continue; +- evt_dir = opendir(dir_path); +- if (!evt_dir) +- goto next; +- +- for_each_event(dir_path, evt_dir, evt_dirent) { +- snprintf(evt_path, MAXPATHLEN, "%s:%s", +- sys_dirent->d_name, evt_dirent->d_name); +- if (!strcmp(evt_path, event_string)) { +- closedir(evt_dir); +- closedir(sys_dir); +- return 1; +- } +- } +- closedir(evt_dir); +-next: +- put_events_file(dir_path); +- } +- closedir(sys_dir); +- return 0; +-} +- +-static bool is_event_supported(u8 type, u64 config) +-{ +- bool ret = true; +- int open_return; +- struct evsel *evsel; +- struct perf_event_attr attr = { +- .type = type, +- .config = config, +- .disabled = 1, +- }; +- struct perf_thread_map *tmap = thread_map__new_by_tid(0); +- +- if (tmap == NULL) +- return false; +- +- evsel = evsel__new(&attr); +- if (evsel) { +- open_return = evsel__open(evsel, NULL, tmap); +- ret = open_return >= 0; +- +- if (open_return == -EACCES) { +- /* +- * This happens if the paranoid value +- * /proc/sys/kernel/perf_event_paranoid is set to 2 +- * Re-run with exclude_kernel set; we don't do that +- * by default as some ARM machines do not support it. +- * +- */ +- evsel->core.attr.exclude_kernel = 1; +- ret = evsel__open(evsel, NULL, tmap) >= 0; +- } +- evsel__delete(evsel); +- } +- +- perf_thread_map__put(tmap); +- return ret; +-} +- +-void print_sdt_events(const char *subsys_glob, const char *event_glob, +- bool name_only) +-{ +- struct probe_cache *pcache; +- struct probe_cache_entry *ent; +- struct strlist *bidlist, *sdtlist; +- struct strlist_config cfg = {.dont_dupstr = true}; +- struct str_node *nd, *nd2; +- char *buf, *path, *ptr = NULL; +- bool show_detail = false; +- int ret; +- +- sdtlist = strlist__new(NULL, &cfg); +- if (!sdtlist) { +- pr_debug("Failed to allocate new strlist for SDT\n"); +- return; +- } +- bidlist = build_id_cache__list_all(true); +- if (!bidlist) { +- pr_debug("Failed to get buildids: %d\n", errno); +- return; +- } +- strlist__for_each_entry(nd, bidlist) { +- pcache = probe_cache__new(nd->s, NULL); +- if (!pcache) +- continue; +- list_for_each_entry(ent, &pcache->entries, node) { +- if (!ent->sdt) +- continue; +- if (subsys_glob && +- !strglobmatch(ent->pev.group, subsys_glob)) +- continue; +- if (event_glob && +- !strglobmatch(ent->pev.event, event_glob)) +- continue; +- ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, +- ent->pev.event, nd->s); +- if (ret > 0) +- strlist__add(sdtlist, buf); +- } +- probe_cache__delete(pcache); +- } +- strlist__delete(bidlist); +- +- strlist__for_each_entry(nd, sdtlist) { +- buf = strchr(nd->s, '@'); +- if (buf) +- *(buf++) = '\0'; +- if (name_only) { +- printf("%s ", nd->s); +- continue; +- } +- nd2 = strlist__next(nd); +- if (nd2) { +- ptr = strchr(nd2->s, '@'); +- if (ptr) +- *ptr = '\0'; +- if (strcmp(nd->s, nd2->s) == 0) +- show_detail = true; +- } +- if (show_detail) { +- path = build_id_cache__origname(buf); +- ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf); +- if (ret > 0) { +- printf(" %-50s [%s]\n", buf, "SDT event"); +- free(buf); +- } +- free(path); +- } else +- printf(" %-50s [%s]\n", nd->s, "SDT event"); +- if (nd2) { +- if (strcmp(nd->s, nd2->s) != 0) +- show_detail = false; +- if (ptr) +- *ptr = '@'; +- } +- } +- strlist__delete(sdtlist); +-} +- +-int print_hwcache_events(const char *event_glob, bool name_only) +-{ +- unsigned int type, op, i, evt_i = 0, evt_num = 0, npmus = 0; +- char name[64], new_name[128]; +- char **evt_list = NULL, **evt_pmus = NULL; +- bool evt_num_known = false; +- struct perf_pmu *pmu = NULL; +- +- if (perf_pmu__has_hybrid()) { +- npmus = perf_pmu__hybrid_pmu_num(); +- evt_pmus = zalloc(sizeof(char *) * npmus); +- if (!evt_pmus) +- goto out_enomem; +- } +- +-restart: +- if (evt_num_known) { +- evt_list = zalloc(sizeof(char *) * evt_num); +- if (!evt_list) +- goto out_enomem; +- } +- +- for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { +- for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { +- /* skip invalid cache type */ +- if (!evsel__is_cache_op_valid(type, op)) +- continue; +- +- for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { +- unsigned int hybrid_supported = 0, j; +- bool supported; +- +- __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); +- if (event_glob != NULL && !strglobmatch(name, event_glob)) +- continue; +- +- if (!perf_pmu__has_hybrid()) { +- if (!is_event_supported(PERF_TYPE_HW_CACHE, +- type | (op << 8) | (i << 16))) { +- continue; +- } +- } else { +- perf_pmu__for_each_hybrid_pmu(pmu) { +- if (!evt_num_known) { +- evt_num++; +- continue; +- } +- +- supported = is_event_supported( +- PERF_TYPE_HW_CACHE, +- type | (op << 8) | (i << 16) | +- ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT)); +- if (supported) { +- snprintf(new_name, sizeof(new_name), "%s/%s/", +- pmu->name, name); +- evt_pmus[hybrid_supported] = strdup(new_name); +- hybrid_supported++; +- } +- } +- +- if (hybrid_supported == 0) +- continue; +- } +- +- if (!evt_num_known) { +- evt_num++; +- continue; +- } +- +- if ((hybrid_supported == 0) || +- (hybrid_supported == npmus)) { +- evt_list[evt_i] = strdup(name); +- if (npmus > 0) { +- for (j = 0; j < npmus; j++) +- zfree(&evt_pmus[j]); +- } +- } else { +- for (j = 0; j < hybrid_supported; j++) { +- evt_list[evt_i++] = evt_pmus[j]; +- evt_pmus[j] = NULL; +- } +- continue; +- } +- +- if (evt_list[evt_i] == NULL) +- goto out_enomem; +- evt_i++; +- } +- } +- } +- +- if (!evt_num_known) { +- evt_num_known = true; +- goto restart; +- } +- +- for (evt_i = 0; evt_i < evt_num; evt_i++) { +- if (!evt_list[evt_i]) +- break; +- } +- +- evt_num = evt_i; +- qsort(evt_list, evt_num, sizeof(char *), cmp_string); +- evt_i = 0; +- while (evt_i < evt_num) { +- if (name_only) { +- printf("%s ", evt_list[evt_i++]); +- continue; +- } +- printf(" %-50s [%s]\n", evt_list[evt_i++], +- event_type_descriptors[PERF_TYPE_HW_CACHE]); +- } +- if (evt_num && pager_in_use()) +- printf("\n"); +- +-out_free: +- evt_num = evt_i; +- for (evt_i = 0; evt_i < evt_num; evt_i++) +- zfree(&evt_list[evt_i]); +- zfree(&evt_list); +- +- for (evt_i = 0; evt_i < npmus; evt_i++) +- zfree(&evt_pmus[evt_i]); +- zfree(&evt_pmus); +- return evt_num; +- +-out_enomem: +- printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]); +- if (evt_list) +- goto out_free; +- return evt_num; +-} +- +-static void print_tool_event(const struct event_symbol *syms, const char *event_glob, +- bool name_only) +-{ +- if (syms->symbol == NULL) +- return; +- +- if (event_glob && !(strglobmatch(syms->symbol, event_glob) || +- (syms->alias && strglobmatch(syms->alias, event_glob)))) +- return; +- +- if (name_only) +- printf("%s ", syms->symbol); +- else { +- char name[MAX_NAME_LEN]; +- if (syms->alias && strlen(syms->alias)) +- snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); +- else +- strlcpy(name, syms->symbol, MAX_NAME_LEN); +- printf(" %-50s [%s]\n", name, "Tool event"); +- } +-} +- +-void print_tool_events(const char *event_glob, bool name_only) +-{ +- // Start at 1 because the first enum entry symbols no tool event +- for (int i = 1; i < PERF_TOOL_MAX; ++i) { +- print_tool_event(event_symbols_tool + i, event_glob, name_only); +- } +- if (pager_in_use()) +- printf("\n"); +-} +- +-void print_symbol_events(const char *event_glob, unsigned type, +- struct event_symbol *syms, unsigned max, +- bool name_only) +-{ +- unsigned int i, evt_i = 0, evt_num = 0; +- char name[MAX_NAME_LEN]; +- char **evt_list = NULL; +- bool evt_num_known = false; +- +-restart: +- if (evt_num_known) { +- evt_list = zalloc(sizeof(char *) * evt_num); +- if (!evt_list) +- goto out_enomem; +- syms -= max; +- } +- +- for (i = 0; i < max; i++, syms++) { +- /* +- * New attr.config still not supported here, the latest +- * example was PERF_COUNT_SW_CGROUP_SWITCHES +- */ +- if (syms->symbol == NULL) +- continue; +- +- if (event_glob != NULL && !(strglobmatch(syms->symbol, event_glob) || +- (syms->alias && strglobmatch(syms->alias, event_glob)))) +- continue; +- +- if (!is_event_supported(type, i)) +- continue; +- +- if (!evt_num_known) { +- evt_num++; +- continue; +- } +- +- if (!name_only && strlen(syms->alias)) +- snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); +- else +- strlcpy(name, syms->symbol, MAX_NAME_LEN); +- +- evt_list[evt_i] = strdup(name); +- if (evt_list[evt_i] == NULL) +- goto out_enomem; +- evt_i++; +- } +- +- if (!evt_num_known) { +- evt_num_known = true; +- goto restart; +- } +- qsort(evt_list, evt_num, sizeof(char *), cmp_string); +- evt_i = 0; +- while (evt_i < evt_num) { +- if (name_only) { +- printf("%s ", evt_list[evt_i++]); +- continue; +- } +- printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); +- } +- if (evt_num && pager_in_use()) +- printf("\n"); +- +-out_free: +- evt_num = evt_i; +- for (evt_i = 0; evt_i < evt_num; evt_i++) +- zfree(&evt_list[evt_i]); +- zfree(&evt_list); +- return; +- +-out_enomem: +- printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); +- if (evt_list) +- goto out_free; +-} +- +-/* +- * Print the help text for the event symbols: +- */ +-void print_events(const char *event_glob, bool name_only, bool quiet_flag, +- bool long_desc, bool details_flag, bool deprecated, +- const char *pmu_name) +-{ +- print_symbol_events(event_glob, PERF_TYPE_HARDWARE, +- event_symbols_hw, PERF_COUNT_HW_MAX, name_only); +- +- print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, +- event_symbols_sw, PERF_COUNT_SW_MAX, name_only); +- print_tool_events(event_glob, name_only); +- +- print_hwcache_events(event_glob, name_only); +- +- print_pmu_events(event_glob, name_only, quiet_flag, long_desc, +- details_flag, deprecated, pmu_name); +- +- if (event_glob != NULL) +- return; +- +- if (!name_only) { +- printf(" %-50s [%s]\n", +- "rNNN", +- event_type_descriptors[PERF_TYPE_RAW]); +- printf(" %-50s [%s]\n", +- "cpu/t1=v1[,t2=v2,t3 ...]/modifier", +- event_type_descriptors[PERF_TYPE_RAW]); +- if (pager_in_use()) +- printf(" (see 'man perf-list' on how to encode it)\n\n"); +- +- printf(" %-50s [%s]\n", +- "mem:[/len][:access]", +- event_type_descriptors[PERF_TYPE_BREAKPOINT]); +- if (pager_in_use()) +- printf("\n"); +- } +- +- print_tracepoint_events(NULL, NULL, name_only); +- +- print_sdt_events(NULL, NULL, name_only); +- +- metricgroup__print(true, true, NULL, name_only, details_flag, +- pmu_name); +- +- print_libpfm_events(name_only, long_desc); +-} +- + int parse_events__is_hardcoded_term(struct parse_events_term *term) + { + return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; +diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h +index a38b8b160e80..ba9fa3ddaf6e 100644 +--- a/tools/perf/util/parse-events.h ++++ b/tools/perf/util/parse-events.h +@@ -11,7 +11,6 @@ + #include + #include + +-struct list_head; + struct evsel; + struct evlist; + struct parse_events_error; +@@ -19,14 +18,6 @@ struct parse_events_error; + struct option; + struct perf_pmu; + +-struct tracepoint_path { +- char *system; +- char *name; +- struct tracepoint_path *next; +-}; +- +-struct tracepoint_path *tracepoint_id_to_path(u64 config); +-struct tracepoint_path *tracepoint_name_to_path(const char *name); + bool have_tracepoints(struct list_head *evlist); + + const char *event_type(int type); +@@ -46,8 +37,6 @@ int parse_events_terms(struct list_head *terms, const char *str); + int parse_filter(const struct option *opt, const char *str, int unset); + int exclude_perf(const struct option *opt, const char *arg, int unset); + +-#define EVENTS_HELP_MAX (128*1024) +- + enum perf_pmu_event_symbol_type { + PMU_EVENT_SYMBOL_ERR, /* not a PMU EVENT */ + PMU_EVENT_SYMBOL, /* normal style PMU event */ +@@ -56,11 +45,6 @@ enum perf_pmu_event_symbol_type { + PMU_EVENT_SYMBOL_SUFFIX2, /* suffix of pre-suf2 style event */ + }; + +-struct perf_pmu_event_symbol { +- char *symbol; +- enum perf_pmu_event_symbol_type type; +-}; +- + enum { + PARSE_EVENTS__TERM_TYPE_NUM, + PARSE_EVENTS__TERM_TYPE_STR, +@@ -219,28 +203,13 @@ void parse_events_update_lists(struct list_head *list_event, + void parse_events_evlist_error(struct parse_events_state *parse_state, + int idx, const char *str); + +-void print_events(const char *event_glob, bool name_only, bool quiet, +- bool long_desc, bool details_flag, bool deprecated, +- const char *pmu_name); +- + struct event_symbol { + const char *symbol; + const char *alias; + }; + extern struct event_symbol event_symbols_hw[]; + extern struct event_symbol event_symbols_sw[]; +-void print_symbol_events(const char *event_glob, unsigned type, +- struct event_symbol *syms, unsigned max, +- bool name_only); +-void print_tool_events(const char *event_glob, bool name_only); +-void print_tracepoint_events(const char *subsys_glob, const char *event_glob, +- bool name_only); +-int print_hwcache_events(const char *event_glob, bool name_only); +-void print_sdt_events(const char *subsys_glob, const char *event_glob, +- bool name_only); +-int is_valid_tracepoint(const char *event_string); + +-int valid_event_mount(const char *eventfs); + char *parse_events_formats_error_string(char *additional_terms); + + void parse_events_error__init(struct parse_events_error *err); +diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c +new file mode 100644 +index 000000000000..ba1ab5134685 +--- /dev/null ++++ b/tools/perf/util/print-events.c +@@ -0,0 +1,572 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "build-id.h" ++#include "debug.h" ++#include "evsel.h" ++#include "metricgroup.h" ++#include "parse-events.h" ++#include "pmu.h" ++#include "print-events.h" ++#include "probe-file.h" ++#include "string2.h" ++#include "strlist.h" ++#include "thread_map.h" ++#include "tracepoint.h" ++#include "pfm.h" ++#include "pmu-hybrid.h" ++ ++#define MAX_NAME_LEN 100 ++ ++static const char * const event_type_descriptors[] = { ++ "Hardware event", ++ "Software event", ++ "Tracepoint event", ++ "Hardware cache event", ++ "Raw hardware event descriptor", ++ "Hardware breakpoint", ++}; ++ ++static const struct event_symbol event_symbols_tool[PERF_TOOL_MAX] = { ++ [PERF_TOOL_DURATION_TIME] = { ++ .symbol = "duration_time", ++ .alias = "", ++ }, ++ [PERF_TOOL_USER_TIME] = { ++ .symbol = "user_time", ++ .alias = "", ++ }, ++ [PERF_TOOL_SYSTEM_TIME] = { ++ .symbol = "system_time", ++ .alias = "", ++ }, ++}; ++ ++static int cmp_string(const void *a, const void *b) ++{ ++ const char * const *as = a; ++ const char * const *bs = b; ++ ++ return strcmp(*as, *bs); ++} ++ ++/* ++ * Print the events from /tracing/events ++ */ ++void print_tracepoint_events(const char *subsys_glob, ++ const char *event_glob, bool name_only) ++{ ++ DIR *sys_dir, *evt_dir; ++ struct dirent *sys_dirent, *evt_dirent; ++ char evt_path[MAXPATHLEN]; ++ char *dir_path; ++ char **evt_list = NULL; ++ unsigned int evt_i = 0, evt_num = 0; ++ bool evt_num_known = false; ++ ++restart: ++ sys_dir = tracing_events__opendir(); ++ if (!sys_dir) ++ return; ++ ++ if (evt_num_known) { ++ evt_list = zalloc(sizeof(char *) * evt_num); ++ if (!evt_list) ++ goto out_close_sys_dir; ++ } ++ ++ for_each_subsystem(sys_dir, sys_dirent) { ++ if (subsys_glob != NULL && ++ !strglobmatch(sys_dirent->d_name, subsys_glob)) ++ continue; ++ ++ dir_path = get_events_file(sys_dirent->d_name); ++ if (!dir_path) ++ continue; ++ evt_dir = opendir(dir_path); ++ if (!evt_dir) ++ goto next; ++ ++ for_each_event(dir_path, evt_dir, evt_dirent) { ++ if (event_glob != NULL && ++ !strglobmatch(evt_dirent->d_name, event_glob)) ++ continue; ++ ++ if (!evt_num_known) { ++ evt_num++; ++ continue; ++ } ++ ++ snprintf(evt_path, MAXPATHLEN, "%s:%s", ++ sys_dirent->d_name, evt_dirent->d_name); ++ ++ evt_list[evt_i] = strdup(evt_path); ++ if (evt_list[evt_i] == NULL) { ++ put_events_file(dir_path); ++ goto out_close_evt_dir; ++ } ++ evt_i++; ++ } ++ closedir(evt_dir); ++next: ++ put_events_file(dir_path); ++ } ++ closedir(sys_dir); ++ ++ if (!evt_num_known) { ++ evt_num_known = true; ++ goto restart; ++ } ++ qsort(evt_list, evt_num, sizeof(char *), cmp_string); ++ evt_i = 0; ++ while (evt_i < evt_num) { ++ if (name_only) { ++ printf("%s ", evt_list[evt_i++]); ++ continue; ++ } ++ printf(" %-50s [%s]\n", evt_list[evt_i++], ++ event_type_descriptors[PERF_TYPE_TRACEPOINT]); ++ } ++ if (evt_num && pager_in_use()) ++ printf("\n"); ++ ++out_free: ++ evt_num = evt_i; ++ for (evt_i = 0; evt_i < evt_num; evt_i++) ++ zfree(&evt_list[evt_i]); ++ zfree(&evt_list); ++ return; ++ ++out_close_evt_dir: ++ closedir(evt_dir); ++out_close_sys_dir: ++ closedir(sys_dir); ++ ++ printf("FATAL: not enough memory to print %s\n", ++ event_type_descriptors[PERF_TYPE_TRACEPOINT]); ++ if (evt_list) ++ goto out_free; ++} ++ ++void print_sdt_events(const char *subsys_glob, const char *event_glob, ++ bool name_only) ++{ ++ struct probe_cache *pcache; ++ struct probe_cache_entry *ent; ++ struct strlist *bidlist, *sdtlist; ++ struct strlist_config cfg = {.dont_dupstr = true}; ++ struct str_node *nd, *nd2; ++ char *buf, *path, *ptr = NULL; ++ bool show_detail = false; ++ int ret; ++ ++ sdtlist = strlist__new(NULL, &cfg); ++ if (!sdtlist) { ++ pr_debug("Failed to allocate new strlist for SDT\n"); ++ return; ++ } ++ bidlist = build_id_cache__list_all(true); ++ if (!bidlist) { ++ pr_debug("Failed to get buildids: %d\n", errno); ++ return; ++ } ++ strlist__for_each_entry(nd, bidlist) { ++ pcache = probe_cache__new(nd->s, NULL); ++ if (!pcache) ++ continue; ++ list_for_each_entry(ent, &pcache->entries, node) { ++ if (!ent->sdt) ++ continue; ++ if (subsys_glob && ++ !strglobmatch(ent->pev.group, subsys_glob)) ++ continue; ++ if (event_glob && ++ !strglobmatch(ent->pev.event, event_glob)) ++ continue; ++ ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, ++ ent->pev.event, nd->s); ++ if (ret > 0) ++ strlist__add(sdtlist, buf); ++ } ++ probe_cache__delete(pcache); ++ } ++ strlist__delete(bidlist); ++ ++ strlist__for_each_entry(nd, sdtlist) { ++ buf = strchr(nd->s, '@'); ++ if (buf) ++ *(buf++) = '\0'; ++ if (name_only) { ++ printf("%s ", nd->s); ++ continue; ++ } ++ nd2 = strlist__next(nd); ++ if (nd2) { ++ ptr = strchr(nd2->s, '@'); ++ if (ptr) ++ *ptr = '\0'; ++ if (strcmp(nd->s, nd2->s) == 0) ++ show_detail = true; ++ } ++ if (show_detail) { ++ path = build_id_cache__origname(buf); ++ ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf); ++ if (ret > 0) { ++ printf(" %-50s [%s]\n", buf, "SDT event"); ++ free(buf); ++ } ++ free(path); ++ } else ++ printf(" %-50s [%s]\n", nd->s, "SDT event"); ++ if (nd2) { ++ if (strcmp(nd->s, nd2->s) != 0) ++ show_detail = false; ++ if (ptr) ++ *ptr = '@'; ++ } ++ } ++ strlist__delete(sdtlist); ++} ++ ++static bool is_event_supported(u8 type, unsigned int config) ++{ ++ bool ret = true; ++ int open_return; ++ struct evsel *evsel; ++ struct perf_event_attr attr = { ++ .type = type, ++ .config = config, ++ .disabled = 1, ++ }; ++ struct perf_thread_map *tmap = thread_map__new_by_tid(0); ++ ++ if (tmap == NULL) ++ return false; ++ ++ evsel = evsel__new(&attr); ++ if (evsel) { ++ open_return = evsel__open(evsel, NULL, tmap); ++ ret = open_return >= 0; ++ ++ if (open_return == -EACCES) { ++ /* ++ * This happens if the paranoid value ++ * /proc/sys/kernel/perf_event_paranoid is set to 2 ++ * Re-run with exclude_kernel set; we don't do that ++ * by default as some ARM machines do not support it. ++ * ++ */ ++ evsel->core.attr.exclude_kernel = 1; ++ ret = evsel__open(evsel, NULL, tmap) >= 0; ++ } ++ evsel__delete(evsel); ++ } ++ ++ perf_thread_map__put(tmap); ++ return ret; ++} ++ ++int print_hwcache_events(const char *event_glob, bool name_only) ++{ ++ unsigned int type, op, i, evt_i = 0, evt_num = 0, npmus = 0; ++ char name[64], new_name[128]; ++ char **evt_list = NULL, **evt_pmus = NULL; ++ bool evt_num_known = false; ++ struct perf_pmu *pmu = NULL; ++ ++ if (perf_pmu__has_hybrid()) { ++ npmus = perf_pmu__hybrid_pmu_num(); ++ evt_pmus = zalloc(sizeof(char *) * npmus); ++ if (!evt_pmus) ++ goto out_enomem; ++ } ++ ++restart: ++ if (evt_num_known) { ++ evt_list = zalloc(sizeof(char *) * evt_num); ++ if (!evt_list) ++ goto out_enomem; ++ } ++ ++ for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { ++ for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { ++ /* skip invalid cache type */ ++ if (!evsel__is_cache_op_valid(type, op)) ++ continue; ++ ++ for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { ++ unsigned int hybrid_supported = 0, j; ++ bool supported; ++ ++ __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); ++ if (event_glob != NULL && !strglobmatch(name, event_glob)) ++ continue; ++ ++ if (!perf_pmu__has_hybrid()) { ++ if (!is_event_supported(PERF_TYPE_HW_CACHE, ++ type | (op << 8) | (i << 16))) { ++ continue; ++ } ++ } else { ++ perf_pmu__for_each_hybrid_pmu(pmu) { ++ if (!evt_num_known) { ++ evt_num++; ++ continue; ++ } ++ ++ supported = is_event_supported( ++ PERF_TYPE_HW_CACHE, ++ type | (op << 8) | (i << 16) | ++ ((__u64)pmu->type << PERF_PMU_TYPE_SHIFT)); ++ if (supported) { ++ snprintf(new_name, sizeof(new_name), ++ "%s/%s/", pmu->name, name); ++ evt_pmus[hybrid_supported] = ++ strdup(new_name); ++ hybrid_supported++; ++ } ++ } ++ ++ if (hybrid_supported == 0) ++ continue; ++ } ++ ++ if (!evt_num_known) { ++ evt_num++; ++ continue; ++ } ++ ++ if ((hybrid_supported == 0) || ++ (hybrid_supported == npmus)) { ++ evt_list[evt_i] = strdup(name); ++ if (npmus > 0) { ++ for (j = 0; j < npmus; j++) ++ zfree(&evt_pmus[j]); ++ } ++ } else { ++ for (j = 0; j < hybrid_supported; j++) { ++ evt_list[evt_i++] = evt_pmus[j]; ++ evt_pmus[j] = NULL; ++ } ++ continue; ++ } ++ ++ if (evt_list[evt_i] == NULL) ++ goto out_enomem; ++ evt_i++; ++ } ++ } ++ } ++ ++ if (!evt_num_known) { ++ evt_num_known = true; ++ goto restart; ++ } ++ ++ for (evt_i = 0; evt_i < evt_num; evt_i++) { ++ if (!evt_list[evt_i]) ++ break; ++ } ++ ++ evt_num = evt_i; ++ qsort(evt_list, evt_num, sizeof(char *), cmp_string); ++ evt_i = 0; ++ while (evt_i < evt_num) { ++ if (name_only) { ++ printf("%s ", evt_list[evt_i++]); ++ continue; ++ } ++ printf(" %-50s [%s]\n", evt_list[evt_i++], ++ event_type_descriptors[PERF_TYPE_HW_CACHE]); ++ } ++ if (evt_num && pager_in_use()) ++ printf("\n"); ++ ++out_free: ++ evt_num = evt_i; ++ for (evt_i = 0; evt_i < evt_num; evt_i++) ++ zfree(&evt_list[evt_i]); ++ zfree(&evt_list); ++ ++ for (evt_i = 0; evt_i < npmus; evt_i++) ++ zfree(&evt_pmus[evt_i]); ++ zfree(&evt_pmus); ++ return evt_num; ++ ++out_enomem: ++ printf("FATAL: not enough memory to print %s\n", ++ event_type_descriptors[PERF_TYPE_HW_CACHE]); ++ if (evt_list) ++ goto out_free; ++ return evt_num; ++} ++ ++static void print_tool_event(const struct event_symbol *syms, const char *event_glob, ++ bool name_only) ++{ ++ if (syms->symbol == NULL) ++ return; ++ ++ if (event_glob && !(strglobmatch(syms->symbol, event_glob) || ++ (syms->alias && strglobmatch(syms->alias, event_glob)))) ++ return; ++ ++ if (name_only) ++ printf("%s ", syms->symbol); ++ else { ++ char name[MAX_NAME_LEN]; ++ ++ if (syms->alias && strlen(syms->alias)) ++ snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); ++ else ++ strlcpy(name, syms->symbol, MAX_NAME_LEN); ++ printf(" %-50s [%s]\n", name, "Tool event"); ++ } ++} ++ ++void print_tool_events(const char *event_glob, bool name_only) ++{ ++ // Start at 1 because the first enum entry means no tool event. ++ for (int i = 1; i < PERF_TOOL_MAX; ++i) ++ print_tool_event(event_symbols_tool + i, event_glob, name_only); ++ ++ if (pager_in_use()) ++ printf("\n"); ++} ++ ++void print_symbol_events(const char *event_glob, unsigned int type, ++ struct event_symbol *syms, unsigned int max, ++ bool name_only) ++{ ++ unsigned int i, evt_i = 0, evt_num = 0; ++ char name[MAX_NAME_LEN]; ++ char **evt_list = NULL; ++ bool evt_num_known = false; ++ ++restart: ++ if (evt_num_known) { ++ evt_list = zalloc(sizeof(char *) * evt_num); ++ if (!evt_list) ++ goto out_enomem; ++ syms -= max; ++ } ++ ++ for (i = 0; i < max; i++, syms++) { ++ /* ++ * New attr.config still not supported here, the latest ++ * example was PERF_COUNT_SW_CGROUP_SWITCHES ++ */ ++ if (syms->symbol == NULL) ++ continue; ++ ++ if (event_glob != NULL && !(strglobmatch(syms->symbol, event_glob) || ++ (syms->alias && strglobmatch(syms->alias, event_glob)))) ++ continue; ++ ++ if (!is_event_supported(type, i)) ++ continue; ++ ++ if (!evt_num_known) { ++ evt_num++; ++ continue; ++ } ++ ++ if (!name_only && strlen(syms->alias)) ++ snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); ++ else ++ strlcpy(name, syms->symbol, MAX_NAME_LEN); ++ ++ evt_list[evt_i] = strdup(name); ++ if (evt_list[evt_i] == NULL) ++ goto out_enomem; ++ evt_i++; ++ } ++ ++ if (!evt_num_known) { ++ evt_num_known = true; ++ goto restart; ++ } ++ qsort(evt_list, evt_num, sizeof(char *), cmp_string); ++ evt_i = 0; ++ while (evt_i < evt_num) { ++ if (name_only) { ++ printf("%s ", evt_list[evt_i++]); ++ continue; ++ } ++ printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); ++ } ++ if (evt_num && pager_in_use()) ++ printf("\n"); ++ ++out_free: ++ evt_num = evt_i; ++ for (evt_i = 0; evt_i < evt_num; evt_i++) ++ zfree(&evt_list[evt_i]); ++ zfree(&evt_list); ++ return; ++ ++out_enomem: ++ printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); ++ if (evt_list) ++ goto out_free; ++} ++ ++/* ++ * Print the help text for the event symbols: ++ */ ++void print_events(const char *event_glob, bool name_only, bool quiet_flag, ++ bool long_desc, bool details_flag, bool deprecated, ++ const char *pmu_name) ++{ ++ print_symbol_events(event_glob, PERF_TYPE_HARDWARE, ++ event_symbols_hw, PERF_COUNT_HW_MAX, name_only); ++ ++ print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, ++ event_symbols_sw, PERF_COUNT_SW_MAX, name_only); ++ print_tool_events(event_glob, name_only); ++ ++ print_hwcache_events(event_glob, name_only); ++ ++ print_pmu_events(event_glob, name_only, quiet_flag, long_desc, ++ details_flag, deprecated, pmu_name); ++ ++ if (event_glob != NULL) ++ return; ++ ++ if (!name_only) { ++ printf(" %-50s [%s]\n", ++ "rNNN", ++ event_type_descriptors[PERF_TYPE_RAW]); ++ printf(" %-50s [%s]\n", ++ "cpu/t1=v1[,t2=v2,t3 ...]/modifier", ++ event_type_descriptors[PERF_TYPE_RAW]); ++ if (pager_in_use()) ++ printf(" (see 'man perf-list' on how to encode it)\n\n"); ++ ++ printf(" %-50s [%s]\n", ++ "mem:[/len][:access]", ++ event_type_descriptors[PERF_TYPE_BREAKPOINT]); ++ if (pager_in_use()) ++ printf("\n"); ++ } ++ ++ print_tracepoint_events(NULL, NULL, name_only); ++ ++ print_sdt_events(NULL, NULL, name_only); ++ ++ metricgroup__print(true, true, NULL, name_only, details_flag, ++ pmu_name); ++ ++ print_libpfm_events(name_only, long_desc); ++} +diff --git a/tools/perf/util/print-events.h b/tools/perf/util/print-events.h +new file mode 100644 +index 000000000000..1da9910d83a6 +--- /dev/null ++++ b/tools/perf/util/print-events.h +@@ -0,0 +1,22 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef __PERF_PRINT_EVENTS_H ++#define __PERF_PRINT_EVENTS_H ++ ++#include ++ ++struct event_symbol; ++ ++void print_events(const char *event_glob, bool name_only, bool quiet_flag, ++ bool long_desc, bool details_flag, bool deprecated, ++ const char *pmu_name); ++int print_hwcache_events(const char *event_glob, bool name_only); ++void print_sdt_events(const char *subsys_glob, const char *event_glob, ++ bool name_only); ++void print_symbol_events(const char *event_glob, unsigned int type, ++ struct event_symbol *syms, unsigned int max, ++ bool name_only); ++void print_tool_events(const char *event_glob, bool name_only); ++void print_tracepoint_events(const char *subsys_glob, const char *event_glob, ++ bool name_only); ++ ++#endif /* __PERF_PRINT_EVENTS_H */ +diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c +index a65f65d0857e..892c323b4ac9 100644 +--- a/tools/perf/util/trace-event-info.c ++++ b/tools/perf/util/trace-event-info.c +@@ -19,16 +19,24 @@ + #include + #include + #include // page_size ++#include + + #include "trace-event.h" ++#include "tracepoint.h" + #include + #include "evsel.h" + #include "debug.h" + + #define VERSION "0.6" ++#define MAX_EVENT_LENGTH 512 + + static int output_fd; + ++struct tracepoint_path { ++ char *system; ++ char *name; ++ struct tracepoint_path *next; ++}; + + int bigendian(void) + { +@@ -400,6 +408,94 @@ put_tracepoints_path(struct tracepoint_path *tps) + } + } + ++static struct tracepoint_path *tracepoint_id_to_path(u64 config) ++{ ++ struct tracepoint_path *path = NULL; ++ DIR *sys_dir, *evt_dir; ++ struct dirent *sys_dirent, *evt_dirent; ++ char id_buf[24]; ++ int fd; ++ u64 id; ++ char evt_path[MAXPATHLEN]; ++ char *dir_path; ++ ++ sys_dir = tracing_events__opendir(); ++ if (!sys_dir) ++ return NULL; ++ ++ for_each_subsystem(sys_dir, sys_dirent) { ++ dir_path = get_events_file(sys_dirent->d_name); ++ if (!dir_path) ++ continue; ++ evt_dir = opendir(dir_path); ++ if (!evt_dir) ++ goto next; ++ ++ for_each_event(dir_path, evt_dir, evt_dirent) { ++ ++ scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, ++ evt_dirent->d_name); ++ fd = open(evt_path, O_RDONLY); ++ if (fd < 0) ++ continue; ++ if (read(fd, id_buf, sizeof(id_buf)) < 0) { ++ close(fd); ++ continue; ++ } ++ close(fd); ++ id = atoll(id_buf); ++ if (id == config) { ++ put_events_file(dir_path); ++ closedir(evt_dir); ++ closedir(sys_dir); ++ path = zalloc(sizeof(*path)); ++ if (!path) ++ return NULL; ++ if (asprintf(&path->system, "%.*s", ++ MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { ++ free(path); ++ return NULL; ++ } ++ if (asprintf(&path->name, "%.*s", ++ MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { ++ zfree(&path->system); ++ free(path); ++ return NULL; ++ } ++ return path; ++ } ++ } ++ closedir(evt_dir); ++next: ++ put_events_file(dir_path); ++ } ++ ++ closedir(sys_dir); ++ return NULL; ++} ++ ++static struct tracepoint_path *tracepoint_name_to_path(const char *name) ++{ ++ struct tracepoint_path *path = zalloc(sizeof(*path)); ++ char *str = strchr(name, ':'); ++ ++ if (path == NULL || str == NULL) { ++ free(path); ++ return NULL; ++ } ++ ++ path->system = strndup(name, str - name); ++ path->name = strdup(str+1); ++ ++ if (path->system == NULL || path->name == NULL) { ++ zfree(&path->system); ++ zfree(&path->name); ++ zfree(&path); ++ } ++ ++ return path; ++} ++ + static struct tracepoint_path * + get_tracepoints_path(struct list_head *pattrs) + { +diff --git a/tools/perf/util/tracepoint.c b/tools/perf/util/tracepoint.c +new file mode 100644 +index 000000000000..89ef56c43311 +--- /dev/null ++++ b/tools/perf/util/tracepoint.c +@@ -0,0 +1,63 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include "tracepoint.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++int tp_event_has_id(const char *dir_path, struct dirent *evt_dir) ++{ ++ char evt_path[MAXPATHLEN]; ++ int fd; ++ ++ snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, evt_dir->d_name); ++ fd = open(evt_path, O_RDONLY); ++ if (fd < 0) ++ return -EINVAL; ++ close(fd); ++ ++ return 0; ++} ++ ++/* ++ * Check whether event is in /tracing/events ++ */ ++int is_valid_tracepoint(const char *event_string) ++{ ++ DIR *sys_dir, *evt_dir; ++ struct dirent *sys_dirent, *evt_dirent; ++ char evt_path[MAXPATHLEN]; ++ char *dir_path; ++ ++ sys_dir = tracing_events__opendir(); ++ if (!sys_dir) ++ return 0; ++ ++ for_each_subsystem(sys_dir, sys_dirent) { ++ dir_path = get_events_file(sys_dirent->d_name); ++ if (!dir_path) ++ continue; ++ evt_dir = opendir(dir_path); ++ if (!evt_dir) ++ goto next; ++ ++ for_each_event(dir_path, evt_dir, evt_dirent) { ++ snprintf(evt_path, MAXPATHLEN, "%s:%s", ++ sys_dirent->d_name, evt_dirent->d_name); ++ if (!strcmp(evt_path, event_string)) { ++ closedir(evt_dir); ++ closedir(sys_dir); ++ return 1; ++ } ++ } ++ closedir(evt_dir); ++next: ++ put_events_file(dir_path); ++ } ++ closedir(sys_dir); ++ return 0; ++} +diff --git a/tools/perf/util/tracepoint.h b/tools/perf/util/tracepoint.h +new file mode 100644 +index 000000000000..c4a110fe87d7 +--- /dev/null ++++ b/tools/perf/util/tracepoint.h +@@ -0,0 +1,25 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef __PERF_TRACEPOINT_H ++#define __PERF_TRACEPOINT_H ++ ++#include ++#include ++ ++int tp_event_has_id(const char *dir_path, struct dirent *evt_dir); ++ ++#define for_each_event(dir_path, evt_dir, evt_dirent) \ ++ while ((evt_dirent = readdir(evt_dir)) != NULL) \ ++ if (evt_dirent->d_type == DT_DIR && \ ++ (strcmp(evt_dirent->d_name, ".")) && \ ++ (strcmp(evt_dirent->d_name, "..")) && \ ++ (!tp_event_has_id(dir_path, evt_dirent))) ++ ++#define for_each_subsystem(sys_dir, sys_dirent) \ ++ while ((sys_dirent = readdir(sys_dir)) != NULL) \ ++ if (sys_dirent->d_type == DT_DIR && \ ++ (strcmp(sys_dirent->d_name, ".")) && \ ++ (strcmp(sys_dirent->d_name, ".."))) ++ ++int is_valid_tracepoint(const char *event_string); ++ ++#endif /* __PERF_TRACEPOINT_H */ +-- +2.35.1 + diff --git a/queue-5.19/perf-parse-events-remove-not-supported-hybrid-cache-.patch b/queue-5.19/perf-parse-events-remove-not-supported-hybrid-cache-.patch new file mode 100644 index 00000000000..9a68ca6ab4e --- /dev/null +++ b/queue-5.19/perf-parse-events-remove-not-supported-hybrid-cache-.patch @@ -0,0 +1,236 @@ +From 068bb60fb09466ffe23a658e3738f3c42cba141c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Sep 2022 11:00:13 +0800 +Subject: perf parse-events: Remove "not supported" hybrid cache events + +From: Zhengjun Xing + +[ Upstream commit 71c86cda750b001100e0d6dc04a88449b7381a59 ] + +By default, we create two hybrid cache events, one is for cpu_core, and +another is for cpu_atom. But Some hybrid hardware cache events are only +available on one CPU PMU. For example, the 'L1-dcache-load-misses' is only +available on cpu_core, while the 'L1-icache-loads' is only available on +cpu_atom. We need to remove "not supported" hybrid cache events. By +extending is_event_supported() to global API and using it to check if the +hybrid cache events are supported before being created, we can remove the +"not supported" hybrid cache events. + +Before: + + # ./perf stat -e L1-dcache-load-misses,L1-icache-loads -a sleep 1 + + Performance counter stats for 'system wide': + + 52,570 cpu_core/L1-dcache-load-misses/ + cpu_atom/L1-dcache-load-misses/ + cpu_core/L1-icache-loads/ + 1,471,817 cpu_atom/L1-icache-loads/ + + 1.004915229 seconds time elapsed + +After: + + # ./perf stat -e L1-dcache-load-misses,L1-icache-loads -a sleep 1 + + Performance counter stats for 'system wide': + + 54,510 cpu_core/L1-dcache-load-misses/ + 1,441,286 cpu_atom/L1-icache-loads/ + + 1.005114281 seconds time elapsed + +Fixes: 30def61f64bac5f5 ("perf parse-events: Create two hybrid cache events") +Reported-by: Yi Ammy +Reviewed-by: Kan Liang +Signed-off-by: Xing Zhengjun +Acked-by: Ian Rogers +Cc: Alexander Shishkin +Cc: Andi Kleen +Cc: Ingo Molnar +Cc: Jin Yao +Cc: Jiri Olsa +Cc: Namhyung Kim +Cc: Peter Zijlstra +Link: https://lore.kernel.org/r/20220923030013.3726410-2-zhengjun.xing@linux.intel.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/util/parse-events-hybrid.c | 21 ++++++++++++--- + tools/perf/util/parse-events.c | 39 +++++++++++++++++++++++++++ + tools/perf/util/parse-events.h | 1 + + tools/perf/util/print-events.c | 39 --------------------------- + 4 files changed, 57 insertions(+), 43 deletions(-) + +diff --git a/tools/perf/util/parse-events-hybrid.c b/tools/perf/util/parse-events-hybrid.c +index 284f8eabd3b9..7c9f9150bad5 100644 +--- a/tools/perf/util/parse-events-hybrid.c ++++ b/tools/perf/util/parse-events-hybrid.c +@@ -33,7 +33,8 @@ static void config_hybrid_attr(struct perf_event_attr *attr, + * If the PMU type ID is 0, the PERF_TYPE_RAW will be applied. + */ + attr->type = type; +- attr->config = attr->config | ((__u64)pmu_type << PERF_PMU_TYPE_SHIFT); ++ attr->config = (attr->config & PERF_HW_EVENT_MASK) | ++ ((__u64)pmu_type << PERF_PMU_TYPE_SHIFT); + } + + static int create_event_hybrid(__u32 config_type, int *idx, +@@ -48,13 +49,25 @@ static int create_event_hybrid(__u32 config_type, int *idx, + __u64 config = attr->config; + + config_hybrid_attr(attr, config_type, pmu->type); ++ ++ /* ++ * Some hybrid hardware cache events are only available on one CPU ++ * PMU. For example, the 'L1-dcache-load-misses' is only available ++ * on cpu_core, while the 'L1-icache-loads' is only available on ++ * cpu_atom. We need to remove "not supported" hybrid cache events. ++ */ ++ if (attr->type == PERF_TYPE_HW_CACHE ++ && !is_event_supported(attr->type, attr->config)) ++ return 0; ++ + evsel = parse_events__add_event_hybrid(list, idx, attr, name, metric_id, + pmu, config_terms); +- if (evsel) ++ if (evsel) { + evsel->pmu_name = strdup(pmu->name); +- else ++ if (!evsel->pmu_name) ++ return -ENOMEM; ++ } else + return -ENOMEM; +- + attr->type = type; + attr->config = config; + return 0; +diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c +index 3acf7452572c..b51c646c212e 100644 +--- a/tools/perf/util/parse-events.c ++++ b/tools/perf/util/parse-events.c +@@ -29,6 +29,7 @@ + #include "util/parse-events-hybrid.h" + #include "util/pmu-hybrid.h" + #include "tracepoint.h" ++#include "thread_map.h" + + #define MAX_NAME_LEN 100 + +@@ -158,6 +159,44 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { + #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) + #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) + ++bool is_event_supported(u8 type, u64 config) ++{ ++ bool ret = true; ++ int open_return; ++ struct evsel *evsel; ++ struct perf_event_attr attr = { ++ .type = type, ++ .config = config, ++ .disabled = 1, ++ }; ++ struct perf_thread_map *tmap = thread_map__new_by_tid(0); ++ ++ if (tmap == NULL) ++ return false; ++ ++ evsel = evsel__new(&attr); ++ if (evsel) { ++ open_return = evsel__open(evsel, NULL, tmap); ++ ret = open_return >= 0; ++ ++ if (open_return == -EACCES) { ++ /* ++ * This happens if the paranoid value ++ * /proc/sys/kernel/perf_event_paranoid is set to 2 ++ * Re-run with exclude_kernel set; we don't do that ++ * by default as some ARM machines do not support it. ++ * ++ */ ++ evsel->core.attr.exclude_kernel = 1; ++ ret = evsel__open(evsel, NULL, tmap) >= 0; ++ } ++ evsel__delete(evsel); ++ } ++ ++ perf_thread_map__put(tmap); ++ return ret; ++} ++ + const char *event_type(int type) + { + switch (type) { +diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h +index ba9fa3ddaf6e..fd97bb74559e 100644 +--- a/tools/perf/util/parse-events.h ++++ b/tools/perf/util/parse-events.h +@@ -19,6 +19,7 @@ struct option; + struct perf_pmu; + + bool have_tracepoints(struct list_head *evlist); ++bool is_event_supported(u8 type, u64 config); + + const char *event_type(int type); + +diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c +index 04050d4f6db8..c4d5d87fae2f 100644 +--- a/tools/perf/util/print-events.c ++++ b/tools/perf/util/print-events.c +@@ -22,7 +22,6 @@ + #include "probe-file.h" + #include "string2.h" + #include "strlist.h" +-#include "thread_map.h" + #include "tracepoint.h" + #include "pfm.h" + #include "pmu-hybrid.h" +@@ -239,44 +238,6 @@ void print_sdt_events(const char *subsys_glob, const char *event_glob, + strlist__delete(sdtlist); + } + +-static bool is_event_supported(u8 type, u64 config) +-{ +- bool ret = true; +- int open_return; +- struct evsel *evsel; +- struct perf_event_attr attr = { +- .type = type, +- .config = config, +- .disabled = 1, +- }; +- struct perf_thread_map *tmap = thread_map__new_by_tid(0); +- +- if (tmap == NULL) +- return false; +- +- evsel = evsel__new(&attr); +- if (evsel) { +- open_return = evsel__open(evsel, NULL, tmap); +- ret = open_return >= 0; +- +- if (open_return == -EACCES) { +- /* +- * This happens if the paranoid value +- * /proc/sys/kernel/perf_event_paranoid is set to 2 +- * Re-run with exclude_kernel set; we don't do that +- * by default as some ARM machines do not support it. +- * +- */ +- evsel->core.attr.exclude_kernel = 1; +- ret = evsel__open(evsel, NULL, tmap) >= 0; +- } +- evsel__delete(evsel); +- } +- +- perf_thread_map__put(tmap); +- return ret; +-} +- + int print_hwcache_events(const char *event_glob, bool name_only) + { + unsigned int type, op, i, evt_i = 0, evt_num = 0, npmus = 0; +-- +2.35.1 + diff --git a/queue-5.19/perf-print-events-fix-perf-list-can-not-display-the-.patch b/queue-5.19/perf-print-events-fix-perf-list-can-not-display-the-.patch new file mode 100644 index 00000000000..123b920dc43 --- /dev/null +++ b/queue-5.19/perf-print-events-fix-perf-list-can-not-display-the-.patch @@ -0,0 +1,101 @@ +From 0e0b25b2b9a8392a7e0c842cff160f02f3af9dc1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Sep 2022 11:00:12 +0800 +Subject: perf print-events: Fix "perf list" can not display the PMU prefix for + some hybrid cache events + +From: Zhengjun Xing + +[ Upstream commit e28c07871c3f2107e316c2590d4703496bd114f4 ] + +Some hybrid hardware cache events are only available on one CPU PMU. For +example, 'L1-dcache-load-misses' is only available on cpu_core. + +We have supported in the perf list clearly reporting this info, the +function works fine before but recently the argument "config" in API +is_event_supported() is changed from "u64" to "unsigned int" which +caused a regression, the "perf list" then can not display the PMU prefix +for some hybrid cache events. + +For the hybrid systems, the PMU type ID is stored at config[63:32], +define config to "unsigned int" will miss the PMU type ID information, +then the regression happened, the config should be defined as "u64". + +Before: + # ./perf list |grep "Hardware cache event" + L1-dcache-load-misses [Hardware cache event] + L1-dcache-loads [Hardware cache event] + L1-dcache-stores [Hardware cache event] + L1-icache-load-misses [Hardware cache event] + L1-icache-loads [Hardware cache event] + LLC-load-misses [Hardware cache event] + LLC-loads [Hardware cache event] + LLC-store-misses [Hardware cache event] + LLC-stores [Hardware cache event] + branch-load-misses [Hardware cache event] + branch-loads [Hardware cache event] + dTLB-load-misses [Hardware cache event] + dTLB-loads [Hardware cache event] + dTLB-store-misses [Hardware cache event] + dTLB-stores [Hardware cache event] + iTLB-load-misses [Hardware cache event] + node-load-misses [Hardware cache event] + node-loads [Hardware cache event] + +After: + # ./perf list |grep "Hardware cache event" + L1-dcache-loads [Hardware cache event] + L1-dcache-stores [Hardware cache event] + L1-icache-load-misses [Hardware cache event] + LLC-load-misses [Hardware cache event] + LLC-loads [Hardware cache event] + LLC-store-misses [Hardware cache event] + LLC-stores [Hardware cache event] + branch-load-misses [Hardware cache event] + branch-loads [Hardware cache event] + cpu_atom/L1-icache-loads/ [Hardware cache event] + cpu_core/L1-dcache-load-misses/ [Hardware cache event] + cpu_core/node-load-misses/ [Hardware cache event] + cpu_core/node-loads/ [Hardware cache event] + dTLB-load-misses [Hardware cache event] + dTLB-loads [Hardware cache event] + dTLB-store-misses [Hardware cache event] + dTLB-stores [Hardware cache event] + iTLB-load-misses [Hardware cache event] + +Fixes: 9b7c7728f4e4ba8d ("perf parse-events: Break out tracepoint and printing") +Reported-by: Yi Ammy +Reviewed-by: Kan Liang +Signed-off-by: Xing Zhengjun +Acked-by: Ian Rogers +Cc: Alexander Shishkin +Cc: Andi Kleen +Cc: Ian Rogers +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Namhyung Kim +Cc: Peter Zijlstra +Link: https://lore.kernel.org/r/20220923030013.3726410-1-zhengjun.xing@linux.intel.com +Signed-off-by: Arnaldo Carvalho de Melo +Stable-dep-of: 71c86cda750b ("perf parse-events: Remove "not supported" hybrid cache events") +Signed-off-by: Sasha Levin +--- + tools/perf/util/print-events.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c +index ba1ab5134685..04050d4f6db8 100644 +--- a/tools/perf/util/print-events.c ++++ b/tools/perf/util/print-events.c +@@ -239,7 +239,7 @@ void print_sdt_events(const char *subsys_glob, const char *event_glob, + strlist__delete(sdtlist); + } + +-static bool is_event_supported(u8 type, unsigned int config) ++static bool is_event_supported(u8 type, u64 config) + { + bool ret = true; + int open_return; +-- +2.35.1 + diff --git a/queue-5.19/perf-test-fix-test-case-87-perf-record-tests-for-hyb.patch b/queue-5.19/perf-test-fix-test-case-87-perf-record-tests-for-hyb.patch new file mode 100644 index 00000000000..6e79a135423 --- /dev/null +++ b/queue-5.19/perf-test-fix-test-case-87-perf-record-tests-for-hyb.patch @@ -0,0 +1,56 @@ +From 26dd7b925f68e1c5ec94f5370caf374d96fc0355 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 27 Sep 2022 13:15:13 +0800 +Subject: perf test: Fix test case 87 ("perf record tests") for hybrid systems + +From: Zhengjun Xing + +[ Upstream commit 457c8b60267054869513ab1fb5513abb0a566dd0 ] + +The test case 87 ("perf record tests") failed on hybrid systems,the event +"cpu/br_inst_retired.near_call/p" is only for non-hybrid system. Correct +the test event to support both non-hybrid and hybrid systems. + +Before: + + # ./perf test 87 + 87: perf record tests : FAILED! + +After: + + # ./perf test 87 + 87: perf record tests : Ok + +Fixes: 24f378e66021f559 ("perf test: Add basic perf record tests") +Reviewed-by: Kan Liang +Signed-off-by: Xing Zhengjun +Acked-by: Ian Rogers +Cc: Alexander Shishkin +Cc: Andi Kleen +Cc: Ingo Molnar +Cc: Jiri Olsa +Cc: Namhyung Kim +Cc: Peter Zijlstra +Link: https://lore.kernel.org/r/20220927051513.3768717-1-zhengjun.xing@linux.intel.com +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/tests/shell/record.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh +index 00c7285ce1ac..301f95427159 100755 +--- a/tools/perf/tests/shell/record.sh ++++ b/tools/perf/tests/shell/record.sh +@@ -61,7 +61,7 @@ test_register_capture() { + echo "Register capture test [Skipped missing registers]" + return + fi +- if ! perf record -o - --intr-regs=di,r8,dx,cx -e cpu/br_inst_retired.near_call/p \ ++ if ! perf record -o - --intr-regs=di,r8,dx,cx -e br_inst_retired.near_call:p \ + -c 1000 --per-thread true 2> /dev/null \ + | perf script -F ip,sym,iregs -i - 2> /dev/null \ + | egrep -q "DI:" +-- +2.35.1 + diff --git a/queue-5.19/perf-tests-record-fail-the-test-if-the-errs-counter-.patch b/queue-5.19/perf-tests-record-fail-the-test-if-the-errs-counter-.patch new file mode 100644 index 00000000000..ce7bbfa6140 --- /dev/null +++ b/queue-5.19/perf-tests-record-fail-the-test-if-the-errs-counter-.patch @@ -0,0 +1,65 @@ +From 2be3625fcc4a3d9d7344f652fc1fd435f27e7e20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 28 Sep 2022 12:55:43 -0300 +Subject: perf tests record: Fail the test if the 'errs' counter is not zero + +From: Arnaldo Carvalho de Melo + +[ Upstream commit 25c5e67cdf744cbb93fd06647611d3036218debe ] + +We were just checking for the 'err' variable, when we should really see +if there was some of the many checked errors that don't stop the test +right away. + +Detected with clang 15.0.0: + + 44 75.23 fedora:37 : FAIL clang version 15.0.0 (Fedora 15.0.0-2.fc37) + + tests/perf-record.c:68:16: error: variable 'errs' set but not used [-Werror,-Wunused-but-set-variable] + int err = -1, errs = 0, i, wakeups = 0; + ^ + 1 error generated. + +The patch introducing this 'perf test' entry had that check: + + + return (err < 0 || errs > 0) ? -1 : 0; + +But at some point we lost that: + + - return (err < 0 || errs > 0) ? -1 : 0; + + if (err == -EACCES) + + return TEST_SKIP; + + if (err < 0) + + return TEST_FAIL; + + return TEST_OK + +Put it back. + +Fixes: 2cf88f4614c996e5 ("perf test: Use skip in PERF_RECORD_*") +Acked-by: Ian Rogers +Cc: Adrian Hunter +Cc: Jiri Olsa +Cc: Namhyung Kim +Link: https://lore.kernel.org/lkml/YzR0n5QhsH9VyYB0@kernel.org +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Sasha Levin +--- + tools/perf/tests/perf-record.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/tests/perf-record.c b/tools/perf/tests/perf-record.c +index 6a001fcfed68..4952abe716f3 100644 +--- a/tools/perf/tests/perf-record.c ++++ b/tools/perf/tests/perf-record.c +@@ -332,7 +332,7 @@ static int test__PERF_RECORD(struct test_suite *test __maybe_unused, int subtest + out: + if (err == -EACCES) + return TEST_SKIP; +- if (err < 0) ++ if (err < 0 || errs != 0) + return TEST_FAIL; + return TEST_OK; + } +-- +2.35.1 + diff --git a/queue-5.19/reset-imx7-fix-the-imx8mp-pcie-phy-perst-support.patch b/queue-5.19/reset-imx7-fix-the-imx8mp-pcie-phy-perst-support.patch new file mode 100644 index 00000000000..0a2f470489a --- /dev/null +++ b/queue-5.19/reset-imx7-fix-the-imx8mp-pcie-phy-perst-support.patch @@ -0,0 +1,44 @@ +From aec760f79a9c3313e605b5d0fbab5671065ec6e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Aug 2022 15:46:01 +0800 +Subject: reset: imx7: Fix the iMX8MP PCIe PHY PERST support + +From: Richard Zhu + +[ Upstream commit 051d9eb403887bb11852b7a4f744728a6a4b1b58 ] + +On i.MX7/iMX8MM/iMX8MQ, the initialized default value of PERST bit(BIT3) +of SRC_PCIEPHY_RCR is 1b'1. +But i.MX8MP has one inversed default value 1b'0 of PERST bit. + +And the PERST bit should be kept 1b'1 after power and clocks are stable. +So fix the i.MX8MP PCIe PHY PERST support here. + +Fixes: e08672c03981 ("reset: imx7: Add support for i.MX8MP SoC") +Signed-off-by: Richard Zhu +Reviewed-by: Philipp Zabel +Tested-by: Marek Vasut +Tested-by: Richard Leitner +Tested-by: Alexander Stein +Signed-off-by: Philipp Zabel +Link: https://lore.kernel.org/r/1661845564-11373-5-git-send-email-hongxing.zhu@nxp.com +Signed-off-by: Sasha Levin +--- + drivers/reset/reset-imx7.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/reset/reset-imx7.c b/drivers/reset/reset-imx7.c +index 185a333df66c..d2408725eb2c 100644 +--- a/drivers/reset/reset-imx7.c ++++ b/drivers/reset/reset-imx7.c +@@ -329,6 +329,7 @@ static int imx8mp_reset_set(struct reset_controller_dev *rcdev, + break; + + case IMX8MP_RESET_PCIE_CTRL_APPS_EN: ++ case IMX8MP_RESET_PCIEPHY_PERST: + value = assert ? 0 : bit; + break; + } +-- +2.35.1 + diff --git a/queue-5.19/revert-drm-bridge-analogix-dp-add-panel-prepare-unpr.patch b/queue-5.19/revert-drm-bridge-analogix-dp-add-panel-prepare-unpr.patch new file mode 100644 index 00000000000..58e46ff61e9 --- /dev/null +++ b/queue-5.19/revert-drm-bridge-analogix-dp-add-panel-prepare-unpr.patch @@ -0,0 +1,88 @@ +From 1fc5e5879ca4422e69268b8e6a20c7069d0b53a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Aug 2022 18:08:04 -0700 +Subject: Revert "drm: bridge: analogix/dp: add panel prepare/unprepare in + suspend/resume time" + +From: Brian Norris + +[ Upstream commit cc62d98bd56d45de4531844ca23913a15136c05b ] + +This reverts commit 211f276ed3d96e964d2d1106a198c7f4a4b3f4c0. + +For quite some time, core DRM helpers already ensure that any relevant +connectors/CRTCs/etc. are disabled, as well as their associated +components (e.g., bridges) when suspending the system. Thus, +analogix_dp_bridge_{enable,disable}() already get called, which in turn +call drm_panel_{prepare,unprepare}(). This makes these drm_panel_*() +calls redundant. + +Besides redundancy, there are a few problems with this handling: + +(1) drm_panel_{prepare,unprepare}() are *not* reference-counted APIs and +are not in general designed to be handled by multiple callers -- +although some panel drivers have a coarse 'prepared' flag that mitigates +some damage, at least. So at a minimum this is redundant and confusing, +but in some cases, this could be actively harmful. + +(2) The error-handling is a bit non-standard. We ignored errors in +suspend(), but handled errors in resume(). And recently, people noticed +that the clk handling is unbalanced in error paths, and getting *that* +right is not actually trivial, given the current way errors are mostly +ignored. + +(3) In the particular way analogix_dp_{suspend,resume}() get used (e.g., +in rockchip_dp_*(), as a late/early callback), we don't necessarily have +a proper PM relationship between the DP/bridge device and the panel +device. So while the DP bridge gets resumed, the panel's parent device +(e.g., platform_device) may still be suspended, and so any prepare() +calls may fail. + +So remove the superfluous, possibly-harmful suspend()/resume() handling +of panel state. + +Fixes: 211f276ed3d9 ("drm: bridge: analogix/dp: add panel prepare/unprepare in suspend/resume time") +Link: https://lore.kernel.org/all/Yv2CPBD3Picg%2FgVe@google.com/ +Signed-off-by: Brian Norris +Reviewed-by: Douglas Anderson +Signed-off-by: Douglas Anderson +Link: https://patchwork.freedesktop.org/patch/msgid/20220822180729.1.I8ac5abe3a4c1c6fd5c061686c6e883c22f69022c@changeid +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 13 ------------- + 1 file changed, 13 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +index 01c8b80e34ec..41431b9d55bd 100644 +--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c ++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +@@ -1863,12 +1863,6 @@ EXPORT_SYMBOL_GPL(analogix_dp_remove); + int analogix_dp_suspend(struct analogix_dp_device *dp) + { + clk_disable_unprepare(dp->clock); +- +- if (dp->plat_data->panel) { +- if (drm_panel_unprepare(dp->plat_data->panel)) +- DRM_ERROR("failed to turnoff the panel\n"); +- } +- + return 0; + } + EXPORT_SYMBOL_GPL(analogix_dp_suspend); +@@ -1883,13 +1877,6 @@ int analogix_dp_resume(struct analogix_dp_device *dp) + return ret; + } + +- if (dp->plat_data->panel) { +- if (drm_panel_prepare(dp->plat_data->panel)) { +- DRM_ERROR("failed to setup the panel\n"); +- return -EBUSY; +- } +- } +- + return 0; + } + EXPORT_SYMBOL_GPL(analogix_dp_resume); +-- +2.35.1 + diff --git a/queue-5.19/selftests-fix-the-if-conditions-of-in-test_extra_fil.patch b/queue-5.19/selftests-fix-the-if-conditions-of-in-test_extra_fil.patch new file mode 100644 index 00000000000..0c5bf3c65d3 --- /dev/null +++ b/queue-5.19/selftests-fix-the-if-conditions-of-in-test_extra_fil.patch @@ -0,0 +1,37 @@ +From 7c3214bcc3823e45077662c0fbe970ab2caaef19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Sep 2022 15:02:37 +0800 +Subject: selftests: Fix the if conditions of in test_extra_filter() + +From: Wang Yufen + +[ Upstream commit bc7a319844891746135dc1f34ab9df78d636a3ac ] + +The socket 2 bind the addr in use, bind should fail with EADDRINUSE. So +if bind success or errno != EADDRINUSE, testcase should be failed. + +Fixes: 3ca8e4029969 ("soreuseport: BPF selection functional test") +Signed-off-by: Wang Yufen +Link: https://lore.kernel.org/r/1663916557-10730-1-git-send-email-wangyufen@huawei.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/net/reuseport_bpf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/net/reuseport_bpf.c b/tools/testing/selftests/net/reuseport_bpf.c +index 072d709c96b4..65aea27d761c 100644 +--- a/tools/testing/selftests/net/reuseport_bpf.c ++++ b/tools/testing/selftests/net/reuseport_bpf.c +@@ -328,7 +328,7 @@ static void test_extra_filter(const struct test_params p) + if (bind(fd1, addr, sockaddr_size())) + error(1, errno, "failed to bind recv socket 1"); + +- if (!bind(fd2, addr, sockaddr_size()) && errno != EADDRINUSE) ++ if (!bind(fd2, addr, sockaddr_size()) || errno != EADDRINUSE) + error(1, errno, "bind socket 2 should fail with EADDRINUSE"); + + free(addr); +-- +2.35.1 + diff --git a/queue-5.19/series b/queue-5.19/series index 1941e3183f3..1cd733f2fc1 100644 --- a/queue-5.19/series +++ b/queue-5.19/series @@ -48,3 +48,51 @@ media-dvb_vb2-fix-possible-out-of-bound-access.patch media-rkvdec-disable-h.264-error-detection.patch media-mediatek-vcodec-drop-platform_get_resource-ioresource_irq.patch media-v4l2-compat-ioctl32.c-zero-buffer-passed-to-v4l2_compat_get_array_args.patch +arm-dts-am33xx-fix-mmchs0-dma-properties.patch +reset-imx7-fix-the-imx8mp-pcie-phy-perst-support.patch +arm-dts-am5748-keep-usb4_tm-disabled.patch +soc-sunxi-sram-actually-claim-sram-regions.patch +soc-sunxi-sram-prevent-the-driver-from-being-unbound.patch +soc-sunxi-sram-fix-probe-function-ordering-issues.patch +soc-sunxi-sram-fix-debugfs-info-for-a64-sram-c.patch +asoc-imx-card-fix-refcount-issue-with-of_node_put.patch +clk-microchip-mpfs-fix-clk_cfg-array-bounds-violatio.patch +clk-microchip-mpfs-make-the-rtc-s-ahb-clock-critical.patch +arm64-dts-qcom-sm8350-fix-ufs-phy-serdes-size.patch +asoc-tas2770-reinit-regcache-on-reset.patch +drm-bridge-lt8912b-add-vsync-hsync.patch +drm-bridge-lt8912b-set-hdmi-or-dvi-mode.patch +drm-bridge-lt8912b-fix-corrupted-image-output.patch +net-macb-fix-zynqmp-sgmii-non-wakeup-source-resume-f.patch +revert-drm-bridge-analogix-dp-add-panel-prepare-unpr.patch +input-melfas_mip4-fix-return-value-check-in-mip4_pro.patch +gpio-mvebu-fix-check-for-pwm-support-on-non-a8k-plat.patch +perf-parse-events-break-out-tracepoint-and-printing.patch +perf-print-events-fix-perf-list-can-not-display-the-.patch +perf-parse-events-remove-not-supported-hybrid-cache-.patch +usbnet-fix-memory-leak-in-usbnet_disconnect.patch +net-sched-act_ct-fix-possible-refcount-leak-in-tcf_c.patch +cxgb4-fix-missing-unlock-on-ethofld-desc-collect-fai.patch +net-mlxbf_gige-fix-an-is_err-vs-null-bug-in-mlxbf_gi.patch +nvme-fix-ioc_pr_clear-and-ioc_pr_release-ioctls-for-.patch +wifi-cfg80211-fix-mcs-divisor-value.patch +wifi-mac80211-fix-regression-with-non-qos-drivers.patch +wifi-mac80211-fix-memory-corruption-in-minstrel_ht_u.patch +net-stmmac-power-up-down-serdes-in-stmmac_open-relea.patch +net-phy-don-t-warn-for-phy_up-state-in-mdio_bus_phy_.patch +selftests-fix-the-if-conditions-of-in-test_extra_fil.patch +ice-xsk-change-batched-tx-descriptor-cleaning.patch +ice-xsk-drop-power-of-2-ring-size-restriction-for-af.patch +vdpa-ifcvf-fix-the-calculation-of-queuepair.patch +virtio-blk-fix-warn_on_once-in-virtio_queue_rq.patch +vdpa-mlx5-fix-mq-to-support-non-power-of-two-num-que.patch +don-t-use-__kernel_write-on-kmap_local_page.patch +clk-imx-imx6sx-remove-the-set_rate_parent-flag-for-q.patch +drm-i915-gt-perf_limit_reasons-are-only-available-fo.patch +clk-iproc-do-not-rely-on-node-name-for-correct-pll-s.patch +clk-imx93-drop-of_match_ptr.patch +net-mscc-ocelot-fix-tagged-vlan-refusal-while-under-.patch +net-ethernet-mtk_eth_soc-fix-mask-of-rx_dma_get_spor.patch +perf-test-fix-test-case-87-perf-record-tests-for-hyb.patch +perf-tests-record-fail-the-test-if-the-errs-counter-.patch +kvm-x86-hide-ia32_platform_dca_cap-31-0-from-the-gue.patch diff --git a/queue-5.19/soc-sunxi-sram-actually-claim-sram-regions.patch b/queue-5.19/soc-sunxi-sram-actually-claim-sram-regions.patch new file mode 100644 index 00000000000..8e1d1f21ff6 --- /dev/null +++ b/queue-5.19/soc-sunxi-sram-actually-claim-sram-regions.patch @@ -0,0 +1,40 @@ +From dcb34d96025f1835ee0d9b36a15378024eed7fbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Aug 2022 23:12:40 -0500 +Subject: soc: sunxi: sram: Actually claim SRAM regions + +From: Samuel Holland + +[ Upstream commit fd362baad2e659ef0fb5652f023a606b248f1781 ] + +sunxi_sram_claim() checks the sram_desc->claimed flag before updating +the register, with the intent that only one device can claim a region. +However, this was ineffective because the flag was never set. + +Fixes: 4af34b572a85 ("drivers: soc: sunxi: Introduce SoC driver to map SRAMs") +Reviewed-by: Jernej Skrabec +Signed-off-by: Samuel Holland +Reviewed-by: Heiko Stuebner +Tested-by: Heiko Stuebner +Signed-off-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20220815041248.53268-4-samuel@sholland.org +Signed-off-by: Sasha Levin +--- + drivers/soc/sunxi/sunxi_sram.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c +index a8f3876963a0..f3d3f9259df9 100644 +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -254,6 +254,7 @@ int sunxi_sram_claim(struct device *dev) + writel(val | ((device << sram_data->offset) & mask), + base + sram_data->reg); + ++ sram_desc->claimed = true; + spin_unlock(&sram_lock); + + return 0; +-- +2.35.1 + diff --git a/queue-5.19/soc-sunxi-sram-fix-debugfs-info-for-a64-sram-c.patch b/queue-5.19/soc-sunxi-sram-fix-debugfs-info-for-a64-sram-c.patch new file mode 100644 index 00000000000..58ea440b12f --- /dev/null +++ b/queue-5.19/soc-sunxi-sram-fix-debugfs-info-for-a64-sram-c.patch @@ -0,0 +1,40 @@ +From 97aa423aed1cc98e02d5b20acd38780dc01a5928 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Aug 2022 23:12:43 -0500 +Subject: soc: sunxi: sram: Fix debugfs info for A64 SRAM C + +From: Samuel Holland + +[ Upstream commit e3c95edb1bd8b9c2cb0caa6ae382fc8080f6a0ed ] + +The labels were backward with respect to the register values. The SRAM +is mapped to the CPU when the register value is 1. + +Fixes: 5e4fb6429761 ("drivers: soc: sunxi: add support for A64 and its SRAM C") +Acked-by: Jernej Skrabec +Signed-off-by: Samuel Holland +Signed-off-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20220815041248.53268-7-samuel@sholland.org +Signed-off-by: Sasha Levin +--- + drivers/soc/sunxi/sunxi_sram.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c +index 52d07bed7664..09754cd1d57d 100644 +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -78,8 +78,8 @@ static struct sunxi_sram_desc sun4i_a10_sram_d = { + + static struct sunxi_sram_desc sun50i_a64_sram_c = { + .data = SUNXI_SRAM_DATA("C", 0x4, 24, 1, +- SUNXI_SRAM_MAP(0, 1, "cpu"), +- SUNXI_SRAM_MAP(1, 0, "de2")), ++ SUNXI_SRAM_MAP(1, 0, "cpu"), ++ SUNXI_SRAM_MAP(0, 1, "de2")), + }; + + static const struct of_device_id sunxi_sram_dt_ids[] = { +-- +2.35.1 + diff --git a/queue-5.19/soc-sunxi-sram-fix-probe-function-ordering-issues.patch b/queue-5.19/soc-sunxi-sram-fix-probe-function-ordering-issues.patch new file mode 100644 index 00000000000..497c04ed9a7 --- /dev/null +++ b/queue-5.19/soc-sunxi-sram-fix-probe-function-ordering-issues.patch @@ -0,0 +1,74 @@ +From dc3b5f0fb39694bcb32d04ccecf9c0c6f8a24332 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Aug 2022 23:12:42 -0500 +Subject: soc: sunxi: sram: Fix probe function ordering issues + +From: Samuel Holland + +[ Upstream commit 49fad91a7b8941979c3e9a35f9894ac45bc5d3d6 ] + +Errors from debugfs are intended to be non-fatal, and should not prevent +the driver from probing. + +Since debugfs file creation is treated as infallible, move it below the +parts of the probe function that can fail. This prevents an error +elsewhere in the probe function from causing the file to leak. Do the +same for the call to of_platform_populate(). + +Finally, checkpatch suggests an octal literal for the file permissions. + +Fixes: 4af34b572a85 ("drivers: soc: sunxi: Introduce SoC driver to map SRAMs") +Fixes: 5828729bebbb ("soc: sunxi: export a regmap for EMAC clock reg on A64") +Reviewed-by: Jernej Skrabec +Signed-off-by: Samuel Holland +Tested-by: Heiko Stuebner +Signed-off-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20220815041248.53268-6-samuel@sholland.org +Signed-off-by: Sasha Levin +--- + drivers/soc/sunxi/sunxi_sram.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c +index a858a37fcdd4..52d07bed7664 100644 +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -332,9 +332,9 @@ static struct regmap_config sunxi_sram_emac_clock_regmap = { + + static int __init sunxi_sram_probe(struct platform_device *pdev) + { +- struct dentry *d; + struct regmap *emac_clock; + const struct sunxi_sramc_variant *variant; ++ struct device *dev = &pdev->dev; + + sram_dev = &pdev->dev; + +@@ -346,13 +346,6 @@ static int __init sunxi_sram_probe(struct platform_device *pdev) + if (IS_ERR(base)) + return PTR_ERR(base); + +- of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); +- +- d = debugfs_create_file("sram", S_IRUGO, NULL, NULL, +- &sunxi_sram_fops); +- if (!d) +- return -ENOMEM; +- + if (variant->num_emac_clocks > 0) { + emac_clock = devm_regmap_init_mmio(&pdev->dev, base, + &sunxi_sram_emac_clock_regmap); +@@ -361,6 +354,10 @@ static int __init sunxi_sram_probe(struct platform_device *pdev) + return PTR_ERR(emac_clock); + } + ++ of_platform_populate(dev->of_node, NULL, NULL, dev); ++ ++ debugfs_create_file("sram", 0444, NULL, NULL, &sunxi_sram_fops); ++ + return 0; + } + +-- +2.35.1 + diff --git a/queue-5.19/soc-sunxi-sram-prevent-the-driver-from-being-unbound.patch b/queue-5.19/soc-sunxi-sram-prevent-the-driver-from-being-unbound.patch new file mode 100644 index 00000000000..b4ad33fa7c4 --- /dev/null +++ b/queue-5.19/soc-sunxi-sram-prevent-the-driver-from-being-unbound.patch @@ -0,0 +1,53 @@ +From 3f9a71e17bad10e1d4cb38e330e11c5b09cef9aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Aug 2022 23:12:41 -0500 +Subject: soc: sunxi: sram: Prevent the driver from being unbound + +From: Samuel Holland + +[ Upstream commit 90e10a1fcd9b24b4ba8c0d35136127473dcd829e ] + +This driver exports a regmap tied to the platform device (as opposed to +a syscon, which exports a regmap tied to the OF node). Because of this, +the driver can never be unbound, as that would destroy the regmap. Use +builtin_platform_driver_probe() to enforce this limitation. + +Fixes: 5828729bebbb ("soc: sunxi: export a regmap for EMAC clock reg on A64") +Reviewed-by: Jernej Skrabec +Signed-off-by: Samuel Holland +Reviewed-by: Heiko Stuebner +Tested-by: Heiko Stuebner +Signed-off-by: Jernej Skrabec +Link: https://lore.kernel.org/r/20220815041248.53268-5-samuel@sholland.org +Signed-off-by: Sasha Levin +--- + drivers/soc/sunxi/sunxi_sram.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/soc/sunxi/sunxi_sram.c b/drivers/soc/sunxi/sunxi_sram.c +index f3d3f9259df9..a858a37fcdd4 100644 +--- a/drivers/soc/sunxi/sunxi_sram.c ++++ b/drivers/soc/sunxi/sunxi_sram.c +@@ -330,7 +330,7 @@ static struct regmap_config sunxi_sram_emac_clock_regmap = { + .writeable_reg = sunxi_sram_regmap_accessible_reg, + }; + +-static int sunxi_sram_probe(struct platform_device *pdev) ++static int __init sunxi_sram_probe(struct platform_device *pdev) + { + struct dentry *d; + struct regmap *emac_clock; +@@ -410,9 +410,8 @@ static struct platform_driver sunxi_sram_driver = { + .name = "sunxi-sram", + .of_match_table = sunxi_sram_dt_match, + }, +- .probe = sunxi_sram_probe, + }; +-module_platform_driver(sunxi_sram_driver); ++builtin_platform_driver_probe(sunxi_sram_driver, sunxi_sram_probe); + + MODULE_AUTHOR("Maxime Ripard "); + MODULE_DESCRIPTION("Allwinner sunXi SRAM Controller Driver"); +-- +2.35.1 + diff --git a/queue-5.19/usbnet-fix-memory-leak-in-usbnet_disconnect.patch b/queue-5.19/usbnet-fix-memory-leak-in-usbnet_disconnect.patch new file mode 100644 index 00000000000..8474f553446 --- /dev/null +++ b/queue-5.19/usbnet-fix-memory-leak-in-usbnet_disconnect.patch @@ -0,0 +1,56 @@ +From 274f2dc6e10bfdba2bb1f3ef3176ad24384c8997 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Sep 2022 21:25:51 -0700 +Subject: usbnet: Fix memory leak in usbnet_disconnect() + +From: Peilin Ye + +[ Upstream commit a43206156263fbaf1f2b7f96257441f331e91bb7 ] + +Currently usbnet_disconnect() unanchors and frees all deferred URBs +using usb_scuttle_anchored_urbs(), which does not free urb->context, +causing a memory leak as reported by syzbot. + +Use a usb_get_from_anchor() while loop instead, similar to what we did +in commit 19cfe912c37b ("Bluetooth: btusb: Fix memory leak in +play_deferred"). Also free urb->sg. + +Reported-and-tested-by: syzbot+dcd3e13cf4472f2e0ba1@syzkaller.appspotmail.com +Fixes: 69ee472f2706 ("usbnet & cdc-ether: Autosuspend for online devices") +Fixes: 638c5115a794 ("USBNET: support DMA SG") +Signed-off-by: Peilin Ye +Link: https://lore.kernel.org/r/20220923042551.2745-1-yepeilin.cs@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/usb/usbnet.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c +index 0ed09bb91c44..bccf63aac6cd 100644 +--- a/drivers/net/usb/usbnet.c ++++ b/drivers/net/usb/usbnet.c +@@ -1601,6 +1601,7 @@ void usbnet_disconnect (struct usb_interface *intf) + struct usbnet *dev; + struct usb_device *xdev; + struct net_device *net; ++ struct urb *urb; + + dev = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); +@@ -1617,7 +1618,11 @@ void usbnet_disconnect (struct usb_interface *intf) + net = dev->net; + unregister_netdev (net); + +- usb_scuttle_anchored_urbs(&dev->deferred); ++ while ((urb = usb_get_from_anchor(&dev->deferred))) { ++ dev_kfree_skb(urb->context); ++ kfree(urb->sg); ++ usb_free_urb(urb); ++ } + + if (dev->driver_info->unbind) + dev->driver_info->unbind(dev, intf); +-- +2.35.1 + diff --git a/queue-5.19/vdpa-ifcvf-fix-the-calculation-of-queuepair.patch b/queue-5.19/vdpa-ifcvf-fix-the-calculation-of-queuepair.patch new file mode 100644 index 00000000000..60352bd31ae --- /dev/null +++ b/queue-5.19/vdpa-ifcvf-fix-the-calculation-of-queuepair.patch @@ -0,0 +1,49 @@ +From 810df6c2e953bb028e80c13d9ce925ca7906646f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 23 Sep 2022 17:10:13 +0800 +Subject: vdpa/ifcvf: fix the calculation of queuepair + +From: Angus Chen + +[ Upstream commit db5db1a00d0816207be3a0166fcb4f523eaf3b52 ] + +The q_pair_id to address a queue pair in the lm bar should be +calculated by queue_id / 2 rather than queue_id / nr_vring. + +Fixes: 2ddae773c93b ("vDPA/ifcvf: detect and use the onboard number of queues directly") +Signed-off-by: Angus Chen +Reviewed-by: Jason Wang +Reviewed-by: Michael S. Tsirkin +Acked-by: Zhu Lingshan +Message-Id: <20220923091013.191-1-angus.chen@jaguarmicro.com> +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + drivers/vdpa/ifcvf/ifcvf_base.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/vdpa/ifcvf/ifcvf_base.c b/drivers/vdpa/ifcvf/ifcvf_base.c +index 48c4dadb0c7c..a4c1b985f79a 100644 +--- a/drivers/vdpa/ifcvf/ifcvf_base.c ++++ b/drivers/vdpa/ifcvf/ifcvf_base.c +@@ -315,7 +315,7 @@ u16 ifcvf_get_vq_state(struct ifcvf_hw *hw, u16 qid) + u32 q_pair_id; + + ifcvf_lm = (struct ifcvf_lm_cfg __iomem *)hw->lm_cfg; +- q_pair_id = qid / hw->nr_vring; ++ q_pair_id = qid / 2; + avail_idx_addr = &ifcvf_lm->vring_lm_cfg[q_pair_id].idx_addr[qid % 2]; + last_avail_idx = vp_ioread16(avail_idx_addr); + +@@ -329,7 +329,7 @@ int ifcvf_set_vq_state(struct ifcvf_hw *hw, u16 qid, u16 num) + u32 q_pair_id; + + ifcvf_lm = (struct ifcvf_lm_cfg __iomem *)hw->lm_cfg; +- q_pair_id = qid / hw->nr_vring; ++ q_pair_id = qid / 2; + avail_idx_addr = &ifcvf_lm->vring_lm_cfg[q_pair_id].idx_addr[qid % 2]; + hw->vring[qid].last_avail_idx = num; + vp_iowrite16(num, avail_idx_addr); +-- +2.35.1 + diff --git a/queue-5.19/vdpa-mlx5-fix-mq-to-support-non-power-of-two-num-que.patch b/queue-5.19/vdpa-mlx5-fix-mq-to-support-non-power-of-two-num-que.patch new file mode 100644 index 00000000000..4d75864f65d --- /dev/null +++ b/queue-5.19/vdpa-mlx5-fix-mq-to-support-non-power-of-two-num-que.patch @@ -0,0 +1,103 @@ +From 776038975f95f955f4d30505f582ec2e0e1d66c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 12 Sep 2022 15:50:19 +0300 +Subject: vdpa/mlx5: Fix MQ to support non power of two num queues + +From: Eli Cohen + +[ Upstream commit a43ae8057cc154fd26a3a23c0e8643bef104d995 ] + +RQT objects require that a power of two value be configured for both +rqt_max_size and rqt_actual size. + +For create_rqt, make sure to round up to the power of two the value of +given by the user who created the vdpa device and given by +ndev->rqt_size. The actual size is also rounded up to the power of two +using the current number of VQs given by ndev->cur_num_vqs. + +Same goes with modify_rqt where we need to make sure act size is power +of two based on the new number of QPs. + +Without this patch, attempt to create a device with non power of two QPs +would result in error from firmware. + +Fixes: 52893733f2c5 ("vdpa/mlx5: Add multiqueue support") +Signed-off-by: Eli Cohen +Message-Id: <20220912125019.833708-1-elic@nvidia.com> +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + drivers/vdpa/mlx5/net/mlx5_vnet.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c +index e85c1d71f4ed..f527cbeb1169 100644 +--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c ++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c +@@ -1297,6 +1297,8 @@ static void teardown_vq(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtqueue * + + static int create_rqt(struct mlx5_vdpa_net *ndev) + { ++ int rqt_table_size = roundup_pow_of_two(ndev->rqt_size); ++ int act_sz = roundup_pow_of_two(ndev->cur_num_vqs / 2); + __be32 *list; + void *rqtc; + int inlen; +@@ -1304,7 +1306,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev) + int i, j; + int err; + +- inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + ndev->rqt_size * MLX5_ST_SZ_BYTES(rq_num); ++ inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + rqt_table_size * MLX5_ST_SZ_BYTES(rq_num); + in = kzalloc(inlen, GFP_KERNEL); + if (!in) + return -ENOMEM; +@@ -1313,12 +1315,12 @@ static int create_rqt(struct mlx5_vdpa_net *ndev) + rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context); + + MLX5_SET(rqtc, rqtc, list_q_type, MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q); +- MLX5_SET(rqtc, rqtc, rqt_max_size, ndev->rqt_size); ++ MLX5_SET(rqtc, rqtc, rqt_max_size, rqt_table_size); + list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]); +- for (i = 0, j = 0; i < ndev->rqt_size; i++, j += 2) ++ for (i = 0, j = 0; i < act_sz; i++, j += 2) + list[i] = cpu_to_be32(ndev->vqs[j % ndev->cur_num_vqs].virtq_id); + +- MLX5_SET(rqtc, rqtc, rqt_actual_size, ndev->rqt_size); ++ MLX5_SET(rqtc, rqtc, rqt_actual_size, act_sz); + err = mlx5_vdpa_create_rqt(&ndev->mvdev, in, inlen, &ndev->res.rqtn); + kfree(in); + if (err) +@@ -1331,6 +1333,7 @@ static int create_rqt(struct mlx5_vdpa_net *ndev) + + static int modify_rqt(struct mlx5_vdpa_net *ndev, int num) + { ++ int act_sz = roundup_pow_of_two(num / 2); + __be32 *list; + void *rqtc; + int inlen; +@@ -1338,7 +1341,7 @@ static int modify_rqt(struct mlx5_vdpa_net *ndev, int num) + int i, j; + int err; + +- inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + ndev->rqt_size * MLX5_ST_SZ_BYTES(rq_num); ++ inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + act_sz * MLX5_ST_SZ_BYTES(rq_num); + in = kzalloc(inlen, GFP_KERNEL); + if (!in) + return -ENOMEM; +@@ -1349,10 +1352,10 @@ static int modify_rqt(struct mlx5_vdpa_net *ndev, int num) + MLX5_SET(rqtc, rqtc, list_q_type, MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q); + + list = MLX5_ADDR_OF(rqtc, rqtc, rq_num[0]); +- for (i = 0, j = 0; i < ndev->rqt_size; i++, j += 2) ++ for (i = 0, j = 0; i < act_sz; i++, j = j + 2) + list[i] = cpu_to_be32(ndev->vqs[j % num].virtq_id); + +- MLX5_SET(rqtc, rqtc, rqt_actual_size, ndev->rqt_size); ++ MLX5_SET(rqtc, rqtc, rqt_actual_size, act_sz); + err = mlx5_vdpa_modify_rqt(&ndev->mvdev, in, inlen, ndev->res.rqtn); + kfree(in); + if (err) +-- +2.35.1 + diff --git a/queue-5.19/virtio-blk-fix-warn_on_once-in-virtio_queue_rq.patch b/queue-5.19/virtio-blk-fix-warn_on_once-in-virtio_queue_rq.patch new file mode 100644 index 00000000000..65af62b2f1b --- /dev/null +++ b/queue-5.19/virtio-blk-fix-warn_on_once-in-virtio_queue_rq.patch @@ -0,0 +1,149 @@ +From 4e24240c6bbfa754e2c81771f09e16d663ec7f63 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 31 Aug 2022 00:01:53 +0900 +Subject: virtio-blk: Fix WARN_ON_ONCE in virtio_queue_rq() + +From: Suwan Kim + +[ Upstream commit 37fafe6b61e4f15d977982635bb785f4e605f7cd ] + +If a request fails at virtio_queue_rqs(), it is inserted to requeue_list +and passed to virtio_queue_rq(). Then blk_mq_start_request() can be called +again at virtio_queue_rq() and trigger WARN_ON_ONCE like below trace because +request state was already set to MQ_RQ_IN_FLIGHT in virtio_queue_rqs() +despite the failure. + +[ 1.890468] ------------[ cut here ]------------ +[ 1.890776] WARNING: CPU: 2 PID: 122 at block/blk-mq.c:1143 +blk_mq_start_request+0x8a/0xe0 +[ 1.891045] Modules linked in: +[ 1.891250] CPU: 2 PID: 122 Comm: journal-offline Not tainted 5.19.0+ #44 +[ 1.891504] Hardware name: ChromiumOS crosvm, BIOS 0 +[ 1.891739] RIP: 0010:blk_mq_start_request+0x8a/0xe0 +[ 1.891961] Code: 12 80 74 22 48 8b 4b 10 8b 89 64 01 00 00 8b 53 +20 83 fa ff 75 08 ba 00 00 00 80 0b 53 24 c1 e1 10 09 d1 89 48 34 5b +41 5e c3 <0f> 0b eb b8 65 8b 05 2b 39 b6 7e 89 c0 48 0f a3 05 39 77 5b +01 0f +[ 1.892443] RSP: 0018:ffffc900002777b0 EFLAGS: 00010202 +[ 1.892673] RAX: 0000000000000000 RBX: ffff888004bc0000 RCX: 0000000000000000 +[ 1.892952] RDX: 0000000000000000 RSI: ffff888003d7c200 RDI: ffff888004bc0000 +[ 1.893228] RBP: 0000000000000000 R08: 0000000000000001 R09: ffff888004bc0100 +[ 1.893506] R10: ffffffffffffffff R11: ffffffff8185ca10 R12: ffff888004bc0000 +[ 1.893797] R13: ffffc90000277900 R14: ffff888004ab2340 R15: ffff888003d86e00 +[ 1.894060] FS: 00007ffa143a4640(0000) GS:ffff88807dd00000(0000) +knlGS:0000000000000000 +[ 1.894412] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 1.894682] CR2: 00005648577d9088 CR3: 00000000053da004 CR4: 0000000000170ee0 +[ 1.894953] Call Trace: +[ 1.895139] +[ 1.895303] virtblk_prep_rq+0x1e5/0x280 +[ 1.895509] virtio_queue_rq+0x5c/0x310 +[ 1.895710] ? virtqueue_add_sgs+0x95/0xb0 +[ 1.895905] ? _raw_spin_unlock_irqrestore+0x16/0x30 +[ 1.896133] ? virtio_queue_rqs+0x340/0x390 +[ 1.896453] ? sbitmap_get+0xfa/0x220 +[ 1.896678] __blk_mq_issue_directly+0x41/0x180 +[ 1.896906] blk_mq_plug_issue_direct+0xd8/0x2c0 +[ 1.897115] blk_mq_flush_plug_list+0x115/0x180 +[ 1.897342] blk_add_rq_to_plug+0x51/0x130 +[ 1.897543] blk_mq_submit_bio+0x3a1/0x570 +[ 1.897750] submit_bio_noacct_nocheck+0x418/0x520 +[ 1.897985] ? submit_bio_noacct+0x1e/0x260 +[ 1.897989] ext4_bio_write_page+0x222/0x420 +[ 1.898000] mpage_process_page_bufs+0x178/0x1c0 +[ 1.899451] mpage_prepare_extent_to_map+0x2d2/0x440 +[ 1.899603] ext4_writepages+0x495/0x1020 +[ 1.899733] do_writepages+0xcb/0x220 +[ 1.899871] ? __seccomp_filter+0x171/0x7e0 +[ 1.900006] file_write_and_wait_range+0xcd/0xf0 +[ 1.900167] ext4_sync_file+0x72/0x320 +[ 1.900308] __x64_sys_fsync+0x66/0xa0 +[ 1.900449] do_syscall_64+0x31/0x50 +[ 1.900595] entry_SYSCALL_64_after_hwframe+0x63/0xcd +[ 1.900747] RIP: 0033:0x7ffa16ec96ea +[ 1.900883] Code: b8 4a 00 00 00 0f 05 48 3d 00 f0 ff ff 77 41 c3 +48 83 ec 18 89 7c 24 0c e8 e3 02 f8 ff 8b 7c 24 0c 89 c2 b8 4a 00 00 +00 0f 05 <48> 3d 00 f0 ff ff 77 36 89 d7 89 44 24 0c e8 43 03 f8 ff 8b +44 24 +[ 1.901302] RSP: 002b:00007ffa143a3ac0 EFLAGS: 00000293 ORIG_RAX: +000000000000004a +[ 1.901499] RAX: ffffffffffffffda RBX: 0000560277ec6fe0 RCX: 00007ffa16ec96ea +[ 1.901696] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000016 +[ 1.901884] RBP: 0000560277ec5910 R08: 0000000000000000 R09: 00007ffa143a4640 +[ 1.902082] R10: 00007ffa16e4d39e R11: 0000000000000293 R12: 00005602773f59e0 +[ 1.902459] R13: 0000000000000000 R14: 00007fffbfc007ff R15: 00007ffa13ba4000 +[ 1.902763] +[ 1.902877] ---[ end trace 0000000000000000 ]--- + +To avoid calling blk_mq_start_request() twice, This patch moves the +execution of blk_mq_start_request() to the end of virtblk_prep_rq(). +And instead of requeuing failed request to plug list in the error path of +virtblk_add_req_batch(), it uses blk_mq_requeue_request() to change failed +request state to MQ_RQ_IDLE. Then virtblk can safely handle the request +on the next trial. + +Fixes: 0e9911fa768f ("virtio-blk: support mq_ops->queue_rqs()") +Reported-by: Alexandre Courbot +Tested-by: Alexandre Courbot +Signed-off-by: Suwan Kim +Message-Id: <20220830150153.12627-1-suwan.kim027@gmail.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Stefan Hajnoczi +Reviewed-by: Pankaj Raghav +Signed-off-by: Sasha Levin +--- + drivers/block/virtio_blk.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c +index 59d6d5faf739..dcd639e58ff0 100644 +--- a/drivers/block/virtio_blk.c ++++ b/drivers/block/virtio_blk.c +@@ -322,14 +322,14 @@ static blk_status_t virtblk_prep_rq(struct blk_mq_hw_ctx *hctx, + if (unlikely(status)) + return status; + +- blk_mq_start_request(req); +- + vbr->sg_table.nents = virtblk_map_data(hctx, req, vbr); + if (unlikely(vbr->sg_table.nents < 0)) { + virtblk_cleanup_cmd(req); + return BLK_STS_RESOURCE; + } + ++ blk_mq_start_request(req); ++ + return BLK_STS_OK; + } + +@@ -391,8 +391,7 @@ static bool virtblk_prep_rq_batch(struct request *req) + } + + static bool virtblk_add_req_batch(struct virtio_blk_vq *vq, +- struct request **rqlist, +- struct request **requeue_list) ++ struct request **rqlist) + { + unsigned long flags; + int err; +@@ -408,7 +407,7 @@ static bool virtblk_add_req_batch(struct virtio_blk_vq *vq, + if (err) { + virtblk_unmap_data(req, vbr); + virtblk_cleanup_cmd(req); +- rq_list_add(requeue_list, req); ++ blk_mq_requeue_request(req, true); + } + } + +@@ -436,7 +435,7 @@ static void virtio_queue_rqs(struct request **rqlist) + + if (!next || req->mq_hctx != next->mq_hctx) { + req->rq_next = NULL; +- kick = virtblk_add_req_batch(vq, rqlist, &requeue_list); ++ kick = virtblk_add_req_batch(vq, rqlist); + if (kick) + virtqueue_notify(vq->vq); + +-- +2.35.1 + diff --git a/queue-5.19/wifi-cfg80211-fix-mcs-divisor-value.patch b/queue-5.19/wifi-cfg80211-fix-mcs-divisor-value.patch new file mode 100644 index 00000000000..e2607717c0e --- /dev/null +++ b/queue-5.19/wifi-cfg80211-fix-mcs-divisor-value.patch @@ -0,0 +1,51 @@ +From 243642e8dfc50e77e2e249324fb78b5f9b6df358 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Sep 2022 23:40:34 +0530 +Subject: wifi: cfg80211: fix MCS divisor value + +From: Tamizh Chelvam Raja + +[ Upstream commit 64e966d1e84b29c9fa916cfeaabbf4013703942e ] + +The Bitrate for HE/EHT MCS6 is calculated wrongly due to the +incorrect MCS divisor value for mcs6. Fix it with the proper +value. + +previous mcs_divisor value = (11769/6144) = 1.915527 + +fixed mcs_divisor value = (11377/6144) = 1.851725 + +Fixes: 9c97c88d2f4b ("cfg80211: Add support to calculate and report 4096-QAM HE rates") +Signed-off-by: Tamizh Chelvam Raja +Link: https://lore.kernel.org/r/20220908181034.9936-1-quic_tamizhr@quicinc.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/wireless/util.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/wireless/util.c b/net/wireless/util.c +index b7257862e0fe..28b7f120501a 100644 +--- a/net/wireless/util.c ++++ b/net/wireless/util.c +@@ -1361,7 +1361,7 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate) + 25599, /* 4.166666... */ + 17067, /* 2.777777... */ + 12801, /* 2.083333... */ +- 11769, /* 1.851851... */ ++ 11377, /* 1.851725... */ + 10239, /* 1.666666... */ + 8532, /* 1.388888... */ + 7680, /* 1.250000... */ +@@ -1444,7 +1444,7 @@ static u32 cfg80211_calculate_bitrate_eht(struct rate_info *rate) + 25599, /* 4.166666... */ + 17067, /* 2.777777... */ + 12801, /* 2.083333... */ +- 11769, /* 1.851851... */ ++ 11377, /* 1.851725... */ + 10239, /* 1.666666... */ + 8532, /* 1.388888... */ + 7680, /* 1.250000... */ +-- +2.35.1 + diff --git a/queue-5.19/wifi-mac80211-fix-memory-corruption-in-minstrel_ht_u.patch b/queue-5.19/wifi-mac80211-fix-memory-corruption-in-minstrel_ht_u.patch new file mode 100644 index 00000000000..951a39c02b6 --- /dev/null +++ b/queue-5.19/wifi-mac80211-fix-memory-corruption-in-minstrel_ht_u.patch @@ -0,0 +1,122 @@ +From 9bc63d2369f273538f99d4ad380f3c8cf85b6e67 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Sep 2022 17:01:35 +0200 +Subject: wifi: mac80211: fix memory corruption in minstrel_ht_update_rates() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Paweł Lenkow + +[ Upstream commit be92292b90bfdc31f332c962882b6d3ea0285fdf ] + +During our testing of WFM200 module over SDIO on i.MX6Q-based platform, +we discovered a memory corruption on the system, tracing back to the wfx +driver. Using kfence, it was possible to trace it back to the root +cause, which is hw->max_rates set to 8 in wfx_init_common, +while the maximum defined by IEEE80211_TX_TABLE_SIZE is 4. + +This causes array out-of-bounds writes during updates of the rate table, +as seen below: + +BUG: KFENCE: memory corruption in kfree_rcu_work+0x320/0x36c + +Corrupted memory at 0xe0a4ffe0 [ 0x03 0x03 0x03 0x03 0x01 0x00 0x00 +0x02 0x02 0x02 0x09 0x00 0x21 0xbb 0xbb 0xbb ] (in kfence-#81): +kfree_rcu_work+0x320/0x36c +process_one_work+0x3ec/0x920 +worker_thread+0x60/0x7a4 +kthread+0x174/0x1b4 +ret_from_fork+0x14/0x2c +0x0 + +kfence-#81: 0xe0a4ffc0-0xe0a4ffdf, size=32, cache=kmalloc-64 + +allocated by task 297 on cpu 0 at 631.039555s: +minstrel_ht_update_rates+0x38/0x2b0 [mac80211] +rate_control_tx_status+0xb4/0x148 [mac80211] +ieee80211_tx_status_ext+0x364/0x1030 [mac80211] +ieee80211_tx_status+0xe0/0x118 [mac80211] +ieee80211_tasklet_handler+0xb0/0xe0 [mac80211] +tasklet_action_common.constprop.0+0x11c/0x148 +__do_softirq+0x1a4/0x61c +irq_exit+0xcc/0x104 +call_with_stack+0x18/0x20 +__irq_svc+0x80/0xb0 +wq_worker_sleeping+0x10/0x100 +wq_worker_sleeping+0x10/0x100 +schedule+0x50/0xe0 +schedule_timeout+0x2e0/0x474 +wait_for_completion+0xdc/0x1ec +mmc_wait_for_req_done+0xc4/0xf8 +mmc_io_rw_extended+0x3b4/0x4ec +sdio_io_rw_ext_helper+0x290/0x384 +sdio_memcpy_toio+0x30/0x38 +wfx_sdio_copy_to_io+0x88/0x108 [wfx] +wfx_data_write+0x88/0x1f0 [wfx] +bh_work+0x1c8/0xcc0 [wfx] +process_one_work+0x3ec/0x920 +worker_thread+0x60/0x7a4 +kthread+0x174/0x1b4 +ret_from_fork+0x14/0x2c 0x0 + +After discussion on the wireless mailing list it was clarified +that the issue has been introduced by: +commit ee0e16ab756a ("mac80211: minstrel_ht: fill all requested rates") +and fix shall be in minstrel_ht_update_rates in rc80211_minstrel_ht.c. + +Fixes: ee0e16ab756a ("mac80211: minstrel_ht: fill all requested rates") +Link: https://lore.kernel.org/all/12e5adcd-8aed-f0f7-70cc-4fb7b656b829@camlingroup.com/ +Link: https://lore.kernel.org/linux-wireless/20220915131445.30600-1-lech.perczak@camlingroup.com/ +Cc: Jérôme Pouiller +Cc: Johannes Berg +Cc: Peter Seiderer +Cc: Kalle Valo +Cc: Krzysztof Drobiński , +Signed-off-by: Paweł Lenkow +Signed-off-by: Lech Perczak +Reviewed-by: Peter Seiderer +Reviewed-by: Jérôme Pouiller +Acked-by: Felix Fietkau +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/rc80211_minstrel_ht.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c +index 5f27e6746762..788a82f9c74d 100644 +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include "rate.h" + #include "sta_info.h" +@@ -1550,6 +1551,7 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) + { + struct ieee80211_sta_rates *rates; + int i = 0; ++ int max_rates = min_t(int, mp->hw->max_rates, IEEE80211_TX_RATE_TABLE_SIZE); + + rates = kzalloc(sizeof(*rates), GFP_ATOMIC); + if (!rates) +@@ -1559,10 +1561,10 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) + minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]); + + /* Fill up remaining, keep one entry for max_probe_rate */ +- for (; i < (mp->hw->max_rates - 1); i++) ++ for (; i < (max_rates - 1); i++) + minstrel_ht_set_rate(mp, mi, rates, i, mi->max_tp_rate[i]); + +- if (i < mp->hw->max_rates) ++ if (i < max_rates) + minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate); + + if (i < IEEE80211_TX_RATE_TABLE_SIZE) +-- +2.35.1 + diff --git a/queue-5.19/wifi-mac80211-fix-regression-with-non-qos-drivers.patch b/queue-5.19/wifi-mac80211-fix-regression-with-non-qos-drivers.patch new file mode 100644 index 00000000000..5c47b3a5df7 --- /dev/null +++ b/queue-5.19/wifi-mac80211-fix-regression-with-non-qos-drivers.patch @@ -0,0 +1,65 @@ +From 40da29cefedf0f9fcd55d408691046d42b1a0055 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 18 Sep 2022 21:20:52 +0200 +Subject: wifi: mac80211: fix regression with non-QoS drivers + +From: Hans de Goede + +[ Upstream commit d873697ef2b7e1b6fdd8e9d449d9354bd5d29a4a ] + +Commit 10cb8e617560 ("mac80211: enable QoS support for nl80211 ctrl port") +changed ieee80211_tx_control_port() to aways call +__ieee80211_select_queue() without checking local->hw.queues. + +__ieee80211_select_queue() returns a queue-id between 0 and 3, which means +that now ieee80211_tx_control_port() may end up setting the queue-mapping +for a skb to a value higher then local->hw.queues if local->hw.queues +is less then 4. + +Specifically this is a problem for ralink rt2500-pci cards where +local->hw.queues is 2. There this causes rt2x00queue_get_tx_queue() to +return NULL and the following error to be logged: "ieee80211 phy0: +rt2x00mac_tx: Error - Attempt to send packet over invalid queue 2", +after which association with the AP fails. + +Other callers of __ieee80211_select_queue() skip calling it when +local->hw.queues < IEEE80211_NUM_ACS, add the same check to +ieee80211_tx_control_port(). This fixes ralink rt2500-pci and +similar cards when less then 4 tx-queues no longer working. + +Fixes: 10cb8e617560 ("mac80211: enable QoS support for nl80211 ctrl port") +Cc: Markus Theil +Suggested-by: Stanislaw Gruszka +Signed-off-by: Hans de Goede +Link: https://lore.kernel.org/r/20220918192052.443529-1-hdegoede@redhat.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/tx.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c +index 3cd24d8170d3..f6f09a3506aa 100644 +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -5761,6 +5761,9 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, + skb_reset_network_header(skb); + skb_reset_mac_header(skb); + ++ if (local->hw.queues < IEEE80211_NUM_ACS) ++ goto start_xmit; ++ + /* update QoS header to prioritize control port frames if possible, + * priorization also happens for control port frames send over + * AF_PACKET +@@ -5776,6 +5779,7 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, + + rcu_read_unlock(); + ++start_xmit: + /* mutex lock is only needed for incrementing the cookie counter */ + mutex_lock(&local->mtx); + +-- +2.35.1 + -- 2.47.3