From c28f3d80383571d3630df1a0e89500d23e855924 Mon Sep 17 00:00:00 2001 From: Utkarsh Patel Date: Thu, 22 Dec 2022 20:22:46 -0800 Subject: [PATCH 001/398] thunderbolt: Do not report errors if on-board retimers are found Currently we return an error even if on-board retimers are found and that's not expected. Fix this to return an error only if there was one and 0 otherwise. Fixes: 1e56c88adecc ("thunderbolt: Runtime resume USB4 port when retimers are scanned") Cc: stable@vger.kernel.org Signed-off-by: Utkarsh Patel Signed-off-by: Mika Westerberg --- drivers/thunderbolt/retimer.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/thunderbolt/retimer.c b/drivers/thunderbolt/retimer.c index 81252e31014a..6ebe7a2886ec 100644 --- a/drivers/thunderbolt/retimer.c +++ b/drivers/thunderbolt/retimer.c @@ -471,10 +471,9 @@ int tb_retimer_scan(struct tb_port *port, bool add) break; } - if (!last_idx) { - ret = 0; + ret = 0; + if (!last_idx) goto out; - } /* Add on-board retimers if they do not exist already */ for (i = 1; i <= last_idx; i++) { From 827e0920dbfb0d92416e56081d70745597403446 Mon Sep 17 00:00:00 2001 From: Benedikt Niedermayr Date: Fri, 9 Dec 2022 12:28:28 +0100 Subject: [PATCH 002/398] memory: omap-gpmc: fix wait pin validation This bug has been introduced after switching from -1 to UINT_MAX for GPMC_WAITPIN_INVALID. The bug leads to an error when the optional gpmc,wait-pin dt-property is not used: ... gpmc_cs_program_settings: invalid wait-pin (-1) ... Signed-off-by: Benedikt Niedermayr Fixes: 8dd7e4af5853 ("memory: omap-gpmc: fix coverity issue "Control flow issues"") Acked-by: Roger Quadros Tested-by: Tony Lindgren Link: https://lore.kernel.org/r/20221209112828.581491-1-benedikt.niedermayr@siemens.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/omap-gpmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 57d9f91fe89b..d78f73db37c8 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -1918,7 +1918,8 @@ int gpmc_cs_program_settings(int cs, struct gpmc_settings *p) } } - if (p->wait_pin > gpmc_nr_waitpins) { + if (p->wait_pin != GPMC_WAITPIN_INVALID && + p->wait_pin > gpmc_nr_waitpins) { pr_err("%s: invalid wait-pin (%d)\n", __func__, p->wait_pin); return -EINVAL; } From ef86b2c2807f41c045e5534d8513a8b83f63bc39 Mon Sep 17 00:00:00 2001 From: Ashish Mhetre Date: Fri, 25 Nov 2022 09:37:52 +0530 Subject: [PATCH 003/398] memory: tegra: Remove clients SID override programming On newer Tegra releases, early boot SID override programming and SID override programming during resume is handled by bootloader. In the function tegra186_mc_program_sid() which is getting removed, SID override register of all clients is written without checking if secure firmware has allowed write on it or not. If write is disabled by secure firmware then it can lead to errors coming from secure firmware and hang in kernel boot. Also, SID override is programmed on-demand during probe_finalize() call of IOMMU which is done in tegra186_mc_client_sid_override() in this same file. This function does it correctly by checking if write is permitted on SID override register. It also checks if SID override register is already written with correct value and skips re-writing it in that case. Fixes: 393d66fd2cac ("memory: tegra: Implement SID override programming") Signed-off-by: Ashish Mhetre Acked-by: Thierry Reding Link: https://lore.kernel.org/r/20221125040752.12627-1-amhetre@nvidia.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/tegra/tegra186.c | 36 --------------------------------- 1 file changed, 36 deletions(-) diff --git a/drivers/memory/tegra/tegra186.c b/drivers/memory/tegra/tegra186.c index 62477e592bf5..7bb73f06fad3 100644 --- a/drivers/memory/tegra/tegra186.c +++ b/drivers/memory/tegra/tegra186.c @@ -22,32 +22,6 @@ #define MC_SID_STREAMID_SECURITY_WRITE_ACCESS_DISABLED BIT(16) #define MC_SID_STREAMID_SECURITY_OVERRIDE BIT(8) -static void tegra186_mc_program_sid(struct tegra_mc *mc) -{ - unsigned int i; - - for (i = 0; i < mc->soc->num_clients; i++) { - const struct tegra_mc_client *client = &mc->soc->clients[i]; - u32 override, security; - - override = readl(mc->regs + client->regs.sid.override); - security = readl(mc->regs + client->regs.sid.security); - - dev_dbg(mc->dev, "client %s: override: %x security: %x\n", - client->name, override, security); - - dev_dbg(mc->dev, "setting SID %u for %s\n", client->sid, - client->name); - writel(client->sid, mc->regs + client->regs.sid.override); - - override = readl(mc->regs + client->regs.sid.override); - security = readl(mc->regs + client->regs.sid.security); - - dev_dbg(mc->dev, "client %s: override: %x security: %x\n", - client->name, override, security); - } -} - static int tegra186_mc_probe(struct tegra_mc *mc) { struct platform_device *pdev = to_platform_device(mc->dev); @@ -85,8 +59,6 @@ populate: if (err < 0) return err; - tegra186_mc_program_sid(mc); - return 0; } @@ -95,13 +67,6 @@ static void tegra186_mc_remove(struct tegra_mc *mc) of_platform_depopulate(mc->dev); } -static int tegra186_mc_resume(struct tegra_mc *mc) -{ - tegra186_mc_program_sid(mc); - - return 0; -} - #if IS_ENABLED(CONFIG_IOMMU_API) static void tegra186_mc_client_sid_override(struct tegra_mc *mc, const struct tegra_mc_client *client, @@ -173,7 +138,6 @@ static int tegra186_mc_probe_device(struct tegra_mc *mc, struct device *dev) const struct tegra_mc_ops tegra186_mc_ops = { .probe = tegra186_mc_probe, .remove = tegra186_mc_remove, - .resume = tegra186_mc_resume, .probe_device = tegra186_mc_probe_device, .handle_irq = tegra30_mc_handle_irq, }; From 340cb392a038cf70540a4cdf2e98a247c66b6df4 Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Fri, 25 Nov 2022 15:37:57 +0800 Subject: [PATCH 004/398] memory: atmel-sdramc: Fix missing clk_disable_unprepare in atmel_ramc_probe() The clk_disable_unprepare() should be called in the error handling of caps->has_mpddr_clk, fix it by replacing devm_clk_get and clk_prepare_enable by devm_clk_get_enabled. Fixes: e81b6abebc87 ("memory: add a driver for atmel ram controllers") Signed-off-by: Gaosheng Cui Link: https://lore.kernel.org/r/20221125073757.3535219-1-cuigaosheng1@huawei.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/atmel-sdramc.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/memory/atmel-sdramc.c b/drivers/memory/atmel-sdramc.c index 9c49d00c2a96..ea6e9e1eaf04 100644 --- a/drivers/memory/atmel-sdramc.c +++ b/drivers/memory/atmel-sdramc.c @@ -47,19 +47,17 @@ static int atmel_ramc_probe(struct platform_device *pdev) caps = of_device_get_match_data(&pdev->dev); if (caps->has_ddrck) { - clk = devm_clk_get(&pdev->dev, "ddrck"); + clk = devm_clk_get_enabled(&pdev->dev, "ddrck"); if (IS_ERR(clk)) return PTR_ERR(clk); - clk_prepare_enable(clk); } if (caps->has_mpddr_clk) { - clk = devm_clk_get(&pdev->dev, "mpddr"); + clk = devm_clk_get_enabled(&pdev->dev, "mpddr"); if (IS_ERR(clk)) { pr_err("AT91 RAMC: couldn't get mpddr clock\n"); return PTR_ERR(clk); } - clk_prepare_enable(clk); } return 0; From cb8fd6f75775165390ededea8799b60d93d9fe3e Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Sat, 26 Nov 2022 12:49:11 +0800 Subject: [PATCH 005/398] memory: mvebu-devbus: Fix missing clk_disable_unprepare in mvebu_devbus_probe() The clk_disable_unprepare() should be called in the error handling of devbus_get_timing_params() and of_platform_populate(), fix it by replacing devm_clk_get and clk_prepare_enable by devm_clk_get_enabled. Fixes: e81b6abebc87 ("memory: add a driver for atmel ram controllers") Signed-off-by: Gaosheng Cui Link: https://lore.kernel.org/r/20221126044911.7226-1-cuigaosheng1@huawei.com Signed-off-by: Krzysztof Kozlowski --- drivers/memory/mvebu-devbus.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/memory/mvebu-devbus.c b/drivers/memory/mvebu-devbus.c index 8450638e8670..efc6c08db2b7 100644 --- a/drivers/memory/mvebu-devbus.c +++ b/drivers/memory/mvebu-devbus.c @@ -280,10 +280,9 @@ static int mvebu_devbus_probe(struct platform_device *pdev) if (IS_ERR(devbus->base)) return PTR_ERR(devbus->base); - clk = devm_clk_get(&pdev->dev, NULL); + clk = devm_clk_get_enabled(&pdev->dev, NULL); if (IS_ERR(clk)) return PTR_ERR(clk); - clk_prepare_enable(clk); /* * Obtain clock period in picoseconds, From ee4e530bdde29a69c58656a919545251a782674e Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 21 Nov 2022 09:50:57 +0100 Subject: [PATCH 006/398] arm64: dts: qcom: sc8280xp: fix primary USB-DP PHY reset The vendor kernel is using the GCC_USB4_DP_PHY_PRIM_BCR and GCC_USB4_1_DP_PHY_PRIM_BCR resets for the USB4-USB3-DP QMP PHYs. Update the primary USB-DP PHY node to match. Fixes: 152d1faf1e2f ("arm64: dts: qcom: add SC8280XP platform") Signed-off-by: Johan Hovold Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221121085058.31213-15-johan+linaro@kernel.org --- arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi index 109c9d2b684d..ad71e68384da 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi @@ -1689,7 +1689,7 @@ clock-names = "aux", "ref_clk_src", "ref", "com_aux"; resets = <&gcc GCC_USB3_PHY_PRIM_BCR>, - <&gcc GCC_USB3_DP_PHY_PRIM_BCR>; + <&gcc GCC_USB4_DP_PHY_PRIM_BCR>; reset-names = "phy", "common"; power-domains = <&gcc USB30_PRIM_GDSC>; From 721c0d68c0f882b6358102b52961ff6eb601839c Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 21 Nov 2022 09:50:58 +0100 Subject: [PATCH 007/398] arm64: dts: qcom: sc8280xp: fix USB-DP PHY nodes Update the USB4-USB3-DP QMP PHY nodes to match the new binding which specifically includes the missing register regions (e.g. DP_PHY) and allows for supporting DisplayPort Alternate Mode. Reviewed-by: Dmitry Baryshkov Signed-off-by: Johan Hovold Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221121085058.31213-16-johan+linaro@kernel.org --- arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 77 ++++++++------------------ 1 file changed, 23 insertions(+), 54 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi index ad71e68384da..71cf81a8eb4d 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -762,7 +763,7 @@ <0>, <0>, <0>, - <&usb_0_ssphy>, + <&usb_0_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, <0>, <0>, <0>, @@ -770,7 +771,7 @@ <0>, <0>, <0>, - <&usb_1_ssphy>, + <&usb_1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, <0>, <0>, <0>, @@ -1673,42 +1674,26 @@ }; }; - usb_0_qmpphy: phy-wrapper@88ec000 { + usb_0_qmpphy: phy@88eb000 { compatible = "qcom,sc8280xp-qmp-usb43dp-phy"; - reg = <0 0x088ec000 0 0x1e4>, - <0 0x088eb000 0 0x40>, - <0 0x088ed000 0 0x1c8>; - #address-cells = <2>; - #size-cells = <2>; - ranges; + reg = <0 0x088eb000 0 0x4000>; clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, - <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_USB4_EUD_CLKREF_CLK>, - <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>; - clock-names = "aux", "ref_clk_src", "ref", "com_aux"; + <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>, + <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; + clock-names = "aux", "ref", "com_aux", "usb3_pipe"; + + power-domains = <&gcc USB30_PRIM_GDSC>; resets = <&gcc GCC_USB3_PHY_PRIM_BCR>, <&gcc GCC_USB4_DP_PHY_PRIM_BCR>; reset-names = "phy", "common"; - power-domains = <&gcc USB30_PRIM_GDSC>; + #clock-cells = <1>; + #phy-cells = <1>; status = "disabled"; - - usb_0_ssphy: usb3-phy@88eb400 { - reg = <0 0x088eb400 0 0x100>, - <0 0x088eb600 0 0x3ec>, - <0 0x088ec400 0 0x364>, - <0 0x088eba00 0 0x100>, - <0 0x088ebc00 0 0x3ec>, - <0 0x088ec200 0 0x18>; - #phy-cells = <0>; - #clock-cells = <0>; - clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; - clock-names = "pipe0"; - clock-output-names = "usb0_phy_pipe_clk_src"; - }; }; usb_1_hsphy: phy@8902000 { @@ -1725,42 +1710,26 @@ status = "disabled"; }; - usb_1_qmpphy: phy-wrapper@8904000 { + usb_1_qmpphy: phy@8903000 { compatible = "qcom,sc8280xp-qmp-usb43dp-phy"; - reg = <0 0x08904000 0 0x1e4>, - <0 0x08903000 0 0x40>, - <0 0x08905000 0 0x1c8>; - #address-cells = <2>; - #size-cells = <2>; - ranges; + reg = <0 0x08903000 0 0x4000>; clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>, - <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_USB4_CLKREF_CLK>, - <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>; - clock-names = "aux", "ref_clk_src", "ref", "com_aux"; + <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>, + <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; + clock-names = "aux", "ref", "com_aux", "usb3_pipe"; + + power-domains = <&gcc USB30_SEC_GDSC>; resets = <&gcc GCC_USB3_PHY_SEC_BCR>, <&gcc GCC_USB4_1_DP_PHY_PRIM_BCR>; reset-names = "phy", "common"; - power-domains = <&gcc USB30_SEC_GDSC>; + #clock-cells = <1>; + #phy-cells = <1>; status = "disabled"; - - usb_1_ssphy: usb3-phy@8903400 { - reg = <0 0x08903400 0 0x100>, - <0 0x08903600 0 0x3ec>, - <0 0x08904400 0 0x364>, - <0 0x08903a00 0 0x100>, - <0 0x08903c00 0 0x3ec>, - <0 0x08904200 0 0x18>; - #phy-cells = <0>; - #clock-cells = <0>; - clocks = <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; - clock-names = "pipe0"; - clock-output-names = "usb1_phy_pipe_clk_src"; - }; }; pmu@9091000 { @@ -1910,7 +1879,7 @@ reg = <0 0x0a600000 0 0xcd00>; interrupts = ; iommus = <&apps_smmu 0x820 0x0>; - phys = <&usb_0_hsphy>, <&usb_0_ssphy>; + phys = <&usb_0_hsphy>, <&usb_0_qmpphy QMP_USB43DP_USB3_PHY>; phy-names = "usb2-phy", "usb3-phy"; }; }; @@ -1964,7 +1933,7 @@ reg = <0 0x0a800000 0 0xcd00>; interrupts = ; iommus = <&apps_smmu 0x860 0x0>; - phys = <&usb_1_hsphy>, <&usb_1_ssphy>; + phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>; phy-names = "usb2-phy", "usb3-phy"; }; }; From 22c7e1a0fa45cd7d028d6b4117161fd0e3427fe0 Mon Sep 17 00:00:00 2001 From: Dominik Kobinski Date: Sun, 11 Dec 2022 11:05:01 +0100 Subject: [PATCH 008/398] arm64: dts: msm8992-bullhead: add memory hole region Add region for memory hole present on bullhead in order to fix a reboot issue on recent kernels Reported-by: Petr Vorel Signed-off-by: Dominik Kobinski Reviewed-by: Konrad Dybcio Tested-by: Petr Vorel Reviewed-by: Petr Vorel Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221211100501.82323-1-dominikkobinski314@gmail.com --- arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi index 87c90e93667f..79de9cc395c4 100644 --- a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi @@ -3,6 +3,7 @@ * Copyright (c) 2015, LGE Inc. All rights reserved. * Copyright (c) 2016, The Linux Foundation. All rights reserved. * Copyright (c) 2021, Petr Vorel + * Copyright (c) 2022, Dominik Kobinski */ /dts-v1/; @@ -51,6 +52,11 @@ reg = <0 0x03400000 0 0x1200000>; no-map; }; + + removed_region: reserved@5000000 { + reg = <0 0x05000000 0 0x2200000>; + no-map; + }; }; }; From 25e8ac233d24051e2c4ff64c34f60609b0988568 Mon Sep 17 00:00:00 2001 From: Vijaya Krishna Nivarthi Date: Fri, 16 Dec 2022 23:08:13 +0530 Subject: [PATCH 009/398] dmaengine: qcom: gpi: Set link_rx bit on GO TRE for rx operation Rx operation on SPI GSI DMA is currently not working. As per GSI spec, link_rx bit is to be set on GO TRE on tx channel whenever there is going to be a DMA TRE on rx channel. This is currently set for duplex operation only. Set the bit for rx operation as well. This is part of changes required to bring up Rx. Fixes: 94b8f0e58fa1 ("dmaengine: qcom: gpi: set chain and link flag for duplex") Signed-off-by: Vijaya Krishna Nivarthi Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/1671212293-14767-1-git-send-email-quic_vnivarth@quicinc.com Signed-off-by: Vinod Koul --- drivers/dma/qcom/gpi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c index 061add832295..59a36cbf9b5f 100644 --- a/drivers/dma/qcom/gpi.c +++ b/drivers/dma/qcom/gpi.c @@ -1756,6 +1756,7 @@ static int gpi_create_spi_tre(struct gchan *chan, struct gpi_desc *desc, tre->dword[3] = u32_encode_bits(TRE_TYPE_GO, TRE_FLAGS_TYPE); if (spi->cmd == SPI_RX) { tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_IEOB); + tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_LINK); } else if (spi->cmd == SPI_TX) { tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_CHAIN); } else { /* SPI_DUPLEX */ From b51b75f0604f17c0f6f3b6f68f1a521a5cc6b04f Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Wed, 7 Dec 2022 14:52:20 -0800 Subject: [PATCH 010/398] dmaengine: idxd: Let probe fail when workqueue cannot be enabled The workqueue is enabled when the appropriate driver is loaded and disabled when the driver is removed. When the driver is removed it assumes that the workqueue was enabled successfully and proceeds to free allocations made during workqueue enabling. Failure during workqueue enabling does not prevent the driver from being loaded. This is because the error path within drv_enable_wq() returns success unless a second failure is encountered during the error path. By returning success it is possible to load the driver even if the workqueue cannot be enabled and allocations that do not exist are attempted to be freed during driver remove. Some examples of problematic flows: (a) idxd_dmaengine_drv_probe() -> drv_enable_wq() -> idxd_wq_request_irq(): In above flow, if idxd_wq_request_irq() fails then idxd_wq_unmap_portal() is called on error exit path, but drv_enable_wq() returns 0 because idxd_wq_disable() succeeds. The driver is thus loaded successfully. idxd_dmaengine_drv_remove()->drv_disable_wq()->idxd_wq_unmap_portal() Above flow on driver unload triggers the WARN in devm_iounmap() because the device resource has already been removed during error path of drv_enable_wq(). (b) idxd_dmaengine_drv_probe() -> drv_enable_wq() -> idxd_wq_request_irq(): In above flow, if idxd_wq_request_irq() fails then idxd_wq_init_percpu_ref() is never called to initialize the percpu counter, yet the driver loads successfully because drv_enable_wq() returns 0. idxd_dmaengine_drv_remove()->__idxd_wq_quiesce()->percpu_ref_kill(): Above flow on driver unload triggers a BUG when attempting to drop the initial ref of the uninitialized percpu ref: BUG: kernel NULL pointer dereference, address: 0000000000000010 Fix the drv_enable_wq() error path by returning the original error that indicates failure of workqueue enabling. This ensures that the probe fails when an error is encountered and the driver remove paths are only attempted when the workqueue was enabled successfully. Fixes: 1f2bb40337f0 ("dmaengine: idxd: move wq_enable() to device.c") Signed-off-by: Reinette Chatre Reviewed-by: Dave Jiang Reviewed-by: Fenghua Yu Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/e8d8116e5efa0fd14fadc5adae6ffd319f0e5ff1.1670452419.git.reinette.chatre@intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index 06f5d3783d77..c5523ced2e3a 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -1390,8 +1390,7 @@ err_res_alloc: err_irq: idxd_wq_unmap_portal(wq); err_map_portal: - rc = idxd_wq_disable(wq, false); - if (rc < 0) + if (idxd_wq_disable(wq, false)) dev_dbg(dev, "wq %s disable failed\n", dev_name(wq_confdev(wq))); err: return rc; From 1beeec45f9ac31eba52478379f70a5fa9c2ad005 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Wed, 7 Dec 2022 14:52:21 -0800 Subject: [PATCH 011/398] dmaengine: idxd: Prevent use after free on completion memory On driver unload any pending descriptors are flushed at the time the interrupt is freed: idxd_dmaengine_drv_remove() -> drv_disable_wq() -> idxd_wq_free_irq() -> idxd_flush_pending_descs(). If there are any descriptors present that need to be flushed this flow triggers a "not present" page fault as below: BUG: unable to handle page fault for address: ff391c97c70c9040 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page The address that triggers the fault is the address of the descriptor that was freed moments earlier via: drv_disable_wq()->idxd_wq_free_resources() Fix the use after free by freeing the descriptors after any possible usage. This is done after idxd_wq_reset() to ensure that the memory remains accessible during possible completion writes by the device. Fixes: 63c14ae6c161 ("dmaengine: idxd: refactor wq driver enable/disable operations") Suggested-by: Dave Jiang Signed-off-by: Reinette Chatre Reviewed-by: Dave Jiang Reviewed-by: Fenghua Yu Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/6c4657d9cff0a0a00501a7b928297ac966e9ec9d.1670452419.git.reinette.chatre@intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index c5523ced2e3a..cd792f3f9873 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -1407,11 +1407,11 @@ void drv_disable_wq(struct idxd_wq *wq) dev_warn(dev, "Clients has claim on wq %d: %d\n", wq->id, idxd_wq_refcount(wq)); - idxd_wq_free_resources(wq); idxd_wq_unmap_portal(wq); idxd_wq_drain(wq); idxd_wq_free_irq(wq); idxd_wq_reset(wq); + idxd_wq_free_resources(wq); percpu_ref_exit(&wq->wq_active); wq->type = IDXD_WQT_NONE; wq->client_count = 0; From 6744a030d81e456883bfbb627ac1f30465c1a989 Mon Sep 17 00:00:00 2001 From: Reinette Chatre Date: Wed, 7 Dec 2022 14:52:22 -0800 Subject: [PATCH 012/398] dmaengine: idxd: Do not call DMX TX callbacks during workqueue disable On driver unload any pending descriptors are flushed and pending DMA descriptors are explicitly completed: idxd_dmaengine_drv_remove() -> drv_disable_wq() -> idxd_wq_free_irq() -> idxd_flush_pending_descs() -> idxd_dma_complete_txd() With this done during driver unload any remaining descriptor is likely stuck and can be dropped. Even so, the descriptor may still have a callback set that could no longer be accessible. An example of such a problem is when the dmatest fails and the dmatest module is unloaded. The failure of dmatest leaves descriptors with dma_async_tx_descriptor::callback pointing to code that no longer exist. This causes a page fault as below at the time the IDXD driver is unloaded when it attempts to run the callback: BUG: unable to handle page fault for address: ffffffffc0665190 #PF: supervisor instruction fetch in kernel mode #PF: error_code(0x0010) - not-present page Fix this by clearing the callback pointers on the transmit descriptors only when workqueue is disabled. Fixes: 403a2e236538 ("dmaengine: idxd: change MSIX allocation based on per wq activation") Signed-off-by: Reinette Chatre Reviewed-by: Dave Jiang Reviewed-by: Fenghua Yu Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/37d06b772aa7f8863ca50f90930ea2fd80b38fc3.1670452419.git.reinette.chatre@intel.com Signed-off-by: Vinod Koul --- drivers/dma/idxd/device.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index cd792f3f9873..29dbb0f52e18 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -1172,8 +1172,19 @@ static void idxd_flush_pending_descs(struct idxd_irq_entry *ie) spin_unlock(&ie->list_lock); list_for_each_entry_safe(desc, itr, &flist, list) { + struct dma_async_tx_descriptor *tx; + list_del(&desc->list); ctype = desc->completion->status ? IDXD_COMPLETE_NORMAL : IDXD_COMPLETE_ABORT; + /* + * wq is being disabled. Any remaining descriptors are + * likely to be stuck and can be dropped. callback could + * point to code that is no longer accessible, for example + * if dmatest module has been unloaded. + */ + tx = &desc->txd; + tx->callback = NULL; + tx->callback_result = NULL; idxd_dma_complete_txd(desc, ctype, true); } } From efab25894a41a920d9581183741e7fadba00719c Mon Sep 17 00:00:00 2001 From: Jayesh Choudhary Date: Mon, 28 Nov 2022 14:20:05 +0530 Subject: [PATCH 013/398] dmaengine: ti: k3-udma: Do conditional decrement of UDMA_CHAN_RT_PEER_BCNT_REG PSIL_EP_NATIVE endpoints may not have PEER registers for BCNT and thus udma_decrement_byte_counters() should not try to decrement these counters. This fixes the issue of crypto IPERF testing where the client side (EVM) hangs without transfer of packets to the server side, seen since this function was added. Fixes: 7c94dcfa8fcf ("dmaengine: ti: k3-udma: Reset UDMA_CHAN_RT byte counters to prevent overflow") Signed-off-by: Jayesh Choudhary Acked-by: Peter Ujfalusi Link: https://lore.kernel.org/r/20221128085005.489964-1-j-choudhary@ti.com Signed-off-by: Vinod Koul --- drivers/dma/ti/k3-udma.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index ce8b80bb34d7..4c62274e0b33 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -762,11 +762,12 @@ static void udma_decrement_byte_counters(struct udma_chan *uc, u32 val) if (uc->desc->dir == DMA_DEV_TO_MEM) { udma_rchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val); udma_rchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val); - udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); + if (uc->config.ep_type != PSIL_EP_NATIVE) + udma_rchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); } else { udma_tchanrt_write(uc, UDMA_CHAN_RT_BCNT_REG, val); udma_tchanrt_write(uc, UDMA_CHAN_RT_SBCNT_REG, val); - if (!uc->bchan) + if (!uc->bchan && uc->config.ep_type != PSIL_EP_NATIVE) udma_tchanrt_write(uc, UDMA_CHAN_RT_PEER_BCNT_REG, val); } } From f96a483f8e131de50ebf30589ffba1a4f6bd12f7 Mon Sep 17 00:00:00 2001 From: Jie Hai Date: Sat, 26 Nov 2022 14:49:38 +0800 Subject: [PATCH 014/398] MAINTAINERS: update Jie Hai's email address Signed-off-by: Jie Hai Link: https://lore.kernel.org/r/20221126064938.50685-1-haijie1@huawei.com Signed-off-by: Vinod Koul --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index f61eb221415b..ef4d96db17c1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9299,7 +9299,7 @@ F: net/dsa/tag_hellcreek.c HISILICON DMA DRIVER M: Zhou Wang -M: Jie Hai +M: Jie Hai L: dmaengine@vger.kernel.org S: Maintained F: drivers/dma/hisi_dma.c From 0154252a3b87f77db1e44516d1ed2e82e2d29c30 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 4 Dec 2022 09:46:14 +0100 Subject: [PATCH 015/398] ARM: dts: qcom: apq8084-ifc6540: fix overriding SDHCI While changing node names of APQ8084 SDHCI, the ones in IFC6540 board were not updated leading to disabled and misconfigured SDHCI. Cc: Fixes: 2477d81901a2 ("ARM: dts: qcom: Fix sdhci node names - use 'mmc@'") Signed-off-by: Krzysztof Kozlowski Reviewed-by: Dmitry Baryshkov Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221204084614.12193-1-krzysztof.kozlowski@linaro.org --- arch/arm/boot/dts/qcom-apq8084-ifc6540.dts | 22 +++++++++++----------- arch/arm/boot/dts/qcom-apq8084.dtsi | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts b/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts index 44cd72f1b1be..116e59a3b76d 100644 --- a/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts +++ b/arch/arm/boot/dts/qcom-apq8084-ifc6540.dts @@ -19,16 +19,16 @@ serial@f995e000 { status = "okay"; }; - - sdhci@f9824900 { - bus-width = <8>; - non-removable; - status = "okay"; - }; - - sdhci@f98a4900 { - cd-gpios = <&tlmm 122 GPIO_ACTIVE_LOW>; - bus-width = <4>; - }; }; }; + +&sdhc_1 { + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 122 GPIO_ACTIVE_LOW>; + bus-width = <4>; +}; diff --git a/arch/arm/boot/dts/qcom-apq8084.dtsi b/arch/arm/boot/dts/qcom-apq8084.dtsi index fe30abfff90a..4b0d2b4f4b6a 100644 --- a/arch/arm/boot/dts/qcom-apq8084.dtsi +++ b/arch/arm/boot/dts/qcom-apq8084.dtsi @@ -421,7 +421,7 @@ status = "disabled"; }; - mmc@f9824900 { + sdhc_1: mmc@f9824900 { compatible = "qcom,apq8084-sdhci", "qcom,sdhci-msm-v4"; reg = <0xf9824900 0x11c>, <0xf9824000 0x800>; reg-names = "hc", "core"; @@ -434,7 +434,7 @@ status = "disabled"; }; - mmc@f98a4900 { + sdhc_2: mmc@f98a4900 { compatible = "qcom,apq8084-sdhci", "qcom,sdhci-msm-v4"; reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>; reg-names = "hc", "core"; From 6c82b94d583a116faf99858379ee34844df963a1 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 22 Nov 2022 13:37:13 +0100 Subject: [PATCH 016/398] Revert "arm64: dts: qcom: sm8250: Disable the not yet supported cluster idle state" Due to recent improvements of the cluster idle state support for Qcom based platforms, we are now able to support the deepest cluster idle state. Let's therefore revert the earlier workaround. This reverts commit cadaa773bcf1 ("arm64: dts: qcom: sm8250: Disable the not yet supported cluster idle state"), which is available from v6.1-rc6. Signed-off-by: Ulf Hansson Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221122123713.65631-1-ulf.hansson@linaro.org --- arch/arm64/boot/dts/qcom/sm8250.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index dab5579946f3..927032863e2f 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi @@ -334,7 +334,6 @@ exit-latency-us = <6562>; min-residency-us = <9987>; local-timer-stop; - status = "disabled"; }; }; }; From 5626af8fc4322a972b59c7b1a6760767f7b58d4f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 15 Dec 2022 17:38:10 +0100 Subject: [PATCH 017/398] pinctrl: sp7021: fix unused function warning sppctl_gpio_inv_get is only used from the debugfs code inside of an #ifdef, so we get a warning without that: drivers/pinctrl/sunplus/sppctl.c:393:12: error: 'sppctl_gpio_inv_get' defined but not used [-Werror=unused-function] 393 | static int sppctl_gpio_inv_get(struct gpio_chip *chip, unsigned int offset) | ^~~~~~~~~~~~~~~~~~~ Replace the #ifdef with an IS_ENABLED() check that avoids the warning. Fixes: aa74c44be19c ("pinctrl: Add driver for Sunplus SP7021") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20221215163822.542622-1-arnd@kernel.org Signed-off-by: Linus Walleij --- drivers/pinctrl/sunplus/sppctl.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/sunplus/sppctl.c b/drivers/pinctrl/sunplus/sppctl.c index 2b3335ab56c6..25101293268f 100644 --- a/drivers/pinctrl/sunplus/sppctl.c +++ b/drivers/pinctrl/sunplus/sppctl.c @@ -499,7 +499,6 @@ static int sppctl_gpio_set_config(struct gpio_chip *chip, unsigned int offset, return 0; } -#ifdef CONFIG_DEBUG_FS static void sppctl_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) { const char *label; @@ -521,7 +520,6 @@ static void sppctl_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) seq_puts(s, "\n"); } } -#endif static int sppctl_gpio_new(struct platform_device *pdev, struct sppctl_pdata *pctl) { @@ -550,9 +548,8 @@ static int sppctl_gpio_new(struct platform_device *pdev, struct sppctl_pdata *pc gchip->get = sppctl_gpio_get; gchip->set = sppctl_gpio_set; gchip->set_config = sppctl_gpio_set_config; -#ifdef CONFIG_DEBUG_FS - gchip->dbg_show = sppctl_gpio_dbg_show; -#endif + gchip->dbg_show = IS_ENABLED(CONFIG_DEBUG_FS) ? + sppctl_gpio_dbg_show : NULL; gchip->base = -1; gchip->ngpio = sppctl_gpio_list_sz; gchip->names = sppctl_gpio_list_s; From 74b91a1bdb994dfaed0074154ca7d493aeb735a6 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sat, 24 Dec 2022 22:43:51 +0100 Subject: [PATCH 018/398] arm64: dts: qcom: sm8350: correct SDHCI interconnect arguments The interconnect providers accept only one argument (cells == 1), so fix a copy&paste from SM8450: sm8350-hdk.dtb: mmc@8804000: interconnects: [[74, 9, 0], [75, 1, 0], [76, 2, 0], [77, 36, 0]] is too long Fixes: 60477435e4de ("arm64: dts: qcom: sm8350: Add SDHCI2") Signed-off-by: Krzysztof Kozlowski Reviewed-by: Konrad Dybcio Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221224214351.18215-1-krzysztof.kozlowski@linaro.org --- arch/arm64/boot/dts/qcom/sm8350.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index 245dce24ec59..fb3cd20a82b5 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi @@ -2382,8 +2382,8 @@ <&rpmhcc RPMH_CXO_CLK>; clock-names = "iface", "core", "xo"; resets = <&gcc GCC_SDCC2_BCR>; - interconnects = <&aggre2_noc MASTER_SDCC_2 0 &mc_virt SLAVE_EBI1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_SDCC_2 0>; + interconnects = <&aggre2_noc MASTER_SDCC_2 &mc_virt SLAVE_EBI1>, + <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_SDCC_2>; interconnect-names = "sdhc-ddr","cpu-sdhc"; iommus = <&apps_smmu 0x4a0 0x0>; power-domains = <&rpmhpd SM8350_CX>; From b814eda949c324791580003303aa608761cfde3f Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Sat, 31 Dec 2022 13:40:25 +0800 Subject: [PATCH 019/398] soc: imx: imx8mp-blk-ctrl: enable global pixclk with HDMI_TX_PHY PD NXP internal information shows that the PHY refclk is gated by the GLOBAL_TX_PIX_CLK_EN bit, so to allow the PHY PLL to lock without the LCDIF being already active, tie this bit to the HDMI_TX_PHY power domain. Fixes: e3442022f543 ("soc: imx: add i.MX8MP HDMI blk-ctrl") Signed-off-by: Lucas Stach Signed-off-by: Shawn Guo --- drivers/soc/imx/imx8mp-blk-ctrl.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c index 0e3b6ba22f94..9852714eb2a4 100644 --- a/drivers/soc/imx/imx8mp-blk-ctrl.c +++ b/drivers/soc/imx/imx8mp-blk-ctrl.c @@ -212,7 +212,7 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, break; case IMX8MP_HDMIBLK_PD_LCDIF: regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, - BIT(7) | BIT(16) | BIT(17) | BIT(18) | + BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20)); regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(11)); regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, @@ -241,6 +241,7 @@ static void imx8mp_hdmi_blk_ctrl_power_on(struct imx8mp_blk_ctrl *bc, regmap_set_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(1)); break; case IMX8MP_HDMIBLK_PD_HDMI_TX_PHY: + regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(7)); regmap_set_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24)); regmap_set_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); regmap_clear_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3)); @@ -270,7 +271,7 @@ static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, BIT(4) | BIT(5) | BIT(6)); regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(11)); regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, - BIT(7) | BIT(16) | BIT(17) | BIT(18) | + BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20)); break; case IMX8MP_HDMIBLK_PD_PAI: @@ -298,6 +299,7 @@ static void imx8mp_hdmi_blk_ctrl_power_off(struct imx8mp_blk_ctrl *bc, case IMX8MP_HDMIBLK_PD_HDMI_TX_PHY: regmap_set_bits(bc->regmap, HDMI_TX_CONTROL0, BIT(3)); regmap_clear_bits(bc->regmap, HDMI_RTX_RESET_CTL0, BIT(12)); + regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL0, BIT(7)); regmap_clear_bits(bc->regmap, HDMI_RTX_CLK_CTL1, BIT(22) | BIT(24)); break; case IMX8MP_HDMIBLK_PD_HDCP: From 8a1ed98fe0f2e7669f0409de0f46f317b275f8be Mon Sep 17 00:00:00 2001 From: Li Jun Date: Fri, 30 Sep 2022 22:54:23 +0800 Subject: [PATCH 020/398] arm64: dts: imx8mp: correct usb clocks After commit cf7f3f4fa9e5 ("clk: imx8mp: fix usb_root_clk parent"), usb_root_clk is no longer for suspend clock so update dts accordingly to use right bus clock and suspend clock. Fixes: fb8587a2c165 ("arm64: dtsi: imx8mp: add usb nodes") Cc: stable@vger.kernel.org # ed1f4ccfe947: clk: imx: imx8mp: add shared clk gate for usb suspend clk Cc: stable@vger.kernel.org # v5.19+ Reviewed-by: Peng Fan Tested-by: Alexander Stein Signed-off-by: Li Jun Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp.dtsi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index 7a6e6221f421..6a04d81c69e6 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -1297,7 +1297,7 @@ reg = <0x32f10100 0x8>, <0x381f0000 0x20>; clocks = <&clk IMX8MP_CLK_HSIO_ROOT>, - <&clk IMX8MP_CLK_USB_ROOT>; + <&clk IMX8MP_CLK_USB_SUSP>; clock-names = "hsio", "suspend"; interrupts = ; power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_USB>; @@ -1310,9 +1310,9 @@ usb_dwc3_0: usb@38100000 { compatible = "snps,dwc3"; reg = <0x38100000 0x10000>; - clocks = <&clk IMX8MP_CLK_HSIO_AXI>, + clocks = <&clk IMX8MP_CLK_USB_ROOT>, <&clk IMX8MP_CLK_USB_CORE_REF>, - <&clk IMX8MP_CLK_USB_ROOT>; + <&clk IMX8MP_CLK_USB_SUSP>; clock-names = "bus_early", "ref", "suspend"; interrupts = ; phys = <&usb3_phy0>, <&usb3_phy0>; @@ -1339,7 +1339,7 @@ reg = <0x32f10108 0x8>, <0x382f0000 0x20>; clocks = <&clk IMX8MP_CLK_HSIO_ROOT>, - <&clk IMX8MP_CLK_USB_ROOT>; + <&clk IMX8MP_CLK_USB_SUSP>; clock-names = "hsio", "suspend"; interrupts = ; power-domains = <&hsio_blk_ctrl IMX8MP_HSIOBLK_PD_USB>; @@ -1352,9 +1352,9 @@ usb_dwc3_1: usb@38200000 { compatible = "snps,dwc3"; reg = <0x38200000 0x10000>; - clocks = <&clk IMX8MP_CLK_HSIO_AXI>, + clocks = <&clk IMX8MP_CLK_USB_ROOT>, <&clk IMX8MP_CLK_USB_CORE_REF>, - <&clk IMX8MP_CLK_USB_ROOT>; + <&clk IMX8MP_CLK_USB_SUSP>; clock-names = "bus_early", "ref", "suspend"; interrupts = ; phys = <&usb3_phy1>, <&usb3_phy1>; From cfd04dd1c4b6c33afc2a934b957d71cf8ddd1539 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 21 Nov 2022 13:29:11 -0300 Subject: [PATCH 021/398] arm64: dts: imx8mp-phycore-som: Remove invalid PMIC property 'regulator-compatible' is not a valid property according to nxp,pca9450-regulator.yaml and causes the following warning: DTC_CHK arch/arm64/boot/dts/freescale/imx8mp-dhcom-pdk2.dtb ... pmic@25: regulators:LDO1: Unevaluated properties are not allowed ('regulator-compatible' was unexpected) Remove the invalid 'regulator-compatible' property. Cc: Teresa Remmet Fixes: 88f7f6bcca37 ("arm64: dts: freescale: Add support for phyBOARD-Pollux-i.MX8MP") Signed-off-by: Fabio Estevam Reviewed-by: Teresa Remmet Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi index 79b290a002c1..ecc4bce6db97 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-phycore-som.dtsi @@ -99,7 +99,6 @@ regulators { buck1: BUCK1 { - regulator-compatible = "BUCK1"; regulator-min-microvolt = <600000>; regulator-max-microvolt = <2187500>; regulator-boot-on; @@ -108,7 +107,6 @@ }; buck2: BUCK2 { - regulator-compatible = "BUCK2"; regulator-min-microvolt = <600000>; regulator-max-microvolt = <2187500>; regulator-boot-on; @@ -119,7 +117,6 @@ }; buck4: BUCK4 { - regulator-compatible = "BUCK4"; regulator-min-microvolt = <600000>; regulator-max-microvolt = <3400000>; regulator-boot-on; @@ -127,7 +124,6 @@ }; buck5: BUCK5 { - regulator-compatible = "BUCK5"; regulator-min-microvolt = <600000>; regulator-max-microvolt = <3400000>; regulator-boot-on; @@ -135,7 +131,6 @@ }; buck6: BUCK6 { - regulator-compatible = "BUCK6"; regulator-min-microvolt = <600000>; regulator-max-microvolt = <3400000>; regulator-boot-on; @@ -143,7 +138,6 @@ }; ldo1: LDO1 { - regulator-compatible = "LDO1"; regulator-min-microvolt = <1600000>; regulator-max-microvolt = <3300000>; regulator-boot-on; @@ -151,7 +145,6 @@ }; ldo2: LDO2 { - regulator-compatible = "LDO2"; regulator-min-microvolt = <800000>; regulator-max-microvolt = <1150000>; regulator-boot-on; @@ -159,7 +152,6 @@ }; ldo3: LDO3 { - regulator-compatible = "LDO3"; regulator-min-microvolt = <800000>; regulator-max-microvolt = <3300000>; regulator-boot-on; @@ -167,13 +159,11 @@ }; ldo4: LDO4 { - regulator-compatible = "LDO4"; regulator-min-microvolt = <800000>; regulator-max-microvolt = <3300000>; }; ldo5: LDO5 { - regulator-compatible = "LDO5"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; regulator-boot-on; From 94e2cf1e0db5b06c7a6ae0878c5cbec925819a8a Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 21 Nov 2022 13:31:23 -0300 Subject: [PATCH 022/398] ARM: dts: imx6ul-pico-dwarf: Use 'clock-frequency' 'clock_frequency' is not a valid property. Use the correct 'clock-frequency' instead. Fixes: 47246fafef84 ("ARM: dts: imx6ul-pico: Add support for the dwarf baseboard") Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6ul-pico-dwarf.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6ul-pico-dwarf.dts b/arch/arm/boot/dts/imx6ul-pico-dwarf.dts index 162dc259edc8..5a74c7f68eb6 100644 --- a/arch/arm/boot/dts/imx6ul-pico-dwarf.dts +++ b/arch/arm/boot/dts/imx6ul-pico-dwarf.dts @@ -32,7 +32,7 @@ }; &i2c2 { - clock_frequency = <100000>; + clock-frequency = <100000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; status = "okay"; From f4dd0845c4f1f5371f1e06fef0e4a1734a2db964 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 21 Nov 2022 13:31:24 -0300 Subject: [PATCH 023/398] ARM: dts: imx7d-pico: Use 'clock-frequency' 'clock_frequency' is not a valid property. Use the correct 'clock-frequency' instead. Fixes: 8b646cfb84c3 ("ARM: dts: imx7d-pico: Add support for the dwarf baseboard") Fixes: 6418fd92417f ("ARM: dts: imx7d-pico: Add support for the nymph baseboard") Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx7d-pico-dwarf.dts | 4 ++-- arch/arm/boot/dts/imx7d-pico-nymph.dts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/boot/dts/imx7d-pico-dwarf.dts b/arch/arm/boot/dts/imx7d-pico-dwarf.dts index 5162fe227d1e..fdc10563f147 100644 --- a/arch/arm/boot/dts/imx7d-pico-dwarf.dts +++ b/arch/arm/boot/dts/imx7d-pico-dwarf.dts @@ -32,7 +32,7 @@ }; &i2c1 { - clock_frequency = <100000>; + clock-frequency = <100000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; @@ -52,7 +52,7 @@ }; &i2c4 { - clock_frequency = <100000>; + clock-frequency = <100000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; diff --git a/arch/arm/boot/dts/imx7d-pico-nymph.dts b/arch/arm/boot/dts/imx7d-pico-nymph.dts index 104a85254adb..5afb1674e012 100644 --- a/arch/arm/boot/dts/imx7d-pico-nymph.dts +++ b/arch/arm/boot/dts/imx7d-pico-nymph.dts @@ -43,7 +43,7 @@ }; &i2c1 { - clock_frequency = <100000>; + clock-frequency = <100000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; @@ -64,7 +64,7 @@ }; &i2c2 { - clock_frequency = <100000>; + clock-frequency = <100000>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; status = "okay"; From 9dfbc72256b5de608ad10989bcbafdbbd1ac8d4e Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 21 Nov 2022 17:22:59 -0300 Subject: [PATCH 024/398] ARM: dts: imx6qdl-gw560x: Remove incorrect 'uart-has-rtscts' The following build warning is seen when running: make dtbs_check DT_SCHEMA_FILES=fsl-imx-uart.yaml arch/arm/boot/dts/imx6dl-gw560x.dtb: serial@2020000: rts-gpios: False schema does not allow [[20, 1, 0]] From schema: Documentation/devicetree/bindings/serial/fsl-imx-uart.yaml The imx6qdl-gw560x board does not expose the UART RTS and CTS as native UART pins, so 'uart-has-rtscts' should not be used. Using 'uart-has-rtscts' with 'rts-gpios' is an invalid combination detected by serial.yaml. Fix the problem by removing the incorrect 'uart-has-rtscts' property. Fixes: b8a559feffb2 ("ARM: dts: imx: add Gateworks Ventana GW5600 support") Signed-off-by: Fabio Estevam Acked-by: Tim Harvey Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx6qdl-gw560x.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/boot/dts/imx6qdl-gw560x.dtsi b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi index 4bc4371e6bae..4b81a975c979 100644 --- a/arch/arm/boot/dts/imx6qdl-gw560x.dtsi +++ b/arch/arm/boot/dts/imx6qdl-gw560x.dtsi @@ -632,7 +632,6 @@ &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; - uart-has-rtscts; rts-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; status = "okay"; }; From 0d1d030f00f3f3eea04017cbd50ffe44a2842ebc Mon Sep 17 00:00:00 2001 From: Emanuele Ghidoli Date: Thu, 1 Dec 2022 13:55:48 +0100 Subject: [PATCH 025/398] arm64: dts: verdin-imx8mm: fix dahlia audio playback Set optional `simple-audio-card,mclk-fs` parameter to ensure a proper clock to the wm8904 audio codec. Without this change with an audio stream rate of 44.1 kHz the playback is completely distorted. Fixes: 6a57f224f734 ("arm64: dts: freescale: add initial support for verdin imx8m mini") Signed-off-by: Emanuele Ghidoli Signed-off-by: Francesco Dolcini Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi index c2a5c2f7b204..7c3f5c54f040 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dahlia.dtsi @@ -9,6 +9,7 @@ simple-audio-card,bitclock-master = <&dailink_master>; simple-audio-card,format = "i2s"; simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,mclk-fs = <256>; simple-audio-card,name = "imx8mm-wm8904"; simple-audio-card,routing = "Headphone Jack", "HPOUTL", From f78985f9f58380eec37f82c8a2c765aa7670fc29 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 2 Dec 2022 17:49:18 +0100 Subject: [PATCH 026/398] ARM: dts: imx: Fix pca9547 i2c-mux node name "make dtbs_check": arch/arm/boot/dts/imx53-ppd.dtb: i2c-switch@70: $nodename:0: 'i2c-switch@70' does not match '^(i2c-?)?mux' From schema: Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml arch/arm/boot/dts/imx53-ppd.dtb: i2c-switch@70: Unevaluated properties are not allowed ('#address-cells', '#size-cells', 'i2c@0', 'i2c@1', 'i2c@2', 'i2c@3', 'i2c@4', 'i2c@5', 'i2c@6', 'i2c@7' were unexpected) From schema: Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml Fix this by renaming the PCA9547 node to "i2c-mux", to match the I2C bus multiplexer/switch DT bindings and the Generic Names Recommendation in the Devicetree Specification. Signed-off-by: Geert Uytterhoeven Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx53-ppd.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/imx53-ppd.dts b/arch/arm/boot/dts/imx53-ppd.dts index 37d0cffea99c..70c4a4852256 100644 --- a/arch/arm/boot/dts/imx53-ppd.dts +++ b/arch/arm/boot/dts/imx53-ppd.dts @@ -488,7 +488,7 @@ scl-gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>; status = "okay"; - i2c-switch@70 { + i2c-mux@70 { compatible = "nxp,pca9547"; #address-cells = <1>; #size-cells = <0>; From 42825d1f269355d63554ab3c3762611e4d8053e9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 2 Dec 2022 17:49:21 +0100 Subject: [PATCH 027/398] ARM: dts: vf610: Fix pca9548 i2c-mux node names "make dtbs_check": arch/arm/boot/dts/vf610-zii-dev-rev-b.dtb: tca9548@70: $nodename:0: 'tca9548@70' does not match '^(i2c-?)?mux' From schema: Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml arch/arm/boot/dts/vf610-zii-dev-rev-b.dtb: tca9548@70: Unevaluated properties are not allowed ('#address-cells', '#size-cells', 'i2c@0', 'i2c@1', 'i2c@2', 'i2c@3', 'i2c@4' were unexpected) From schema: /scratch/geert/linux/linux-renesas/Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml ... Fix this by renaming PCA9548 nodes to "i2c-mux", to match the I2C bus multiplexer/switch DT bindings and the Generic Names Recommendation in the Devicetree Specification. Signed-off-by: Geert Uytterhoeven Signed-off-by: Shawn Guo --- arch/arm/boot/dts/vf610-zii-dev-rev-b.dts | 2 +- arch/arm/boot/dts/vf610-zii-dev-rev-c.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts index 42ed4a04a12e..6280c5e86a12 100644 --- a/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts +++ b/arch/arm/boot/dts/vf610-zii-dev-rev-b.dts @@ -345,7 +345,7 @@ }; &i2c2 { - tca9548@70 { + i2c-mux@70 { compatible = "nxp,pca9548"; pinctrl-0 = <&pinctrl_i2c_mux_reset>; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts b/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts index f892977da9e4..c00d39562a10 100644 --- a/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts +++ b/arch/arm/boot/dts/vf610-zii-dev-rev-c.dts @@ -340,7 +340,7 @@ }; &i2c2 { - tca9548@70 { + i2c-mux@70 { compatible = "nxp,pca9548"; pinctrl-0 = <&pinctrl_i2c_mux_reset>; pinctrl-names = "default"; From b025b4f5c288e29bbea421613a5b4eacf9261fbb Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 2 Dec 2022 17:49:22 +0100 Subject: [PATCH 028/398] arm64: dts: freescale: Fix pca954x i2c-mux node names "make dtbs_check": arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dtb: pca9547@77: $nodename:0: 'pca9547@77' does not match '^(i2c-?)?mux' From schema: Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dtb: pca9547@77: Unevaluated properties are not allowed ('#address-cells', '#size-cells', 'i2c@4' were unexpected) From schema: Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.yaml ... Fix this by renaming PCA954x nodes to "i2c-mux", to match the I2C bus multiplexer/switch DT bindings and the Generic Names Recommendation in the Devicetree Specification. Signed-off-by: Geert Uytterhoeven Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts | 2 +- arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts | 2 +- arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts | 2 +- arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts | 2 +- arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts | 2 +- arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts | 2 +- arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi | 2 +- arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi | 2 +- arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi | 2 +- arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dts | 2 +- arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts | 4 ++-- arch/arm64/boot/dts/freescale/imx8qxp-mek.dts | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts index 5a8d85a7d161..bbdf989058ff 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts @@ -110,7 +110,7 @@ &i2c0 { status = "okay"; - pca9547@77 { + i2c-mux@77 { compatible = "nxp,pca9547"; reg = <0x77>; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts index 9b726c2a4842..dda27ed7aaf2 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1043a-qds.dts @@ -89,7 +89,7 @@ &i2c0 { status = "okay"; - pca9547@77 { + i2c-mux@77 { compatible = "nxp,pca9547"; reg = <0x77>; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts index b2fcbba60d3a..3b0ed9305f2b 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-qds.dts @@ -88,7 +88,7 @@ &i2c0 { status = "okay"; - pca9547@77 { + i2c-mux@77 { compatible = "nxp,pca9547"; reg = <0x77>; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts index 41d8b15f25a5..aa52ff73ff9e 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts @@ -53,7 +53,7 @@ &i2c0 { status = "okay"; - i2c-switch@77 { + i2c-mux@77 { compatible = "nxp,pca9547"; reg = <0x77>; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts index 1bfbce69cc8b..ee8e932628d1 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts @@ -136,7 +136,7 @@ &i2c0 { status = "okay"; - i2c-switch@77 { + i2c-mux@77 { compatible = "nxp,pca9547"; reg = <0x77>; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts b/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts index ef6c8967533e..d4867d6cf47c 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts +++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-ten64.dts @@ -245,7 +245,7 @@ &i2c3 { status = "okay"; - i2c-switch@70 { + i2c-mux@70 { compatible = "nxp,pca9540"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi index f598669e742f..52c5a43b30a0 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-qds.dtsi @@ -103,7 +103,7 @@ &i2c0 { status = "okay"; - pca9547@77 { + i2c-mux@77 { compatible = "nxp,pca9547"; reg = <0x77>; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi index 3d9647b3da14..537cecb13dd0 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi @@ -44,7 +44,7 @@ &i2c0 { status = "okay"; - pca9547@75 { + i2c-mux@75 { compatible = "nxp,pca9547"; reg = <0x75>; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi index afb455210bd0..d32a52ab00a4 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi @@ -54,7 +54,7 @@ &i2c0 { status = "okay"; - i2c-switch@77 { + i2c-mux@77 { compatible = "nxp,pca9547"; #address-cells = <1>; #size-cells = <0>; diff --git a/arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dts b/arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dts index 74c09891600f..6357078185ed 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-nitrogen-r2.dts @@ -214,7 +214,7 @@ pinctrl-0 = <&pinctrl_i2c3>; status = "okay"; - i2cmux@70 { + i2c-mux@70 { compatible = "nxp,pca9540"; reg = <0x70>; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts b/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts index 9dda2a1554c3..8614c18b5998 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts @@ -133,7 +133,7 @@ pinctrl-0 = <&pinctrl_i2c1>; status = "okay"; - i2cmux@70 { + i2c-mux@70 { compatible = "nxp,pca9546"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1_pca9546>; @@ -216,7 +216,7 @@ pinctrl-0 = <&pinctrl_i2c4>; status = "okay"; - pca9546: i2cmux@70 { + pca9546: i2c-mux@70 { compatible = "nxp,pca9546"; reg = <0x70>; #address-cells = <1>; diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts index 07d8dd8160f6..afa883389456 100644 --- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts +++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts @@ -61,7 +61,7 @@ pinctrl-0 = <&pinctrl_lpi2c1 &pinctrl_ioexp_rst>; status = "okay"; - i2c-switch@71 { + i2c-mux@71 { compatible = "nxp,pca9646", "nxp,pca9546"; #address-cells = <1>; #size-cells = <0>; From 5225ba9db112ec4ed67da5e4d8b72e618573955e Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Fri, 2 Dec 2022 13:10:37 -0600 Subject: [PATCH 029/398] arm64: dts: imx8mm-beacon: Fix ecspi2 pinmux Early hardware did not support hardware handshaking on the UART, but final production hardware did. When the hardware was updated the chip select was changed to facilitate hardware handshaking on UART3. Fix the ecspi2 pin mux to eliminate a pin conflict with UART3 and allow the EEPROM to operate again. Fixes: 4ce01ce36d77 ("arm64: dts: imx8mm-beacon: Enable RTS-CTS on UART3") Signed-off-by: Adam Ford Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi index 03266bd90a06..169f047fbca5 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi @@ -120,7 +120,7 @@ &ecspi2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_espi2>; - cs-gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; + cs-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; status = "okay"; eeprom@0 { @@ -316,7 +316,7 @@ MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82 MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82 MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82 - MX8MM_IOMUXC_ECSPI1_SS0_GPIO5_IO9 0x41 + MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x41 >; }; From ef10d57936ead5e817ef7cea6a87531085e77773 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Sun, 4 Dec 2022 10:44:17 +0100 Subject: [PATCH 030/398] arm64: dts: imx8mq-thor96: fix no-mmc property for SDHCI There is no "no-emmc" property, so intention for SD/SDIO only nodes was to use "no-mmc". Signed-off-by: Krzysztof Kozlowski Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mq-thor96.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts b/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts index 5d5aa6537225..6e6182709d22 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts @@ -339,7 +339,7 @@ bus-width = <4>; non-removable; no-sd; - no-emmc; + no-mmc; status = "okay"; brcmf: wifi@1 { @@ -359,7 +359,7 @@ cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; bus-width = <4>; no-sdio; - no-emmc; + no-mmc; disable-wp; status = "okay"; }; From 6c620a30515c494b5eeb3dc0e40d3220ea04c53b Mon Sep 17 00:00:00 2001 From: Emanuele Ghidoli Date: Wed, 7 Dec 2022 11:27:49 +0100 Subject: [PATCH 031/398] arm64: dts: verdin-imx8mm: fix dev board audio playback Set optional `simple-audio-card,mclk-fs` parameter to ensure a proper clock to the nau8822 audio codec. Without this change with an audio stream rate of 44.1 kHz the playback is faster. Set the MCLK at the right frequency, codec can properly use it to generate 44.1 kHz I2S-FS. Fixes: 6a57f224f734 ("arm64: dts: freescale: add initial support for verdin imx8m mini") Signed-off-by: Emanuele Ghidoli Signed-off-by: Francesco Dolcini Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi index 73cc3fafa018..b2bcd2282170 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-dev.dtsi @@ -11,6 +11,7 @@ simple-audio-card,bitclock-master = <&dailink_master>; simple-audio-card,format = "i2s"; simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,mclk-fs = <256>; simple-audio-card,name = "imx8mm-nau8822"; simple-audio-card,routing = "Headphones", "LHP", From 62f0147fd4d86620853bee027800f988d3013656 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Thu, 8 Dec 2022 17:06:58 +0800 Subject: [PATCH 032/398] arm64: dts: imx93-11x11-evk: correct clock and strobe pad setting For clock and strobe pad of usdhc, need to config as pull down. Current pad config set these pad as both pull up and pull down, this is wrong, so fix it here. Find this issue when enable HS400ES mode on one Micron eMMC chip, CMD8 always meet CRC error in HS400ES/HS400 mode. Fixes: e37907bd8294 ("arm64: dts: freescale: add i.MX93 11x11 EVK basic support") Signed-off-by: Haibo Chen Reviewed-by: Peng Fan Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts index 69786c326db0..27f9a9f33134 100644 --- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts @@ -74,7 +74,7 @@ pinctrl_usdhc1: usdhc1grp { fsl,pins = < - MX93_PAD_SD1_CLK__USDHC1_CLK 0x17fe + MX93_PAD_SD1_CLK__USDHC1_CLK 0x15fe MX93_PAD_SD1_CMD__USDHC1_CMD 0x13fe MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x13fe MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x13fe @@ -84,7 +84,7 @@ MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x13fe MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x13fe MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x13fe - MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x17fe + MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe >; }; @@ -102,7 +102,7 @@ pinctrl_usdhc2: usdhc2grp { fsl,pins = < - MX93_PAD_SD2_CLK__USDHC2_CLK 0x17fe + MX93_PAD_SD2_CLK__USDHC2_CLK 0x15fe MX93_PAD_SD2_CMD__USDHC2_CMD 0x13fe MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x13fe MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x13fe From 87b30c4b0efb6a194a7b8eac2568a3da520d905f Mon Sep 17 00:00:00 2001 From: Dario Binacchi Date: Thu, 8 Dec 2022 17:54:03 +0100 Subject: [PATCH 033/398] ARM: imx: add missing of_node_put() Calling of_find_compatible_node() returns a node pointer with refcount incremented. Use of_node_put() on it when done. The patch fixes the same problem on different i.MX platforms. Fixes: 8b88f7ef31dde ("ARM: mx25: Retrieve IIM base from dt") Fixes: 94b2bec1b0e05 ("ARM: imx27: Retrieve the SYSCTRL base address from devicetree") Fixes: 3172225d45bd9 ("ARM: imx31: Retrieve the IIM base address from devicetree") Fixes: f68ea682d1da7 ("ARM: imx35: Retrieve the IIM base address from devicetree") Fixes: ee18a7154ee08 ("ARM: imx5: retrieve iim base from device tree") Signed-off-by: Dario Binacchi Reviewed-by: Fabio Estevam Reviewed-by: Martin Kaiser Signed-off-by: Shawn Guo --- arch/arm/mach-imx/cpu-imx25.c | 1 + arch/arm/mach-imx/cpu-imx27.c | 1 + arch/arm/mach-imx/cpu-imx31.c | 1 + arch/arm/mach-imx/cpu-imx35.c | 1 + arch/arm/mach-imx/cpu-imx5.c | 1 + 5 files changed, 5 insertions(+) diff --git a/arch/arm/mach-imx/cpu-imx25.c b/arch/arm/mach-imx/cpu-imx25.c index 3e63445cde06..cc86977d0a34 100644 --- a/arch/arm/mach-imx/cpu-imx25.c +++ b/arch/arm/mach-imx/cpu-imx25.c @@ -23,6 +23,7 @@ static int mx25_read_cpu_rev(void) np = of_find_compatible_node(NULL, NULL, "fsl,imx25-iim"); iim_base = of_iomap(np, 0); + of_node_put(np); BUG_ON(!iim_base); rev = readl(iim_base + MXC_IIMSREV); iounmap(iim_base); diff --git a/arch/arm/mach-imx/cpu-imx27.c b/arch/arm/mach-imx/cpu-imx27.c index bf70e13bbe9e..1d2893908368 100644 --- a/arch/arm/mach-imx/cpu-imx27.c +++ b/arch/arm/mach-imx/cpu-imx27.c @@ -28,6 +28,7 @@ static int mx27_read_cpu_rev(void) np = of_find_compatible_node(NULL, NULL, "fsl,imx27-ccm"); ccm_base = of_iomap(np, 0); + of_node_put(np); BUG_ON(!ccm_base); /* * now we have access to the IO registers. As we need diff --git a/arch/arm/mach-imx/cpu-imx31.c b/arch/arm/mach-imx/cpu-imx31.c index b9c24b851d1a..35c544924e50 100644 --- a/arch/arm/mach-imx/cpu-imx31.c +++ b/arch/arm/mach-imx/cpu-imx31.c @@ -39,6 +39,7 @@ static int mx31_read_cpu_rev(void) np = of_find_compatible_node(NULL, NULL, "fsl,imx31-iim"); iim_base = of_iomap(np, 0); + of_node_put(np); BUG_ON(!iim_base); /* read SREV register from IIM module */ diff --git a/arch/arm/mach-imx/cpu-imx35.c b/arch/arm/mach-imx/cpu-imx35.c index 80e7d8ab9f1b..1fe75b39c2d9 100644 --- a/arch/arm/mach-imx/cpu-imx35.c +++ b/arch/arm/mach-imx/cpu-imx35.c @@ -21,6 +21,7 @@ static int mx35_read_cpu_rev(void) np = of_find_compatible_node(NULL, NULL, "fsl,imx35-iim"); iim_base = of_iomap(np, 0); + of_node_put(np); BUG_ON(!iim_base); rev = imx_readl(iim_base + MXC_IIMSREV); diff --git a/arch/arm/mach-imx/cpu-imx5.c b/arch/arm/mach-imx/cpu-imx5.c index ad56263778f9..a67c89bf155d 100644 --- a/arch/arm/mach-imx/cpu-imx5.c +++ b/arch/arm/mach-imx/cpu-imx5.c @@ -28,6 +28,7 @@ static u32 imx5_read_srev_reg(const char *compat) np = of_find_compatible_node(NULL, NULL, compat); iim_base = of_iomap(np, 0); + of_node_put(np); WARN_ON(!iim_base); srev = readl(iim_base + IIM_SREV) & 0xff; From c10a5855488bbd9912ddae3ad2d1f2e4b1a3c275 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Fri, 16 Dec 2022 01:05:26 +0100 Subject: [PATCH 034/398] arm64: dts: imx8mm: Drop xtal clock specifier from eDM SBC The clk_xtal32k have clock-cells = <0>, drop the bogus specifier. Fixes: 9509593f327a ("arm64: dts: imx8mm: Model PMIC to SNVS RTC clock path on Data Modul i.MX8M Mini eDM SBC") Signed-off-by: Marek Vasut Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dts b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dts index 24f61db33eba..752f409a30b1 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dts @@ -275,7 +275,7 @@ compatible = "rohm,bd71847"; reg = <0x4b>; #clock-cells = <0>; - clocks = <&clk_xtal32k 0>; + clocks = <&clk_xtal32k>; clock-output-names = "clk-32k-out"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pmic>; From 21b84ebeee79d91e405f87f051e9489ef30ecad6 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Fri, 26 Aug 2022 21:13:03 +0200 Subject: [PATCH 035/398] soc: imx: imx8mp-blk-ctrl: don't set power device name Setting the device name after it has been registered confuses the sysfs cleanup paths. This has already been fixed for the imx8m-blk-ctrl driver in b64b46fbaa1d ("Revert "soc: imx: imx8m-blk-ctrl: set power device name""), but the same problem exists in imx8mp-blk-ctrl. Fixes: 556f5cf9568a ("soc: imx: add i.MX8MP HSIO blk-ctrl") Signed-off-by: Lucas Stach Reviewed-by: Peng Fan Signed-off-by: Shawn Guo --- drivers/soc/imx/imx8mp-blk-ctrl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/soc/imx/imx8mp-blk-ctrl.c b/drivers/soc/imx/imx8mp-blk-ctrl.c index 9852714eb2a4..0f13853901df 100644 --- a/drivers/soc/imx/imx8mp-blk-ctrl.c +++ b/drivers/soc/imx/imx8mp-blk-ctrl.c @@ -592,7 +592,6 @@ static int imx8mp_blk_ctrl_probe(struct platform_device *pdev) ret = PTR_ERR(domain->power_dev); goto cleanup_pds; } - dev_set_name(domain->power_dev, "%s", data->name); domain->genpd.name = data->name; domain->genpd.power_on = imx8mp_blk_ctrl_power_on; From b3b75ace2085aca623c57e04ea7218ae690090fb Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sat, 17 Dec 2022 12:08:48 -0600 Subject: [PATCH 036/398] arm64: dts: imx8mp: Fix missing GPC Interrupt The GPC node references an interrupt parent, but it doesn't state the interrupt itself. According to the TRM, this IRQ is 87. This also eliminate an error detected from dt_binding_check Fixes: fc0f05124621 ("arm64: dts: imx8mp: add GPC node with GPU power domains") Signed-off-by: Adam Ford Reviewed-by: Laurent Pinchart Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index 6a04d81c69e6..f26b1b26f4a3 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -524,6 +524,7 @@ compatible = "fsl,imx8mp-gpc"; reg = <0x303a0000 0x1000>; interrupt-parent = <&gic>; + interrupts = ; interrupt-controller; #interrupt-cells = <3>; From 10e2f328bd900787fd2db24e474f87e1d525ccc4 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sat, 17 Dec 2022 12:08:49 -0600 Subject: [PATCH 037/398] arm64: dts: imx8mp: Fix power-domain typo dt_binding_check detects an issue with the pgc_hsiomix power domain: pgc: 'power-domains@17' does not match any of the regexes This is because 'power-domains' should be 'power-domain' Fixes: 2ae42e0c0b67 ("arm64: dts: imx8mp: add HSIO power-domains") Signed-off-by: Adam Ford Reviewed-by: Laurent Pinchart Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index f26b1b26f4a3..03034b439c1f 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -591,7 +591,7 @@ reg = ; }; - pgc_hsiomix: power-domains@17 { + pgc_hsiomix: power-domain@17 { #power-domain-cells = <0>; reg = ; clocks = <&clk IMX8MP_CLK_HSIO_AXI>, From 9a65c759e4666476a6642ad87b4db8a67cb957d0 Mon Sep 17 00:00:00 2001 From: Marco Felsch Date: Sun, 1 Jan 2023 12:50:42 +0800 Subject: [PATCH 038/398] arm64: dts: imx8mp-evk: pcie0-refclk cosmetic cleanup Use the correct indention. Fixes: d50650500064 ("arm64: dts: imx8mp-evk: Add PCIe support") Signed-off-by: Marco Felsch Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts index d4c7ca16abd0..f2d93437084b 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -36,8 +36,8 @@ pcie0_refclk: pcie0-refclk { compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <100000000>; + #clock-cells = <0>; + clock-frequency = <100000000>; }; reg_can1_stby: regulator-can1-stby { From cc2e9d2b26c86c1dd8687f6916e5f621bcacd6f7 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Tue, 27 Dec 2022 22:05:48 -0800 Subject: [PATCH 039/398] mm, slab: periodically resched in drain_freelist() drain_freelist() can be called with a very large number of slabs to free, such as for kmem_cache_shrink(), or depending on various settings of the slab cache when doing periodic reaping. If there is a potentially long list of slabs to drain, periodically schedule to ensure we aren't saturating the cpu for too long. Signed-off-by: David Rientjes Reviewed-by: Hyeonggon Yoo <42.hyeyoo@gmail.com> Signed-off-by: Vlastimil Babka --- mm/slab.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm/slab.c b/mm/slab.c index 7a269db050ee..29300fc1289a 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2211,6 +2211,8 @@ static int drain_freelist(struct kmem_cache *cache, raw_spin_unlock_irq(&n->list_lock); slab_destroy(cache, slab); nr_freed++; + + cond_resched(); } out: return nr_freed; From 1e336aa0c0250ec84c6f16efac40c9f0138e367d Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Wed, 7 Dec 2022 19:23:15 +0800 Subject: [PATCH 040/398] mmc: sdhci-esdhc-imx: correct the tuning start tap and step setting Current code logic may be impacted by the setting of ROM/Bootloader, so unmask these bits first, then setting these bits accordingly. Fixes: 2b16cf326b70 ("mmc: sdhci-esdhc-imx: move tuning static configuration into hwinit function") Signed-off-by: Haibo Chen Acked-by: Adrian Hunter Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20221207112315.1812222-1-haibo.chen@nxp.com Signed-off-by: Ulf Hansson --- drivers/mmc/host/sdhci-esdhc-imx.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 89ef0c80ac37..9e73c34b6401 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -107,6 +107,7 @@ #define ESDHC_TUNING_START_TAP_DEFAULT 0x1 #define ESDHC_TUNING_START_TAP_MASK 0x7f #define ESDHC_TUNING_CMD_CRC_CHECK_DISABLE (1 << 7) +#define ESDHC_TUNING_STEP_DEFAULT 0x1 #define ESDHC_TUNING_STEP_MASK 0x00070000 #define ESDHC_TUNING_STEP_SHIFT 16 @@ -1368,7 +1369,7 @@ static void sdhci_esdhc_imx_hwinit(struct sdhci_host *host) struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host); struct cqhci_host *cq_host = host->mmc->cqe_private; - int tmp; + u32 tmp; if (esdhc_is_usdhc(imx_data)) { /* @@ -1423,17 +1424,24 @@ static void sdhci_esdhc_imx_hwinit(struct sdhci_host *host) if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) { tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL); - tmp |= ESDHC_STD_TUNING_EN | - ESDHC_TUNING_START_TAP_DEFAULT; - if (imx_data->boarddata.tuning_start_tap) { - tmp &= ~ESDHC_TUNING_START_TAP_MASK; + tmp |= ESDHC_STD_TUNING_EN; + + /* + * ROM code or bootloader may config the start tap + * and step, unmask them first. + */ + tmp &= ~(ESDHC_TUNING_START_TAP_MASK | ESDHC_TUNING_STEP_MASK); + if (imx_data->boarddata.tuning_start_tap) tmp |= imx_data->boarddata.tuning_start_tap; - } + else + tmp |= ESDHC_TUNING_START_TAP_DEFAULT; if (imx_data->boarddata.tuning_step) { - tmp &= ~ESDHC_TUNING_STEP_MASK; tmp |= imx_data->boarddata.tuning_step << ESDHC_TUNING_STEP_SHIFT; + } else { + tmp |= ESDHC_TUNING_STEP_DEFAULT + << ESDHC_TUNING_STEP_SHIFT; } /* Disable the CMD CRC check for tuning, if not, need to From b3d40c3ec3dc4ad78017de6c3a38979f57aaaab8 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang Date: Tue, 22 Nov 2022 21:48:23 +0800 Subject: [PATCH 041/398] HID: intel_ish-hid: Add check for ishtp_dma_tx_map As the kcalloc may return NULL pointer, it should be better to check the ishtp_dma_tx_map before use in order to avoid NULL pointer dereference. Fixes: 3703f53b99e4 ("HID: intel_ish-hid: ISH Transport layer") Signed-off-by: Jiasheng Jiang Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ishtp/dma-if.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/hid/intel-ish-hid/ishtp/dma-if.c b/drivers/hid/intel-ish-hid/ishtp/dma-if.c index 40554c8daca0..00046cbfd4ed 100644 --- a/drivers/hid/intel-ish-hid/ishtp/dma-if.c +++ b/drivers/hid/intel-ish-hid/ishtp/dma-if.c @@ -104,6 +104,11 @@ void *ishtp_cl_get_dma_send_buf(struct ishtp_device *dev, int required_slots = (size / DMA_SLOT_SIZE) + 1 * (size % DMA_SLOT_SIZE != 0); + if (!dev->ishtp_dma_tx_map) { + dev_err(dev->devc, "Fail to allocate Tx map\n"); + return NULL; + } + spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags); for (i = 0; i <= (dev->ishtp_dma_num_slots - required_slots); i++) { free = 1; @@ -150,6 +155,11 @@ void ishtp_cl_release_dma_acked_mem(struct ishtp_device *dev, return; } + if (!dev->ishtp_dma_tx_map) { + dev_err(dev->devc, "Fail to allocate Tx map\n"); + return; + } + i = (msg_addr - dev->ishtp_host_dma_tx_buf) / DMA_SLOT_SIZE; spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags); for (j = 0; j < acked_slots; j++) { From ae066f374687d7dd06bb8c732f66d6ab3c3fd480 Mon Sep 17 00:00:00 2001 From: Tim Harvey Date: Wed, 28 Dec 2022 12:26:06 -0800 Subject: [PATCH 042/398] arm64: dts: imx8mm-venice-gw7901: fix USB2 controller OC polarity The GW7901 has USB2 routed to a USB VBUS supply with over-current protection via an active-low pin. Define the OC pin polarity properly. Fixes: 2b1649a83afc ("arm64: dts: imx: Add i.mx8mm Gateworks gw7901 dts support") Signed-off-by: Tim Harvey Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts index 750a1f07ecb7..6433c205f8dd 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw7901.dts @@ -771,6 +771,7 @@ &usbotg2 { dr_mode = "host"; vbus-supply = <®_usb2_vbus>; + over-current-active-low; status = "okay"; }; From 490748874ebf1875420fc29b335bba2075dd1b5e Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Sat, 31 Dec 2022 13:58:48 +0400 Subject: [PATCH 043/398] soc: imx8m: Fix incorrect check for of_clk_get_by_name() of_clk_get_by_name() returns error pointers instead of NULL. Use IS_ERR() checks the return value to catch errors. Fixes: 836fb30949d9 ("soc: imx8m: Enable OCOTP clock before reading the register") Signed-off-by: Miaoqian Lin Signed-off-by: Shawn Guo --- drivers/soc/imx/soc-imx8m.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/imx/soc-imx8m.c b/drivers/soc/imx/soc-imx8m.c index 28144c699b0c..32ed9dc88e45 100644 --- a/drivers/soc/imx/soc-imx8m.c +++ b/drivers/soc/imx/soc-imx8m.c @@ -66,8 +66,8 @@ static u32 __init imx8mq_soc_revision(void) ocotp_base = of_iomap(np, 0); WARN_ON(!ocotp_base); clk = of_clk_get_by_name(np, NULL); - if (!clk) { - WARN_ON(!clk); + if (IS_ERR(clk)) { + WARN_ON(IS_ERR(clk)); return 0; } From 8509419758f2cc28dd05370385af0d91573b76b4 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Tue, 9 Aug 2022 21:25:09 -0500 Subject: [PATCH 044/398] mmc: sunxi-mmc: Fix clock refcount imbalance during unbind If the controller is suspended by runtime PM, the clock is already disabled, so do not try to disable it again during removal. Use pm_runtime_disable() to flush any pending runtime PM transitions. Fixes: 9a8e1e8cc2c0 ("mmc: sunxi: Add runtime_pm support") Signed-off-by: Samuel Holland Acked-by: Jernej Skrabec Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220810022509.43743-1-samuel@sholland.org Signed-off-by: Ulf Hansson --- drivers/mmc/host/sunxi-mmc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c index b16e12e62e72..3db9f32d6a7b 100644 --- a/drivers/mmc/host/sunxi-mmc.c +++ b/drivers/mmc/host/sunxi-mmc.c @@ -1492,9 +1492,11 @@ static int sunxi_mmc_remove(struct platform_device *pdev) struct sunxi_mmc_host *host = mmc_priv(mmc); mmc_remove_host(mmc); - pm_runtime_force_suspend(&pdev->dev); - disable_irq(host->irq); - sunxi_mmc_disable(host); + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) { + disable_irq(host->irq); + sunxi_mmc_disable(host); + } dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); mmc_free_host(mmc); From 13678f3feb3009b23aab424864fd0dac0765c83e Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 29 Oct 2022 22:56:36 -0700 Subject: [PATCH 045/398] reset: ti-sci: honor TI_SCI_PROTOCOL setting when not COMPILE_TEST There is a build error when COMPILE_TEST=y, TI_SCI_PROTOCOL=m, and RESET_TI_SCI=y: drivers/reset/reset-ti-sci.o: in function `ti_sci_reset_probe': reset-ti-sci.c:(.text+0x22c): undefined reference to `devm_ti_sci_get_handle' Fix this by making RESET_TI_SCI honor the Kconfig setting of TI_SCI_PROTOCOL when COMPILE_TEST is not set. When COMPILE_TEST is set, TI_SCI_PROTOCOL must be disabled (=n). Fixes: a6af504184c9 ("reset: ti-sci: Allow building under COMPILE_TEST") Signed-off-by: Randy Dunlap Reported-by: kernel test robot Cc: Nishanth Menon Cc: Tero Kristo Cc: Santosh Shilimkar Cc: linux-arm-kernel@lists.infradead.org Cc: Philipp Zabel Reviewed-by: Nishanth Menon Link: https://lore.kernel.org/r/20221030055636.3139-1-rdunlap@infradead.org Signed-off-by: Philipp Zabel --- drivers/reset/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index de176c2fbad9..2a52c990d4fe 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -257,7 +257,7 @@ config RESET_SUNXI config RESET_TI_SCI tristate "TI System Control Interface (TI-SCI) reset driver" - depends on TI_SCI_PROTOCOL || COMPILE_TEST + depends on TI_SCI_PROTOCOL || (COMPILE_TEST && TI_SCI_PROTOCOL=n) help This enables the reset driver support over TI System Control Interface available on some new TI's SoCs. If you wish to use reset resources From 3a2390c6777e3f6662980c6cfc25cafe9e4fef98 Mon Sep 17 00:00:00 2001 From: Hui Tang Date: Mon, 14 Nov 2022 08:49:58 +0800 Subject: [PATCH 046/398] reset: uniphier-glue: Fix possible null-ptr-deref It will cause null-ptr-deref when resource_size(res) invoked, if platform_get_resource() returns NULL. Fixes: 499fef09a323 ("reset: uniphier: add USB3 core reset control") Signed-off-by: Hui Tang Reviewed-by: Kunihiko Hayashi Link: https://lore.kernel.org/r/20221114004958.258513-1-tanghui20@huawei.com Signed-off-by: Philipp Zabel --- drivers/reset/reset-uniphier-glue.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/reset/reset-uniphier-glue.c b/drivers/reset/reset-uniphier-glue.c index 146fd5d45e99..15abac9fc72c 100644 --- a/drivers/reset/reset-uniphier-glue.c +++ b/drivers/reset/reset-uniphier-glue.c @@ -47,7 +47,6 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct uniphier_glue_reset_priv *priv; struct resource *res; - resource_size_t size; int i, ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -60,7 +59,6 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev) return -EINVAL; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - size = resource_size(res); priv->rdata.membase = devm_ioremap_resource(dev, res); if (IS_ERR(priv->rdata.membase)) return PTR_ERR(priv->rdata.membase); @@ -96,7 +94,7 @@ static int uniphier_glue_reset_probe(struct platform_device *pdev) spin_lock_init(&priv->rdata.lock); priv->rdata.rcdev.owner = THIS_MODULE; - priv->rdata.rcdev.nr_resets = size * BITS_PER_BYTE; + priv->rdata.rcdev.nr_resets = resource_size(res) * BITS_PER_BYTE; priv->rdata.rcdev.ops = &reset_simple_ops; priv->rdata.rcdev.of_node = dev->of_node; priv->rdata.active_low = true; From f6ca5059dc0d6608dc46070f48e396d611f240d6 Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 22 Dec 2022 18:38:19 +0000 Subject: [PATCH 047/398] firmware: arm_scmi: Clear stale xfer->hdr.status Stale error status reported from a previous message transaction must be cleared before starting a new transaction to avoid being confusingly reported in the following SCMI message dump traces. Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20221222183823.518856-2-cristian.marussi@arm.com Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/driver.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index f818d00bb2c6..ffdad59ec81f 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -910,6 +910,8 @@ static int do_xfer(const struct scmi_protocol_handle *ph, xfer->hdr.protocol_id, xfer->hdr.seq, xfer->hdr.poll_completion); + /* Clear any stale status */ + xfer->hdr.status = SCMI_SUCCESS; xfer->state = SCMI_XFER_SENT_OK; /* * Even though spinlocking is not needed here since no race is possible From ad78b81a1077f7d956952cd8bdfe1e61504e3eb8 Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 22 Dec 2022 18:38:20 +0000 Subject: [PATCH 048/398] firmware: arm_scmi: Harden shared memory access in fetch_response A misbheaving SCMI platform firmware could reply with out-of-spec messages, shorter than the mimimum size comprising a header and a status field. Harden shmem_fetch_response to properly truncate such a bad messages. Fixes: 5c8a47a5a91d ("firmware: arm_scmi: Make scmi core independent of the transport type") Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20221222183823.518856-3-cristian.marussi@arm.com Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/shmem.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c index 1dfe534b8518..135f8718000f 100644 --- a/drivers/firmware/arm_scmi/shmem.c +++ b/drivers/firmware/arm_scmi/shmem.c @@ -81,10 +81,11 @@ u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem) void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, struct scmi_xfer *xfer) { + size_t len = ioread32(&shmem->length); + xfer->hdr.status = ioread32(shmem->msg_payload); /* Skip the length of header and status in shmem area i.e 8 bytes */ - xfer->rx.len = min_t(size_t, xfer->rx.len, - ioread32(&shmem->length) - 8); + xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0); /* Take a copy to the rx buffer.. */ memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len); From 9bae076cd4e3e3c3dc185cae829d80b2dddec86e Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 22 Dec 2022 18:38:21 +0000 Subject: [PATCH 049/398] firmware: arm_scmi: Harden shared memory access in fetch_notification A misbheaving SCMI platform firmware could reply with out-of-spec notifications, shorter than the mimimum size comprising a header. Fixes: d5141f37c42e ("firmware: arm_scmi: Add notifications support in transport layer") Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20221222183823.518856-4-cristian.marussi@arm.com Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/shmem.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c index 135f8718000f..87b4f4d35f06 100644 --- a/drivers/firmware/arm_scmi/shmem.c +++ b/drivers/firmware/arm_scmi/shmem.c @@ -94,8 +94,10 @@ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem, size_t max_len, struct scmi_xfer *xfer) { + size_t len = ioread32(&shmem->length); + /* Skip only the length of header in shmem area i.e 4 bytes */ - xfer->rx.len = min_t(size_t, max_len, ioread32(&shmem->length) - 4); + xfer->rx.len = min_t(size_t, max_len, len > 4 ? len - 4 : 0); /* Take a copy to the rx buffer.. */ memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len); From e325285de2cd82fbdcc4df8898e4c6a597674816 Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 22 Dec 2022 18:38:23 +0000 Subject: [PATCH 050/398] firmware: arm_scmi: Fix virtio channels cleanup on shutdown When unloading the SCMI core stack module, configured to use the virtio SCMI transport, LOCKDEP reports the splat down below about unsafe locks dependencies. In order to avoid this possible unsafe locking scenario call upfront virtio_break_device() before getting hold of vioch->lock. ===================================================== WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected 6.1.0-00067-g6b934395ba07-dirty #4 Not tainted ----------------------------------------------------- rmmod/307 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire: ffff000080c510e0 (&dev->vqs_list_lock){+.+.}-{3:3}, at: virtio_break_device+0x28/0x68 and this task is already holding: ffff00008288ada0 (&channels[i].lock){-.-.}-{3:3}, at: virtio_chan_free+0x60/0x168 [scmi_module] which would create a new lock dependency: (&channels[i].lock){-.-.}-{3:3} -> (&dev->vqs_list_lock){+.+.}-{3:3} but this new dependency connects a HARDIRQ-irq-safe lock: (&channels[i].lock){-.-.}-{3:3} ... which became HARDIRQ-irq-safe at: lock_acquire+0x128/0x398 _raw_spin_lock_irqsave+0x78/0x140 scmi_vio_complete_cb+0xb4/0x3b8 [scmi_module] vring_interrupt+0x84/0x120 vm_interrupt+0x94/0xe8 __handle_irq_event_percpu+0xb4/0x3d8 handle_irq_event_percpu+0x20/0x68 handle_irq_event+0x50/0xb0 handle_fasteoi_irq+0xac/0x138 generic_handle_domain_irq+0x34/0x50 gic_handle_irq+0xa0/0xd8 call_on_irq_stack+0x2c/0x54 do_interrupt_handler+0x8c/0x90 el1_interrupt+0x40/0x78 el1h_64_irq_handler+0x18/0x28 el1h_64_irq+0x64/0x68 _raw_write_unlock_irq+0x48/0x80 ep_start_scan+0xf0/0x128 do_epoll_wait+0x390/0x858 do_compat_epoll_pwait.part.34+0x1c/0xb8 __arm64_sys_epoll_pwait+0x80/0xd0 invoke_syscall+0x4c/0x110 el0_svc_common.constprop.3+0x98/0x120 do_el0_svc+0x34/0xd0 el0_svc+0x40/0x98 el0t_64_sync_handler+0x98/0xc0 el0t_64_sync+0x170/0x174 to a HARDIRQ-irq-unsafe lock: (&dev->vqs_list_lock){+.+.}-{3:3} ... which became HARDIRQ-irq-unsafe at: ... lock_acquire+0x128/0x398 _raw_spin_lock+0x58/0x70 __vring_new_virtqueue+0x130/0x1c0 vring_create_virtqueue+0xc4/0x2b8 vm_find_vqs+0x20c/0x430 init_vq+0x308/0x390 virtblk_probe+0x114/0x9b0 virtio_dev_probe+0x1a4/0x248 really_probe+0xc8/0x3a8 __driver_probe_device+0x84/0x190 driver_probe_device+0x44/0x110 __driver_attach+0x104/0x1e8 bus_for_each_dev+0x7c/0xd0 driver_attach+0x2c/0x38 bus_add_driver+0x1e4/0x258 driver_register+0x6c/0x128 register_virtio_driver+0x2c/0x48 virtio_blk_init+0x70/0xac do_one_initcall+0x84/0x420 kernel_init_freeable+0x2d0/0x340 kernel_init+0x2c/0x138 ret_from_fork+0x10/0x20 other info that might help us debug this: Possible interrupt unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&dev->vqs_list_lock); local_irq_disable(); lock(&channels[i].lock); lock(&dev->vqs_list_lock); lock(&channels[i].lock); *** DEADLOCK *** ================ Fixes: 42e90eb53bf3f ("firmware: arm_scmi: Add a virtio channel refcount") Signed-off-by: Cristian Marussi Link: https://lore.kernel.org/r/20221222183823.518856-6-cristian.marussi@arm.com Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/virtio.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c index 33c9b81a55cd..1db975c08896 100644 --- a/drivers/firmware/arm_scmi/virtio.c +++ b/drivers/firmware/arm_scmi/virtio.c @@ -160,7 +160,6 @@ static void scmi_vio_channel_cleanup_sync(struct scmi_vio_channel *vioch) } vioch->shutdown_done = &vioch_shutdown_done; - virtio_break_device(vioch->vqueue->vdev); if (!vioch->is_rx && vioch->deferred_tx_wq) /* Cannot be kicked anymore after this...*/ vioch->deferred_tx_wq = NULL; @@ -482,6 +481,12 @@ static int virtio_chan_free(int id, void *p, void *data) struct scmi_chan_info *cinfo = p; struct scmi_vio_channel *vioch = cinfo->transport_info; + /* + * Break device to inhibit further traffic flowing while shutting down + * the channels: doing it later holding vioch->lock creates unsafe + * locking dependency chains as reported by LOCKDEP. + */ + virtio_break_device(vioch->vqueue->vdev); scmi_vio_channel_cleanup_sync(vioch); scmi_free_channel(cinfo, data, id); From 937e7a39068d806c1a951f19e38e1326be20f1b0 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 29 Dec 2022 12:07:46 +0200 Subject: [PATCH 051/398] pinctrl: nomadik: Add missing header(s) Do not imply that some of the generic headers may be always included. Instead, include explicitly what we are direct user of. While at it, sort headers alphabetically. Fixes: e5530adc17a7 ("pinctrl: Clean up headers") Cc: Randy Dunlap Reported-by: Arnd Bergmann Reported-by: kernel test robot Signed-off-by: Andy Shevchenko Link: https://lore.kernel.org/r/20221229100746.35047-1-andriy.shevchenko@linux.intel.com Signed-off-by: Linus Walleij --- drivers/pinctrl/nomadik/pinctrl-ab8500.c | 3 +- drivers/pinctrl/nomadik/pinctrl-ab8505.c | 3 +- drivers/pinctrl/nomadik/pinctrl-abx500.c | 36 ++++++++++--------- drivers/pinctrl/nomadik/pinctrl-abx500.h | 4 +++ .../pinctrl/nomadik/pinctrl-nomadik-db8500.c | 3 ++ .../pinctrl/nomadik/pinctrl-nomadik-stn8815.c | 3 ++ drivers/pinctrl/nomadik/pinctrl-nomadik.c | 34 +++++++++--------- drivers/pinctrl/nomadik/pinctrl-nomadik.h | 5 +++ 8 files changed, 57 insertions(+), 34 deletions(-) diff --git a/drivers/pinctrl/nomadik/pinctrl-ab8500.c b/drivers/pinctrl/nomadik/pinctrl-ab8500.c index 3106a21cd277..d7b244df058f 100644 --- a/drivers/pinctrl/nomadik/pinctrl-ab8500.c +++ b/drivers/pinctrl/nomadik/pinctrl-ab8500.c @@ -6,9 +6,10 @@ */ #include -#include #include + #include + #include "pinctrl-abx500.h" /* All the pins that can be used for GPIO and some other functions */ diff --git a/drivers/pinctrl/nomadik/pinctrl-ab8505.c b/drivers/pinctrl/nomadik/pinctrl-ab8505.c index b93af1fb37f0..45aa958b573e 100644 --- a/drivers/pinctrl/nomadik/pinctrl-ab8505.c +++ b/drivers/pinctrl/nomadik/pinctrl-ab8505.c @@ -6,9 +6,10 @@ */ #include -#include #include + #include + #include "pinctrl-abx500.h" /* All the pins that can be used for GPIO and some other functions */ diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.c b/drivers/pinctrl/nomadik/pinctrl-abx500.c index 7aa534576a45..28c3403df1b0 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.c +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.c @@ -6,33 +6,37 @@ * * Driver allows to use AxB5xx unused pins to be used as GPIO */ -#include -#include -#include -#include +#include #include +#include +#include +#include +#include +#include +#include #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include + #include #include -#include -#include -#include -#include -#include -#include -#include "pinctrl-abx500.h" +#include +#include +#include +#include +#include +#include + #include "../core.h" #include "../pinconf.h" #include "../pinctrl-utils.h" +#include "pinctrl-abx500.h" + /* * GPIO registers offset * Bank: 0x10 diff --git a/drivers/pinctrl/nomadik/pinctrl-abx500.h b/drivers/pinctrl/nomadik/pinctrl-abx500.h index 90bb12fe8073..d67522084675 100644 --- a/drivers/pinctrl/nomadik/pinctrl-abx500.h +++ b/drivers/pinctrl/nomadik/pinctrl-abx500.h @@ -2,6 +2,10 @@ #ifndef PINCTRL_PINCTRL_ABx500_H #define PINCTRL_PINCTRL_ABx500_H +#include + +struct pinctrl_pin_desc; + /* Package definitions */ #define PINCTRL_AB8500 0 #define PINCTRL_AB8505 1 diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c index 758d21f0a850..490e0959e8be 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-db8500.c @@ -1,6 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include + #include + #include "pinctrl-nomadik.h" /* All the pins that can be used for GPIO and some other functions */ diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c index c0d7c86d0939..1552222ac68e 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik-stn8815.c @@ -1,6 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 #include +#include + #include + #include "pinctrl-nomadik.h" /* All the pins that can be used for GPIO and some other functions */ diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index f7d02513d8cc..86a638077a69 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -7,30 +7,34 @@ * Rewritten based on work by Prafulla WADASKAR * Copyright (C) 2011-2013 Linus Walleij */ -#include -#include -#include -#include -#include +#include #include +#include #include #include -#include +#include #include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include + /* Since we request GPIOs from ourself */ #include -#include "pinctrl-nomadik.h" +#include +#include +#include +#include + #include "../core.h" #include "../pinctrl-utils.h" +#include "pinctrl-nomadik.h" + /* * The GPIO module in the Nomadik family of Systems-on-Chip is an * AMBA device, managing 32 pins and alternate functions. The logic block @@ -907,8 +911,6 @@ static int nmk_gpio_get_mode(struct nmk_gpio_chip *nmk_chip, int offset) return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0); } -#include - static void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev, struct gpio_chip *chip, unsigned offset, unsigned gpio) diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.h b/drivers/pinctrl/nomadik/pinctrl-nomadik.h index 84e297757335..1ef2559bc571 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.h +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.h @@ -2,6 +2,11 @@ #ifndef PINCTRL_PINCTRL_NOMADIK_H #define PINCTRL_PINCTRL_NOMADIK_H +#include +#include + +#include + /* Package definitions */ #define PINCTRL_NMK_STN8815 0 #define PINCTRL_NMK_DB8500 1 From df875276d8c69b27e1ed242d3cee6bc23d3b7f43 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 10 Dec 2022 21:03:49 +0100 Subject: [PATCH 052/398] dt-bindings: interconnect: Add UFS clocks to MSM8996 A2NoC MSM8996 A2NoC contains a UFS master, which means the UFS hardware is accessed every time sync_state is called within the interconnect framework. It's all good on devices where this clock is already enabled (most likely from the bootloader), but devices with eMMC storage are rather unlikely to have it like that. Add the missing 2 clocks to the binding. Signed-off-by: Konrad Dybcio Acked-by: Krzysztof Kozlowski Tested-by: Dmitry Baryshkov #db820c Link: https://lore.kernel.org/r/20221210200353.418391-2-konrad.dybcio@linaro.org Signed-off-by: Georgi Djakov --- .../bindings/interconnect/qcom,rpm.yaml | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml b/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml index 4b37aa88a375..5e6be4e79201 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,rpm.yaml @@ -84,7 +84,6 @@ allOf: - qcom,msm8939-pcnoc - qcom,msm8939-snoc - qcom,msm8996-a1noc - - qcom,msm8996-a2noc - qcom,msm8996-bimc - qcom,msm8996-cnoc - qcom,msm8996-pnoc @@ -186,6 +185,29 @@ allOf: required: - power-domains + - if: + properties: + compatible: + contains: + enum: + - qcom,msm8996-a2noc + + then: + properties: + clock-names: + items: + - const: bus + - const: bus_a + - const: aggre2_ufs_axi + - const: ufs_axi + + clocks: + items: + - description: Bus Clock + - description: Bus A Clock + - description: Aggregate2 NoC UFS AXI Clock + - description: UFS AXI Clock + - if: properties: compatible: From 60426ff08af6a21275d9c879c0dfb09406469868 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 10 Dec 2022 21:03:50 +0100 Subject: [PATCH 053/398] interconnect: qcom: msm8996: Provide UFS clocks to A2NoC On eMMC devices the bootloader has no business enabling UFS clocks. That results in a platform hang and hard reboot when trying to vote on paths including MASTER_UFS and since sync_state guarantees that it's done at boot time, this effectively prevents such devices from booting. Fix that. Fixes: 7add937f5222 ("interconnect: qcom: Add MSM8996 interconnect provider driver") Signed-off-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Tested-by: Dmitry Baryshkov #db820c Link: https://lore.kernel.org/r/20221210200353.418391-3-konrad.dybcio@linaro.org Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/msm8996.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c index c2903ae3b3bc..7ddb1f23fb2a 100644 --- a/drivers/interconnect/qcom/msm8996.c +++ b/drivers/interconnect/qcom/msm8996.c @@ -33,6 +33,13 @@ static const char * const bus_a0noc_clocks[] = { "aggre0_noc_mpu_cfg" }; +static const char * const bus_a2noc_clocks[] = { + "bus", + "bus_a", + "aggre2_ufs_axi", + "ufs_axi" +}; + static const u16 mas_a0noc_common_links[] = { MSM8996_SLAVE_A0NOC_SNOC }; @@ -1859,6 +1866,8 @@ static const struct qcom_icc_desc msm8996_a2noc = { .type = QCOM_ICC_NOC, .nodes = a2noc_nodes, .num_nodes = ARRAY_SIZE(a2noc_nodes), + .clocks = bus_a2noc_clocks, + .num_clocks = ARRAY_SIZE(bus_a2noc_clocks), .regmap_cfg = &msm8996_a2noc_regmap_config }; From 4be39d5d86c690c60e2afe55787fc5ec4409d0f0 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 10 Dec 2022 21:03:51 +0100 Subject: [PATCH 054/398] interconnect: qcom: msm8996: Fix regmap max_register values The device tree reg starts at BUS_BASE + QoS_OFFSET, but the regmap configs in the ICC driver had values suggesting the reg started at BUS_BASE. Shrink them down (where they haven't been already, so for providers where QoS_OFFSET = 0) to make sure they stay within their window. Fixes: 7add937f5222 ("interconnect: qcom: Add MSM8996 interconnect provider driver") Signed-off-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Tested-by: Dmitry Baryshkov #db820c Link: https://lore.kernel.org/r/20221210200353.418391-4-konrad.dybcio@linaro.org Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/msm8996.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c index 7ddb1f23fb2a..25a1a32bc611 100644 --- a/drivers/interconnect/qcom/msm8996.c +++ b/drivers/interconnect/qcom/msm8996.c @@ -1813,7 +1813,7 @@ static const struct regmap_config msm8996_a0noc_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = 0x9000, + .max_register = 0x6000, .fast_io = true }; @@ -1837,7 +1837,7 @@ static const struct regmap_config msm8996_a1noc_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = 0x7000, + .max_register = 0x5000, .fast_io = true }; @@ -1858,7 +1858,7 @@ static const struct regmap_config msm8996_a2noc_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = 0xa000, + .max_register = 0x7000, .fast_io = true }; @@ -1886,7 +1886,7 @@ static const struct regmap_config msm8996_bimc_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = 0x62000, + .max_register = 0x5a000, .fast_io = true }; @@ -1997,7 +1997,7 @@ static const struct regmap_config msm8996_mnoc_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, - .max_register = 0x20000, + .max_register = 0x1c000, .fast_io = true }; From dd42ec8ea5b979edcebbf0ba05807d866884b567 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sat, 10 Dec 2022 21:03:52 +0100 Subject: [PATCH 055/398] interconnect: qcom: rpm: Use _optional func for provider clocks It turned out that - very unfortunately - msm8996 needs a binding update, adding 2 more clocks to the A2NoC node. Use the _optional variant of devm_clk_get to make sure old DTs will still probe with newer versions of the driver. Signed-off-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Tested-by: Dmitry Baryshkov #db820c Link: https://lore.kernel.org/r/20221210200353.418391-5-konrad.dybcio@linaro.org Signed-off-by: Georgi Djakov --- drivers/interconnect/qcom/icc-rpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c index ba6781f54ab7..df3196f72536 100644 --- a/drivers/interconnect/qcom/icc-rpm.c +++ b/drivers/interconnect/qcom/icc-rpm.c @@ -488,7 +488,7 @@ int qnoc_probe(struct platform_device *pdev) } regmap_done: - ret = devm_clk_bulk_get(dev, qp->num_clks, qp->bus_clks); + ret = devm_clk_bulk_get_optional(dev, qp->num_clks, qp->bus_clks); if (ret) return ret; From c45219cba101f32853d011da2ba46a1b2338dc4c Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 5 Jan 2023 13:02:08 +0100 Subject: [PATCH 056/398] Revert "arm64: dts: meson-sm1-odroid-hc4: disable unused USB PHY0" This reverts commit 703e84d6615a4a95fb504c8f2e4c9426b86f3930. USB device enumeration was not working on Odroid HC4 as both USB2 PHYs need to be enabled. This is inherited from the GLX USB design [1]. [1]: https://lore.kernel.org/all/20170814224542.18257-1-martin.blumenstingl@googlemail.com/T/ Signed-off-by: Pierre-Olivier Mercier Acked-by: Neil Armstrong Reviewed-by: Martin Blumenstingl Link: https://lore.kernel.org/r/20230105120206.28964-1-nemunaire@nemunai.re Signed-off-by: Neil Armstrong --- arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts index e3486f60645a..a1f0c38ccadd 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts @@ -131,10 +131,6 @@ }; &usb { - phys = <&usb2_phy1>; - phy-names = "usb2-phy1"; -}; - -&usb2_phy0 { - status = "disabled"; + phys = <&usb2_phy0>, <&usb2_phy1>; + phy-names = "usb2-phy0", "usb2-phy1"; }; From 2a33ad4a0ba5a527b92aeef9a313aefec197fe28 Mon Sep 17 00:00:00 2001 From: Basavaraj Natikar Date: Mon, 2 Jan 2023 22:00:42 +0530 Subject: [PATCH 057/398] HID: amd_sfh: Fix warning unwind goto Return directly instead of using existing goto will not cleanup previously allocated resources. Hence replace return with goto to fix warning unwind goto which cleanups previously allocated resources. Fixes: 93ce5e0231d7 ("HID: amd_sfh: Implement SFH1.1 functionality") Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Basavaraj Natikar Signed-off-by: Jiri Kosina --- drivers/hid/amd-sfh-hid/amd_sfh_client.c | 2 +- drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c index ab125f79408f..1fb0f7105fb2 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c @@ -282,7 +282,7 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) } rc = mp2_ops->get_rep_desc(cl_idx, cl_data->report_descr[i]); if (rc) - return rc; + goto cleanup; mp2_ops->start(privdata, info); status = amd_sfh_wait_for_response (privdata, cl_data->sensor_idx[i], SENSOR_ENABLED); diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c index 4da2f9f62aba..a1d6e08fab7d 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c @@ -160,7 +160,7 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata) } rc = mp2_ops->get_rep_desc(cl_idx, cl_data->report_descr[i]); if (rc) - return rc; + goto cleanup; writel(0, privdata->mmio + AMD_P2C_MSG(0)); mp2_ops->start(privdata, info); From d3178e8a434b58678d99257c0387810a24042fb6 Mon Sep 17 00:00:00 2001 From: Hao Sun Date: Wed, 4 Jan 2023 09:47:09 +0800 Subject: [PATCH 058/398] bpf: Skip invalid kfunc call in backtrack_insn The verifier skips invalid kfunc call in check_kfunc_call(), which would be captured in fixup_kfunc_call() if such insn is not eliminated by dead code elimination. However, this can lead to the following warning in backtrack_insn(), also see [1]: ------------[ cut here ]------------ verifier backtracking bug WARNING: CPU: 6 PID: 8646 at kernel/bpf/verifier.c:2756 backtrack_insn kernel/bpf/verifier.c:2756 __mark_chain_precision kernel/bpf/verifier.c:3065 mark_chain_precision kernel/bpf/verifier.c:3165 adjust_reg_min_max_vals kernel/bpf/verifier.c:10715 check_alu_op kernel/bpf/verifier.c:10928 do_check kernel/bpf/verifier.c:13821 [inline] do_check_common kernel/bpf/verifier.c:16289 [...] So make backtracking conservative with this by returning ENOTSUPP. [1] https://lore.kernel.org/bpf/CACkBjsaXNceR8ZjkLG=dT3P=4A8SBsg0Z5h5PWLryF5=ghKq=g@mail.gmail.com/ Reported-by: syzbot+4da3ff23081bafe74fc2@syzkaller.appspotmail.com Signed-off-by: Hao Sun Signed-off-by: Daniel Borkmann Acked-by: Yonghong Song Link: https://lore.kernel.org/bpf/20230104014709.9375-1-sunhao.th@gmail.com --- kernel/bpf/verifier.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 85f96c1e9f62..c4c0985daac0 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2748,6 +2748,12 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, */ if (insn->src_reg == 0 && is_callback_calling_function(insn->imm)) return -ENOTSUPP; + /* kfunc with imm==0 is invalid and fixup_kfunc_call will + * catch this error later. Make backtracking conservative + * with ENOTSUPP. + */ + if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL && insn->imm == 0) + return -ENOTSUPP; /* regular helper call sets R0 */ *reg_mask &= ~1; if (*reg_mask & 0x3f) { From 26658868354963afbff672ad6f7a85c44c311975 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 29 Dec 2022 16:16:47 +0100 Subject: [PATCH 059/398] dt-bindings: soc: qcom: apr: Make qcom,protection-domain optional again The protection domain functionality exists only in SoCs starting from MSM8998 [1], while the APR bindings are also used on older platforms. Commit 41288c305836 ("ASoC: dt-bindings: qcom,apr: Split services to shared schema") made the "qcom,protection-domain" required but it should remain optional to avoid dtbs_check warnings on older platforms, e.g.: arch/arm64/boot/dts/qcom/apq8096-db820c.dtb: apr: service@3: 'qcom,protection-domain' is a required property From schema: Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml [1]: https://lore.kernel.org/all/20200312120842.21991-1-sibis@codeaurora.org/ Fixes: 41288c305836 ("ASoC: dt-bindings: qcom,apr: Split services to shared schema") Signed-off-by: Stephan Gerhold Reviewed-by: Krzysztof Kozlowski Reviewed-by: Bjorn Andersson Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221229151648.19839-2-stephan@gerhold.net --- .../devicetree/bindings/soc/qcom/qcom,apr-services.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,apr-services.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,apr-services.yaml index 290555426c39..bdf482db32aa 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,apr-services.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,apr-services.yaml @@ -39,8 +39,8 @@ properties: qcom,protection-domain: $ref: /schemas/types.yaml#/definitions/string-array description: | - Protection domain service name and path for APR service - possible values are:: + Protection domain service name and path for APR service (if supported). + Possible values are:: "avs/audio", "msm/adsp/audio_pd". "kernel/elf_loader", "msm/modem/wlan_pd". "tms/servreg", "msm/adsp/audio_pd". @@ -49,6 +49,5 @@ properties: required: - reg - - qcom,protection-domain additionalProperties: true From 599d41fb8ea8bd2a99ca9525dd69405020e43dda Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Thu, 29 Dec 2022 16:16:48 +0100 Subject: [PATCH 060/398] soc: qcom: apr: Make qcom,protection-domain optional again APR should not fail if the service device tree node does not have the qcom,protection-domain property, since this functionality does not exist on older platforms such as MSM8916 and MSM8996. Ignore -EINVAL (returned when the property does not exist) to fix a regression on 6.2-rc1 that prevents audio from working: qcom,apr remoteproc0:smd-edge.apr_audio_svc.-1.-1: Failed to read second value of qcom,protection-domain qcom,apr remoteproc0:smd-edge.apr_audio_svc.-1.-1: Failed to add apr 3 svc Fixes: 6d7860f5750d ("soc: qcom: apr: Add check for idr_alloc and of_property_read_string_index") Signed-off-by: Stephan Gerhold Reviewed-by: Bjorn Andersson Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221229151648.19839-3-stephan@gerhold.net --- drivers/soc/qcom/apr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c index cd44f17dad3d..d51abb462ae5 100644 --- a/drivers/soc/qcom/apr.c +++ b/drivers/soc/qcom/apr.c @@ -461,9 +461,10 @@ static int apr_add_device(struct device *dev, struct device_node *np, goto out; } + /* Protection domain is optional, it does not exist on older platforms */ ret = of_property_read_string_index(np, "qcom,protection-domain", 1, &adev->service_path); - if (ret < 0) { + if (ret < 0 && ret != -EINVAL) { dev_err(dev, "Failed to read second value of qcom,protection-domain\n"); goto out; } From a3d81bc1eaef48e34dd0b9b48eefed9e02a06451 Mon Sep 17 00:00:00 2001 From: Hao Sun Date: Fri, 6 Jan 2023 16:48:38 +0800 Subject: [PATCH 061/398] bpf: Skip task with pid=1 in send_signal_common() The following kernel panic can be triggered when a task with pid=1 attaches a prog that attempts to send killing signal to itself, also see [1] for more details: Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b CPU: 3 PID: 1 Comm: systemd Not tainted 6.1.0-09652-g59fe41b5255f #148 Call Trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x100/0x178 lib/dump_stack.c:106 panic+0x2c4/0x60f kernel/panic.c:275 do_exit.cold+0x63/0xe4 kernel/exit.c:789 do_group_exit+0xd4/0x2a0 kernel/exit.c:950 get_signal+0x2460/0x2600 kernel/signal.c:2858 arch_do_signal_or_restart+0x78/0x5d0 arch/x86/kernel/signal.c:306 exit_to_user_mode_loop kernel/entry/common.c:168 [inline] exit_to_user_mode_prepare+0x15f/0x250 kernel/entry/common.c:203 __syscall_exit_to_user_mode_work kernel/entry/common.c:285 [inline] syscall_exit_to_user_mode+0x1d/0x50 kernel/entry/common.c:296 do_syscall_64+0x44/0xb0 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x63/0xcd So skip task with pid=1 in bpf_send_signal_common() to avoid the panic. [1] https://lore.kernel.org/bpf/20221222043507.33037-1-sunhao.th@gmail.com Signed-off-by: Hao Sun Signed-off-by: Daniel Borkmann Acked-by: Stanislav Fomichev Link: https://lore.kernel.org/bpf/20230106084838.12690-1-sunhao.th@gmail.com --- kernel/trace/bpf_trace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 3bbd3f0c810c..f47274de012b 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -848,6 +848,9 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) return -EPERM; if (unlikely(!nmi_uaccess_okay())) return -EPERM; + /* Task should not be pid=1 to avoid kernel panic. */ + if (unlikely(is_global_init(current))) + return -EPERM; if (irqs_disabled()) { /* Do an early check on signal validity. Otherwise, From eaf2213ba563b2d74a1f2c13a6b258273f689802 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 7 Jan 2023 16:47:41 +0900 Subject: [PATCH 062/398] tomoyo: fix broken dependency on *.conf.default If *.conf.default is updated, builtin-policy.h should be rebuilt, but this does not work when compiled with O= option. [Without this commit] $ touch security/tomoyo/policy/exception_policy.conf.default $ make O=/tmp security/tomoyo/ make[1]: Entering directory '/tmp' GEN Makefile CALL /home/masahiro/ref/linux/scripts/checksyscalls.sh DESCEND objtool make[1]: Leaving directory '/tmp' [With this commit] $ touch security/tomoyo/policy/exception_policy.conf.default $ make O=/tmp security/tomoyo/ make[1]: Entering directory '/tmp' GEN Makefile CALL /home/masahiro/ref/linux/scripts/checksyscalls.sh DESCEND objtool POLICY security/tomoyo/builtin-policy.h CC security/tomoyo/common.o AR security/tomoyo/built-in.a make[1]: Leaving directory '/tmp' $(srctree)/ is essential because $(wildcard ) does not follow VPATH. Fixes: f02dee2d148b ("tomoyo: Do not generate empty policy files") Signed-off-by: Masahiro Yamada Signed-off-by: Tetsuo Handa --- security/tomoyo/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile index cca5a3012fee..221eaadffb09 100644 --- a/security/tomoyo/Makefile +++ b/security/tomoyo/Makefile @@ -10,7 +10,7 @@ endef quiet_cmd_policy = POLICY $@ cmd_policy = ($(call do_policy,profile); $(call do_policy,exception_policy); $(call do_policy,domain_policy); $(call do_policy,manager); $(call do_policy,stat)) >$@ -$(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(src)/policy/*.conf.default) FORCE +$(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(srctree)/$(src)/policy/*.conf.default) FORCE $(call if_changed,policy) $(obj)/common.o: $(obj)/builtin-policy.h From df4840c1b880136fea97a1d64724995778c2475f Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 7 Jan 2023 16:47:42 +0900 Subject: [PATCH 063/398] tomoyo: avoid unneeded creation of builtin-policy.h When CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING=y, builtin-policy.h is unneeded. Signed-off-by: Masahiro Yamada Signed-off-by: Tetsuo Handa --- security/tomoyo/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile index 221eaadffb09..1b18a02ccd2e 100644 --- a/security/tomoyo/Makefile +++ b/security/tomoyo/Makefile @@ -13,4 +13,6 @@ quiet_cmd_policy = POLICY $@ $(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(srctree)/$(src)/policy/*.conf.default) FORCE $(call if_changed,policy) +ifndef CONFIG_SECURITY_TOMOYO_INSECURE_BUILTIN_SETTING $(obj)/common.o: $(obj)/builtin-policy.h +endif From 43d5f5d63699724d47f0d9e0eae516a260d232b4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 6 Jan 2023 13:44:56 +0000 Subject: [PATCH 064/398] riscv: dts: sifive: fu740: fix size of pcie 32bit memory The 32-bit memory resource is needed for non-prefetchable memory allocations on the PCIe bus, however with some cards (such as the SM768) the system fails to allocate memory from this. Checking the allocation against the datasheet, it looks like there has been a mis-calcualation of the resource for the first memory region (0x0060090000..0x0070ffffff) which in the data-sheet for the fu740 (v1p2) is from 0x0060000000..0x007fffffff. Changing this to allocate from 0x0060090000..0x007fffffff fixes the probing issues. Fixes: ae80d5148085 ("riscv: dts: Add PCIe support for the SiFive FU740-C000 SoC") Cc: Paul Walmsley Cc: Greentime Hu Signed-off-by: Ben Dooks Cc: stable@vger.kernel.org Tested-by: Ron Economos # from IRC Reviewed-by: Conor Dooley Signed-off-by: Conor Dooley --- arch/riscv/boot/dts/sifive/fu740-c000.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi index 43bed6c0a84f..5235fd1c9cb6 100644 --- a/arch/riscv/boot/dts/sifive/fu740-c000.dtsi +++ b/arch/riscv/boot/dts/sifive/fu740-c000.dtsi @@ -328,7 +328,7 @@ bus-range = <0x0 0xff>; ranges = <0x81000000 0x0 0x60080000 0x0 0x60080000 0x0 0x10000>, /* I/O */ <0x82000000 0x0 0x60090000 0x0 0x60090000 0x0 0xff70000>, /* mem */ - <0x82000000 0x0 0x70000000 0x0 0x70000000 0x0 0x1000000>, /* mem */ + <0x82000000 0x0 0x70000000 0x0 0x70000000 0x0 0x10000000>, /* mem */ <0xc3000000 0x20 0x00000000 0x20 0x00000000 0x20 0x00000000>; /* mem prefetchable */ num-lanes = <0x8>; interrupts = <56>, <57>, <58>, <59>, <60>, <61>, <62>, <63>, <64>; From e3c9405ec56b6b0a75d993427bfc7f4194f73754 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Sat, 7 Jan 2023 15:37:47 +0100 Subject: [PATCH 065/398] docs: kbuild: remove mention to dropped $(objtree) feature Commit 8d613a1d048c ("kbuild: drop $(objtree)/ prefix support for clean-files") dropped support for prefixing with $(objtree). Thus update the documentation to match that change. Signed-off-by: Miguel Ojeda Signed-off-by: Masahiro Yamada --- Documentation/kbuild/makefiles.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 6b7368d1f516..38bc74eaa547 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -1042,7 +1042,7 @@ $(clean-files). When executing "make clean", the file "crc32table.h" will be deleted. Kbuild will assume files to be in the same relative directory as the -Makefile, except if prefixed with $(objtree). +Makefile. To exclude certain files or directories from make clean, use the $(no-clean-files) variable. From b409ea4534204d4e6da3017d8713ce338f44b489 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 8 Jan 2023 21:35:57 +0900 Subject: [PATCH 066/398] init/version-timestamp.c: remove unneeded #include The kbuild test robot detected this by 'make versioncheck'. Fixes: 2df8220cc511 ("kbuild: build init/built-in.a just once") Reported-by: kernel test robot Signed-off-by: Masahiro Yamada --- init/version-timestamp.c | 1 - 1 file changed, 1 deletion(-) diff --git a/init/version-timestamp.c b/init/version-timestamp.c index 179e93bae539..043cbf80a766 100644 --- a/init/version-timestamp.c +++ b/init/version-timestamp.c @@ -2,7 +2,6 @@ #include #include -#include #include #include #include From 23257cfc1cb7202fd0065e9f4a6a0aac1c04c4a9 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 29 Dec 2022 14:10:30 +0200 Subject: [PATCH 067/398] thunderbolt: Do not call PM runtime functions in tb_retimer_scan() We cannot call PM runtime functions in tb_retimer_scan() because it will also be called when retimers are scanned from userspace (happens when there is no device connected on ChromeOS for instance) and at the same USB4 port runtime resume hook. This leads to hang because neither can proceed. Fix this by runtime resuming USB4 ports in tb_scan_port() instead. This makes sure the ports are runtime PM active when retimers are added under it while avoiding the reported hang as well. Reported-by: Utkarsh Patel Fixes: 1e56c88adecc ("thunderbolt: Runtime resume USB4 port when retimers are scanned") Cc: stable@vger.kernel.org Acked-by: Yehezkel Bernat Signed-off-by: Mika Westerberg --- drivers/thunderbolt/retimer.c | 17 +++-------------- drivers/thunderbolt/tb.c | 20 +++++++++++++++----- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/thunderbolt/retimer.c b/drivers/thunderbolt/retimer.c index 6ebe7a2886ec..56008eb91e2e 100644 --- a/drivers/thunderbolt/retimer.c +++ b/drivers/thunderbolt/retimer.c @@ -427,13 +427,6 @@ int tb_retimer_scan(struct tb_port *port, bool add) { u32 status[TB_MAX_RETIMER_INDEX + 1] = {}; int ret, i, last_idx = 0; - struct usb4_port *usb4; - - usb4 = port->usb4; - if (!usb4) - return 0; - - pm_runtime_get_sync(&usb4->dev); /* * Send broadcast RT to make sure retimer indices facing this @@ -441,7 +434,7 @@ int tb_retimer_scan(struct tb_port *port, bool add) */ ret = usb4_port_enumerate_retimers(port); if (ret) - goto out; + return ret; /* * Enable sideband channel for each retimer. We can do this @@ -471,11 +464,11 @@ int tb_retimer_scan(struct tb_port *port, bool add) break; } - ret = 0; if (!last_idx) - goto out; + return 0; /* Add on-board retimers if they do not exist already */ + ret = 0; for (i = 1; i <= last_idx; i++) { struct tb_retimer *rt; @@ -489,10 +482,6 @@ int tb_retimer_scan(struct tb_port *port, bool add) } } -out: - pm_runtime_mark_last_busy(&usb4->dev); - pm_runtime_put_autosuspend(&usb4->dev); - return ret; } diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 462845804427..3f1ab30c4fb1 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -628,11 +628,15 @@ static void tb_scan_port(struct tb_port *port) * Downstream switch is reachable through two ports. * Only scan on the primary port (link_nr == 0). */ + + if (port->usb4) + pm_runtime_get_sync(&port->usb4->dev); + if (tb_wait_for_port(port, false) <= 0) - return; + goto out_rpm_put; if (port->remote) { tb_port_dbg(port, "port already has a remote\n"); - return; + goto out_rpm_put; } tb_retimer_scan(port, true); @@ -647,12 +651,12 @@ static void tb_scan_port(struct tb_port *port) */ if (PTR_ERR(sw) == -EIO || PTR_ERR(sw) == -EADDRNOTAVAIL) tb_scan_xdomain(port); - return; + goto out_rpm_put; } if (tb_switch_configure(sw)) { tb_switch_put(sw); - return; + goto out_rpm_put; } /* @@ -681,7 +685,7 @@ static void tb_scan_port(struct tb_port *port) if (tb_switch_add(sw)) { tb_switch_put(sw); - return; + goto out_rpm_put; } /* Link the switches using both links if available */ @@ -733,6 +737,12 @@ static void tb_scan_port(struct tb_port *port) tb_add_dp_resources(sw); tb_scan_switch(sw); + +out_rpm_put: + if (port->usb4) { + pm_runtime_mark_last_busy(&port->usb4->dev); + pm_runtime_put_autosuspend(&port->usb4->dev); + } } static void tb_deactivate_and_free_tunnel(struct tb_tunnel *tunnel) From e8ff07fb33026c5c1bb5b81293496faba5d68059 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Fri, 20 May 2022 13:35:19 +0300 Subject: [PATCH 068/398] thunderbolt: Use correct function to calculate maximum USB3 link rate We need to take minimum of both sides of the USB3 link into consideration, not just the downstream port. Fix this by calling tb_usb3_max_link_rate() instead. Fixes: 0bd680cd900c ("thunderbolt: Add USB3 bandwidth management") Cc: stable@vger.kernel.org Acked-by: Yehezkel Bernat Signed-off-by: Mika Westerberg --- drivers/thunderbolt/tunnel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index 2c3cf7fc3357..1fc3c29b24f8 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -1275,7 +1275,7 @@ static void tb_usb3_reclaim_available_bandwidth(struct tb_tunnel *tunnel, return; } else if (!ret) { /* Use maximum link rate if the link valid is not set */ - ret = usb4_usb3_port_max_link_rate(tunnel->src_port); + ret = tb_usb3_max_link_rate(tunnel->dst_port, tunnel->src_port); if (ret < 0) { tb_tunnel_warn(tunnel, "failed to read maximum link rate\n"); return; From 84ee211c83212f4d35b56e0603acdcc41f860f1b Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Thu, 8 Sep 2022 09:45:22 +0300 Subject: [PATCH 069/398] thunderbolt: Disable XDomain lane 1 only in software connection manager When firmware connection manager is in use we should not touch the lane adapter (well or any) configuration space so do this only when we know that the software connection manager is active. Fixes: 8e1de7042596 ("thunderbolt: Add support for XDomain lane bonding") Cc: stable@vger.kernel.org Acked-by: Yehezkel Bernat Signed-off-by: Mika Westerberg --- drivers/thunderbolt/xdomain.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c index cfa83486c9da..3c51e47dd86b 100644 --- a/drivers/thunderbolt/xdomain.c +++ b/drivers/thunderbolt/xdomain.c @@ -1419,12 +1419,19 @@ static int tb_xdomain_get_properties(struct tb_xdomain *xd) * registered, we notify the userspace that it has changed. */ if (!update) { - struct tb_port *port; + /* + * Now disable lane 1 if bonding was not enabled. Do + * this only if bonding was possible at the beginning + * (that is we are the connection manager and there are + * two lanes). + */ + if (xd->bonding_possible) { + struct tb_port *port; - /* Now disable lane 1 if bonding was not enabled */ - port = tb_port_at(xd->route, tb_xdomain_parent(xd)); - if (!port->bonded) - tb_port_disable(port->dual_link_port); + port = tb_port_at(xd->route, tb_xdomain_parent(xd)); + if (!port->bonded) + tb_port_disable(port->dual_link_port); + } if (device_add(&xd->dev)) { dev_err(&xd->dev, "failed to add XDomain device\n"); From 80f8be7af03ffe90dc4df998b16bfa212afbdde9 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 8 Jan 2023 22:47:26 +0900 Subject: [PATCH 070/398] tomoyo: Omit use of bin2c bin2c was, as its name implies, introduced to convert a binary file to C code. However, I did not see any good reason ever for using this tool because using the .incbin directive is much faster, and often results in simpler code. Most of the uses of bin2c have been killed, for example: - 13610aa908dc ("kernel/configs: use .incbin directive to embed config_data.gz") - 4c0f032d4963 ("s390/purgatory: Omit use of bin2c") security/tomoyo/Makefile has even less reason for using bin2c because the policy files are text data. So, sed is enough for converting them to C string literals, and what is nicer, generates human-readable builtin-policy.h. This is the last user of bin2c. After this commit lands, bin2c will be removed. Signed-off-by: Masahiro Yamada [penguin-kernel: Update sed script to also escape backslash and quote ] Signed-off-by: Tetsuo Handa --- security/tomoyo/Kconfig | 1 - security/tomoyo/Makefile | 15 ++++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig index b9f867100a9f..772d2ab58fd1 100644 --- a/security/tomoyo/Kconfig +++ b/security/tomoyo/Kconfig @@ -7,7 +7,6 @@ config SECURITY_TOMOYO select SECURITY_PATH select SECURITY_NETWORK select SRCU - select BUILD_BIN2C default n help This selects TOMOYO Linux, pathname-based access control. diff --git a/security/tomoyo/Makefile b/security/tomoyo/Makefile index 1b18a02ccd2e..884ff155edc3 100644 --- a/security/tomoyo/Makefile +++ b/security/tomoyo/Makefile @@ -2,13 +2,14 @@ obj-y = audit.o common.o condition.o domain.o environ.o file.o gc.o group.o load_policy.o memory.o mount.o network.o realpath.o securityfs_if.o tomoyo.o util.o targets += builtin-policy.h -define do_policy -echo "static char tomoyo_builtin_$(1)[] __initdata ="; \ -$(objtree)/scripts/bin2c <$(firstword $(wildcard $(obj)/policy/$(1).conf $(srctree)/$(src)/policy/$(1).conf.default) /dev/null); \ -echo ";" -endef -quiet_cmd_policy = POLICY $@ - cmd_policy = ($(call do_policy,profile); $(call do_policy,exception_policy); $(call do_policy,domain_policy); $(call do_policy,manager); $(call do_policy,stat)) >$@ + +quiet_cmd_policy = POLICY $@ + cmd_policy = { \ + $(foreach x, profile exception_policy domain_policy manager stat, \ + printf 'static char tomoyo_builtin_$x[] __initdata =\n'; \ + sed -e 's/\\/\\\\/g' -e 's/\"/\\"/g' -e 's/\(.*\)/\t"\1\\n"/' -- $(firstword $(filter %/$x.conf %/$x.conf.default, $^) /dev/null); \ + printf '\t"";\n';) \ + } > $@ $(obj)/builtin-policy.h: $(wildcard $(obj)/policy/*.conf $(srctree)/$(src)/policy/*.conf.default) FORCE $(call if_changed,policy) From 3a73746b267e5c6a87c9ad26f8c6a48e44da609c Mon Sep 17 00:00:00 2001 From: Daisuke Matsuda Date: Tue, 20 Dec 2022 17:08:47 +0900 Subject: [PATCH 071/398] RDMA/rxe: Fix inaccurate constants in rxe_type_info ibv_query_device() has reported incorrect device attributes, which are actually not used by the device. Make the constants correspond with the attributes shown to users. Fixes: 3ccffe8abf2f ("RDMA/rxe: Move max_elem into rxe_type_info") Fixes: 3225717f6dfa ("RDMA/rxe: Replace red-black trees by xarrays") Link: https://lore.kernel.org/r/20221220080848.253785-1-matsuda-daisuke@fujitsu.com Signed-off-by: Daisuke Matsuda Reviewed-by: Li Zhijian Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe_pool.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_pool.c b/drivers/infiniband/sw/rxe/rxe_pool.c index f50620f5a0a1..1151c0b5ccea 100644 --- a/drivers/infiniband/sw/rxe/rxe_pool.c +++ b/drivers/infiniband/sw/rxe/rxe_pool.c @@ -23,16 +23,16 @@ static const struct rxe_type_info { .size = sizeof(struct rxe_ucontext), .elem_offset = offsetof(struct rxe_ucontext, elem), .min_index = 1, - .max_index = UINT_MAX, - .max_elem = UINT_MAX, + .max_index = RXE_MAX_UCONTEXT, + .max_elem = RXE_MAX_UCONTEXT, }, [RXE_TYPE_PD] = { .name = "pd", .size = sizeof(struct rxe_pd), .elem_offset = offsetof(struct rxe_pd, elem), .min_index = 1, - .max_index = UINT_MAX, - .max_elem = UINT_MAX, + .max_index = RXE_MAX_PD, + .max_elem = RXE_MAX_PD, }, [RXE_TYPE_AH] = { .name = "ah", @@ -40,7 +40,7 @@ static const struct rxe_type_info { .elem_offset = offsetof(struct rxe_ah, elem), .min_index = RXE_MIN_AH_INDEX, .max_index = RXE_MAX_AH_INDEX, - .max_elem = RXE_MAX_AH_INDEX - RXE_MIN_AH_INDEX + 1, + .max_elem = RXE_MAX_AH, }, [RXE_TYPE_SRQ] = { .name = "srq", @@ -49,7 +49,7 @@ static const struct rxe_type_info { .cleanup = rxe_srq_cleanup, .min_index = RXE_MIN_SRQ_INDEX, .max_index = RXE_MAX_SRQ_INDEX, - .max_elem = RXE_MAX_SRQ_INDEX - RXE_MIN_SRQ_INDEX + 1, + .max_elem = RXE_MAX_SRQ, }, [RXE_TYPE_QP] = { .name = "qp", @@ -58,7 +58,7 @@ static const struct rxe_type_info { .cleanup = rxe_qp_cleanup, .min_index = RXE_MIN_QP_INDEX, .max_index = RXE_MAX_QP_INDEX, - .max_elem = RXE_MAX_QP_INDEX - RXE_MIN_QP_INDEX + 1, + .max_elem = RXE_MAX_QP, }, [RXE_TYPE_CQ] = { .name = "cq", @@ -66,8 +66,8 @@ static const struct rxe_type_info { .elem_offset = offsetof(struct rxe_cq, elem), .cleanup = rxe_cq_cleanup, .min_index = 1, - .max_index = UINT_MAX, - .max_elem = UINT_MAX, + .max_index = RXE_MAX_CQ, + .max_elem = RXE_MAX_CQ, }, [RXE_TYPE_MR] = { .name = "mr", @@ -76,7 +76,7 @@ static const struct rxe_type_info { .cleanup = rxe_mr_cleanup, .min_index = RXE_MIN_MR_INDEX, .max_index = RXE_MAX_MR_INDEX, - .max_elem = RXE_MAX_MR_INDEX - RXE_MIN_MR_INDEX + 1, + .max_elem = RXE_MAX_MR, }, [RXE_TYPE_MW] = { .name = "mw", @@ -85,7 +85,7 @@ static const struct rxe_type_info { .cleanup = rxe_mw_cleanup, .min_index = RXE_MIN_MW_INDEX, .max_index = RXE_MAX_MW_INDEX, - .max_elem = RXE_MAX_MW_INDEX - RXE_MIN_MW_INDEX + 1, + .max_elem = RXE_MAX_MW, }, }; From 1aefe5c177c1922119afb4ee443ddd6ac3140b37 Mon Sep 17 00:00:00 2001 From: Daisuke Matsuda Date: Tue, 20 Dec 2022 17:08:48 +0900 Subject: [PATCH 072/398] RDMA/rxe: Prevent faulty rkey generation If you create MRs more than 0x10000 times after loading the module, responder starts to reply NAKs for RDMA/Atomic operations because of rkey violation detected in check_rkey(). The root cause is that rkeys are incremented each time a new MR is created and the value overflows into the range reserved for MWs. This commit also increases the value of RXE_MAX_MW that has been limited unlike other parameters. Fixes: 0994a1bcd5f7 ("RDMA/rxe: Bump up default maximum values used via uverbs") Link: https://lore.kernel.org/r/20221220080848.253785-2-matsuda-daisuke@fujitsu.com Signed-off-by: Daisuke Matsuda Tested-by: Li Zhijian Reviewed-by: Li Zhijian Signed-off-by: Jason Gunthorpe --- drivers/infiniband/sw/rxe/rxe_param.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_param.h b/drivers/infiniband/sw/rxe/rxe_param.h index a754fc902e3d..7b41d79e72b2 100644 --- a/drivers/infiniband/sw/rxe/rxe_param.h +++ b/drivers/infiniband/sw/rxe/rxe_param.h @@ -98,11 +98,11 @@ enum rxe_device_param { RXE_MAX_SRQ = DEFAULT_MAX_VALUE - RXE_MIN_SRQ_INDEX, RXE_MIN_MR_INDEX = 0x00000001, - RXE_MAX_MR_INDEX = DEFAULT_MAX_VALUE, - RXE_MAX_MR = DEFAULT_MAX_VALUE - RXE_MIN_MR_INDEX, - RXE_MIN_MW_INDEX = 0x00010001, - RXE_MAX_MW_INDEX = 0x00020000, - RXE_MAX_MW = 0x00001000, + RXE_MAX_MR_INDEX = DEFAULT_MAX_VALUE >> 1, + RXE_MAX_MR = RXE_MAX_MR_INDEX - RXE_MIN_MR_INDEX, + RXE_MIN_MW_INDEX = RXE_MAX_MR_INDEX + 1, + RXE_MAX_MW_INDEX = DEFAULT_MAX_VALUE, + RXE_MAX_MW = RXE_MAX_MW_INDEX - RXE_MIN_MW_INDEX, RXE_MAX_PKT_PER_ACK = 64, From cd2d0d45a3d2c199344305a1e8fed42347cf4bec Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 9 Jan 2023 09:30:53 +0100 Subject: [PATCH 073/398] ARM: pxa: enable PXA310/PXA320 for DT-only build After commit b5aaaa666a85 ("ARM: pxa: add Kconfig dependencies for ATAGS based boards"), the default PXA build no longer includes support for the board files that are considered unused. As a side-effect of this, the PXA310 and PXA320 support is not built into the kernel any more, even though it should work in principle as long as the symbols are enabled. As Robert points out, there are dts files for zylonite and cm-x300, though those have not made it into the mainline kernel. Link: https://lore.kernel.org/linux-arm-kernel/m2sfglh02h.fsf@free.fr/ Reported-by: Robert Jarzmik Signed-off-by: Arnd Bergmann --- arch/arm/mach-pxa/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index b90d98bae68d..03e25af6f48c 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -45,6 +45,8 @@ config MACH_PXA27X_DT config MACH_PXA3XX_DT bool "Support PXA3xx platforms from device tree" select CPU_PXA300 + select CPU_PXA310 + select CPU_PXA320 select PINCTRL select POWER_SUPPLY select PXA3xx From 75b58cf5ce21650c1b3b88d8310f3415ce905018 Mon Sep 17 00:00:00 2001 From: Klaus Kudielka Date: Sat, 7 Jan 2023 15:41:48 +0100 Subject: [PATCH 074/398] Revert "ARM: dts: armada-38x: Fix compatible string for gpios" This reverts commit c4de4667f15d04ef5920bacf41e514ec7d1ef03d, which causes a regression on Turris Omnia (Armada 385): GPIO interrupts cease to work, ending up in the DSA switch being non-functional. The blamed commit is incorrect in the first place: If compatible = "marvell,armadaxp-gpio", the second (address, size) pair of the reg property must to point to the per-CPU interrupt registers <0x18800 0x30> / <0x18840 0x30>, and not to the blink enable registers <0x181c0 0x08> / <0x181c8 0x08>. But even fixing that leaves the GPIO interrupts broken on the Omnia. Furthermore: Commit 5f79c651e81e explains very well, why the gpio-mvebu driver does not work reliably with per-CPU interrupts. Commit 988c8c0cd04d deprecates compatible = marvell,armadaxp-gpio for this reason. Fixes: c4de4667f15d ("ARM: dts: armada-38x: Fix compatible string for gpios") Reported-by: Klaus Kudielka Link: https://lore.kernel.org/r/f24474e70c1a4e9692bd596ef6d97ceda9511245.camel@gmail.com/ Signed-off-by: Klaus Kudielka Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-38x.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi index 12933eff419f..446861b6b17b 100644 --- a/arch/arm/boot/dts/armada-38x.dtsi +++ b/arch/arm/boot/dts/armada-38x.dtsi @@ -304,7 +304,7 @@ }; gpio0: gpio@18100 { - compatible = "marvell,armadaxp-gpio", + compatible = "marvell,armada-370-gpio", "marvell,orion-gpio"; reg = <0x18100 0x40>, <0x181c0 0x08>; reg-names = "gpio", "pwm"; @@ -323,7 +323,7 @@ }; gpio1: gpio@18140 { - compatible = "marvell,armadaxp-gpio", + compatible = "marvell,armada-370-gpio", "marvell,orion-gpio"; reg = <0x18140 0x40>, <0x181c8 0x08>; reg-names = "gpio", "pwm"; From a4d5d2ef5b1f6cddee0fec35d86404df148b9074 Mon Sep 17 00:00:00 2001 From: Klaus Kudielka Date: Sat, 7 Jan 2023 15:41:49 +0100 Subject: [PATCH 075/398] Revert "ARM: dts: armada-39x: Fix compatible string for gpios" This reverts commit d10886a4e6f85ee18d47a1066a52168461370ded. If compatible = "marvell,armadaxp-gpio", the reg property requires a second (address, size) pair, which points to the per-CPU interrupt registers <0x18800 0x30> / <0x18840 0x30>. Furthermore: Commit 5f79c651e81e explains very well, why the gpio-mvebu driver does not work reliably with per-CPU interrupts. Commit 988c8c0cd04d deprecates compatible = marvell,armadaxp-gpio for this reason. Signed-off-by: Klaus Kudielka Reviewed-by: Andrew Lunn Signed-off-by: Gregory CLEMENT --- arch/arm/boot/dts/armada-39x.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/armada-39x.dtsi b/arch/arm/boot/dts/armada-39x.dtsi index 1e05208d9f34..9d1cac49c022 100644 --- a/arch/arm/boot/dts/armada-39x.dtsi +++ b/arch/arm/boot/dts/armada-39x.dtsi @@ -213,7 +213,7 @@ }; gpio0: gpio@18100 { - compatible = "marvell,armadaxp-gpio", "marvell,orion-gpio"; + compatible = "marvell,orion-gpio"; reg = <0x18100 0x40>; ngpios = <32>; gpio-controller; @@ -227,7 +227,7 @@ }; gpio1: gpio@18140 { - compatible = "marvell,armadaxp-gpio", "marvell,orion-gpio"; + compatible = "marvell,orion-gpio"; reg = <0x18140 0x40>; ngpios = <28>; gpio-controller; From daec8b54e9445566d003ac46e267e73755b5f55a Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Mon, 12 Dec 2022 14:59:52 +0100 Subject: [PATCH 076/398] ARM: footbridge: drop unnecessary inclusion isa-rtc.c doesn't use any definition from bcd.h, remove its inclusion Signed-off-by: Alexandre Belloni Link: https://lore.kernel.org/r/20221212135953.212303-1-alexandre.belloni@bootlin.com Signed-off-by: Arnd Bergmann --- arch/arm/mach-footbridge/isa-rtc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-footbridge/isa-rtc.c b/arch/arm/mach-footbridge/isa-rtc.c index b8f741a3a37e..237b828dd2f1 100644 --- a/arch/arm/mach-footbridge/isa-rtc.c +++ b/arch/arm/mach-footbridge/isa-rtc.c @@ -20,7 +20,6 @@ #include #include -#include #include #include "common.h" From ef01f4e25c1760920e2c94f1c232350277ace69b Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Fri, 6 Jan 2023 10:43:59 -0500 Subject: [PATCH 077/398] bpf: restore the ebpf program ID for BPF_AUDIT_UNLOAD and PERF_BPF_EVENT_PROG_UNLOAD When changing the ebpf program put() routines to support being called from within IRQ context the program ID was reset to zero prior to calling the perf event and audit UNLOAD record generators, which resulted in problems as the ebpf program ID was bogus (always zero). This patch addresses this problem by removing an unnecessary call to bpf_prog_free_id() in __bpf_prog_offload_destroy() and adjusting __bpf_prog_put() to only call bpf_prog_free_id() after audit and perf have finished their bpf program unload tasks in bpf_prog_put_deferred(). For the record, no one can determine, or remember, why it was necessary to free the program ID, and remove it from the IDR, prior to executing bpf_prog_put_deferred(); regardless, both Stanislav and Alexei agree that the approach in this patch should be safe. It is worth noting that when moving the bpf_prog_free_id() call, the do_idr_lock parameter was forced to true as the ebpf devs determined this was the correct as the do_idr_lock should always be true. The do_idr_lock parameter will be removed in a follow-up patch, but it was kept here to keep the patch small in an effort to ease any stable backports. I also modified the bpf_audit_prog() logic used to associate the AUDIT_BPF record with other associated records, e.g. @ctx != NULL. Instead of keying off the operation, it now keys off the execution context, e.g. '!in_irg && !irqs_disabled()', which is much more appropriate and should help better connect the UNLOAD operations with the associated audit state (other audit records). Cc: stable@vger.kernel.org Fixes: d809e134be7a ("bpf: Prepare bpf_prog_put() to be called from irq context.") Reported-by: Burn Alting Reported-by: Jiri Olsa Suggested-by: Stanislav Fomichev Suggested-by: Alexei Starovoitov Signed-off-by: Paul Moore Acked-by: Stanislav Fomichev Link: https://lore.kernel.org/r/20230106154400.74211-1-paul@paul-moore.com Signed-off-by: Alexei Starovoitov --- kernel/bpf/offload.c | 3 --- kernel/bpf/syscall.c | 6 ++---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c index 13e4efc971e6..190d9f9dc987 100644 --- a/kernel/bpf/offload.c +++ b/kernel/bpf/offload.c @@ -216,9 +216,6 @@ static void __bpf_prog_offload_destroy(struct bpf_prog *prog) if (offload->dev_state) offload->offdev->ops->destroy(prog); - /* Make sure BPF_PROG_GET_NEXT_ID can't find this dead program */ - bpf_prog_free_id(prog, true); - list_del_init(&offload->offloads); kfree(offload); prog->aux->offload = NULL; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 64131f88c553..61bb19e81b9c 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1972,7 +1972,7 @@ static void bpf_audit_prog(const struct bpf_prog *prog, unsigned int op) return; if (audit_enabled == AUDIT_OFF) return; - if (op == BPF_AUDIT_LOAD) + if (!in_irq() && !irqs_disabled()) ctx = audit_context(); ab = audit_log_start(ctx, GFP_ATOMIC, AUDIT_BPF); if (unlikely(!ab)) @@ -2067,6 +2067,7 @@ static void bpf_prog_put_deferred(struct work_struct *work) prog = aux->prog; perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_UNLOAD, 0); bpf_audit_prog(prog, BPF_AUDIT_UNLOAD); + bpf_prog_free_id(prog, true); __bpf_prog_put_noref(prog, true); } @@ -2075,9 +2076,6 @@ static void __bpf_prog_put(struct bpf_prog *prog, bool do_idr_lock) struct bpf_prog_aux *aux = prog->aux; if (atomic64_dec_and_test(&aux->refcnt)) { - /* bpf_prog_free_id() must be called first */ - bpf_prog_free_id(prog, do_idr_lock); - if (in_irq() || irqs_disabled()) { INIT_WORK(&aux->work, bpf_prog_put_deferred); schedule_work(&aux->work); From e7895f017b79410bf4591396a733b876dc1e0e9d Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Fri, 6 Jan 2023 10:44:00 -0500 Subject: [PATCH 078/398] bpf: remove the do_idr_lock parameter from bpf_prog_free_id() It was determined that the do_idr_lock parameter to bpf_prog_free_id() was not necessary as it should always be true. Suggested-by: Stanislav Fomichev Signed-off-by: Paul Moore Acked-by: Stanislav Fomichev Link: https://lore.kernel.org/r/20230106154400.74211-2-paul@paul-moore.com Signed-off-by: Alexei Starovoitov --- include/linux/bpf.h | 2 +- kernel/bpf/syscall.c | 20 ++++++-------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 3de24cfb7a3d..634d37a599fa 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1832,7 +1832,7 @@ void bpf_prog_inc(struct bpf_prog *prog); struct bpf_prog * __must_check bpf_prog_inc_not_zero(struct bpf_prog *prog); void bpf_prog_put(struct bpf_prog *prog); -void bpf_prog_free_id(struct bpf_prog *prog, bool do_idr_lock); +void bpf_prog_free_id(struct bpf_prog *prog); void bpf_map_free_id(struct bpf_map *map, bool do_idr_lock); struct btf_field *btf_record_find(const struct btf_record *rec, diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 61bb19e81b9c..ecca9366c7a6 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -2001,7 +2001,7 @@ static int bpf_prog_alloc_id(struct bpf_prog *prog) return id > 0 ? 0 : id; } -void bpf_prog_free_id(struct bpf_prog *prog, bool do_idr_lock) +void bpf_prog_free_id(struct bpf_prog *prog) { unsigned long flags; @@ -2013,18 +2013,10 @@ void bpf_prog_free_id(struct bpf_prog *prog, bool do_idr_lock) if (!prog->aux->id) return; - if (do_idr_lock) - spin_lock_irqsave(&prog_idr_lock, flags); - else - __acquire(&prog_idr_lock); - + spin_lock_irqsave(&prog_idr_lock, flags); idr_remove(&prog_idr, prog->aux->id); prog->aux->id = 0; - - if (do_idr_lock) - spin_unlock_irqrestore(&prog_idr_lock, flags); - else - __release(&prog_idr_lock); + spin_unlock_irqrestore(&prog_idr_lock, flags); } static void __bpf_prog_put_rcu(struct rcu_head *rcu) @@ -2067,11 +2059,11 @@ static void bpf_prog_put_deferred(struct work_struct *work) prog = aux->prog; perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_UNLOAD, 0); bpf_audit_prog(prog, BPF_AUDIT_UNLOAD); - bpf_prog_free_id(prog, true); + bpf_prog_free_id(prog); __bpf_prog_put_noref(prog, true); } -static void __bpf_prog_put(struct bpf_prog *prog, bool do_idr_lock) +static void __bpf_prog_put(struct bpf_prog *prog) { struct bpf_prog_aux *aux = prog->aux; @@ -2087,7 +2079,7 @@ static void __bpf_prog_put(struct bpf_prog *prog, bool do_idr_lock) void bpf_prog_put(struct bpf_prog *prog) { - __bpf_prog_put(prog, true); + __bpf_prog_put(prog); } EXPORT_SYMBOL_GPL(bpf_prog_put); From 6acd87d50998ef0afafc441613aeaf5a8f5c9eff Mon Sep 17 00:00:00 2001 From: Siddh Raman Pant Date: Fri, 9 Dec 2022 15:51:51 +0530 Subject: [PATCH 079/398] erofs/zmap.c: Fix incorrect offset calculation Effective offset to add to length was being incorrectly calculated, which resulted in iomap->length being set to 0, triggering a WARN_ON in iomap_iter_done(). Fix that, and describe it in comments. This was reported as a crash by syzbot under an issue about a warning encountered in iomap_iter_done(), but unrelated to erofs. C reproducer: https://syzkaller.appspot.com/text?tag=ReproC&x=1037a6b2880000 Kernel config: https://syzkaller.appspot.com/text?tag=KernelConfig&x=e2021a61197ebe02 Dashboard link: https://syzkaller.appspot.com/bug?extid=a8e049cd3abd342936b6 Reported-by: syzbot+a8e049cd3abd342936b6@syzkaller.appspotmail.com Suggested-by: Gao Xiang Signed-off-by: Siddh Raman Pant Reviewed-by: Gao Xiang Reviewed-by: Chao Yu Link: https://lore.kernel.org/r/20221209102151.311049-1-code@siddh.me Signed-off-by: Gao Xiang --- fs/erofs/zmap.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index 0150570c33aa..98fb90b9af71 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -793,12 +793,16 @@ static int z_erofs_iomap_begin_report(struct inode *inode, loff_t offset, iomap->type = IOMAP_HOLE; iomap->addr = IOMAP_NULL_ADDR; /* - * No strict rule how to describe extents for post EOF, yet - * we need do like below. Otherwise, iomap itself will get + * No strict rule on how to describe extents for post EOF, yet + * we need to do like below. Otherwise, iomap itself will get * into an endless loop on post EOF. + * + * Calculate the effective offset by subtracting extent start + * (map.m_la) from the requested offset, and add it to length. + * (NB: offset >= map.m_la always) */ if (iomap->offset >= inode->i_size) - iomap->length = length + map.m_la - offset; + iomap->length = length + offset - map.m_la; } iomap->flags = 0; return 0; From 12724ba38992bd045e92a9a88a868a530f89d13e Mon Sep 17 00:00:00 2001 From: Gao Xiang Date: Tue, 10 Jan 2023 15:49:27 +0800 Subject: [PATCH 080/398] erofs: fix kvcalloc() misuse with __GFP_NOFAIL As reported by syzbot [1], kvcalloc() cannot work with __GFP_NOFAIL. Let's use kcalloc() instead. [1] https://lore.kernel.org/r/0000000000007796bd05f1852ec2@google.com Reported-by: syzbot+c3729cda01706a04fb98@syzkaller.appspotmail.com Fixes: fe3e5914e6dc ("erofs: try to leave (de)compressed_pages on stack if possible") Fixes: 4f05687fd703 ("erofs: introduce struct z_erofs_decompress_backend") Reviewed-by: Chao Yu Signed-off-by: Gao Xiang Link: https://lore.kernel.org/r/20230110074927.41651-1-hsiangkao@linux.alibaba.com --- fs/erofs/zdata.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index ccf7c55d477f..5200bb86e264 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -1032,12 +1032,12 @@ static int z_erofs_decompress_pcluster(struct z_erofs_decompress_backend *be, if (!be->decompressed_pages) be->decompressed_pages = - kvcalloc(be->nr_pages, sizeof(struct page *), - GFP_KERNEL | __GFP_NOFAIL); + kcalloc(be->nr_pages, sizeof(struct page *), + GFP_KERNEL | __GFP_NOFAIL); if (!be->compressed_pages) be->compressed_pages = - kvcalloc(pclusterpages, sizeof(struct page *), - GFP_KERNEL | __GFP_NOFAIL); + kcalloc(pclusterpages, sizeof(struct page *), + GFP_KERNEL | __GFP_NOFAIL); z_erofs_parse_out_bvecs(be); err2 = z_erofs_parse_in_bvecs(be, &overlapped); @@ -1085,7 +1085,7 @@ out: } if (be->compressed_pages < be->onstack_pages || be->compressed_pages >= be->onstack_pages + Z_EROFS_ONSTACK_PAGES) - kvfree(be->compressed_pages); + kfree(be->compressed_pages); z_erofs_fill_other_copies(be, err); for (i = 0; i < be->nr_pages; ++i) { @@ -1104,7 +1104,7 @@ out: } if (be->decompressed_pages != be->onstack_pages) - kvfree(be->decompressed_pages); + kfree(be->decompressed_pages); pcl->length = 0; pcl->partial = true; From 80502ffab2fa92ba9777e381efea2efddc348d13 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Thu, 15 Dec 2022 15:54:02 +1300 Subject: [PATCH 081/398] arm64: dts: marvell: AC5/AC5X: Fix address for UART1 The correct address offset is 0x12100. Fixes: 31be791e26cf ("arm64: dts: marvell: Add UART1-3 for AC5/AC5X") Signed-off-by: Chris Packham Signed-off-by: Gregory CLEMENT --- arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi index 7308f7b6b22c..8bce64069138 100644 --- a/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi +++ b/arch/arm64/boot/dts/marvell/ac5-98dx25xx.dtsi @@ -98,7 +98,7 @@ uart1: serial@12100 { compatible = "snps,dw-apb-uart"; - reg = <0x11000 0x100>; + reg = <0x12100 0x100>; reg-shift = <2>; interrupts = ; reg-io-width = <1>; From 0afec5e9cea732cb47014655685a2a47fb180c31 Mon Sep 17 00:00:00 2001 From: Yonatan Nachum Date: Mon, 9 Jan 2023 13:37:11 +0000 Subject: [PATCH 082/398] RDMA/core: Fix ib block iterator counter overflow When registering a new DMA MR after selecting the best aligned page size for it, we iterate over the given sglist to split each entry to smaller, aligned to the selected page size, DMA blocks. In given circumstances where the sg entry and page size fit certain sizes and the sg entry is not aligned to the selected page size, the total size of the aligned pages we need to cover the sg entry is >= 4GB. Under this circumstances, while iterating page aligned blocks, the counter responsible for counting how much we advanced from the start of the sg entry is overflowed because its type is u32 and we pass 4GB in size. This can lead to an infinite loop inside the iterator function because the overflow prevents the counter to be larger than the size of the sg entry. Fix the presented problem by changing the advancement condition to eliminate overflow. Backtrace: [ 192.374329] efa_reg_user_mr_dmabuf [ 192.376783] efa_register_mr [ 192.382579] pgsz_bitmap 0xfffff000 rounddown 0x80000000 [ 192.386423] pg_sz [0x80000000] umem_length[0xc0000000] [ 192.392657] start 0x0 length 0xc0000000 params.page_shift 31 params.page_num 3 [ 192.399559] hp_cnt[3], pages_in_hp[524288] [ 192.403690] umem->sgt_append.sgt.nents[1] [ 192.407905] number entries: [1], pg_bit: [31] [ 192.411397] biter->__sg_nents [1] biter->__sg [0000000008b0c5d8] [ 192.415601] biter->__sg_advance [665837568] sg_dma_len[3221225472] [ 192.419823] biter->__sg_nents [1] biter->__sg [0000000008b0c5d8] [ 192.423976] biter->__sg_advance [2813321216] sg_dma_len[3221225472] [ 192.428243] biter->__sg_nents [1] biter->__sg [0000000008b0c5d8] [ 192.432397] biter->__sg_advance [665837568] sg_dma_len[3221225472] Fixes: a808273a495c ("RDMA/verbs: Add a DMA iterator to return aligned contiguous memory blocks") Signed-off-by: Yonatan Nachum Link: https://lore.kernel.org/r/20230109133711.13678-1-ynachum@amazon.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/core/verbs.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index 26b021f43ba4..11b1c1603aeb 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -2957,15 +2957,18 @@ EXPORT_SYMBOL(__rdma_block_iter_start); bool __rdma_block_iter_next(struct ib_block_iter *biter) { unsigned int block_offset; + unsigned int sg_delta; if (!biter->__sg_nents || !biter->__sg) return false; biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance; block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1); - biter->__sg_advance += BIT_ULL(biter->__pg_bit) - block_offset; + sg_delta = BIT_ULL(biter->__pg_bit) - block_offset; - if (biter->__sg_advance >= sg_dma_len(biter->__sg)) { + if (sg_dma_len(biter->__sg) - biter->__sg_advance > sg_delta) { + biter->__sg_advance += sg_delta; + } else { biter->__sg_advance = 0; biter->__sg = sg_next(biter->__sg); biter->__sg_nents--; From 0a0a6e80472c98947d73c3d13bcd7d101895f55d Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 9 Jan 2023 12:31:11 -0500 Subject: [PATCH 083/398] IB/hfi1: Reject a zero-length user expected buffer A zero length user buffer makes no sense and the code does not handle it correctly. Instead, reject a zero length as invalid. Fixes: 97736f36dbeb ("IB/hfi1: Validate page aligned for a given virtual addres") Signed-off-by: Dean Luick Signed-off-by: Dennis Dalessandro Link: https://lore.kernel.org/r/167328547120.1472310.6362802432127399257.stgit@awfm-02.cornelisnetworks.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/hfi1/user_exp_rcv.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c index 186d30291260..3c609b11e71c 100644 --- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c @@ -256,6 +256,8 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd, if (!PAGE_ALIGNED(tinfo->vaddr)) return -EINVAL; + if (tinfo->length == 0) + return -EINVAL; tidbuf = kzalloc(sizeof(*tidbuf), GFP_KERNEL); if (!tidbuf) From ecf91551cdd2925ed6d9a9d99074fa5f67b90596 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 9 Jan 2023 12:31:16 -0500 Subject: [PATCH 084/398] IB/hfi1: Reserve user expected TIDs To avoid a race, reserve the number of user expected TIDs before setup. Fixes: 7e7a436ecb6e ("staging/hfi1: Add TID entry program function body") Signed-off-by: Dean Luick Signed-off-by: Dennis Dalessandro Link: https://lore.kernel.org/r/167328547636.1472310.7419712824785353905.stgit@awfm-02.cornelisnetworks.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/hfi1/user_exp_rcv.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c index 3c609b11e71c..d7487555d109 100644 --- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c @@ -282,16 +282,13 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd, /* Find sets of physically contiguous pages */ tidbuf->n_psets = find_phys_blocks(tidbuf, pinned); - /* - * We don't need to access this under a lock since tid_used is per - * process and the same process cannot be in hfi1_user_exp_rcv_clear() - * and hfi1_user_exp_rcv_setup() at the same time. - */ + /* Reserve the number of expected tids to be used. */ spin_lock(&fd->tid_lock); if (fd->tid_used + tidbuf->n_psets > fd->tid_limit) pageset_count = fd->tid_limit - fd->tid_used; else pageset_count = tidbuf->n_psets; + fd->tid_used += pageset_count; spin_unlock(&fd->tid_lock); if (!pageset_count) @@ -400,10 +397,11 @@ unlock: nomem: hfi1_cdbg(TID, "total mapped: tidpairs:%u pages:%u (%d)", tididx, mapped_pages, ret); + /* adjust reserved tid_used to actual count */ + spin_lock(&fd->tid_lock); + fd->tid_used -= pageset_count - tididx; + spin_unlock(&fd->tid_lock); if (tididx) { - spin_lock(&fd->tid_lock); - fd->tid_used += tididx; - spin_unlock(&fd->tid_lock); tinfo->tidcnt = tididx; tinfo->length = mapped_pages * PAGE_SIZE; From e0c4a422f5246abefbf7c178ef99a1f2dc3c5f62 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 9 Jan 2023 12:31:21 -0500 Subject: [PATCH 085/398] IB/hfi1: Fix expected receive setup error exit issues Fix three error exit issues in expected receive setup. Re-arrange error exits to increase readability. Issues and fixes: 1. Possible missed page unpin if tidlist copyout fails and not all pinned pages where made part of a TID. Fix: Unpin the unused pages. 2. Return success with unset return values tidcnt and length when no pages were pinned. Fix: Return -ENOSPC if no pages were pinned. 3. Return success with unset return values tidcnt and length when no rcvarray entries available. Fix: Return -ENOSPC if no rcvarray entries are available. Fixes: 7e7a436ecb6e ("staging/hfi1: Add TID entry program function body") Fixes: 97736f36dbeb ("IB/hfi1: Validate page aligned for a given virtual addres") Fixes: f404ca4c7ea8 ("IB/hfi1: Refactor hfi_user_exp_rcv_setup() IOCTL") Signed-off-by: Dean Luick Signed-off-by: Dennis Dalessandro Link: https://lore.kernel.org/r/167328548150.1472310.1492305874804187634.stgit@awfm-02.cornelisnetworks.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/hfi1/user_exp_rcv.c | 87 ++++++++++++++--------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c index d7487555d109..88df8ca4bb57 100644 --- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c @@ -268,15 +268,14 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd, tidbuf->psets = kcalloc(uctxt->expected_count, sizeof(*tidbuf->psets), GFP_KERNEL); if (!tidbuf->psets) { - kfree(tidbuf); - return -ENOMEM; + ret = -ENOMEM; + goto fail_release_mem; } pinned = pin_rcv_pages(fd, tidbuf); if (pinned <= 0) { - kfree(tidbuf->psets); - kfree(tidbuf); - return pinned; + ret = (pinned < 0) ? pinned : -ENOSPC; + goto fail_unpin; } /* Find sets of physically contiguous pages */ @@ -291,14 +290,16 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd, fd->tid_used += pageset_count; spin_unlock(&fd->tid_lock); - if (!pageset_count) - goto bail; + if (!pageset_count) { + ret = -ENOSPC; + goto fail_unreserve; + } ngroups = pageset_count / dd->rcv_entries.group_size; tidlist = kcalloc(pageset_count, sizeof(*tidlist), GFP_KERNEL); if (!tidlist) { ret = -ENOMEM; - goto nomem; + goto fail_unreserve; } tididx = 0; @@ -394,44 +395,60 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd, } unlock: mutex_unlock(&uctxt->exp_mutex); -nomem: hfi1_cdbg(TID, "total mapped: tidpairs:%u pages:%u (%d)", tididx, mapped_pages, ret); + + /* fail if nothing was programmed, set error if none provided */ + if (tididx == 0) { + if (ret >= 0) + ret = -ENOSPC; + goto fail_unreserve; + } + /* adjust reserved tid_used to actual count */ spin_lock(&fd->tid_lock); fd->tid_used -= pageset_count - tididx; spin_unlock(&fd->tid_lock); - if (tididx) { - tinfo->tidcnt = tididx; - tinfo->length = mapped_pages * PAGE_SIZE; - if (copy_to_user(u64_to_user_ptr(tinfo->tidlist), - tidlist, sizeof(tidlist[0]) * tididx)) { - /* - * On failure to copy to the user level, we need to undo - * everything done so far so we don't leak resources. - */ - tinfo->tidlist = (unsigned long)&tidlist; - hfi1_user_exp_rcv_clear(fd, tinfo); - tinfo->tidlist = 0; - ret = -EFAULT; - goto bail; - } + /* unpin all pages not covered by a TID */ + unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages, pinned - mapped_pages, + false); + + tinfo->tidcnt = tididx; + tinfo->length = mapped_pages * PAGE_SIZE; + + if (copy_to_user(u64_to_user_ptr(tinfo->tidlist), + tidlist, sizeof(tidlist[0]) * tididx)) { + ret = -EFAULT; + goto fail_unprogram; } - /* - * If not everything was mapped (due to insufficient RcvArray entries, - * for example), unpin all unmapped pages so we can pin them nex time. - */ - if (mapped_pages != pinned) - unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages, - (pinned - mapped_pages), false); -bail: - kfree(tidbuf->psets); - kfree(tidlist); kfree(tidbuf->pages); + kfree(tidbuf->psets); kfree(tidbuf); - return ret > 0 ? 0 : ret; + kfree(tidlist); + return 0; + +fail_unprogram: + /* unprogram, unmap, and unpin all allocated TIDs */ + tinfo->tidlist = (unsigned long)tidlist; + hfi1_user_exp_rcv_clear(fd, tinfo); + tinfo->tidlist = 0; + pinned = 0; /* nothing left to unpin */ + pageset_count = 0; /* nothing left reserved */ +fail_unreserve: + spin_lock(&fd->tid_lock); + fd->tid_used -= pageset_count; + spin_unlock(&fd->tid_lock); +fail_unpin: + if (pinned > 0) + unpin_rcv_pages(fd, tidbuf, NULL, 0, pinned, false); +fail_release_mem: + kfree(tidbuf->pages); + kfree(tidbuf->psets); + kfree(tidbuf); + kfree(tidlist); + return ret; } int hfi1_user_exp_rcv_clear(struct hfi1_filedata *fd, From 1c7edde1b5720ddb0aff5ca8c7f605a0f92526eb Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 9 Jan 2023 12:31:26 -0500 Subject: [PATCH 086/398] IB/hfi1: Immediately remove invalid memory from hardware When a user expected receive page is unmapped, it should be immediately removed from hardware rather than depend on a reaction from user space. Fixes: 2677a7680e77 ("IB/hfi1: Fix memory leak during unexpected shutdown") Signed-off-by: Dean Luick Signed-off-by: Dennis Dalessandro Link: https://lore.kernel.org/r/167328548663.1472310.7871808081861622659.stgit@awfm-02.cornelisnetworks.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/hfi1/user_exp_rcv.c | 43 +++++++++++++++-------- drivers/infiniband/hw/hfi1/user_exp_rcv.h | 1 + 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c index 88df8ca4bb57..f402af1e2903 100644 --- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c @@ -28,8 +28,9 @@ static int program_rcvarray(struct hfi1_filedata *fd, struct tid_user_buf *, unsigned int start, u16 count, u32 *tidlist, unsigned int *tididx, unsigned int *pmapped); -static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo, - struct tid_group **grp); +static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo); +static void __clear_tid_node(struct hfi1_filedata *fd, + struct tid_rb_node *node); static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node); static const struct mmu_interval_notifier_ops tid_mn_ops = { @@ -469,7 +470,7 @@ int hfi1_user_exp_rcv_clear(struct hfi1_filedata *fd, mutex_lock(&uctxt->exp_mutex); for (tididx = 0; tididx < tinfo->tidcnt; tididx++) { - ret = unprogram_rcvarray(fd, tidinfo[tididx], NULL); + ret = unprogram_rcvarray(fd, tidinfo[tididx]); if (ret) { hfi1_cdbg(TID, "Failed to unprogram rcv array %d", ret); @@ -723,6 +724,7 @@ static int set_rcvarray_entry(struct hfi1_filedata *fd, } node->fdata = fd; + mutex_init(&node->invalidate_mutex); node->phys = page_to_phys(pages[0]); node->npages = npages; node->rcventry = rcventry; @@ -762,8 +764,7 @@ out_unmap: return -EFAULT; } -static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo, - struct tid_group **grp) +static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo) { struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_devdata *dd = uctxt->dd; @@ -786,9 +787,6 @@ static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo, if (!node || node->rcventry != (uctxt->expected_base + rcventry)) return -EBADF; - if (grp) - *grp = node->grp; - if (fd->use_mn) mmu_interval_notifier_remove(&node->notifier); cacheless_tid_rb_remove(fd, node); @@ -796,23 +794,34 @@ static int unprogram_rcvarray(struct hfi1_filedata *fd, u32 tidinfo, return 0; } -static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node) +static void __clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node) { struct hfi1_ctxtdata *uctxt = fd->uctxt; struct hfi1_devdata *dd = uctxt->dd; + mutex_lock(&node->invalidate_mutex); + if (node->freed) + goto done; + node->freed = true; + trace_hfi1_exp_tid_unreg(uctxt->ctxt, fd->subctxt, node->rcventry, node->npages, node->notifier.interval_tree.start, node->phys, node->dma_addr); - /* - * Make sure device has seen the write before we unpin the - * pages. - */ + /* Make sure device has seen the write before pages are unpinned */ hfi1_put_tid(dd, node->rcventry, PT_INVALID_FLUSH, 0, 0); unpin_rcv_pages(fd, NULL, node, 0, node->npages, true); +done: + mutex_unlock(&node->invalidate_mutex); +} + +static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node) +{ + struct hfi1_ctxtdata *uctxt = fd->uctxt; + + __clear_tid_node(fd, node); node->grp->used--; node->grp->map &= ~(1 << (node->rcventry - node->grp->base)); @@ -871,10 +880,16 @@ static bool tid_rb_invalidate(struct mmu_interval_notifier *mni, if (node->freed) return true; + /* take action only if unmapping */ + if (range->event != MMU_NOTIFY_UNMAP) + return true; + trace_hfi1_exp_tid_inval(uctxt->ctxt, fdata->subctxt, node->notifier.interval_tree.start, node->rcventry, node->npages, node->dma_addr); - node->freed = true; + + /* clear the hardware rcvarray entry */ + __clear_tid_node(fdata, node); spin_lock(&fdata->invalid_lock); if (fdata->invalid_tid_idx < uctxt->expected_count) { diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.h b/drivers/infiniband/hw/hfi1/user_exp_rcv.h index 8c53e416bf84..2ddb3dac7d91 100644 --- a/drivers/infiniband/hw/hfi1/user_exp_rcv.h +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.h @@ -27,6 +27,7 @@ struct tid_user_buf { struct tid_rb_node { struct mmu_interval_notifier notifier; struct hfi1_filedata *fdata; + struct mutex invalidate_mutex; /* covers hw removal */ unsigned long phys; struct tid_group *grp; u32 rcventry; From b3deec25847bda34e34d5d7be02f633caf000bd8 Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 9 Jan 2023 12:31:31 -0500 Subject: [PATCH 087/398] IB/hfi1: Remove user expected buffer invalidate race During setup, there is a possible race between a page invalidate and hardware programming. Add a covering invalidate over the user target range during setup. If anything within that range is invalidated during setup, fail the setup. Once set up, each TID will have its own invalidate callback and invalidate. Fixes: 3889551db212 ("RDMA/hfi1: Use mmu_interval_notifier_insert for user_exp_rcv") Signed-off-by: Dean Luick Signed-off-by: Dennis Dalessandro Link: https://lore.kernel.org/r/167328549178.1472310.9867497376936699488.stgit@awfm-02.cornelisnetworks.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/hfi1/user_exp_rcv.c | 58 +++++++++++++++++++++-- drivers/infiniband/hw/hfi1/user_exp_rcv.h | 2 + 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c index f402af1e2903..b02f2f0809c8 100644 --- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c @@ -23,6 +23,9 @@ static void cacheless_tid_rb_remove(struct hfi1_filedata *fdata, static bool tid_rb_invalidate(struct mmu_interval_notifier *mni, const struct mmu_notifier_range *range, unsigned long cur_seq); +static bool tid_cover_invalidate(struct mmu_interval_notifier *mni, + const struct mmu_notifier_range *range, + unsigned long cur_seq); static int program_rcvarray(struct hfi1_filedata *fd, struct tid_user_buf *, struct tid_group *grp, unsigned int start, u16 count, @@ -36,6 +39,9 @@ static void clear_tid_node(struct hfi1_filedata *fd, struct tid_rb_node *node); static const struct mmu_interval_notifier_ops tid_mn_ops = { .invalidate = tid_rb_invalidate, }; +static const struct mmu_interval_notifier_ops tid_cover_ops = { + .invalidate = tid_cover_invalidate, +}; /* * Initialize context and file private data needed for Expected @@ -254,6 +260,7 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd, tididx = 0, mapped, mapped_pages = 0; u32 *tidlist = NULL; struct tid_user_buf *tidbuf; + unsigned long mmu_seq = 0; if (!PAGE_ALIGNED(tinfo->vaddr)) return -EINVAL; @@ -264,6 +271,7 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd, if (!tidbuf) return -ENOMEM; + mutex_init(&tidbuf->cover_mutex); tidbuf->vaddr = tinfo->vaddr; tidbuf->length = tinfo->length; tidbuf->psets = kcalloc(uctxt->expected_count, sizeof(*tidbuf->psets), @@ -273,6 +281,16 @@ int hfi1_user_exp_rcv_setup(struct hfi1_filedata *fd, goto fail_release_mem; } + if (fd->use_mn) { + ret = mmu_interval_notifier_insert( + &tidbuf->notifier, current->mm, + tidbuf->vaddr, tidbuf->npages * PAGE_SIZE, + &tid_cover_ops); + if (ret) + goto fail_release_mem; + mmu_seq = mmu_interval_read_begin(&tidbuf->notifier); + } + pinned = pin_rcv_pages(fd, tidbuf); if (pinned <= 0) { ret = (pinned < 0) ? pinned : -ENOSPC; @@ -415,6 +433,20 @@ unlock: unpin_rcv_pages(fd, tidbuf, NULL, mapped_pages, pinned - mapped_pages, false); + if (fd->use_mn) { + /* check for an invalidate during setup */ + bool fail = false; + + mutex_lock(&tidbuf->cover_mutex); + fail = mmu_interval_read_retry(&tidbuf->notifier, mmu_seq); + mutex_unlock(&tidbuf->cover_mutex); + + if (fail) { + ret = -EBUSY; + goto fail_unprogram; + } + } + tinfo->tidcnt = tididx; tinfo->length = mapped_pages * PAGE_SIZE; @@ -424,6 +456,8 @@ unlock: goto fail_unprogram; } + if (fd->use_mn) + mmu_interval_notifier_remove(&tidbuf->notifier); kfree(tidbuf->pages); kfree(tidbuf->psets); kfree(tidbuf); @@ -442,6 +476,8 @@ fail_unreserve: fd->tid_used -= pageset_count; spin_unlock(&fd->tid_lock); fail_unpin: + if (fd->use_mn) + mmu_interval_notifier_remove(&tidbuf->notifier); if (pinned > 0) unpin_rcv_pages(fd, tidbuf, NULL, 0, pinned, false); fail_release_mem: @@ -740,11 +776,6 @@ static int set_rcvarray_entry(struct hfi1_filedata *fd, &tid_mn_ops); if (ret) goto out_unmap; - /* - * FIXME: This is in the wrong order, the notifier should be - * established before the pages are pinned by pin_rcv_pages. - */ - mmu_interval_read_begin(&node->notifier); } fd->entry_to_rb[node->rcventry - uctxt->expected_base] = node; @@ -919,6 +950,23 @@ static bool tid_rb_invalidate(struct mmu_interval_notifier *mni, return true; } +static bool tid_cover_invalidate(struct mmu_interval_notifier *mni, + const struct mmu_notifier_range *range, + unsigned long cur_seq) +{ + struct tid_user_buf *tidbuf = + container_of(mni, struct tid_user_buf, notifier); + + /* take action only if unmapping */ + if (range->event == MMU_NOTIFY_UNMAP) { + mutex_lock(&tidbuf->cover_mutex); + mmu_interval_set_seq(mni, cur_seq); + mutex_unlock(&tidbuf->cover_mutex); + } + + return true; +} + static void cacheless_tid_rb_remove(struct hfi1_filedata *fdata, struct tid_rb_node *tnode) { diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.h b/drivers/infiniband/hw/hfi1/user_exp_rcv.h index 2ddb3dac7d91..f8ee997d0050 100644 --- a/drivers/infiniband/hw/hfi1/user_exp_rcv.h +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.h @@ -16,6 +16,8 @@ struct tid_pageset { }; struct tid_user_buf { + struct mmu_interval_notifier notifier; + struct mutex cover_mutex; unsigned long vaddr; unsigned long length; unsigned int npages; From e66b7920aa5ac5b1a1997a454004ba9246a3c005 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 30 Dec 2022 21:07:47 +0100 Subject: [PATCH 088/398] wifi: mac80211: fix initialization of rx->link and rx->link_sta There are some codepaths that do not initialize rx->link_sta properly. This causes a crash in places which assume that rx->link_sta is valid if rx->sta is valid. One known instance is triggered by __ieee80211_rx_h_amsdu being called from fast-rx. It results in a crash like this one: BUG: kernel NULL pointer dereference, address: 00000000000000a8 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page PGD 0 P4D 0 Oops: 0002 [#1] PREEMPT SMP PTI CPU: 1 PID: 506 Comm: mt76-usb-rx phy Tainted: G E 6.1.0-debian64x+1.7 #3 Hardware name: ZOTAC ZBOX-ID92/ZBOX-IQ01/ZBOX-ID92/ZBOX-IQ01, BIOS B220P007 05/21/2014 RIP: 0010:ieee80211_deliver_skb+0x62/0x1f0 [mac80211] Code: 00 48 89 04 24 e8 9e a7 c3 df 89 c0 48 03 1c c5 a0 ea 39 a1 4c 01 6b 08 48 ff 03 48 83 7d 28 00 74 11 48 8b 45 30 48 63 55 44 <48> 83 84 d0 a8 00 00 00 01 41 8b 86 c0 11 00 00 8d 50 fd 83 fa 01 RSP: 0018:ffff999040803b10 EFLAGS: 00010286 RAX: 0000000000000000 RBX: ffffb9903f496480 RCX: 0000000000000000 RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 RBP: ffff999040803ce0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000000 R12: ffff8d21828ac900 R13: 000000000000004a R14: ffff8d2198ed89c0 R15: ffff8d2198ed8000 FS: 0000000000000000(0000) GS:ffff8d24afe80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000000000a8 CR3: 0000000429810002 CR4: 00000000001706e0 Call Trace: __ieee80211_rx_h_amsdu+0x1b5/0x240 [mac80211] ? ieee80211_prepare_and_rx_handle+0xcdd/0x1320 [mac80211] ? __local_bh_enable_ip+0x3b/0xa0 ieee80211_prepare_and_rx_handle+0xcdd/0x1320 [mac80211] ? prepare_transfer+0x109/0x1a0 [xhci_hcd] ieee80211_rx_list+0xa80/0xda0 [mac80211] mt76_rx_complete+0x207/0x2e0 [mt76] mt76_rx_poll_complete+0x357/0x5a0 [mt76] mt76u_rx_worker+0x4f5/0x600 [mt76_usb] ? mt76_get_min_avg_rssi+0x140/0x140 [mt76] __mt76_worker_fn+0x50/0x80 [mt76] kthread+0xed/0x120 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x22/0x30 Since the initialization of rx->link and rx->link_sta is rather convoluted and duplicated in many places, clean it up by using a helper function to set it. Fixes: ccdde7c74ffd ("wifi: mac80211: properly implement MLO key handling") Fixes: b320d6c456ff ("wifi: mac80211: use correct rx link_sta instead of default") Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20221230200747.19040-1-nbd@nbd.name [remove unnecessary rx->sta->sta.mlo check] Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 222 +++++++++++++++++++++------------------------- 1 file changed, 99 insertions(+), 123 deletions(-) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7e3ab6e1b28f..c518287b2356 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -4049,6 +4049,58 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) #undef CALL_RXH } +static bool +ieee80211_rx_is_valid_sta_link_id(struct ieee80211_sta *sta, u8 link_id) +{ + if (!sta->mlo) + return false; + + return !!(sta->valid_links & BIT(link_id)); +} + +static bool ieee80211_rx_data_set_link(struct ieee80211_rx_data *rx, + u8 link_id) +{ + rx->link_id = link_id; + rx->link = rcu_dereference(rx->sdata->link[link_id]); + + if (!rx->sta) + return rx->link; + + if (!ieee80211_rx_is_valid_sta_link_id(&rx->sta->sta, link_id)) + return false; + + rx->link_sta = rcu_dereference(rx->sta->link[link_id]); + + return rx->link && rx->link_sta; +} + +static bool ieee80211_rx_data_set_sta(struct ieee80211_rx_data *rx, + struct ieee80211_sta *pubsta, + int link_id) +{ + struct sta_info *sta; + + sta = container_of(pubsta, struct sta_info, sta); + + rx->link_id = link_id; + rx->sta = sta; + + if (sta) { + rx->local = sta->sdata->local; + if (!rx->sdata) + rx->sdata = sta->sdata; + rx->link_sta = &sta->deflink; + } + + if (link_id < 0) + rx->link = &rx->sdata->deflink; + else if (!ieee80211_rx_data_set_link(rx, link_id)) + return false; + + return true; +} + /* * This function makes calls into the RX path, therefore * it has to be invoked under RCU read lock. @@ -4057,16 +4109,19 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) { struct sk_buff_head frames; struct ieee80211_rx_data rx = { - .sta = sta, - .sdata = sta->sdata, - .local = sta->local, /* This is OK -- must be QoS data frame */ .security_idx = tid, .seqno_idx = tid, - .link_id = -1, }; struct tid_ampdu_rx *tid_agg_rx; - u8 link_id; + int link_id = -1; + + /* FIXME: statistics won't be right with this */ + if (sta->sta.valid_links) + link_id = ffs(sta->sta.valid_links) - 1; + + if (!ieee80211_rx_data_set_sta(&rx, &sta->sta, link_id)) + return; tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); if (!tid_agg_rx) @@ -4086,10 +4141,6 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) }; drv_event_callback(rx.local, rx.sdata, &event); } - /* FIXME: statistics won't be right with this */ - link_id = sta->sta.valid_links ? ffs(sta->sta.valid_links) - 1 : 0; - rx.link = rcu_dereference(sta->sdata->link[link_id]); - rx.link_sta = rcu_dereference(sta->link[link_id]); ieee80211_rx_handlers(&rx, &frames); } @@ -4105,7 +4156,6 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid, /* This is OK -- must be QoS data frame */ .security_idx = tid, .seqno_idx = tid, - .link_id = -1, }; int i, diff; @@ -4116,10 +4166,8 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid, sta = container_of(pubsta, struct sta_info, sta); - rx.sta = sta; - rx.sdata = sta->sdata; - rx.link = &rx.sdata->deflink; - rx.local = sta->local; + if (!ieee80211_rx_data_set_sta(&rx, pubsta, -1)) + return; rcu_read_lock(); tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); @@ -4506,15 +4554,6 @@ void ieee80211_check_fast_rx_iface(struct ieee80211_sub_if_data *sdata) mutex_unlock(&local->sta_mtx); } -static bool -ieee80211_rx_is_valid_sta_link_id(struct ieee80211_sta *sta, u8 link_id) -{ - if (!sta->mlo) - return false; - - return !!(sta->valid_links & BIT(link_id)); -} - static void ieee80211_rx_8023(struct ieee80211_rx_data *rx, struct ieee80211_fast_rx *fast_rx, int orig_len) @@ -4625,7 +4664,6 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx, struct sk_buff *skb = rx->skb; struct ieee80211_hdr *hdr = (void *)skb->data; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - struct sta_info *sta = rx->sta; int orig_len = skb->len; int hdrlen = ieee80211_hdrlen(hdr->frame_control); int snap_offs = hdrlen; @@ -4637,7 +4675,6 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx, u8 da[ETH_ALEN]; u8 sa[ETH_ALEN]; } addrs __aligned(2); - struct link_sta_info *link_sta; struct ieee80211_sta_rx_stats *stats; /* for parallel-rx, we need to have DUP_VALIDATED, otherwise we write @@ -4740,18 +4777,10 @@ static bool ieee80211_invoke_fast_rx(struct ieee80211_rx_data *rx, drop: dev_kfree_skb(skb); - if (rx->link_id >= 0) { - link_sta = rcu_dereference(sta->link[rx->link_id]); - if (!link_sta) - return true; - } else { - link_sta = &sta->deflink; - } - if (fast_rx->uses_rss) - stats = this_cpu_ptr(link_sta->pcpu_rx_stats); + stats = this_cpu_ptr(rx->link_sta->pcpu_rx_stats); else - stats = &link_sta->rx_stats; + stats = &rx->link_sta->rx_stats; stats->dropped++; return true; @@ -4769,8 +4798,8 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, struct ieee80211_local *local = rx->local; struct ieee80211_sub_if_data *sdata = rx->sdata; struct ieee80211_hdr *hdr = (void *)skb->data; - struct link_sta_info *link_sta = NULL; - struct ieee80211_link_data *link; + struct link_sta_info *link_sta = rx->link_sta; + struct ieee80211_link_data *link = rx->link; rx->skb = skb; @@ -4792,35 +4821,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, if (!ieee80211_accept_frame(rx)) return false; - if (rx->link_id >= 0) { - link = rcu_dereference(rx->sdata->link[rx->link_id]); - - /* we might race link removal */ - if (!link) - return true; - rx->link = link; - - if (rx->sta) { - rx->link_sta = - rcu_dereference(rx->sta->link[rx->link_id]); - if (!rx->link_sta) - return true; - } - } else { - if (rx->sta) - rx->link_sta = &rx->sta->deflink; - - rx->link = &sdata->deflink; - } - - if (unlikely(!is_multicast_ether_addr(hdr->addr1) && - rx->link_id >= 0 && rx->sta && rx->sta->sta.mlo)) { - link_sta = rcu_dereference(rx->sta->link[rx->link_id]); - - if (WARN_ON_ONCE(!link_sta)) - return true; - } - if (!consume) { struct skb_shared_hwtstamps *shwt; @@ -4840,7 +4840,7 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, shwt->hwtstamp = skb_hwtstamps(skb)->hwtstamp; } - if (unlikely(link_sta)) { + if (unlikely(rx->sta && rx->sta->sta.mlo)) { /* translate to MLD addresses */ if (ether_addr_equal(link->conf->addr, hdr->addr1)) ether_addr_copy(hdr->addr1, rx->sdata->vif.addr); @@ -4870,6 +4870,7 @@ static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw, struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_fast_rx *fast_rx; struct ieee80211_rx_data rx; + int link_id = -1; memset(&rx, 0, sizeof(rx)); rx.skb = skb; @@ -4886,12 +4887,8 @@ static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw, if (!pubsta) goto drop; - rx.sta = container_of(pubsta, struct sta_info, sta); - rx.sdata = rx.sta->sdata; - - if (status->link_valid && - !ieee80211_rx_is_valid_sta_link_id(pubsta, status->link_id)) - goto drop; + if (status->link_valid) + link_id = status->link_id; /* * TODO: Should the frame be dropped if the right link_id is not @@ -4900,19 +4897,8 @@ static void __ieee80211_rx_handle_8023(struct ieee80211_hw *hw, * link_id is used only for stats purpose and updating the stats on * the deflink is fine? */ - if (status->link_valid) - rx.link_id = status->link_id; - - if (rx.link_id >= 0) { - struct ieee80211_link_data *link; - - link = rcu_dereference(rx.sdata->link[rx.link_id]); - if (!link) - goto drop; - rx.link = link; - } else { - rx.link = &rx.sdata->deflink; - } + if (!ieee80211_rx_data_set_sta(&rx, pubsta, link_id)) + goto drop; fast_rx = rcu_dereference(rx.sta->fast_rx); if (!fast_rx) @@ -4930,6 +4916,8 @@ static bool ieee80211_rx_for_interface(struct ieee80211_rx_data *rx, { struct link_sta_info *link_sta; struct ieee80211_hdr *hdr = (void *)skb->data; + struct sta_info *sta; + int link_id = -1; /* * Look up link station first, in case there's a @@ -4939,24 +4927,19 @@ static bool ieee80211_rx_for_interface(struct ieee80211_rx_data *rx, */ link_sta = link_sta_info_get_bss(rx->sdata, hdr->addr2); if (link_sta) { - rx->sta = link_sta->sta; - rx->link_id = link_sta->link_id; + sta = link_sta->sta; + link_id = link_sta->link_id; } else { struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - rx->sta = sta_info_get_bss(rx->sdata, hdr->addr2); - if (rx->sta) { - if (status->link_valid && - !ieee80211_rx_is_valid_sta_link_id(&rx->sta->sta, - status->link_id)) - return false; - - rx->link_id = status->link_valid ? status->link_id : -1; - } else { - rx->link_id = -1; - } + sta = sta_info_get_bss(rx->sdata, hdr->addr2); + if (status->link_valid) + link_id = status->link_id; } + if (!ieee80211_rx_data_set_sta(rx, &sta->sta, link_id)) + return false; + return ieee80211_prepare_and_rx_handle(rx, skb, consume); } @@ -5015,19 +4998,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (ieee80211_is_data(fc)) { struct sta_info *sta, *prev_sta; - u8 link_id = status->link_id; + int link_id = -1; + + if (status->link_valid) + link_id = status->link_id; if (pubsta) { - rx.sta = container_of(pubsta, struct sta_info, sta); - rx.sdata = rx.sta->sdata; - - if (status->link_valid && - !ieee80211_rx_is_valid_sta_link_id(pubsta, link_id)) + if (!ieee80211_rx_data_set_sta(&rx, pubsta, link_id)) goto out; - if (status->link_valid) - rx.link_id = status->link_id; - /* * In MLO connection, fetch the link_id using addr2 * when the driver does not pass link_id in status. @@ -5045,7 +5024,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (!link_sta) goto out; - rx.link_id = link_sta->link_id; + ieee80211_rx_data_set_link(&rx, link_sta->link_id); } if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) @@ -5061,30 +5040,27 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, continue; } - if ((status->link_valid && - !ieee80211_rx_is_valid_sta_link_id(&prev_sta->sta, - link_id)) || - (!status->link_valid && prev_sta->sta.mlo)) + rx.sdata = prev_sta->sdata; + if (!ieee80211_rx_data_set_sta(&rx, &prev_sta->sta, + link_id)) + goto out; + + if (!status->link_valid && prev_sta->sta.mlo) continue; - rx.link_id = status->link_valid ? link_id : -1; - rx.sta = prev_sta; - rx.sdata = prev_sta->sdata; ieee80211_prepare_and_rx_handle(&rx, skb, false); prev_sta = sta; } if (prev_sta) { - if ((status->link_valid && - !ieee80211_rx_is_valid_sta_link_id(&prev_sta->sta, - link_id)) || - (!status->link_valid && prev_sta->sta.mlo)) + rx.sdata = prev_sta->sdata; + if (!ieee80211_rx_data_set_sta(&rx, &prev_sta->sta, + link_id)) goto out; - rx.link_id = status->link_valid ? link_id : -1; - rx.sta = prev_sta; - rx.sdata = prev_sta->sdata; + if (!status->link_valid && prev_sta->sta.mlo) + goto out; if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) return; From 4444bc2116aecdcde87dce80373540adc8bd478b Mon Sep 17 00:00:00 2001 From: Alexander Wetzel Date: Fri, 30 Dec 2022 13:18:49 +0100 Subject: [PATCH 089/398] wifi: mac80211: Proper mark iTXQs for resumption When a running wake_tx_queue() call is aborted due to a hw queue stop the corresponding iTXQ is not always correctly marked for resumption: wake_tx_push_queue() can stops the queue run without setting @IEEE80211_TXQ_STOP_NETIF_TX. Without the @IEEE80211_TXQ_STOP_NETIF_TX flag __ieee80211_wake_txqs() will not schedule a new queue run and remaining frames in the queue get stuck till another frame is queued to it. Fix the issue for all drivers - also the ones with custom wake_tx_queue callbacks - by moving the logic into ieee80211_tx_dequeue() and drop the redundant @txqs_stopped. @IEEE80211_TXQ_STOP_NETIF_TX is also renamed to @IEEE80211_TXQ_DIRTY to better describe the flag. Fixes: c850e31f79f0 ("wifi: mac80211: add internal handler for wake_tx_queue") Signed-off-by: Alexander Wetzel Link: https://lore.kernel.org/r/20221230121850.218810-1-alexander@wetzel-home.de Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg --- include/net/mac80211.h | 4 ---- net/mac80211/debugfs_sta.c | 5 +++-- net/mac80211/driver-ops.h | 2 +- net/mac80211/ieee80211_i.h | 2 +- net/mac80211/tx.c | 20 +++++++++++------- net/mac80211/util.c | 42 +++----------------------------------- 6 files changed, 21 insertions(+), 54 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 689da327ce2e..e3235b9c02c2 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -1832,8 +1832,6 @@ struct ieee80211_vif_cfg { * @drv_priv: data area for driver use, will always be aligned to * sizeof(void \*). * @txq: the multicast data TX queue - * @txqs_stopped: per AC flag to indicate that intermediate TXQs are stopped, - * protected by fq->lock. * @offload_flags: 802.3 -> 802.11 enapsulation offload flags, see * &enum ieee80211_offload_flags. * @mbssid_tx_vif: Pointer to the transmitting interface if MBSSID is enabled. @@ -1863,8 +1861,6 @@ struct ieee80211_vif { bool probe_req_reg; bool rx_mcast_action_reg; - bool txqs_stopped[IEEE80211_NUM_ACS]; - struct ieee80211_vif *mbssid_tx_vif; /* must be last */ diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 7a3d7893e19d..f1914bf39f0e 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -167,7 +167,7 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf, continue; txqi = to_txq_info(sta->sta.txq[i]); p += scnprintf(p, bufsz + buf - p, - "%d %d %u %u %u %u %u %u %u %u %u 0x%lx(%s%s%s)\n", + "%d %d %u %u %u %u %u %u %u %u %u 0x%lx(%s%s%s%s)\n", txqi->txq.tid, txqi->txq.ac, txqi->tin.backlog_bytes, @@ -182,7 +182,8 @@ static ssize_t sta_aqm_read(struct file *file, char __user *userbuf, txqi->flags, test_bit(IEEE80211_TXQ_STOP, &txqi->flags) ? "STOP" : "RUN", test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags) ? " AMPDU" : "", - test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags) ? " NO-AMSDU" : ""); + test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags) ? " NO-AMSDU" : "", + test_bit(IEEE80211_TXQ_DIRTY, &txqi->flags) ? " DIRTY" : ""); } rcu_read_unlock(); diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 809bad53e15b..5d13a3dfd366 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h @@ -1199,7 +1199,7 @@ static inline void drv_wake_tx_queue(struct ieee80211_local *local, /* In reconfig don't transmit now, but mark for waking later */ if (local->in_reconfig) { - set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txq->flags); + set_bit(IEEE80211_TXQ_DIRTY, &txq->flags); return; } diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 63ff0d2524b6..d16606e84e22 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -838,7 +838,7 @@ enum txq_info_flags { IEEE80211_TXQ_STOP, IEEE80211_TXQ_AMPDU, IEEE80211_TXQ_NO_AMSDU, - IEEE80211_TXQ_STOP_NETIF_TX, + IEEE80211_TXQ_DIRTY, }; /** diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 2171cd1ca807..178043f84489 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3783,6 +3783,8 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_tx_data tx; ieee80211_tx_result r; struct ieee80211_vif *vif = txq->vif; + int q = vif->hw_queue[txq->ac]; + bool q_stopped; WARN_ON_ONCE(softirq_count() == 0); @@ -3790,17 +3792,21 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw, return NULL; begin: + spin_lock(&local->queue_stop_reason_lock); + q_stopped = local->queue_stop_reasons[q]; + spin_unlock(&local->queue_stop_reason_lock); + + if (unlikely(q_stopped)) { + /* mark for waking later */ + set_bit(IEEE80211_TXQ_DIRTY, &txqi->flags); + return NULL; + } + spin_lock_bh(&fq->lock); - if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags) || - test_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags)) + if (unlikely(test_bit(IEEE80211_TXQ_STOP, &txqi->flags))) goto out; - if (vif->txqs_stopped[txq->ac]) { - set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags); - goto out; - } - /* Make sure fragments stay together. */ skb = __skb_dequeue(&txqi->frags); if (unlikely(skb)) { diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 6f5407038459..261ac667887f 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -292,22 +292,12 @@ static void wake_tx_push_queue(struct ieee80211_local *local, struct ieee80211_sub_if_data *sdata, struct ieee80211_txq *queue) { - int q = sdata->vif.hw_queue[queue->ac]; struct ieee80211_tx_control control = { .sta = queue->sta, }; struct sk_buff *skb; - unsigned long flags; - bool q_stopped; while (1) { - spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - q_stopped = local->queue_stop_reasons[q]; - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - - if (q_stopped) - break; - skb = ieee80211_tx_dequeue(&local->hw, queue); if (!skb) break; @@ -347,8 +337,6 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) local_bh_disable(); spin_lock(&fq->lock); - sdata->vif.txqs_stopped[ac] = false; - if (!test_bit(SDATA_STATE_RUNNING, &sdata->state)) goto out; @@ -370,7 +358,7 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) if (ac != txq->ac) continue; - if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX, + if (!test_and_clear_bit(IEEE80211_TXQ_DIRTY, &txqi->flags)) continue; @@ -385,7 +373,7 @@ static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) txqi = to_txq_info(vif->txq); - if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags) || + if (!test_and_clear_bit(IEEE80211_TXQ_DIRTY, &txqi->flags) || (ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac) goto out; @@ -517,8 +505,6 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, bool refcounted) { struct ieee80211_local *local = hw_to_local(hw); - struct ieee80211_sub_if_data *sdata; - int n_acs = IEEE80211_NUM_ACS; trace_stop_queue(local, queue, reason); @@ -530,29 +516,7 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, else local->q_stop_reasons[queue][reason]++; - if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue])) - return; - - if (local->hw.queues < IEEE80211_NUM_ACS) - n_acs = 1; - - rcu_read_lock(); - list_for_each_entry_rcu(sdata, &local->interfaces, list) { - int ac; - - if (!sdata->dev) - continue; - - for (ac = 0; ac < n_acs; ac++) { - if (sdata->vif.hw_queue[ac] == queue || - sdata->vif.cab_queue == queue) { - spin_lock(&local->fq.lock); - sdata->vif.txqs_stopped[ac] = true; - spin_unlock(&local->fq.lock); - } - } - } - rcu_read_unlock(); + set_bit(reason, &local->queue_stop_reasons[queue]); } void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, From 69403bad97aa0162e3d7911b27e25abe774093df Mon Sep 17 00:00:00 2001 From: Alexander Wetzel Date: Fri, 30 Dec 2022 13:18:50 +0100 Subject: [PATCH 090/398] wifi: mac80211: sdata can be NULL during AMPDU start ieee80211_tx_ba_session_handle_start() may get NULL for sdata when a deauthentication is ongoing. Here a trace triggering the race with the hostapd test multi_ap_fronthaul_on_ap: (gdb) list *drv_ampdu_action+0x46 0x8b16 is in drv_ampdu_action (net/mac80211/driver-ops.c:396). 391 int ret = -EOPNOTSUPP; 392 393 might_sleep(); 394 395 sdata = get_bss_sdata(sdata); 396 if (!check_sdata_in_driver(sdata)) 397 return -EIO; 398 399 trace_drv_ampdu_action(local, sdata, params); 400 wlan0: moving STA 02:00:00:00:03:00 to state 3 wlan0: associated wlan0: deauthenticating from 02:00:00:00:03:00 by local choice (Reason: 3=DEAUTH_LEAVING) wlan3.sta1: Open BA session requested for 02:00:00:00:00:00 tid 0 wlan3.sta1: dropped frame to 02:00:00:00:00:00 (unauthorized port) wlan0: moving STA 02:00:00:00:03:00 to state 2 wlan0: moving STA 02:00:00:00:03:00 to state 1 wlan0: Removed STA 02:00:00:00:03:00 wlan0: Destroyed STA 02:00:00:00:03:00 BUG: unable to handle page fault for address: fffffffffffffb48 PGD 11814067 P4D 11814067 PUD 11816067 PMD 0 Oops: 0000 [#1] PREEMPT SMP PTI CPU: 2 PID: 133397 Comm: kworker/u16:1 Tainted: G W 6.1.0-rc8-wt+ #59 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.0-20220807_005459-localhost 04/01/2014 Workqueue: phy3 ieee80211_ba_session_work [mac80211] RIP: 0010:drv_ampdu_action+0x46/0x280 [mac80211] Code: 53 48 89 f3 be 89 01 00 00 e8 d6 43 bf ef e8 21 46 81 f0 83 bb a0 1b 00 00 04 75 0e 48 8b 9b 28 0d 00 00 48 81 eb 10 0e 00 00 <8b> 93 58 09 00 00 f6 c2 20 0f 84 3b 01 00 00 8b 05 dd 1c 0f 00 85 RSP: 0018:ffffc900025ebd20 EFLAGS: 00010287 RAX: 0000000000000000 RBX: fffffffffffff1f0 RCX: ffff888102228240 RDX: 0000000080000000 RSI: ffffffff918c5de0 RDI: ffff888102228b40 RBP: ffffc900025ebd40 R08: 0000000000000001 R09: 0000000000000001 R10: 0000000000000001 R11: 0000000000000000 R12: ffff888118c18ec0 R13: 0000000000000000 R14: ffffc900025ebd60 R15: ffff888018b7efb8 FS: 0000000000000000(0000) GS:ffff88817a600000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: fffffffffffffb48 CR3: 0000000105228006 CR4: 0000000000170ee0 Call Trace: ieee80211_tx_ba_session_handle_start+0xd0/0x190 [mac80211] ieee80211_ba_session_work+0xff/0x2e0 [mac80211] process_one_work+0x29f/0x620 worker_thread+0x4d/0x3d0 ? process_one_work+0x620/0x620 kthread+0xfb/0x120 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x22/0x30 Signed-off-by: Alexander Wetzel Link: https://lore.kernel.org/r/20221230121850.218810-2-alexander@wetzel-home.de Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg --- net/mac80211/agg-tx.c | 6 +++++- net/mac80211/driver-ops.c | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 9c40f8d3bce8..3dbb724d7dc4 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -491,7 +491,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) { struct tid_ampdu_tx *tid_tx; struct ieee80211_local *local = sta->local; - struct ieee80211_sub_if_data *sdata = sta->sdata; + struct ieee80211_sub_if_data *sdata; struct ieee80211_ampdu_params params = { .sta = &sta->sta, .action = IEEE80211_AMPDU_TX_START, @@ -521,6 +521,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) */ synchronize_net(); + sdata = sta->sdata; params.ssn = sta->tid_seq[tid] >> 4; ret = drv_ampdu_action(local, sdata, ¶ms); tid_tx->ssn = params.ssn; @@ -534,6 +535,9 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) */ set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state); } else if (ret) { + if (!sdata) + return; + ht_dbg(sdata, "BA request denied - HW unavailable for %pM tid %d\n", sta->sta.addr, tid); diff --git a/net/mac80211/driver-ops.c b/net/mac80211/driver-ops.c index d737db4e07e2..cfb09e4aed4d 100644 --- a/net/mac80211/driver-ops.c +++ b/net/mac80211/driver-ops.c @@ -392,6 +392,9 @@ int drv_ampdu_action(struct ieee80211_local *local, might_sleep(); + if (!sdata) + return -EIO; + sdata = get_bss_sdata(sdata); if (!check_sdata_in_driver(sdata)) return -EIO; From 592234e941f1addaa598601c9227e3b72d608625 Mon Sep 17 00:00:00 2001 From: Alexander Wetzel Date: Fri, 6 Jan 2023 23:31:41 +0100 Subject: [PATCH 091/398] wifi: mac80211: Fix iTXQ AMPDU fragmentation handling mac80211 must not enable aggregation wile transmitting a fragmented MPDU. Enforce that for mac80211 internal TX queues (iTXQs). Reported-by: kernel test robot Link: https://lore.kernel.org/oe-lkp/202301021738.7cd3e6ae-oliver.sang@intel.com Signed-off-by: Alexander Wetzel Link: https://lore.kernel.org/r/20230106223141.98696-1-alexander@wetzel-home.de Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg --- net/mac80211/agg-tx.c | 2 -- net/mac80211/ht.c | 31 +++++++++++++++++++++++++++++++ net/mac80211/tx.c | 18 ++++++------------ 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 3dbb724d7dc4..f9514bacbd4a 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -511,8 +511,6 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) */ clear_bit(HT_AGG_STATE_WANT_START, &tid_tx->state); - ieee80211_agg_stop_txq(sta, tid); - /* * Make sure no packets are being processed. This ensures that * we have a valid starting sequence number and that in-flight diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 83bc41346ae7..5315ab750280 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c @@ -391,6 +391,37 @@ void ieee80211_ba_session_work(struct work_struct *work) tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; if (!blocked && tid_tx) { + struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]); + struct ieee80211_sub_if_data *sdata = + vif_to_sdata(txqi->txq.vif); + struct fq *fq = &sdata->local->fq; + + spin_lock_bh(&fq->lock); + + /* Allow only frags to be dequeued */ + set_bit(IEEE80211_TXQ_STOP, &txqi->flags); + + if (!skb_queue_empty(&txqi->frags)) { + /* Fragmented Tx is ongoing, wait for it to + * finish. Reschedule worker to retry later. + */ + + spin_unlock_bh(&fq->lock); + spin_unlock_bh(&sta->lock); + + /* Give the task working on the txq a chance + * to send out the queued frags + */ + synchronize_net(); + + mutex_unlock(&sta->ampdu_mlme.mtx); + + ieee80211_queue_work(&sdata->local->hw, work); + return; + } + + spin_unlock_bh(&fq->lock); + /* * Assign it over to the normal tid_tx array * where it "goes live". diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 178043f84489..defe97a31724 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1129,7 +1129,6 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, struct sk_buff *purge_skb = NULL; if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { - info->flags |= IEEE80211_TX_CTL_AMPDU; reset_agg_timer = true; } else if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) { /* @@ -1161,7 +1160,6 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx, if (!tid_tx) { /* do nothing, let packet pass through */ } else if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) { - info->flags |= IEEE80211_TX_CTL_AMPDU; reset_agg_timer = true; } else { queued = true; @@ -3677,8 +3675,7 @@ static void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, info->band = fast_tx->band; info->control.vif = &sdata->vif; info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT | - IEEE80211_TX_CTL_DONTFRAG | - (ampdu ? IEEE80211_TX_CTL_AMPDU : 0); + IEEE80211_TX_CTL_DONTFRAG; info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT | u32_encode_bits(IEEE80211_LINK_UNSPECIFIED, IEEE80211_TX_CTRL_MLO_LINK); @@ -3804,9 +3801,6 @@ begin: spin_lock_bh(&fq->lock); - if (unlikely(test_bit(IEEE80211_TXQ_STOP, &txqi->flags))) - goto out; - /* Make sure fragments stay together. */ skb = __skb_dequeue(&txqi->frags); if (unlikely(skb)) { @@ -3816,6 +3810,9 @@ begin: IEEE80211_SKB_CB(skb)->control.flags &= ~IEEE80211_TX_INTCFL_NEED_TXPROCESSING; } else { + if (unlikely(test_bit(IEEE80211_TXQ_STOP, &txqi->flags))) + goto out; + skb = fq_tin_dequeue(fq, tin, fq_tin_dequeue_func); } @@ -3866,9 +3863,8 @@ begin: } if (test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags)) - info->flags |= IEEE80211_TX_CTL_AMPDU; - else - info->flags &= ~IEEE80211_TX_CTL_AMPDU; + info->flags |= (IEEE80211_TX_CTL_AMPDU | + IEEE80211_TX_CTL_DONTFRAG); if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) { if (!ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL)) { @@ -4602,8 +4598,6 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, info = IEEE80211_SKB_CB(skb); memset(info, 0, sizeof(*info)); - if (tid_tx) - info->flags |= IEEE80211_TX_CTL_AMPDU; info->hw_queue = sdata->vif.hw_queue[queue]; From 0eb38842ada035d71bb06fb9116f26f24ee0f998 Mon Sep 17 00:00:00 2001 From: Aloka Dixit Date: Wed, 21 Dec 2022 10:56:16 -0800 Subject: [PATCH 092/398] wifi: mac80211: reset multiple BSSID options in stop_ap() Reset multiple BSSID options when all AP related configurations are reset in ieee80211_stop_ap(). Stale values result in HWSIM test failures (e.g. p2p_group_cli_invalid), if run after 'he_ap_ema'. Reported-by: Jouni Malinen Signed-off-by: Aloka Dixit Link: https://lore.kernel.org/r/20221221185616.11514-1-quic_alokad@quicinc.com Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 8f9a2ab502b3..672eff6f5d32 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -147,6 +147,7 @@ static int ieee80211_set_ap_mbssid_options(struct ieee80211_sub_if_data *sdata, link_conf->bssid_index = 0; link_conf->nontransmitted = false; link_conf->ema_ap = false; + link_conf->bssid_indicator = 0; if (sdata->vif.type != NL80211_IFTYPE_AP || !params.tx_wdev) return -EINVAL; @@ -1511,6 +1512,12 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev, kfree(link_conf->ftmr_params); link_conf->ftmr_params = NULL; + sdata->vif.mbssid_tx_vif = NULL; + link_conf->bssid_index = 0; + link_conf->nontransmitted = false; + link_conf->ema_ap = false; + link_conf->bssid_indicator = 0; + __sta_info_flush(sdata, true); ieee80211_free_keys(sdata, true); From fa22b51ace8aa106267636f36170e940e676809c Mon Sep 17 00:00:00 2001 From: Sriram R Date: Thu, 8 Dec 2022 09:30:50 +0530 Subject: [PATCH 093/398] mac80211: Fix MLO address translation for multiple bss case When multiple interfaces are present in the local interface list, new skb copy is taken before rx processing except for the first interface. The address translation happens each time only on the original skb since the hdr pointer is not updated properly to the newly created skb. As a result frames start to drop in userspace when address based checks or search fails. Signed-off-by: Sriram R Link: https://lore.kernel.org/r/20221208040050.25922-1-quic_srirrama@quicinc.com Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c518287b2356..c6562a6d2503 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -4838,6 +4838,9 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, */ shwt = skb_hwtstamps(rx->skb); shwt->hwtstamp = skb_hwtstamps(skb)->hwtstamp; + + /* Update the hdr pointer to the new skb for translation below */ + hdr = (struct ieee80211_hdr *)rx->skb->data; } if (unlikely(rx->sta && rx->sta->sta.mlo)) { From f216033d770f7ca0eda491fe01a9f02e7af59576 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 14 Dec 2022 14:03:26 +0100 Subject: [PATCH 094/398] wifi: mac80211: fix MLO + AP_VLAN check Instead of preventing adding AP_VLAN to MLO enabled APs, this check was preventing adding more than one 4-addr AP_VLAN regardless of the MLO status. Fix this by adding missing extra checks. Fixes: ae960ee90bb1 ("wifi: mac80211: prevent VLANs on MLDs") Signed-off-by: Felix Fietkau Link: https://lore.kernel.org/r/20221214130326.37756-1-nbd@nbd.name Cc: stable@vger.kernel.org Signed-off-by: Johannes Berg --- net/mac80211/iface.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index d49a5906a943..e20c3fe9a0b1 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -364,7 +364,9 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, /* No support for VLAN with MLO yet */ if (iftype == NL80211_IFTYPE_AP_VLAN && - nsdata->wdev.use_4addr) + sdata->wdev.use_4addr && + nsdata->vif.type == NL80211_IFTYPE_AP && + nsdata->vif.valid_links) return -EOPNOTSUPP; /* From eef034ac6690118c88f357b00e2b3239c9d8575d Mon Sep 17 00:00:00 2001 From: Alexander Potapenko Date: Tue, 10 Jan 2023 13:49:30 +0100 Subject: [PATCH 095/398] affs: initialize fsdata in affs_truncate() When aops->write_begin() does not initialize fsdata, KMSAN may report an error passing the latter to aops->write_end(). Fix this by unconditionally initializing fsdata. Fixes: f2b6a16eb8f5 ("fs: affs convert to new aops") Suggested-by: Eric Biggers Signed-off-by: Alexander Potapenko Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/affs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/affs/file.c b/fs/affs/file.c index cefa222f7881..8daeed31e1af 100644 --- a/fs/affs/file.c +++ b/fs/affs/file.c @@ -880,7 +880,7 @@ affs_truncate(struct inode *inode) if (inode->i_size > AFFS_I(inode)->mmu_private) { struct address_space *mapping = inode->i_mapping; struct page *page; - void *fsdata; + void *fsdata = NULL; loff_t isize = inode->i_size; int res; From 380cd3a34b7f9825a60ccb045611af9cb4533b70 Mon Sep 17 00:00:00 2001 From: Dominik Kobinski Date: Fri, 30 Dec 2022 20:48:45 +0100 Subject: [PATCH 096/398] arm64: dts: msm8994-angler: fix the memory map Add reserved regions for memory hole and tz app mem to prevent rebooting. Also enable cont_splash_mem, it is the same as the generic 8994 one. Reported-by: Petr Vorel Signed-off-by: Dominik Kobinski Reviewed-by: Petr Vorel Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221230194845.57780-1-dominikkobinski314@gmail.com --- .../qcom/msm8994-huawei-angler-rev-101.dts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8994-huawei-angler-rev-101.dts b/arch/arm64/boot/dts/qcom/msm8994-huawei-angler-rev-101.dts index 85abff0e9b3f..7b0f62144c3e 100644 --- a/arch/arm64/boot/dts/qcom/msm8994-huawei-angler-rev-101.dts +++ b/arch/arm64/boot/dts/qcom/msm8994-huawei-angler-rev-101.dts @@ -9,9 +9,6 @@ #include "msm8994.dtsi" -/* Angler's firmware does not report where the memory is allocated */ -/delete-node/ &cont_splash_mem; - / { model = "Huawei Nexus 6P"; compatible = "huawei,angler", "qcom,msm8994"; @@ -28,6 +25,22 @@ chosen { stdout-path = "serial0:115200n8"; }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + tzapp_mem: tzapp@4800000 { + reg = <0 0x04800000 0 0x1900000>; + no-map; + }; + + removed_region: reserved@6300000 { + reg = <0 0x06300000 0 0xD00000>; + no-map; + }; + }; }; &blsp1_uart2 { From 6049aae52392539e505bfb8ccbcff3c26f1d2f0b Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sat, 17 Dec 2022 17:05:41 +0100 Subject: [PATCH 097/398] PM: AVS: qcom-cpr: Fix an error handling path in cpr_probe() If an error occurs after a successful pm_genpd_init() call, it should be undone by a corresponding pm_genpd_remove(). Add the missing call in the error handling path, as already done in the remove function. Fixes: bf6910abf548 ("power: avs: Add support for CPR (Core Power Reduction)") Signed-off-by: Christophe JAILLET Reviewed-by: Ulf Hansson Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/0f520597dbad89ab99c217c8986912fa53eaf5f9.1671293108.git.christophe.jaillet@wanadoo.fr --- drivers/soc/qcom/cpr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/cpr.c b/drivers/soc/qcom/cpr.c index e9b854ed1bdf..144ea68e0920 100644 --- a/drivers/soc/qcom/cpr.c +++ b/drivers/soc/qcom/cpr.c @@ -1708,12 +1708,16 @@ static int cpr_probe(struct platform_device *pdev) ret = of_genpd_add_provider_simple(dev->of_node, &drv->pd); if (ret) - return ret; + goto err_remove_genpd; platform_set_drvdata(pdev, drv); cpr_debugfs_init(drv); return 0; + +err_remove_genpd: + pm_genpd_remove(&drv->pd); + return ret; } static int cpr_remove(struct platform_device *pdev) From 2bd5ab93335bf2c4d22c8db427822ae637ed8dc3 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 19 Dec 2022 14:19:17 +0100 Subject: [PATCH 098/398] arm64: dts: qcom: msm8992: Don't use sfpb mutex MSM8992 uses the same mutex hardware as MSM8994. This was wrong from the start, but never presented as an issue until the sfpb compatible was given different driver data. Fixes: 6a6d1978f9c0 ("arm64: dts: msm8992 SoC and LG Bullhead (Nexus 5X) support") Reported-by: Eugene Lepshy Signed-off-by: Konrad Dybcio Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221219131918.446587-1-konrad.dybcio@linaro.org --- arch/arm64/boot/dts/qcom/msm8992.dtsi | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8992.dtsi b/arch/arm64/boot/dts/qcom/msm8992.dtsi index 10adb4986ef1..02fc3795dbfd 100644 --- a/arch/arm64/boot/dts/qcom/msm8992.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8992.dtsi @@ -37,10 +37,6 @@ compatible = "qcom,rpmcc-msm8992", "qcom,rpmcc"; }; -&tcsr_mutex { - compatible = "qcom,sfpb-mutex"; -}; - &timer { interrupts = , , From 69876bc6fd4de3ad2dc7826fe269e91fa2c1807f Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 19 Dec 2022 14:19:18 +0100 Subject: [PATCH 099/398] arm64: dts: qcom: msm8992-libra: Fix the memory map The memory map was wrong. Fix it to prevent the device from randomly rebooting. Fixes: 0f5cdb31e850 ("arm64: dts: qcom: Add Xiaomi Libra (Mi 4C) device tree") Signed-off-by: Konrad Dybcio Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20221219131918.446587-2-konrad.dybcio@linaro.org --- .../boot/dts/qcom/msm8992-xiaomi-libra.dts | 77 +++++++++++++++---- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts index b242c272d2af..fcca1ba94da6 100644 --- a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts +++ b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts @@ -11,6 +11,12 @@ #include #include +/delete-node/ &adsp_mem; +/delete-node/ &audio_mem; +/delete-node/ &mpss_mem; +/delete-node/ &peripheral_region; +/delete-node/ &rmtfs_mem; + / { model = "Xiaomi Mi 4C"; compatible = "xiaomi,libra", "qcom,msm8992"; @@ -70,25 +76,67 @@ #size-cells = <2>; ranges; - /* This is for getting crash logs using Android downstream kernels */ + memory_hole: hole@6400000 { + reg = <0 0x06400000 0 0x600000>; + no-map; + }; + + memory_hole2: hole2@6c00000 { + reg = <0 0x06c00000 0 0x2400000>; + no-map; + }; + + mpss_mem: mpss@9000000 { + reg = <0 0x09000000 0 0x5a00000>; + no-map; + }; + + tzapp: tzapp@ea00000 { + reg = <0 0x0ea00000 0 0x1900000>; + no-map; + }; + + mdm_rfsa_mem: mdm-rfsa@ca0b0000 { + reg = <0 0xca0b0000 0 0x10000>; + no-map; + }; + + rmtfs_mem: rmtfs@ca100000 { + compatible = "qcom,rmtfs-mem"; + reg = <0 0xca100000 0 0x180000>; + no-map; + + qcom,client-id = <1>; + }; + + audio_mem: audio@cb400000 { + reg = <0 0xcb000000 0 0x400000>; + no-mem; + }; + + qseecom_mem: qseecom@cb400000 { + reg = <0 0xcb400000 0 0x1c00000>; + no-mem; + }; + + adsp_rfsa_mem: adsp-rfsa@cd000000 { + reg = <0 0xcd000000 0 0x10000>; + no-map; + }; + + sensor_rfsa_mem: sensor-rfsa@cd010000 { + reg = <0 0xcd010000 0 0x10000>; + no-map; + }; + ramoops@dfc00000 { compatible = "ramoops"; - reg = <0x0 0xdfc00000 0x0 0x40000>; + reg = <0 0xdfc00000 0 0x40000>; console-size = <0x10000>; record-size = <0x10000>; ftrace-size = <0x10000>; pmsg-size = <0x20000>; }; - - modem_region: modem_region@9000000 { - reg = <0x0 0x9000000 0x0 0x5a00000>; - no-map; - }; - - tzapp: modem_region@ea00000 { - reg = <0x0 0xea00000 0x0 0x1900000>; - no-map; - }; }; }; @@ -130,11 +178,6 @@ status = "okay"; }; -&peripheral_region { - reg = <0x0 0x7400000 0x0 0x1c00000>; - no-map; -}; - &pm8994_spmi_regulators { VDD_APC0: s8 { regulator-min-microvolt = <680000>; From 8debed3efe3a731451ad9a91a7a74eeb18a7f7eb Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 9 Jan 2023 04:23:17 +0900 Subject: [PATCH 100/398] kbuild: export top-level LDFLAGS_vmlinux only to scripts/Makefile.vmlinux Nathan Chancellor reports that $(NM) emits an error message when GNU Make 4.4 is used to build the ARM zImage. $ make-4.4 ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- O=build defconfig zImage [snip] LD vmlinux NM System.map SORTTAB vmlinux OBJCOPY arch/arm/boot/Image Kernel: arch/arm/boot/Image is ready arm-linux-gnueabi-nm: 'arch/arm/boot/compressed/../../../../vmlinux': No such file /bin/sh: 1: arithmetic expression: expecting primary: " " LDS arch/arm/boot/compressed/vmlinux.lds AS arch/arm/boot/compressed/head.o GZIP arch/arm/boot/compressed/piggy_data AS arch/arm/boot/compressed/piggy.o CC arch/arm/boot/compressed/misc.o This occurs since GNU Make commit 98da874c4303 ("[SV 10593] Export variables to $(shell ...) commands"), and the O= option is needed to reproduce it. The generated zImage is correct despite the error message. As the commit description of 98da874c4303 [1] says, exported variables are passed down to $(shell ) functions, which means exported recursive variables might be expanded earlier than before, in the parse stage. The following test code demonstrates the change for GNU Make 4.4. [Test Makefile] $(shell echo hello > foo) export foo = $(shell cat bar/../foo) $(shell mkdir bar) all: @echo $(foo) [GNU Make 4.3] $ rm -rf bar; make-4.3 hello [GNU Make 4.4] $ rm -rf bar; make-4.4 cat: bar/../foo: No such file or directory hello The 'foo' is a resursively expanded (i.e. lazily expanded) variable. GNU Make 4.3 expands 'foo' just before running the recipe '@echo $(foo)', at this point, the directory 'bar' exists. GNU Make 4.4 expands 'foo' to evaluate $(shell mkdir bar) because it is exported. At this point, the directory 'bar' does not exit yet. The cat command cannot resolve the bar/../foo path, hence the error message. Let's get back to the kernel Makefile. In arch/arm/boot/compressed/Makefile, KBSS_SZ is referenced by LDFLAGS_vmlinux, which is recursive and also exported by the top Makefile. GNU Make 4.3 expands KBSS_SZ just before running the recipes, so no error message. GNU Make 4.4 expands KBSS_SZ in the parse stage, where the directory arm/arm/boot/compressed does not exit yet. When compiled with O=, the output directory is created by $(shell mkdir -p $(obj-dirs)) in scripts/Makefile.build. There are two ways to fix this particular issue: - change "$(obj)/../../../../vmlinux" in KBSS_SZ to "vmlinux" - unexport LDFLAGS_vmlinux This commit takes the latter course because it is what I originally intended. Commit 3ec8a5b33dea ("kbuild: do not export LDFLAGS_vmlinux") unexported LDFLAGS_vmlinux. Commit 5d4aeffbf709 ("kbuild: rebuild .vmlinux.export.o when its prerequisite is updated") accidentally exported it again. We can clean up arch/arm/boot/compressed/Makefile later. [1]: https://git.savannah.gnu.org/cgit/make.git/commit/?id=98da874c43035a490cdca81331724f233a3d0c9a Link: https://lore.kernel.org/all/Y7i8+EjwdnhHtlrr@dev-arch.thelio-3990X/ Fixes: 5d4aeffbf709 ("kbuild: rebuild .vmlinux.export.o when its prerequisite is updated") Reported-by: Nathan Chancellor Signed-off-by: Masahiro Yamada Reviewed-by: Nicolas Schier Tested-by: Nathan Chancellor --- Makefile | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 460716314fb3..7607e20385a8 100644 --- a/Makefile +++ b/Makefile @@ -549,7 +549,7 @@ LDFLAGS_MODULE = CFLAGS_KERNEL = RUSTFLAGS_KERNEL = AFLAGS_KERNEL = -export LDFLAGS_vmlinux = +LDFLAGS_vmlinux = # Use USERINCLUDE when you must reference the UAPI directories only. USERINCLUDE := \ @@ -1248,6 +1248,18 @@ vmlinux.o modules.builtin.modinfo modules.builtin: vmlinux_o @: PHONY += vmlinux +# LDFLAGS_vmlinux in the top Makefile defines linker flags for the top vmlinux, +# not for decompressors. LDFLAGS_vmlinux in arch/*/boot/compressed/Makefile is +# unrelated; the decompressors just happen to have the same base name, +# arch/*/boot/compressed/vmlinux. +# Export LDFLAGS_vmlinux only to scripts/Makefile.vmlinux. +# +# _LDFLAGS_vmlinux is a workaround for the 'private export' bug: +# https://savannah.gnu.org/bugs/?61463 +# For Make > 4.4, the following simple code will work: +# vmlinux: private export LDFLAGS_vmlinux := $(LDFLAGS_vmlinux) +vmlinux: private _LDFLAGS_vmlinux := $(LDFLAGS_vmlinux) +vmlinux: export LDFLAGS_vmlinux = $(_LDFLAGS_vmlinux) vmlinux: vmlinux.o $(KBUILD_LDS) modpost $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.vmlinux From 74d3320f6f7cf72de88a7e8df573821f6db90239 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 10 Jan 2023 14:48:00 +0900 Subject: [PATCH 101/398] kbuild: fix 'make modules' error when CONFIG_DEBUG_INFO_BTF_MODULES=y When CONFIG_DEBUG_INFO_BTF_MODULES=y, running 'make modules' in the clean kernel tree will get the following error. $ grep CONFIG_DEBUG_INFO_BTF_MODULES .config CONFIG_DEBUG_INFO_BTF_MODULES=y $ make -s clean $ make modules [snip] AR vmlinux.a ar: ./built-in.a: No such file or directory make: *** [Makefile:1241: vmlinux.a] Error 1 'modules' depends on 'vmlinux', but builtin objects are not built. Define KBUILD_BUILTIN. Fixes: f73edc8951b2 ("kbuild: unify two modpost invocations") Signed-off-by: Masahiro Yamada --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 7607e20385a8..eb02f3823ce6 100644 --- a/Makefile +++ b/Makefile @@ -1545,6 +1545,7 @@ endif # *.ko are usually independent of vmlinux, but CONFIG_DEBUG_INFOBTF_MODULES # is an exception. ifdef CONFIG_DEBUG_INFO_BTF_MODULES +KBUILD_BUILTIN := 1 modules: vmlinux endif From a1904fa4dfc929e5ea36bd409cf0d800df56fb8b Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Mon, 2 Jan 2023 12:52:55 +0100 Subject: [PATCH 102/398] firmware: raspberrypi: Fix type assignment We silently cast an unsigned int into a __le32 which makes sparse complain. Moreover, we never actually convert endianness between the CPU's and the expected little-endian value. Fix both at once by calling cpu_to_le32(). Fixes: 40c31955e4e9 ("firmware: raspberrypi: Provide a helper to query a clock max rate") Reported-by: kernel test robot Link: https://lore.kernel.org/r/20221116091712.1309651-3-maxime@cerno.tech Signed-off-by: Maxime Ripard Link: https://lore.kernel.org/r/20230102115255.17802-1-maxime@cerno.tech Signed-off-by: Florian Fainelli --- include/soc/bcm2835/raspberrypi-firmware.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/soc/bcm2835/raspberrypi-firmware.h b/include/soc/bcm2835/raspberrypi-firmware.h index ab955591cb72..73cac8d0287e 100644 --- a/include/soc/bcm2835/raspberrypi-firmware.h +++ b/include/soc/bcm2835/raspberrypi-firmware.h @@ -170,7 +170,7 @@ struct rpi_firmware_clk_rate_request { #define RPI_FIRMWARE_CLK_RATE_REQUEST(_id) \ { \ - .id = _id, \ + .id = cpu_to_le32(_id), \ } #if IS_ENABLED(CONFIG_RASPBERRYPI_FIRMWARE) From 980a637d11fe8dfc734f508a422185c2de55e669 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 4 Jan 2023 09:35:09 +0100 Subject: [PATCH 103/398] ARM: omap1: fix !ARCH_OMAP1_ANY link failures While compile-testing randconfig builds for the upcoming boardfile removal, I noticed that an earlier patch of mine was completely broken, and the introduction of CONFIG_ARCH_OMAP1_ANY only replaced one set of build failures with another one, now resulting in link failures like ld: drivers/video/fbdev/omap/omapfb_main.o: in function `omapfb_do_probe': drivers/video/fbdev/omap/omapfb_main.c:1703: undefined reference to `omap_set_dma_priority' ld: drivers/dma/ti/omap-dma.o: in function `omap_dma_free_chan_resources': drivers/dma/ti/omap-dma.c:777: undefined reference to `omap_free_dma' drivers/dma/ti/omap-dma.c:1685: undefined reference to `omap_get_plat_info' ld: drivers/usb/gadget/udc/omap_udc.o: in function `next_in_dma': drivers/usb/gadget/udc/omap_udc.c:820: undefined reference to `omap_get_dma_active_status' I tried reworking it, but the resulting patch ended up much bigger than simply avoiding the original problem of unused-function warnings like arch/arm/mach-omap1/mcbsp.c:76:30: error: unused variable 'omap1_mcbsp_ops' [-Werror,-Wunused-variable] As a result, revert the previous fix, and rearrange the code that produces warnings to hide them. For mcbsp, the #ifdef check can simply be removed as the cpu_is_omapxxx() checks already achieve the same result, while in the io.c the easiest solution appears to be to merge the common map bits into each soc specific portion. This gets cleaned in a nicer way after omap7xx support gets dropped, as the remaining SoCs all have the exact same I/O map. Fixes: 615dce5bf736 ("ARM: omap1: fix build with no SoC selected") Cc: stable@vger.kernel.org Acked-by: Aaro Koskinen Signed-off-by: Arnd Bergmann --- arch/arm/mach-omap1/Kconfig | 5 +---- arch/arm/mach-omap1/Makefile | 4 ---- arch/arm/mach-omap1/io.c | 32 +++++++++++++++----------------- arch/arm/mach-omap1/mcbsp.c | 21 --------------------- arch/arm/mach-omap1/pm.h | 7 ------- include/linux/soc/ti/omap1-io.h | 4 ++-- 6 files changed, 18 insertions(+), 55 deletions(-) diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index 538a960257cc..7ec7ada287e0 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig @@ -4,6 +4,7 @@ menuconfig ARCH_OMAP1 depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 depends on CPU_LITTLE_ENDIAN depends on ATAGS + select ARCH_OMAP select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_OMAP select CLKSRC_MMIO @@ -45,10 +46,6 @@ config ARCH_OMAP16XX select CPU_ARM926T select OMAP_DM_TIMER -config ARCH_OMAP1_ANY - select ARCH_OMAP - def_bool ARCH_OMAP730 || ARCH_OMAP850 || ARCH_OMAP15XX || ARCH_OMAP16XX - config ARCH_OMAP bool diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index 506074b86333..0615cb0ba580 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -3,8 +3,6 @@ # Makefile for the linux kernel. # -ifdef CONFIG_ARCH_OMAP1_ANY - # Common support obj-y := io.o id.o sram-init.o sram.o time.o irq.o mux.o flash.o \ serial.o devices.o dma.o omap-dma.o fb.o @@ -59,5 +57,3 @@ obj-$(CONFIG_ARCH_OMAP730) += gpio7xx.o obj-$(CONFIG_ARCH_OMAP850) += gpio7xx.o obj-$(CONFIG_ARCH_OMAP15XX) += gpio15xx.o obj-$(CONFIG_ARCH_OMAP16XX) += gpio16xx.o - -endif diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index d2db9b8aed3f..0074b011a05a 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c @@ -22,17 +22,14 @@ * The machine specific code may provide the extra mapping besides the * default mapping provided here. */ -static struct map_desc omap_io_desc[] __initdata = { +#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850) +static struct map_desc omap7xx_io_desc[] __initdata = { { .virtual = OMAP1_IO_VIRT, .pfn = __phys_to_pfn(OMAP1_IO_PHYS), .length = OMAP1_IO_SIZE, .type = MT_DEVICE - } -}; - -#if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850) -static struct map_desc omap7xx_io_desc[] __initdata = { + }, { .virtual = OMAP7XX_DSP_BASE, .pfn = __phys_to_pfn(OMAP7XX_DSP_START), @@ -49,6 +46,12 @@ static struct map_desc omap7xx_io_desc[] __initdata = { #ifdef CONFIG_ARCH_OMAP15XX static struct map_desc omap1510_io_desc[] __initdata = { + { + .virtual = OMAP1_IO_VIRT, + .pfn = __phys_to_pfn(OMAP1_IO_PHYS), + .length = OMAP1_IO_SIZE, + .type = MT_DEVICE + }, { .virtual = OMAP1510_DSP_BASE, .pfn = __phys_to_pfn(OMAP1510_DSP_START), @@ -65,6 +68,12 @@ static struct map_desc omap1510_io_desc[] __initdata = { #if defined(CONFIG_ARCH_OMAP16XX) static struct map_desc omap16xx_io_desc[] __initdata = { + { + .virtual = OMAP1_IO_VIRT, + .pfn = __phys_to_pfn(OMAP1_IO_PHYS), + .length = OMAP1_IO_SIZE, + .type = MT_DEVICE + }, { .virtual = OMAP16XX_DSP_BASE, .pfn = __phys_to_pfn(OMAP16XX_DSP_START), @@ -79,18 +88,9 @@ static struct map_desc omap16xx_io_desc[] __initdata = { }; #endif -/* - * Maps common IO regions for omap1 - */ -static void __init omap1_map_common_io(void) -{ - iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc)); -} - #if defined (CONFIG_ARCH_OMAP730) || defined (CONFIG_ARCH_OMAP850) void __init omap7xx_map_io(void) { - omap1_map_common_io(); iotable_init(omap7xx_io_desc, ARRAY_SIZE(omap7xx_io_desc)); } #endif @@ -98,7 +98,6 @@ void __init omap7xx_map_io(void) #ifdef CONFIG_ARCH_OMAP15XX void __init omap15xx_map_io(void) { - omap1_map_common_io(); iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); } #endif @@ -106,7 +105,6 @@ void __init omap15xx_map_io(void) #if defined(CONFIG_ARCH_OMAP16XX) void __init omap16xx_map_io(void) { - omap1_map_common_io(); iotable_init(omap16xx_io_desc, ARRAY_SIZE(omap16xx_io_desc)); } #endif diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c index 05c25c432449..b1632cbe37e6 100644 --- a/arch/arm/mach-omap1/mcbsp.c +++ b/arch/arm/mach-omap1/mcbsp.c @@ -89,7 +89,6 @@ static struct omap_mcbsp_ops omap1_mcbsp_ops = { #define OMAP1610_MCBSP2_BASE 0xfffb1000 #define OMAP1610_MCBSP3_BASE 0xe1017000 -#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) struct resource omap7xx_mcbsp_res[][6] = { { { @@ -159,14 +158,7 @@ static struct omap_mcbsp_platform_data omap7xx_mcbsp_pdata[] = { }; #define OMAP7XX_MCBSP_RES_SZ ARRAY_SIZE(omap7xx_mcbsp_res[1]) #define OMAP7XX_MCBSP_COUNT ARRAY_SIZE(omap7xx_mcbsp_res) -#else -#define omap7xx_mcbsp_res_0 NULL -#define omap7xx_mcbsp_pdata NULL -#define OMAP7XX_MCBSP_RES_SZ 0 -#define OMAP7XX_MCBSP_COUNT 0 -#endif -#ifdef CONFIG_ARCH_OMAP15XX struct resource omap15xx_mcbsp_res[][6] = { { { @@ -266,14 +258,7 @@ static struct omap_mcbsp_platform_data omap15xx_mcbsp_pdata[] = { }; #define OMAP15XX_MCBSP_RES_SZ ARRAY_SIZE(omap15xx_mcbsp_res[1]) #define OMAP15XX_MCBSP_COUNT ARRAY_SIZE(omap15xx_mcbsp_res) -#else -#define omap15xx_mcbsp_res_0 NULL -#define omap15xx_mcbsp_pdata NULL -#define OMAP15XX_MCBSP_RES_SZ 0 -#define OMAP15XX_MCBSP_COUNT 0 -#endif -#ifdef CONFIG_ARCH_OMAP16XX struct resource omap16xx_mcbsp_res[][6] = { { { @@ -373,12 +358,6 @@ static struct omap_mcbsp_platform_data omap16xx_mcbsp_pdata[] = { }; #define OMAP16XX_MCBSP_RES_SZ ARRAY_SIZE(omap16xx_mcbsp_res[1]) #define OMAP16XX_MCBSP_COUNT ARRAY_SIZE(omap16xx_mcbsp_res) -#else -#define omap16xx_mcbsp_res_0 NULL -#define omap16xx_mcbsp_pdata NULL -#define OMAP16XX_MCBSP_RES_SZ 0 -#define OMAP16XX_MCBSP_COUNT 0 -#endif static void omap_mcbsp_register_board_cfg(struct resource *res, int res_count, struct omap_mcbsp_platform_data *config, int size) diff --git a/arch/arm/mach-omap1/pm.h b/arch/arm/mach-omap1/pm.h index d9165709c532..0d1f092821ff 100644 --- a/arch/arm/mach-omap1/pm.h +++ b/arch/arm/mach-omap1/pm.h @@ -106,13 +106,6 @@ #define OMAP7XX_IDLECT3 0xfffece24 #define OMAP7XX_IDLE_LOOP_REQUEST 0x0C00 -#if !defined(CONFIG_ARCH_OMAP730) && \ - !defined(CONFIG_ARCH_OMAP850) && \ - !defined(CONFIG_ARCH_OMAP15XX) && \ - !defined(CONFIG_ARCH_OMAP16XX) -#warning "Power management for this processor not implemented yet" -#endif - #ifndef __ASSEMBLER__ #include diff --git a/include/linux/soc/ti/omap1-io.h b/include/linux/soc/ti/omap1-io.h index f7f12728d4a6..9a60f45899d3 100644 --- a/include/linux/soc/ti/omap1-io.h +++ b/include/linux/soc/ti/omap1-io.h @@ -5,7 +5,7 @@ #ifndef __ASSEMBLER__ #include -#ifdef CONFIG_ARCH_OMAP1_ANY +#ifdef CONFIG_ARCH_OMAP1 /* * NOTE: Please use ioremap + __raw_read/write where possible instead of these */ @@ -15,7 +15,7 @@ extern u32 omap_readl(u32 pa); extern void omap_writeb(u8 v, u32 pa); extern void omap_writew(u16 v, u32 pa); extern void omap_writel(u32 v, u32 pa); -#else +#elif defined(CONFIG_COMPILE_TEST) static inline u8 omap_readb(u32 pa) { return 0; } static inline u16 omap_readw(u32 pa) { return 0; } static inline u32 omap_readl(u32 pa) { return 0; } From 9d46ce57f4d1c626bb48170226ea5e35deb5877c Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 13 Dec 2022 22:06:49 +0100 Subject: [PATCH 104/398] ARM: omap1: fix building gpio15xx In some randconfig builds, the asm/irq.h header is not included in gpio15xx.c, so add an explicit include to avoid a build fialure: In file included from arch/arm/mach-omap1/gpio15xx.c:15: arch/arm/mach-omap1/irqs.h:99:34: error: 'NR_IRQS_LEGACY' undeclared here (not in a function) 99 | #define IH2_BASE (NR_IRQS_LEGACY + 32) | ^~~~~~~~~~~~~~ arch/arm/mach-omap1/irqs.h:105:38: note: in expansion of macro 'IH2_BASE' 105 | #define INT_MPUIO (5 + IH2_BASE) | ^~~~~~~~ arch/arm/mach-omap1/gpio15xx.c:28:27: note: in expansion of macro 'INT_MPUIO' 28 | .start = INT_MPUIO, | ^~~~~~~~~ Acked-by: Aaro Koskinen Signed-off-by: Arnd Bergmann --- arch/arm/mach-omap1/gpio15xx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index c675f11de99d..61fa26efd865 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "irqs.h" From 7124c93887cc4e6c5b48920f83115e4a5892e870 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 9 Jan 2023 22:25:29 -0800 Subject: [PATCH 105/398] phy: ti: fix Kconfig warning and operator precedence Fix Kconfig depends operator precedence to prevent a Kconfig warning: WARNING: unmet direct dependencies detected for MUX_MMIO Depends on [n]: MULTIPLEXER [=m] && OF [=n] Selected by [m]: - PHY_AM654_SERDES [=m] && (OF [=n] && ARCH_K3 || COMPILE_TEST [=y]) && COMMON_CLK [=y] Fixes: 71e2f5c5c224 ("phy: ti: Add a new SERDES driver for TI's AM654x SoC") Fixes: 091876cc355d ("phy: ti: j721e-wiz: Add support for WIZ module present in TI J721E SoC") Signed-off-by: Randy Dunlap Cc: Vinod Koul Cc: Kishon Vijay Abraham I Cc: linux-phy@lists.infradead.org Cc: Arnd Bergmann Link: https://lore.kernel.org/r/20230110062529.22668-1-rdunlap@infradead.org Signed-off-by: Vinod Koul --- drivers/phy/ti/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/phy/ti/Kconfig b/drivers/phy/ti/Kconfig index 15a3bcf32308..b905902d5750 100644 --- a/drivers/phy/ti/Kconfig +++ b/drivers/phy/ti/Kconfig @@ -23,7 +23,7 @@ config PHY_DM816X_USB config PHY_AM654_SERDES tristate "TI AM654 SERDES support" - depends on OF && ARCH_K3 || COMPILE_TEST + depends on OF && (ARCH_K3 || COMPILE_TEST) depends on COMMON_CLK select GENERIC_PHY select MULTIPLEXER @@ -35,7 +35,7 @@ config PHY_AM654_SERDES config PHY_J721E_WIZ tristate "TI J721E WIZ (SERDES Wrapper) support" - depends on OF && ARCH_K3 || COMPILE_TEST + depends on OF && (ARCH_K3 || COMPILE_TEST) depends on HAS_IOMEM && OF_ADDRESS depends on COMMON_CLK select GENERIC_PHY From 0f9c608d4a1eb852d6769d2fc5906c71c02565ae Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 11 Jan 2023 10:38:22 +0100 Subject: [PATCH 106/398] init/Kconfig: fix LOCALVERSION_AUTO help text It was never guaranteed to be exactly eight, but since commit 548b8b5168c9 ("scripts/setlocalversion: make git describe output more reliable"), it has been exactly 12. Signed-off-by: Rasmus Villemoes Signed-off-by: Masahiro Yamada --- init/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/Kconfig b/init/Kconfig index 7e5c3ddc341d..ccd3cdcf3df1 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -204,7 +204,7 @@ config LOCALVERSION_AUTO appended after any matching localversion* files, and after the value set in CONFIG_LOCALVERSION. - (The actual string used here is the first eight characters produced + (The actual string used here is the first 12 characters produced by running the command: $ git rev-parse --verify HEAD From 169dd78043f7f4eabdef8d7ba0d4ddffe5cb3930 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 11 Jan 2023 11:11:56 +0100 Subject: [PATCH 107/398] scripts: rpm: make clear that mkspec script contains 4.13 feature A fix was made in the mkspec script that uses a feature, ie. the OR expression, which requires RPM 4.13. However, the script indicates another minimum version. Lower versions may have success by using the --no-deps option as suggested, but feels like bumping the version to 4.13 is reasonable as it put me on the wrong track at first with RPM 4.11 on my Centos7 machine. Fixes: 02a893bc9975 ("kbuild: rpm-pkg: add libelf-devel as alternative for BuildRequires") Signed-off-by: Arend van Spriel Signed-off-by: Masahiro Yamada --- scripts/package/mkspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/package/mkspec b/scripts/package/mkspec index adab28fa7f89..094e52c979a8 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -1,7 +1,7 @@ #!/bin/sh # # Output a simple RPM spec file. -# This version assumes a minimum of RPM 4.0.3. +# This version assumes a minimum of RPM 4.13 # # The only gothic bit here is redefining install_post to avoid # stripping the symbols from files in the kernel which we want From e752e5454e6417da3f40ec1306a041ea96c56423 Mon Sep 17 00:00:00 2001 From: "Joel Fernandes (Google)" Date: Mon, 9 Jan 2023 22:25:47 +0000 Subject: [PATCH 108/398] adreno: Shutdown the GPU properly During kexec on ARM device, we notice that device_shutdown() only calls pm_runtime_force_suspend() while shutting down the GPU. This means the GPU kthread is still running and further, there maybe active submits. This causes all kinds of issues during a kexec reboot: Warning from shutdown path: [ 292.509662] WARNING: CPU: 0 PID: 6304 at [...] adreno_runtime_suspend+0x3c/0x44 [ 292.509863] Hardware name: Google Lazor (rev3 - 8) with LTE (DT) [ 292.509872] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 292.509881] pc : adreno_runtime_suspend+0x3c/0x44 [ 292.509891] lr : pm_generic_runtime_suspend+0x30/0x44 [ 292.509905] sp : ffffffc014473bf0 [...] [ 292.510043] Call trace: [ 292.510051] adreno_runtime_suspend+0x3c/0x44 [ 292.510061] pm_generic_runtime_suspend+0x30/0x44 [ 292.510071] pm_runtime_force_suspend+0x54/0xc8 [ 292.510081] adreno_shutdown+0x1c/0x28 [ 292.510090] platform_shutdown+0x2c/0x38 [ 292.510104] device_shutdown+0x158/0x210 [ 292.510119] kernel_restart_prepare+0x40/0x4c And here from GPU kthread, an SError OOPs: [ 192.648789] el1h_64_error+0x7c/0x80 [ 192.648812] el1_interrupt+0x20/0x58 [ 192.648833] el1h_64_irq_handler+0x18/0x24 [ 192.648854] el1h_64_irq+0x7c/0x80 [ 192.648873] local_daif_inherit+0x10/0x18 [ 192.648900] el1h_64_sync_handler+0x48/0xb4 [ 192.648921] el1h_64_sync+0x7c/0x80 [ 192.648941] a6xx_gmu_set_oob+0xbc/0x1fc [ 192.648968] a6xx_hw_init+0x44/0xe38 [ 192.648991] msm_gpu_hw_init+0x48/0x80 [ 192.649013] msm_gpu_submit+0x5c/0x1a8 [ 192.649034] msm_job_run+0xb0/0x11c [ 192.649058] drm_sched_main+0x170/0x434 [ 192.649086] kthread+0x134/0x300 [ 192.649114] ret_from_fork+0x10/0x20 Fix by calling adreno_system_suspend() in the device_shutdown() path. [ Applied Rob Clark feedback on fixing adreno_unbind() similarly, also tested as above. ] Cc: Rob Clark Cc: Steven Rostedt Cc: Ricardo Ribalda Cc: Ross Zwisler Signed-off-by: Joel Fernandes (Google) Reviewed-by: Ricardo Ribalda Reviewed-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/517633/ Link: https://lore.kernel.org/r/20230109222547.1368644-1-joel@joelfernandes.org Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 628806423f7d..36f062c7582f 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -551,13 +551,14 @@ static int adreno_bind(struct device *dev, struct device *master, void *data) return 0; } +static int adreno_system_suspend(struct device *dev); static void adreno_unbind(struct device *dev, struct device *master, void *data) { struct msm_drm_private *priv = dev_get_drvdata(master); struct msm_gpu *gpu = dev_to_gpu(dev); - pm_runtime_force_suspend(dev); + WARN_ON_ONCE(adreno_system_suspend(dev)); gpu->funcs->destroy(gpu); priv->gpu_pdev = NULL; @@ -609,7 +610,7 @@ static int adreno_remove(struct platform_device *pdev) static void adreno_shutdown(struct platform_device *pdev) { - pm_runtime_force_suspend(&pdev->dev); + WARN_ON_ONCE(adreno_system_suspend(&pdev->dev)); } static const struct of_device_id dt_match[] = { From a66f1efcf748febea7758c4c3c8b5bc5294949ef Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 10 Jan 2023 13:28:59 -0800 Subject: [PATCH 109/398] drm/msm/gpu: Fix potential double-free If userspace was calling the MSM_SET_PARAM ioctl on multiple threads to set the COMM or CMDLINE param, it could trigger a race causing the previous value to be kfree'd multiple times. Fix this by serializing on the gpu lock. Signed-off-by: Rob Clark Fixes: d4726d770068 ("drm/msm: Add a way to override processes comm/cmdline") Patchwork: https://patchwork.freedesktop.org/patch/517778/ Link: https://lore.kernel.org/r/20230110212903.1925878-1-robdclark@gmail.com --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 4 ++++ drivers/gpu/drm/msm/msm_gpu.c | 2 ++ drivers/gpu/drm/msm/msm_gpu.h | 12 ++++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 57586c794b84..3605f095b2de 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -352,6 +352,8 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx, /* Ensure string is null terminated: */ str[len] = '\0'; + mutex_lock(&gpu->lock); + if (param == MSM_PARAM_COMM) { paramp = &ctx->comm; } else { @@ -361,6 +363,8 @@ int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx, kfree(*paramp); *paramp = str; + mutex_unlock(&gpu->lock); + return 0; } case MSM_PARAM_SYSPROF: diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 021f4e29b613..4f495eecc34b 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -335,6 +335,8 @@ static void get_comm_cmdline(struct msm_gem_submit *submit, char **comm, char ** struct msm_file_private *ctx = submit->queue->ctx; struct task_struct *task; + WARN_ON(!mutex_is_locked(&submit->gpu->lock)); + /* Note that kstrdup will return NULL if argument is NULL: */ *comm = kstrdup(ctx->comm, GFP_KERNEL); *cmd = kstrdup(ctx->cmdline, GFP_KERNEL); diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index 58a72e6b1400..a89bfdc3d7f9 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -366,10 +366,18 @@ struct msm_file_private { */ int sysprof; - /** comm: Overridden task comm, see MSM_PARAM_COMM */ + /** + * comm: Overridden task comm, see MSM_PARAM_COMM + * + * Accessed under msm_gpu::lock + */ char *comm; - /** cmdline: Overridden task cmdline, see MSM_PARAM_CMDLINE */ + /** + * cmdline: Overridden task cmdline, see MSM_PARAM_CMDLINE + * + * Accessed under msm_gpu::lock + */ char *cmdline; /** From c273289fac370b6488757236cd62cc2cf04830b7 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Wed, 4 Jan 2023 12:54:42 +0100 Subject: [PATCH 110/398] selftests: netfilter: fix transaction test script timeout handling The kselftest framework uses a default timeout of 45 seconds for all test scripts. Increase the timeout to two minutes for the netfilter tests, this should hopefully be enough, Make sure that, should the script be canceled, the net namespace and the spawned ping instances are removed. Fixes: 25d8bcedbf43 ("selftests: add script to stress-test nft packet path vs. control plane") Reported-by: Mirsad Goran Todorovac Signed-off-by: Florian Westphal Tested-by: Mirsad Goran Todorovac Signed-off-by: Pablo Neira Ayuso --- .../selftests/netfilter/nft_trans_stress.sh | 16 +++++++++------- tools/testing/selftests/netfilter/settings | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 tools/testing/selftests/netfilter/settings diff --git a/tools/testing/selftests/netfilter/nft_trans_stress.sh b/tools/testing/selftests/netfilter/nft_trans_stress.sh index a7f62ad4f661..2ffba45a78bf 100755 --- a/tools/testing/selftests/netfilter/nft_trans_stress.sh +++ b/tools/testing/selftests/netfilter/nft_trans_stress.sh @@ -10,12 +10,20 @@ ksft_skip=4 testns=testns-$(mktemp -u "XXXXXXXX") +tmp="" tables="foo bar baz quux" global_ret=0 eret=0 lret=0 +cleanup() { + ip netns pids "$testns" | xargs kill 2>/dev/null + ip netns del "$testns" + + rm -f "$tmp" +} + check_result() { local r=$1 @@ -43,6 +51,7 @@ if [ $? -ne 0 ];then exit $ksft_skip fi +trap cleanup EXIT tmp=$(mktemp) for table in $tables; do @@ -139,11 +148,4 @@ done check_result $lret "add/delete with nftrace enabled" -pkill -9 ping - -wait - -rm -f "$tmp" -ip netns del "$testns" - exit $global_ret diff --git a/tools/testing/selftests/netfilter/settings b/tools/testing/selftests/netfilter/settings new file mode 100644 index 000000000000..6091b45d226b --- /dev/null +++ b/tools/testing/selftests/netfilter/settings @@ -0,0 +1 @@ +timeout=120 From 9ea4b476cea1b7d461d16dda25ca3c7e616e2d15 Mon Sep 17 00:00:00 2001 From: Gavrilov Ilia Date: Wed, 11 Jan 2023 11:57:39 +0000 Subject: [PATCH 111/398] netfilter: ipset: Fix overflow before widen in the bitmap_ip_create() function. When first_ip is 0, last_ip is 0xFFFFFFFF, and netmask is 31, the value of an arithmetic expression 2 << (netmask - mask_bits - 1) is subject to overflow due to a failure casting operands to a larger data type before performing the arithmetic. Note that it's harmless since the value will be checked at the next step. Found by InfoTeCS on behalf of Linux Verification Center (linuxtesting.org) with SVACE. Fixes: b9fed748185a ("netfilter: ipset: Check and reject crazy /0 input parameters") Signed-off-by: Ilia.Gavrilov Reviewed-by: Simon Horman Signed-off-by: Pablo Neira Ayuso --- net/netfilter/ipset/ip_set_bitmap_ip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c index a8ce04a4bb72..e4fa00abde6a 100644 --- a/net/netfilter/ipset/ip_set_bitmap_ip.c +++ b/net/netfilter/ipset/ip_set_bitmap_ip.c @@ -308,8 +308,8 @@ bitmap_ip_create(struct net *net, struct ip_set *set, struct nlattr *tb[], return -IPSET_ERR_BITMAP_RANGE; pr_debug("mask_bits %u, netmask %u\n", mask_bits, netmask); - hosts = 2 << (32 - netmask - 1); - elements = 2 << (netmask - mask_bits - 1); + hosts = 2U << (32 - netmask - 1); + elements = 2UL << (netmask - mask_bits - 1); } if (elements > IPSET_BITMAP_MAX_RANGE + 1) return -IPSET_ERR_BITMAP_RANGE_SIZE; From 696e1a48b1a1b01edad542a1ef293665864a4dd0 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 11 Jan 2023 17:07:33 +0100 Subject: [PATCH 112/398] netfilter: nft_payload: incorrect arithmetics when fetching VLAN header bits If the offset + length goes over the ethernet + vlan header, then the length is adjusted to copy the bytes that are within the boundaries of the vlan_ethhdr scratchpad area. The remaining bytes beyond ethernet + vlan header are copied directly from the skbuff data area. Fix incorrect arithmetic operator: subtract, not add, the size of the vlan header in case of double-tagged packets to adjust the length accordingly to address CVE-2023-0179. Reported-by: Davide Ornaghi Fixes: f6ae9f120dad ("netfilter: nft_payload: add C-VLAN support") Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nft_payload.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c index 17b418a5a593..3a3c7746e88f 100644 --- a/net/netfilter/nft_payload.c +++ b/net/netfilter/nft_payload.c @@ -63,7 +63,7 @@ nft_payload_copy_vlan(u32 *d, const struct sk_buff *skb, u8 offset, u8 len) return false; if (offset + len > VLAN_ETH_HLEN + vlan_hlen) - ethlen -= offset + len - VLAN_ETH_HLEN + vlan_hlen; + ethlen -= offset + len - VLAN_ETH_HLEN - vlan_hlen; memcpy(dst_u8, vlanh + offset - vlan_hlen, ethlen); From ed02363fbbed52a3f5ea0d188edd09045a806eb5 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Mon, 12 Dec 2022 10:19:37 +0800 Subject: [PATCH 113/398] btrfs: add extra error messages to cover non-ENOMEM errors from device_add_list() [BUG] When test case btrfs/219 (aka, mount a registered device but with a lower generation) failed, there is not any useful information for the end user to find out what's going wrong. The mount failure just looks like this: # mount -o loop /tmp/219.img2 /mnt/btrfs/ mount: /mnt/btrfs: mount(2) system call failed: File exists. dmesg(1) may have more information after failed mount system call. While the dmesg contains nothing but the loop device change: loop1: detected capacity change from 0 to 524288 [CAUSE] In device_list_add() we have a lot of extra checks to reject invalid cases. That function also contains the regular device scan result like the following prompt: BTRFS: device fsid 6222333e-f9f1-47e6-b306-55ddd4dcaef4 devid 1 transid 8 /dev/loop0 scanned by systemd-udevd (3027) But unfortunately not all errors have their own error messages, thus if we hit something wrong in device_add_list(), there may be no error messages at all. [FIX] Add errors message for all non-ENOMEM errors. For ENOMEM, I'd say we're in a much worse situation, and there should be some OOM messages way before our call sites. CC: stable@vger.kernel.org # 6.0+ Signed-off-by: Qu Wenruo Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/volumes.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index aa25fa335d3e..bf0decaac7f3 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -768,8 +768,11 @@ static noinline struct btrfs_device *device_list_add(const char *path, BTRFS_SUPER_FLAG_CHANGING_FSID_V2); error = lookup_bdev(path, &path_devt); - if (error) + if (error) { + btrfs_err(NULL, "failed to lookup block device for path %s: %d", + path, error); return ERR_PTR(error); + } if (fsid_change_in_progress) { if (!has_metadata_uuid) @@ -836,6 +839,9 @@ static noinline struct btrfs_device *device_list_add(const char *path, unsigned int nofs_flag; if (fs_devices->opened) { + btrfs_err(NULL, + "device %s belongs to fsid %pU, and the fs is already mounted", + path, fs_devices->fsid); mutex_unlock(&fs_devices->device_list_mutex); return ERR_PTR(-EBUSY); } @@ -905,6 +911,9 @@ static noinline struct btrfs_device *device_list_add(const char *path, * generation are equal. */ mutex_unlock(&fs_devices->device_list_mutex); + btrfs_err(NULL, +"device %s already registered with a higher generation, found %llu expect %llu", + path, found_transid, device->generation); return ERR_PTR(-EEXIST); } From 75181406b4eafacc531ff2ee5fb032bd93317e2b Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 10 Jan 2023 15:14:17 +0800 Subject: [PATCH 114/398] btrfs: qgroup: do not warn on record without old_roots populated [BUG] There are some reports from the mailing list that since v6.1 kernel, the WARN_ON() inside btrfs_qgroup_account_extent() gets triggered during rescan: WARNING: CPU: 3 PID: 6424 at fs/btrfs/qgroup.c:2756 btrfs_qgroup_account_extents+0x1ae/0x260 [btrfs] CPU: 3 PID: 6424 Comm: snapperd Tainted: P OE 6.1.2-1-default #1 openSUSE Tumbleweed 05c7a1b1b61d5627475528f71f50444637b5aad7 RIP: 0010:btrfs_qgroup_account_extents+0x1ae/0x260 [btrfs] Call Trace: btrfs_commit_transaction+0x30c/0xb40 [btrfs c39c9c546c241c593f03bd6d5f39ea1b676250f6] ? start_transaction+0xc3/0x5b0 [btrfs c39c9c546c241c593f03bd6d5f39ea1b676250f6] btrfs_qgroup_rescan+0x42/0xc0 [btrfs c39c9c546c241c593f03bd6d5f39ea1b676250f6] btrfs_ioctl+0x1ab9/0x25c0 [btrfs c39c9c546c241c593f03bd6d5f39ea1b676250f6] ? __rseq_handle_notify_resume+0xa9/0x4a0 ? mntput_no_expire+0x4a/0x240 ? __seccomp_filter+0x319/0x4d0 __x64_sys_ioctl+0x90/0xd0 do_syscall_64+0x5b/0x80 ? syscall_exit_to_user_mode+0x17/0x40 ? do_syscall_64+0x67/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7fd9b790d9bf [CAUSE] Since commit e15e9f43c7ca ("btrfs: introduce BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING to skip qgroup accounting"), if our qgroup is already in inconsistent state, we will no longer do the time-consuming backref walk. This can leave some qgroup records without a valid old_roots ulist. Normally this is fine, as btrfs_qgroup_account_extents() would also skip those records if we have NO_ACCOUNTING flag set. But there is a small window, if we have NO_ACCOUNTING flag set, and inserted some qgroup_record without a old_roots ulist, but then the user triggered a qgroup rescan. During btrfs_qgroup_rescan(), we firstly clear NO_ACCOUNTING flag, then commit current transaction. And since we have a qgroup_record with old_roots = NULL, we trigger the WARN_ON() during btrfs_qgroup_account_extents(). [FIX] Unfortunately due to the introduction of NO_ACCOUNTING flag, the assumption that every qgroup_record would have its old_roots populated is no longer correct. Fix the false alerts and drop the WARN_ON(). Reported-by: Lukas Straub Reported-by: HanatoK Fixes: e15e9f43c7ca ("btrfs: introduce BTRFS_QGROUP_RUNTIME_FLAG_NO_ACCOUNTING to skip qgroup accounting") CC: stable@vger.kernel.org # 6.1 Link: https://lore.kernel.org/linux-btrfs/2403c697-ddaf-58ad-3829-0335fc89df09@gmail.com/ Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- fs/btrfs/qgroup.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index d275bf24b250..00851c86aa8a 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -2765,9 +2765,19 @@ int btrfs_qgroup_account_extents(struct btrfs_trans_handle *trans) /* * Old roots should be searched when inserting qgroup - * extent record + * extent record. + * + * But for INCONSISTENT (NO_ACCOUNTING) -> rescan case, + * we may have some record inserted during + * NO_ACCOUNTING (thus no old_roots populated), but + * later we start rescan, which clears NO_ACCOUNTING, + * leaving some inserted records without old_roots + * populated. + * + * Those cases are rare and should not cause too much + * time spent during commit_transaction(). */ - if (WARN_ON(!record->old_roots)) { + if (!record->old_roots) { /* Search commit root to find old_roots */ ret = btrfs_find_all_roots(&ctx, false); if (ret < 0) From 85e79ec7b78f863178ca488fd8cb5b3de6347756 Mon Sep 17 00:00:00 2001 From: Naohiro Aota Date: Tue, 10 Jan 2023 15:04:32 +0900 Subject: [PATCH 115/398] btrfs: zoned: enable metadata over-commit for non-ZNS setup The commit 79417d040f4f ("btrfs: zoned: disable metadata overcommit for zoned") disabled the metadata over-commit to track active zones properly. However, it also introduced a heavy overhead by allocating new metadata block groups and/or flushing dirty buffers to release the space reservations. Specifically, a workload (write only without any sync operations) worsen its performance from 343.77 MB/sec (v5.19) to 182.89 MB/sec (v6.0). The performance is still bad on current misc-next which is 187.95 MB/sec. And, with this patch applied, it improves back to 326.70 MB/sec (+73.82%). This patch introduces a new fs_info->flag BTRFS_FS_NO_OVERCOMMIT to indicate it needs to disable the metadata over-commit. The flag is enabled when a device with max active zones limit is loaded into a file-system. Fixes: 79417d040f4f ("btrfs: zoned: disable metadata overcommit for zoned") CC: stable@vger.kernel.org # 6.0+ Reviewed-by: Johannes Thumshirn Signed-off-by: Naohiro Aota Signed-off-by: David Sterba --- fs/btrfs/fs.h | 6 ++++++ fs/btrfs/space-info.c | 3 ++- fs/btrfs/zoned.c | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h index a749367e5ae2..37b86acfcbcf 100644 --- a/fs/btrfs/fs.h +++ b/fs/btrfs/fs.h @@ -119,6 +119,12 @@ enum { /* Indicate that we want to commit the transaction. */ BTRFS_FS_NEED_TRANS_COMMIT, + /* + * Indicate metadata over-commit is disabled. This is set when active + * zone tracking is needed. + */ + BTRFS_FS_NO_OVERCOMMIT, + #if BITS_PER_LONG == 32 /* Indicate if we have error/warn message printed on 32bit systems */ BTRFS_FS_32BIT_ERROR, diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c index d28ee4e36f3d..69c09508afb5 100644 --- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -407,7 +407,8 @@ int btrfs_can_overcommit(struct btrfs_fs_info *fs_info, return 0; used = btrfs_space_info_used(space_info, true); - if (btrfs_is_zoned(fs_info) && (space_info->flags & BTRFS_BLOCK_GROUP_METADATA)) + if (test_bit(BTRFS_FS_NO_OVERCOMMIT, &fs_info->flags) && + (space_info->flags & BTRFS_BLOCK_GROUP_METADATA)) avail = 0; else avail = calc_available_free_space(fs_info, space_info, flush); diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c index a759668477bb..1f503e8e42d4 100644 --- a/fs/btrfs/zoned.c +++ b/fs/btrfs/zoned.c @@ -539,6 +539,8 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache) } atomic_set(&zone_info->active_zones_left, max_active_zones - nactive); + /* Overcommit does not work well with active zone tacking. */ + set_bit(BTRFS_FS_NO_OVERCOMMIT, &fs_info->flags); } /* Validate superblock log */ From 0e678153f5be7e6c8d28835f5a678618da4b7a9c Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Thu, 22 Dec 2022 21:55:10 +0100 Subject: [PATCH 116/398] mm/hugetlb: fix PTE marker handling in hugetlb_change_protection() Patch series "mm/hugetlb: uffd-wp fixes for hugetlb_change_protection()". Playing with virtio-mem and background snapshots (using uffd-wp) on hugetlb in QEMU, I managed to trigger a VM_BUG_ON(). Looking into the details, hugetlb_change_protection() seems to not handle uffd-wp correctly in all cases. Patch #1 fixes my test case. I don't have reproducers for patch #2, as it requires running into migration entries. I did not yet check in detail yet if !hugetlb code requires similar care. This patch (of 2): There are two problematic cases when stumbling over a PTE marker in hugetlb_change_protection(): (1) We protect an uffd-wp PTE marker a second time using uffd-wp: we will end up in the "!huge_pte_none(pte)" case and mess up the PTE marker. (2) We unprotect a uffd-wp PTE marker: we will similarly end up in the "!huge_pte_none(pte)" case even though we cleared the PTE, because the "pte" variable is stale. We'll mess up the PTE marker. For example, if we later stumble over such a "wrongly modified" PTE marker, we'll treat it like a present PTE that maps some garbage page. This can, for example, be triggered by mapping a memfd backed by huge pages, registering uffd-wp, uffd-wp'ing an unmapped page and (a) uffd-wp'ing it a second time; or (b) uffd-unprotecting it; or (c) unregistering uffd-wp. Then, ff we trigger fallocate(FALLOC_FL_PUNCH_HOLE) on that file range, we will run into a VM_BUG_ON: [ 195.039560] page:00000000ba1f2987 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x0 [ 195.039565] flags: 0x7ffffc0001000(reserved|node=0|zone=0|lastcpupid=0x1fffff) [ 195.039568] raw: 0007ffffc0001000 ffffe742c0000008 ffffe742c0000008 0000000000000000 [ 195.039569] raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000 [ 195.039569] page dumped because: VM_BUG_ON_PAGE(compound && !PageHead(page)) [ 195.039573] ------------[ cut here ]------------ [ 195.039574] kernel BUG at mm/rmap.c:1346! [ 195.039579] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI [ 195.039581] CPU: 7 PID: 4777 Comm: qemu-system-x86 Not tainted 6.0.12-200.fc36.x86_64 #1 [ 195.039583] Hardware name: LENOVO 20WNS1F81N/20WNS1F81N, BIOS N35ET50W (1.50 ) 09/15/2022 [ 195.039584] RIP: 0010:page_remove_rmap+0x45b/0x550 [ 195.039588] Code: [...] [ 195.039589] RSP: 0018:ffffbc03c3633ba8 EFLAGS: 00010292 [ 195.039591] RAX: 0000000000000040 RBX: ffffe742c0000000 RCX: 0000000000000000 [ 195.039592] RDX: 0000000000000002 RSI: ffffffff8e7aac1a RDI: 00000000ffffffff [ 195.039592] RBP: 0000000000000001 R08: 0000000000000000 R09: ffffbc03c3633a08 [ 195.039593] R10: 0000000000000003 R11: ffffffff8f146328 R12: ffff9b04c42754b0 [ 195.039594] R13: ffffffff8fcc6328 R14: ffffbc03c3633c80 R15: ffff9b0484ab9100 [ 195.039595] FS: 00007fc7aaf68640(0000) GS:ffff9b0bbf7c0000(0000) knlGS:0000000000000000 [ 195.039596] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 195.039597] CR2: 000055d402c49110 CR3: 0000000159392003 CR4: 0000000000772ee0 [ 195.039598] PKRU: 55555554 [ 195.039599] Call Trace: [ 195.039600] [ 195.039602] __unmap_hugepage_range+0x33b/0x7d0 [ 195.039605] unmap_hugepage_range+0x55/0x70 [ 195.039608] hugetlb_vmdelete_list+0x77/0xa0 [ 195.039611] hugetlbfs_fallocate+0x410/0x550 [ 195.039612] ? _raw_spin_unlock_irqrestore+0x23/0x40 [ 195.039616] vfs_fallocate+0x12e/0x360 [ 195.039618] __x64_sys_fallocate+0x40/0x70 [ 195.039620] do_syscall_64+0x58/0x80 [ 195.039623] ? syscall_exit_to_user_mode+0x17/0x40 [ 195.039624] ? do_syscall_64+0x67/0x80 [ 195.039626] entry_SYSCALL_64_after_hwframe+0x63/0xcd [ 195.039628] RIP: 0033:0x7fc7b590651f [ 195.039653] Code: [...] [ 195.039654] RSP: 002b:00007fc7aaf66e70 EFLAGS: 00000293 ORIG_RAX: 000000000000011d [ 195.039655] RAX: ffffffffffffffda RBX: 0000558ef4b7f370 RCX: 00007fc7b590651f [ 195.039656] RDX: 0000000018000000 RSI: 0000000000000003 RDI: 000000000000000c [ 195.039657] RBP: 0000000008000000 R08: 0000000000000000 R09: 0000000000000073 [ 195.039658] R10: 0000000008000000 R11: 0000000000000293 R12: 0000000018000000 [ 195.039658] R13: 00007fb8bbe00000 R14: 000000000000000c R15: 0000000000001000 [ 195.039661] Fix it by not going into the "!huge_pte_none(pte)" case if we stumble over an exclusive marker. spin_unlock() + continue would get the job done. However, instead, make it clearer that there are no fall-through statements: we process each case (hwpoison, migration, marker, !none, none) and then unlock the page table to continue with the next PTE. Let's avoid "continue" statements and use a single spin_unlock() at the end. Link: https://lkml.kernel.org/r/20221222205511.675832-1-david@redhat.com Link: https://lkml.kernel.org/r/20221222205511.675832-2-david@redhat.com Fixes: 60dfaad65aa9 ("mm/hugetlb: allow uffd wr-protect none ptes") Signed-off-by: David Hildenbrand Reviewed-by: Peter Xu Reviewed-by: Mike Kravetz Cc: Miaohe Lin Cc: Muchun Song Cc: Signed-off-by: Andrew Morton --- mm/hugetlb.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index db895230ee7e..3f0686b54701 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -6658,10 +6658,8 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, } pte = huge_ptep_get(ptep); if (unlikely(is_hugetlb_entry_hwpoisoned(pte))) { - spin_unlock(ptl); - continue; - } - if (unlikely(is_hugetlb_entry_migration(pte))) { + /* Nothing to do. */ + } else if (unlikely(is_hugetlb_entry_migration(pte))) { swp_entry_t entry = pte_to_swp_entry(pte); struct page *page = pfn_swap_entry_to_page(entry); @@ -6682,18 +6680,13 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, set_huge_pte_at(mm, address, ptep, newpte); pages++; } - spin_unlock(ptl); - continue; - } - if (unlikely(pte_marker_uffd_wp(pte))) { - /* - * This is changing a non-present pte into a none pte, - * no need for huge_ptep_modify_prot_start/commit(). - */ + } else if (unlikely(is_pte_marker(pte))) { + /* No other markers apply for now. */ + WARN_ON_ONCE(!pte_marker_uffd_wp(pte)); if (uffd_wp_resolve) + /* Safe to modify directly (non-present->none). */ huge_pte_clear(mm, address, ptep, psize); - } - if (!huge_pte_none(pte)) { + } else if (!huge_pte_none(pte)) { pte_t old_pte; unsigned int shift = huge_page_shift(hstate_vma(vma)); From 44f86392bdd165da7e43d3c772aeb1e128ffd6c8 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Thu, 22 Dec 2022 21:55:11 +0100 Subject: [PATCH 117/398] mm/hugetlb: fix uffd-wp handling for migration entries in hugetlb_change_protection() We have to update the uffd-wp SWP PTE bit independent of the type of migration entry. Currently, if we're unlucky and we want to install/clear the uffd-wp bit just while we're migrating a read-only mapped hugetlb page, we would miss to set/clear the uffd-wp bit. Further, if we're processing a readable-exclusive migration entry and neither want to set or clear the uffd-wp bit, we could currently end up losing the uffd-wp bit. Note that the same would hold for writable migrating entries, however, having a writable migration entry with the uffd-wp bit set would already mean that something went wrong. Note that the change from !is_readable_migration_entry -> writable_migration_entry is harmless and actually cleaner, as raised by Miaohe Lin and discussed in [1]. [1] https://lkml.kernel.org/r/90dd6a93-4500-e0de-2bf0-bf522c311b0c@huawei.com Link: https://lkml.kernel.org/r/20221222205511.675832-3-david@redhat.com Fixes: 60dfaad65aa9 ("mm/hugetlb: allow uffd wr-protect none ptes") Signed-off-by: David Hildenbrand Reviewed-by: Mike Kravetz Cc: Miaohe Lin Cc: Muchun Song Cc: Peter Xu Cc: Signed-off-by: Andrew Morton --- mm/hugetlb.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 3f0686b54701..bd7d39227344 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -6662,10 +6662,9 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, } else if (unlikely(is_hugetlb_entry_migration(pte))) { swp_entry_t entry = pte_to_swp_entry(pte); struct page *page = pfn_swap_entry_to_page(entry); + pte_t newpte = pte; - if (!is_readable_migration_entry(entry)) { - pte_t newpte; - + if (is_writable_migration_entry(entry)) { if (PageAnon(page)) entry = make_readable_exclusive_migration_entry( swp_offset(entry)); @@ -6673,13 +6672,15 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, entry = make_readable_migration_entry( swp_offset(entry)); newpte = swp_entry_to_pte(entry); - if (uffd_wp) - newpte = pte_swp_mkuffd_wp(newpte); - else if (uffd_wp_resolve) - newpte = pte_swp_clear_uffd_wp(newpte); - set_huge_pte_at(mm, address, ptep, newpte); pages++; } + + if (uffd_wp) + newpte = pte_swp_mkuffd_wp(newpte); + else if (uffd_wp_resolve) + newpte = pte_swp_clear_uffd_wp(newpte); + if (!pte_same(pte, newpte)) + set_huge_pte_at(mm, address, ptep, newpte); } else if (unlikely(is_pte_marker(pte))) { /* No other markers apply for now. */ WARN_ON_ONCE(!pte_marker_uffd_wp(pte)); From ab0c3f1251b4670978fde0bd54161795a139b060 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Thu, 22 Dec 2022 12:41:50 -0800 Subject: [PATCH 118/398] mm/khugepaged: fix collapse_pte_mapped_thp() to allow anon_vma uprobe_write_opcode() uses collapse_pte_mapped_thp() to restore huge pmd, when removing a breakpoint from hugepage text: vma->anon_vma is always set in that case, so undo the prohibition. And MADV_COLLAPSE ought to be able to collapse some page tables in a vma which happens to have anon_vma set from CoWing elsewhere. Is anon_vma lock required? Almost not: if any page other than expected subpage of the non-anon huge page is found in the page table, collapse is aborted without making any change. However, it is possible that an anon page was CoWed from this extent in another mm or vma, in which case a concurrent lookup might look here: so keep it away while clearing pmd (but perhaps we shall go back to using pmd_lock() there in future). Note that collapse_pte_mapped_thp() is exceptional in freeing a page table without having cleared its ptes: I'm uneasy about that, and had thought pte_clear()ing appropriate; but exclusive i_mmap lock does fix the problem, and we would have to move the mmu_notification if clearing those ptes. What this fixes is not a dangerous instability. But I suggest Cc stable because uprobes "healing" has regressed in that way, so this should follow 8d3c106e19e8 into those stable releases where it was backported (and may want adjustment there - I'll supply backports as needed). Link: https://lkml.kernel.org/r/b740c9fb-edba-92ba-59fb-7a5592e5dfc@google.com Fixes: 8d3c106e19e8 ("mm/khugepaged: take the right locks for page table retraction") Signed-off-by: Hugh Dickins Acked-by: David Hildenbrand Cc: Jann Horn Cc: Yang Shi Cc: Zach O'Keefe Cc: Song Liu Cc: [5.4+] Signed-off-by: Andrew Morton --- mm/khugepaged.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 5cb401aa2b9d..9a0135b39b19 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -1460,14 +1460,6 @@ int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr, if (!hugepage_vma_check(vma, vma->vm_flags, false, false, false)) return SCAN_VMA_CHECK; - /* - * Symmetry with retract_page_tables(): Exclude MAP_PRIVATE mappings - * that got written to. Without this, we'd have to also lock the - * anon_vma if one exists. - */ - if (vma->anon_vma) - return SCAN_VMA_CHECK; - /* Keep pmd pgtable for uffd-wp; see comment in retract_page_tables() */ if (userfaultfd_wp(vma)) return SCAN_PTE_UFFD_WP; @@ -1567,8 +1559,14 @@ int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr, } /* step 4: remove pte entries */ + /* we make no change to anon, but protect concurrent anon page lookup */ + if (vma->anon_vma) + anon_vma_lock_write(vma->anon_vma); + collapse_and_free_pmd(mm, vma, haddr, pmd); + if (vma->anon_vma) + anon_vma_unlock_write(vma->anon_vma); i_mmap_unlock_write(vma->vm_file->f_mapping); maybe_install_pmd: From 51d3d5eb74ff53b92dcff48b30ae2ed8edd85a32 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Fri, 9 Dec 2022 09:09:12 +0100 Subject: [PATCH 119/398] mm/userfaultfd: enable writenotify while userfaultfd-wp is enabled for a VMA Currently, we don't enable writenotify when enabling userfaultfd-wp on a shared writable mapping (for now only shmem and hugetlb). The consequence is that vma->vm_page_prot will still include write permissions, to be set as default for all PTEs that get remapped (e.g., mprotect(), NUMA hinting, page migration, ...). So far, vma->vm_page_prot is assumed to be a safe default, meaning that we only add permissions (e.g., mkwrite) but not remove permissions (e.g., wrprotect). For example, when enabling softdirty tracking, we enable writenotify. With uffd-wp on shared mappings, that changed. More details on vma->vm_page_prot semantics were summarized in [1]. This is problematic for uffd-wp: we'd have to manually check for a uffd-wp PTEs/PMDs and manually write-protect PTEs/PMDs, which is error prone. Prone to such issues is any code that uses vma->vm_page_prot to set PTE permissions: primarily pte_modify() and mk_pte(). Instead, let's enable writenotify such that PTEs/PMDs/... will be mapped write-protected as default and we will only allow selected PTEs that are definitely safe to be mapped without write-protection (see can_change_pte_writable()) to be writable. In the future, we might want to enable write-bit recovery -- e.g., can_change_pte_writable() -- at more locations, for example, also when removing uffd-wp protection. This fixes two known cases: (a) remove_migration_pte() mapping uffd-wp'ed PTEs writable, resulting in uffd-wp not triggering on write access. (b) do_numa_page() / do_huge_pmd_numa_page() mapping uffd-wp'ed PTEs/PMDs writable, resulting in uffd-wp not triggering on write access. Note that do_numa_page() / do_huge_pmd_numa_page() can be reached even without NUMA hinting (which currently doesn't seem to be applicable to shmem), for example, by using uffd-wp with a PROT_WRITE shmem VMA. On such a VMA, userfaultfd-wp is currently non-functional. Note that when enabling userfaultfd-wp, there is no need to walk page tables to enforce the new default protection for the PTEs: we know that they cannot be uffd-wp'ed yet, because that can only happen after enabling uffd-wp for the VMA in general. Also note that this makes mprotect() on ranges with uffd-wp'ed PTEs not accidentally set the write bit -- which would result in uffd-wp not triggering on later write access. This commit makes uffd-wp on shmem behave just like uffd-wp on anonymous memory in that regard, even though, mixing mprotect with uffd-wp is controversial. [1] https://lkml.kernel.org/r/92173bad-caa3-6b43-9d1e-9a471fdbc184@redhat.com Link: https://lkml.kernel.org/r/20221209080912.7968-1-david@redhat.com Fixes: b1f9e876862d ("mm/uffd: enable write protection for shmem & hugetlbfs") Signed-off-by: David Hildenbrand Reported-by: Ives van Hoorne Debugged-by: Peter Xu Acked-by: Peter Xu Cc: Hugh Dickins Cc: Alistair Popple Cc: Mike Rapoport Cc: Nadav Amit Cc: Andrea Arcangeli Cc: Signed-off-by: Andrew Morton --- fs/userfaultfd.c | 28 ++++++++++++++++++++++------ mm/mmap.c | 4 ++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index 98ac37e34e3d..cc694846617a 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -108,6 +108,21 @@ static bool userfaultfd_is_initialized(struct userfaultfd_ctx *ctx) return ctx->features & UFFD_FEATURE_INITIALIZED; } +static void userfaultfd_set_vm_flags(struct vm_area_struct *vma, + vm_flags_t flags) +{ + const bool uffd_wp_changed = (vma->vm_flags ^ flags) & VM_UFFD_WP; + + vma->vm_flags = flags; + /* + * For shared mappings, we want to enable writenotify while + * userfaultfd-wp is enabled (see vma_wants_writenotify()). We'll simply + * recalculate vma->vm_page_prot whenever userfaultfd-wp changes. + */ + if ((vma->vm_flags & VM_SHARED) && uffd_wp_changed) + vma_set_page_prot(vma); +} + static int userfaultfd_wake_function(wait_queue_entry_t *wq, unsigned mode, int wake_flags, void *key) { @@ -618,7 +633,8 @@ static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx, for_each_vma(vmi, vma) { if (vma->vm_userfaultfd_ctx.ctx == release_new_ctx) { vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX; - vma->vm_flags &= ~__VM_UFFD_FLAGS; + userfaultfd_set_vm_flags(vma, + vma->vm_flags & ~__VM_UFFD_FLAGS); } } mmap_write_unlock(mm); @@ -652,7 +668,7 @@ int dup_userfaultfd(struct vm_area_struct *vma, struct list_head *fcs) octx = vma->vm_userfaultfd_ctx.ctx; if (!octx || !(octx->features & UFFD_FEATURE_EVENT_FORK)) { vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX; - vma->vm_flags &= ~__VM_UFFD_FLAGS; + userfaultfd_set_vm_flags(vma, vma->vm_flags & ~__VM_UFFD_FLAGS); return 0; } @@ -733,7 +749,7 @@ void mremap_userfaultfd_prep(struct vm_area_struct *vma, } else { /* Drop uffd context if remap feature not enabled */ vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX; - vma->vm_flags &= ~__VM_UFFD_FLAGS; + userfaultfd_set_vm_flags(vma, vma->vm_flags & ~__VM_UFFD_FLAGS); } } @@ -895,7 +911,7 @@ static int userfaultfd_release(struct inode *inode, struct file *file) prev = vma; } - vma->vm_flags = new_flags; + userfaultfd_set_vm_flags(vma, new_flags); vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX; } mmap_write_unlock(mm); @@ -1463,7 +1479,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, * the next vma was merged into the current one and * the current one has not been updated yet. */ - vma->vm_flags = new_flags; + userfaultfd_set_vm_flags(vma, new_flags); vma->vm_userfaultfd_ctx.ctx = ctx; if (is_vm_hugetlb_page(vma) && uffd_disable_huge_pmd_share(vma)) @@ -1651,7 +1667,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, * the next vma was merged into the current one and * the current one has not been updated yet. */ - vma->vm_flags = new_flags; + userfaultfd_set_vm_flags(vma, new_flags); vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX; skip: diff --git a/mm/mmap.c b/mm/mmap.c index 87d929316d57..420476fcfbfc 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1524,6 +1524,10 @@ int vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot) if (vma_soft_dirty_enabled(vma) && !is_vm_hugetlb_page(vma)) return 1; + /* Do we need write faults for uffd-wp tracking? */ + if (userfaultfd_wp(vma)) + return 1; + /* Specialty mapping? */ if (vm_flags & VM_PFNMAP) return 0; From 52dc031088f00e323140ece4004e70c33153c6dd Mon Sep 17 00:00:00 2001 From: Zach O'Keefe Date: Sat, 24 Dec 2022 00:20:34 -0800 Subject: [PATCH 120/398] mm/MADV_COLLAPSE: don't expand collapse when vm_end is past requested end MADV_COLLAPSE acts on one hugepage-aligned/sized region at a time, until it has collapsed all eligible memory contained within the bounds supplied by the user. At the top of each hugepage iteration we (re)lock mmap_lock and (re)validate the VMA for eligibility and update variables that might have changed while mmap_lock was dropped. One thing that might occur is that the VMA could be resized, and as such, we refetch vma->vm_end to make sure we don't collapse past the end of the VMA's new end. However, it's possible that when refetching vma->vm_end that we expand the region acted on by MADV_COLLAPSE if vma->vm_end is greater than size+len supplied by the user. The consequence here is that we may attempt to collapse more memory than requested, possibly yielding either "too much success" or "false failure" user-visible results. An example of the former is if we MADV_COLLAPSE the first 4MiB of a 2TiB mmap()'d file, the incorrect refetch would cause the operation to block for much longer than anticipated as we attempt to collapse the entire TiB region. An example of the latter is that applying MADV_COLLPSE to a 4MiB file mapped to the start of a 6MiB VMA will successfully collapse the first 4MiB, then incorrectly attempt to collapse the last hugepage-aligned/sized region -- fail (since readahead/page cache lookup will fail) -- and report a failure to the user. I don't believe there is a kernel stability concern here as we always (re)validate the VMA / region accordingly. Also as Hugh mentions, the user-visible effects are: we try to collapse more memory than requested by the user, and/or failing an operation that should have otherwise succeeded. An example is trying to collapse a 4MiB file contained within a 12MiB VMA. Don't expand the acted-on region when refetching vma->vm_end. Link: https://lkml.kernel.org/r/20221224082035.3197140-1-zokeefe@google.com Fixes: 4d24de9425f7 ("mm: MADV_COLLAPSE: refetch vm_end after reacquiring mmap_lock") Signed-off-by: Zach O'Keefe Reported-by: Hugh Dickins Cc: Yang Shi Cc: Signed-off-by: Andrew Morton --- mm/khugepaged.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 9a0135b39b19..79be13133322 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -2647,7 +2647,7 @@ int madvise_collapse(struct vm_area_struct *vma, struct vm_area_struct **prev, goto out_nolock; } - hend = vma->vm_end & HPAGE_PMD_MASK; + hend = min(hend, vma->vm_end & HPAGE_PMD_MASK); } mmap_assert_locked(mm); memset(cc->node_load, 0, sizeof(cc->node_load)); From 3de0c269adc6c2fac0bb1fb11965f0de699dc32b Mon Sep 17 00:00:00 2001 From: Zach O'Keefe Date: Sat, 24 Dec 2022 00:20:35 -0800 Subject: [PATCH 121/398] mm/shmem: restore SHMEM_HUGE_DENY precedence over MADV_COLLAPSE SHMEM_HUGE_DENY is for emergency use by the admin, to disable allocation of shmem huge pages if, for example, a dangerous bug is found in their usage: see "deny" in Documentation/mm/transhuge.rst. An app using madvise(,,MADV_COLLAPSE) should not be allowed to override it: restore its precedence over shmem_huge_force. Restore SHMEM_HUGE_DENY precedence over MADV_COLLAPSE. Link: https://lkml.kernel.org/r/20221224082035.3197140-2-zokeefe@google.com Fixes: 7c6c6cc4d3a2 ("mm/shmem: add flag to enforce shmem THP in hugepage_vma_check()") Signed-off-by: Zach O'Keefe Suggested-by: Hugh Dickins Acked-by: David Hildenbrand Cc: Yang Shi Cc: Signed-off-by: Andrew Morton --- mm/shmem.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mm/shmem.c b/mm/shmem.c index c301487be5fb..0005ab2c29af 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -478,12 +478,10 @@ bool shmem_is_huge(struct vm_area_struct *vma, struct inode *inode, if (vma && ((vma->vm_flags & VM_NOHUGEPAGE) || test_bit(MMF_DISABLE_THP, &vma->vm_mm->flags))) return false; - if (shmem_huge_force) - return true; - if (shmem_huge == SHMEM_HUGE_FORCE) - return true; if (shmem_huge == SHMEM_HUGE_DENY) return false; + if (shmem_huge_force || shmem_huge == SHMEM_HUGE_FORCE) + return true; switch (SHMEM_SB(inode->i_sb)->huge) { case SHMEM_HUGE_ALWAYS: From a1193de562f54c7c9f60ca9f2db96e50a7608de1 Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Wed, 4 Jan 2023 16:02:40 -0800 Subject: [PATCH 122/398] mm: fix vma->anon_name memory leak for anonymous shmem VMAs free_anon_vma_name() is missing a check for anonymous shmem VMA which leads to a memory leak due to refcount not being dropped. Fix this by calling anon_vma_name_put() unconditionally. It will free vma->anon_name whenever it's non-NULL. Link: https://lkml.kernel.org/r/20230105000241.1450843-1-surenb@google.com Fixes: d09e8ca6cb93 ("mm: anonymous shared memory naming") Signed-off-by: Suren Baghdasaryan Suggested-by: David Hildenbrand Reviewed-by: David Hildenbrand Reported-by: syzbot+91edf9178386a07d06a7@syzkaller.appspotmail.com Cc: Hugh Dickins Cc: Pasha Tatashin Signed-off-by: Andrew Morton --- include/linux/mm_inline.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index e8ed225d8f7c..ff3f3f23f649 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -413,8 +413,7 @@ static inline void free_anon_vma_name(struct vm_area_struct *vma) * Not using anon_vma_name because it generates a warning if mmap_lock * is not held, which might be the case here. */ - if (!vma->vm_file) - anon_vma_name_put(vma->anon_name); + anon_vma_name_put(vma->anon_name); } static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1, From b30c14cd61025eeea2f2e8569606cd167ba9ad2d Mon Sep 17 00:00:00 2001 From: James Houghton Date: Wed, 4 Jan 2023 23:19:10 +0000 Subject: [PATCH 123/398] hugetlb: unshare some PMDs when splitting VMAs PMD sharing can only be done in PUD_SIZE-aligned pieces of VMAs; however, it is possible that HugeTLB VMAs are split without unsharing the PMDs first. Without this fix, it is possible to hit the uffd-wp-related WARN_ON_ONCE in hugetlb_change_protection [1]. The key there is that hugetlb_unshare_all_pmds will not attempt to unshare PMDs in non-PUD_SIZE-aligned sections of the VMA. It might seem ideal to unshare in hugetlb_vm_op_open, but we need to unshare in both the new and old VMAs, so unsharing in hugetlb_vm_op_split seems natural. [1]: https://lore.kernel.org/linux-mm/CADrL8HVeOkj0QH5VZZbRzybNE8CG-tEGFshnA+bG9nMgcWtBSg@mail.gmail.com/ Link: https://lkml.kernel.org/r/20230104231910.1464197-1-jthoughton@google.com Fixes: 6dfeaff93be1 ("hugetlb/userfaultfd: unshare all pmds for hugetlbfs when register wp") Signed-off-by: James Houghton Reviewed-by: Mike Kravetz Acked-by: Peter Xu Cc: Axel Rasmussen Cc: Muchun Song Cc: Signed-off-by: Andrew Morton --- mm/hugetlb.c | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index bd7d39227344..2ce912c915eb 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -94,6 +94,8 @@ static int hugetlb_acct_memory(struct hstate *h, long delta); static void hugetlb_vma_lock_free(struct vm_area_struct *vma); static void hugetlb_vma_lock_alloc(struct vm_area_struct *vma); static void __hugetlb_vma_unlock_write_free(struct vm_area_struct *vma); +static void hugetlb_unshare_pmds(struct vm_area_struct *vma, + unsigned long start, unsigned long end); static inline bool subpool_is_free(struct hugepage_subpool *spool) { @@ -4834,6 +4836,25 @@ static int hugetlb_vm_op_split(struct vm_area_struct *vma, unsigned long addr) { if (addr & ~(huge_page_mask(hstate_vma(vma)))) return -EINVAL; + + /* + * PMD sharing is only possible for PUD_SIZE-aligned address ranges + * in HugeTLB VMAs. If we will lose PUD_SIZE alignment due to this + * split, unshare PMDs in the PUD_SIZE interval surrounding addr now. + */ + if (addr & ~PUD_MASK) { + /* + * hugetlb_vm_op_split is called right before we attempt to + * split the VMA. We will need to unshare PMDs in the old and + * new VMAs, so let's unshare before we split. + */ + unsigned long floor = addr & PUD_MASK; + unsigned long ceil = floor + PUD_SIZE; + + if (floor >= vma->vm_start && ceil <= vma->vm_end) + hugetlb_unshare_pmds(vma, floor, ceil); + } + return 0; } @@ -7322,26 +7343,21 @@ void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, int re } } -/* - * This function will unconditionally remove all the shared pmd pgtable entries - * within the specific vma for a hugetlbfs memory range. - */ -void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) +static void hugetlb_unshare_pmds(struct vm_area_struct *vma, + unsigned long start, + unsigned long end) { struct hstate *h = hstate_vma(vma); unsigned long sz = huge_page_size(h); struct mm_struct *mm = vma->vm_mm; struct mmu_notifier_range range; - unsigned long address, start, end; + unsigned long address; spinlock_t *ptl; pte_t *ptep; if (!(vma->vm_flags & VM_MAYSHARE)) return; - start = ALIGN(vma->vm_start, PUD_SIZE); - end = ALIGN_DOWN(vma->vm_end, PUD_SIZE); - if (start >= end) return; @@ -7373,6 +7389,16 @@ void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) mmu_notifier_invalidate_range_end(&range); } +/* + * This function will unconditionally remove all the shared pmd pgtable entries + * within the specific vma for a hugetlbfs memory range. + */ +void hugetlb_unshare_all_pmds(struct vm_area_struct *vma) +{ + hugetlb_unshare_pmds(vma, ALIGN(vma->vm_start, PUD_SIZE), + ALIGN_DOWN(vma->vm_end, PUD_SIZE)); +} + #ifdef CONFIG_CMA static bool cma_reserve_called __initdata; From fed15f1345dc8a7fc8baa81e8b55c3ba010d7f4b Mon Sep 17 00:00:00 2001 From: Peter Xu Date: Wed, 4 Jan 2023 17:52:05 -0500 Subject: [PATCH 124/398] mm/hugetlb: pre-allocate pgtable pages for uffd wr-protects Userfaultfd-wp uses pte markers to mark wr-protected pages for both shmem and hugetlb. Shmem has pre-allocation ready for markers, but hugetlb path was overlooked. Doing so by calling huge_pte_alloc() if the initial pgtable walk fails to find the huge ptep. It's possible that huge_pte_alloc() can fail with high memory pressure, in that case stop the loop immediately and fail silently. This is not the most ideal solution but it matches with what we do with shmem meanwhile it avoids the splat in dmesg. Link: https://lkml.kernel.org/r/20230104225207.1066932-2-peterx@redhat.com Fixes: 60dfaad65aa9 ("mm/hugetlb: allow uffd wr-protect none ptes") Signed-off-by: Peter Xu Reported-by: James Houghton Reviewed-by: Mike Kravetz Acked-by: David Hildenbrand Acked-by: James Houghton Cc: Andrea Arcangeli Cc: Axel Rasmussen Cc: Muchun Song Cc: Nadav Amit Cc: [5.19+] Signed-off-by: Andrew Morton --- mm/hugetlb.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 2ce912c915eb..f96794be71d5 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -6660,8 +6660,17 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, spinlock_t *ptl; ptep = huge_pte_offset(mm, address, psize); if (!ptep) { - address |= last_addr_mask; - continue; + if (!uffd_wp) { + address |= last_addr_mask; + continue; + } + /* + * Userfaultfd wr-protect requires pgtable + * pre-allocations to install pte markers. + */ + ptep = huge_pte_alloc(mm, vma, address, psize); + if (!ptep) + break; } ptl = huge_pte_lock(h, mm, ptep); if (huge_pmd_unshare(mm, vma, address, ptep)) { From 1beb8ae302a01fb487787f5a4fb97cf5338a86c1 Mon Sep 17 00:00:00 2001 From: Nhat Pham Date: Fri, 6 Jan 2023 14:00:16 -0800 Subject: [PATCH 125/398] Docs/admin-guide/mm/zswap: remove zsmalloc's lack of writeback warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Writeback has been implemented for zsmalloc, so this warning no longer holds. Link: https://lkml.kernel.org/r/20230106220016.172303-1-nphamcs@gmail.com Fixes: 9997bc017549a ("zsmalloc: implement writeback mechanism for zsmalloc") Suggested-by: Thomas Weißschuh Signed-off-by: Nhat Pham Reviewed-by: Sergey Senozhatsky Cc: Johannes Weiner Cc: Jonathan Corbet Signed-off-by: Andrew Morton --- Documentation/admin-guide/mm/zswap.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Documentation/admin-guide/mm/zswap.rst b/Documentation/admin-guide/mm/zswap.rst index f67de481c7f6..6dd74a18268b 100644 --- a/Documentation/admin-guide/mm/zswap.rst +++ b/Documentation/admin-guide/mm/zswap.rst @@ -70,9 +70,7 @@ e.g. ``zswap.zpool=zbud``. It can also be changed at runtime using the sysfs The zbud type zpool allocates exactly 1 page to store 2 compressed pages, which means the compression ratio will always be 2:1 or worse (because of half-full zbud pages). The zsmalloc type zpool has a more complex compressed page -storage method, and it can achieve greater storage densities. However, -zsmalloc does not implement compressed page eviction, so once zswap fills it -cannot evict the oldest page, it can only reject new pages. +storage method, and it can achieve greater storage densities. When a swap page is passed from frontswap to zswap, zswap maintains a mapping of the swap entry, a combination of the swap type and swap offset, to the zpool From 7633355e5c7f29c049a9048e461427d1d8ed3051 Mon Sep 17 00:00:00 2001 From: Ryusuke Konishi Date: Thu, 5 Jan 2023 14:53:56 +0900 Subject: [PATCH 126/398] nilfs2: fix general protection fault in nilfs_btree_insert() If nilfs2 reads a corrupted disk image and tries to reads a b-tree node block by calling __nilfs_btree_get_block() against an invalid virtual block address, it returns -ENOENT because conversion of the virtual block address to a disk block address fails. However, this return value is the same as the internal code that b-tree lookup routines return to indicate that the block being searched does not exist, so functions that operate on that b-tree may misbehave. When nilfs_btree_insert() receives this spurious 'not found' code from nilfs_btree_do_lookup(), it misunderstands that the 'not found' check was successful and continues the insert operation using incomplete lookup path data, causing the following crash: general protection fault, probably for non-canonical address 0xdffffc0000000005: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f] ... RIP: 0010:nilfs_btree_get_nonroot_node fs/nilfs2/btree.c:418 [inline] RIP: 0010:nilfs_btree_prepare_insert fs/nilfs2/btree.c:1077 [inline] RIP: 0010:nilfs_btree_insert+0x6d3/0x1c10 fs/nilfs2/btree.c:1238 Code: bc 24 80 00 00 00 4c 89 f8 48 c1 e8 03 42 80 3c 28 00 74 08 4c 89 ff e8 4b 02 92 fe 4d 8b 3f 49 83 c7 28 4c 89 f8 48 c1 e8 03 <42> 80 3c 28 00 74 08 4c 89 ff e8 2e 02 92 fe 4d 8b 3f 49 83 c7 02 ... Call Trace: nilfs_bmap_do_insert fs/nilfs2/bmap.c:121 [inline] nilfs_bmap_insert+0x20d/0x360 fs/nilfs2/bmap.c:147 nilfs_get_block+0x414/0x8d0 fs/nilfs2/inode.c:101 __block_write_begin_int+0x54c/0x1a80 fs/buffer.c:1991 __block_write_begin fs/buffer.c:2041 [inline] block_write_begin+0x93/0x1e0 fs/buffer.c:2102 nilfs_write_begin+0x9c/0x110 fs/nilfs2/inode.c:261 generic_perform_write+0x2e4/0x5e0 mm/filemap.c:3772 __generic_file_write_iter+0x176/0x400 mm/filemap.c:3900 generic_file_write_iter+0xab/0x310 mm/filemap.c:3932 call_write_iter include/linux/fs.h:2186 [inline] new_sync_write fs/read_write.c:491 [inline] vfs_write+0x7dc/0xc50 fs/read_write.c:584 ksys_write+0x177/0x2a0 fs/read_write.c:637 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd ... This patch fixes the root cause of this problem by replacing the error code that __nilfs_btree_get_block() returns on block address conversion failure from -ENOENT to another internal code -EINVAL which means that the b-tree metadata is corrupted. By returning -EINVAL, it propagates without glitches, and for all relevant b-tree operations, functions in the upper bmap layer output an error message indicating corrupted b-tree metadata via nilfs_bmap_convert_error(), and code -EIO will be eventually returned as it should be. Link: https://lkml.kernel.org/r/000000000000bd89e205f0e38355@google.com Link: https://lkml.kernel.org/r/20230105055356.8811-1-konishi.ryusuke@gmail.com Signed-off-by: Ryusuke Konishi Reported-by: syzbot+ede796cecd5296353515@syzkaller.appspotmail.com Tested-by: Ryusuke Konishi Cc: Signed-off-by: Andrew Morton --- fs/nilfs2/btree.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index b9d15c3df3cc..40ce92a332fe 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c @@ -480,9 +480,18 @@ static int __nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr, ret = nilfs_btnode_submit_block(btnc, ptr, 0, REQ_OP_READ, &bh, &submit_ptr); if (ret) { - if (ret != -EEXIST) - return ret; - goto out_check; + if (likely(ret == -EEXIST)) + goto out_check; + if (ret == -ENOENT) { + /* + * Block address translation failed due to invalid + * value of 'ptr'. In this case, return internal code + * -EINVAL (broken bmap) to notify bmap layer of fatal + * metadata corruption. + */ + ret = -EINVAL; + } + return ret; } if (ra) { From 0de4a7f5ba5744d1de5ce0b076bb73a86530c60c Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Wed, 4 Jan 2023 02:09:33 +0100 Subject: [PATCH 127/398] kasan: mark kasan_kunit_executing as static Mark kasan_kunit_executing as static, as it is only used within mm/kasan/report.c. Link: https://lkml.kernel.org/r/f64778a4683b16a73bba72576f73bf4a2b45a82f.1672794398.git.andreyknvl@google.com Fixes: c8c7016f50c8 ("kasan: fail non-kasan KUnit tests on KASAN reports") Reported-by: kernel test robot Signed-off-by: Andrey Konovalov Reviewed-by: Marco Elver Cc: Alexander Potapenko Cc: Andrey Ryabinin Cc: Dmitry Vyukov Signed-off-by: Andrew Morton --- mm/kasan/report.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/kasan/report.c b/mm/kasan/report.c index 1d02757e90a3..22598b20c7b7 100644 --- a/mm/kasan/report.c +++ b/mm/kasan/report.c @@ -119,7 +119,7 @@ EXPORT_SYMBOL_GPL(kasan_restore_multi_shot); * Whether the KASAN KUnit test suite is currently being executed. * Updated in kasan_test.c. */ -bool kasan_kunit_executing; +static bool kasan_kunit_executing; void kasan_kunit_test_suite_start(void) { From d09dce1fff8a9da10144e878ef4bbf90c65559e5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Mon, 2 Jan 2023 13:16:14 -0800 Subject: [PATCH 128/398] lib/win_minmax: use /* notation for regular comments Don't use kernel-doc "/**" notation for non-kernel-doc comments. Prevents a kernel-doc warning: lib/win_minmax.c:31: warning: expecting prototype for lib/minmax.c(). Prototype was for minmax_subwin_update() instead Link: https://lkml.kernel.org/r/20230102211614.26343-1-rdunlap@infradead.org Signed-off-by: Randy Dunlap Cc: Neal Cardwell Cc: Eric Dumazet Cc: David S. Miller Signed-off-by: Andrew Morton --- lib/win_minmax.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/win_minmax.c b/lib/win_minmax.c index 6bdc1cd15f76..ec10506834b6 100644 --- a/lib/win_minmax.c +++ b/lib/win_minmax.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 -/** +/* * lib/minmax.c: windowed min/max tracker * * Kathleen Nichols' algorithm for tracking the minimum (or maximum) From 0411d6ee50e3b74a793848e4f41f45860163f5cc Mon Sep 17 00:00:00 2001 From: SeongJae Park Date: Fri, 6 Jan 2023 20:33:31 +0000 Subject: [PATCH 129/398] include/linux/mm: fix release_pages_arg kernel doc comment Commit 449c796768c9 ("mm: teach release_pages() to take an array of encoded page pointers too") added the kernel doc comment for release_pages() on top of 'union release_pages_arg', so making 'make htmldocs' complains as below: ./include/linux/mm.h:1268: warning: cannot understand function prototype: 'typedef union ' The kernel doc comment for the function is already on top of the function's definition in mm/swap.c, and the new comment is actually not for the function but indeed release_pages_arg. Fixing the comment to reflect the intent would be one option. But, kernel doc cannot parse the union as below due to the attribute. ./include/linux/mm.h:1272: error: Cannot parse struct or union! Modify the comment to reflect the intent but do not mark it as a kernel doc comment. Link: https://lkml.kernel.org/r/20230106203331.127532-1-sj@kernel.org Fixes: 449c796768c9 ("mm: teach release_pages() to take an array of encoded page pointers too") Signed-off-by: SeongJae Park Acked-by: Randy Dunlap Signed-off-by: Andrew Morton --- include/linux/mm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index f3f196e4d66d..8f857163ac89 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1270,10 +1270,10 @@ static inline void folio_put_refs(struct folio *folio, int refs) __folio_put(folio); } -/** - * release_pages - release an array of pages or folios +/* + * union release_pages_arg - an array of pages or folios * - * This just releases a simple array of multiple pages, and + * release_pages() releases a simple array of multiple pages, and * accepts various different forms of said page array: either * a regular old boring array of pages, an array of folios, or * an array of encoded page pointers. From 8651a137e62ebfde3df95cbb1ca055d013ec5b9e Mon Sep 17 00:00:00 2001 From: Lorenzo Stoakes Date: Sat, 7 Jan 2023 00:00:05 +0000 Subject: [PATCH 130/398] mm: update mmap_sem comments to refer to mmap_lock The rename from mm->mmap_sem to mm->mmap_lock was performed in commit da1c55f1b272 ("mmap locking API: rename mmap_sem to mmap_lock") and commit c1e8d7c6a7a6 ("map locking API: convert mmap_sem comments"), however some incorrect comments remain. This patch simply corrects those comments which are obviously incorrect within mm itself. Link: https://lkml.kernel.org/r/33fba04389ab63fc4980e7ba5442f521df6dc657.1673048927.git.lstoakes@gmail.com Signed-off-by: Lorenzo Stoakes Cc: David Hildenbrand Cc: Matthew Wilcox Cc: Mike Kravetz Cc: Muchun Song Cc: Vlastimil Babka Signed-off-by: Andrew Morton --- include/linux/mm_types.h | 2 +- include/linux/page_ref.h | 2 +- mm/hugetlb.c | 4 ++-- mm/madvise.c | 2 +- mm/mmap.c | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 3b8475007734..9757067c3053 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -581,7 +581,7 @@ struct vm_area_struct { /* * For private and shared anonymous mappings, a pointer to a null * terminated string containing the name given to the vma, or NULL if - * unnamed. Serialized by mmap_sem. Use anon_vma_name to access. + * unnamed. Serialized by mmap_lock. Use anon_vma_name to access. */ struct anon_vma_name *anon_name; #endif diff --git a/include/linux/page_ref.h b/include/linux/page_ref.h index 2e677e6ad09f..d7c2d33baa7f 100644 --- a/include/linux/page_ref.h +++ b/include/linux/page_ref.h @@ -301,7 +301,7 @@ static inline bool folio_ref_try_add_rcu(struct folio *folio, int count) * * You can also use this function if you're holding a lock that prevents * pages being frozen & removed; eg the i_pages lock for the page cache - * or the mmap_sem or page table lock for page tables. In this case, + * or the mmap_lock or page table lock for page tables. In this case, * it will always succeed, and you could have used a plain folio_get(), * but it's sometimes more convenient to have a common function called * from both locked and RCU-protected contexts. diff --git a/mm/hugetlb.c b/mm/hugetlb.c index f96794be71d5..7fcdb98c9e68 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1183,7 +1183,7 @@ void hugetlb_dup_vma_private(struct vm_area_struct *vma) /* * Reset and decrement one ref on hugepage private reservation. - * Called with mm->mmap_sem writer semaphore held. + * Called with mm->mmap_lock writer semaphore held. * This function should be only used by move_vma() and operate on * same sized vma. It should never come here with last ref on the * reservation. @@ -5152,7 +5152,7 @@ static void move_huge_pte(struct vm_area_struct *vma, unsigned long old_addr, /* * We don't have to worry about the ordering of src and dst ptlocks - * because exclusive mmap_sem (or the i_mmap_lock) prevents deadlock. + * because exclusive mmap_lock (or the i_mmap_lock) prevents deadlock. */ if (src_ptl != dst_ptl) spin_lock_nested(src_ptl, SINGLE_DEPTH_NESTING); diff --git a/mm/madvise.c b/mm/madvise.c index a56a6d17e201..b6ea204d4e23 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -130,7 +130,7 @@ static int replace_anon_vma_name(struct vm_area_struct *vma, #endif /* CONFIG_ANON_VMA_NAME */ /* * Update the vm_flags on region of a vma, splitting it or merging it as - * necessary. Must be called with mmap_sem held for writing; + * necessary. Must be called with mmap_lock held for writing; * Caller should ensure anon_name stability by raising its refcount even when * anon_name belongs to a valid vma because this function might free that vma. */ diff --git a/mm/mmap.c b/mm/mmap.c index 420476fcfbfc..425a9349e610 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2294,7 +2294,7 @@ static inline int munmap_sidetree(struct vm_area_struct *vma, * @start: The aligned start address to munmap. * @end: The aligned end address to munmap. * @uf: The userfaultfd list_head - * @downgrade: Set to true to attempt a write downgrade of the mmap_sem + * @downgrade: Set to true to attempt a write downgrade of the mmap_lock * * If @downgrade is true, check return code for potential release of the lock. */ @@ -2469,7 +2469,7 @@ map_count_exceeded: * @len: The length of the range to munmap * @uf: The userfaultfd list_head * @downgrade: set to true if the user wants to attempt to write_downgrade the - * mmap_sem + * mmap_lock * * This function takes a @mas that is either pointing to the previous VMA or set * to MA_START and sets it up to remove the mapping(s). The @len will be From 5316a017d093f644675a56523bcf5787ba8f4fef Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 6 Jan 2023 22:30:14 +0300 Subject: [PATCH 131/398] proc: fix PIE proc-empty-vm, proc-pid-vm tests vsyscall detection code uses direct call to the beginning of the vsyscall page: asm ("call %P0" :: "i" (0xffffffffff600000)) It generates "call rel32" instruction but it is not relocated if binary is PIE, so binary segfaults into random userspace address and vsyscall page status is detected incorrectly. Do more direct: asm ("call *%rax") which doesn't do need any relocaltions. Mark g_vsyscall as volatile for a good measure, I didn't find instruction setting it to 0. Now the code is obviously correct: xor eax, eax mov rdi, rbp mov rsi, rbp mov DWORD PTR [rip+0x2d15], eax # g_vsyscall = 0 mov rax, 0xffffffffff600000 call rax mov DWORD PTR [rip+0x2d02], 1 # g_vsyscall = 1 mov eax, DWORD PTR ds:0xffffffffff600000 mov DWORD PTR [rip+0x2cf1], 2 # g_vsyscall = 2 mov edi, [rip+0x2ceb] # exit(g_vsyscall) call exit Note: fixed proc-empty-vm test oopses 5.19.0-28-generic kernel but this is separate story. Link: https://lkml.kernel.org/r/Y7h2xvzKLg36DSq8@p183 Fixes: 5bc73bb3451b9 ("proc: test how it holds up with mapping'less process") Signed-off-by: Alexey Dobriyan Reported-by: Mirsad Goran Todorovac Tested-by: Mirsad Goran Todorovac Cc: Signed-off-by: Andrew Morton --- tools/testing/selftests/proc/proc-empty-vm.c | 12 +++++++----- tools/testing/selftests/proc/proc-pid-vm.c | 9 +++++---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/tools/testing/selftests/proc/proc-empty-vm.c b/tools/testing/selftests/proc/proc-empty-vm.c index d95b1cb43d9d..7588428b8fcd 100644 --- a/tools/testing/selftests/proc/proc-empty-vm.c +++ b/tools/testing/selftests/proc/proc-empty-vm.c @@ -25,6 +25,7 @@ #undef NDEBUG #include #include +#include #include #include #include @@ -41,7 +42,7 @@ * 1: vsyscall VMA is --xp vsyscall=xonly * 2: vsyscall VMA is r-xp vsyscall=emulate */ -static int g_vsyscall; +static volatile int g_vsyscall; static const char *g_proc_pid_maps_vsyscall; static const char *g_proc_pid_smaps_vsyscall; @@ -147,11 +148,12 @@ static void vsyscall(void) g_vsyscall = 0; /* gettimeofday(NULL, NULL); */ + uint64_t rax = 0xffffffffff600000; asm volatile ( - "call %P0" - : - : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL) - : "rax", "rcx", "r11" + "call *%[rax]" + : [rax] "+a" (rax) + : "D" (NULL), "S" (NULL) + : "rcx", "r11" ); g_vsyscall = 1; diff --git a/tools/testing/selftests/proc/proc-pid-vm.c b/tools/testing/selftests/proc/proc-pid-vm.c index 69551bfa215c..cacbd2a4aec9 100644 --- a/tools/testing/selftests/proc/proc-pid-vm.c +++ b/tools/testing/selftests/proc/proc-pid-vm.c @@ -257,11 +257,12 @@ static void vsyscall(void) g_vsyscall = 0; /* gettimeofday(NULL, NULL); */ + uint64_t rax = 0xffffffffff600000; asm volatile ( - "call %P0" - : - : "i" (0xffffffffff600000), "D" (NULL), "S" (NULL) - : "rax", "rcx", "r11" + "call *%[rax]" + : [rax] "+a" (rax) + : "D" (NULL), "S" (NULL) + : "rcx", "r11" ); g_vsyscall = 1; From bf61acbed8a8b38949a247333ee253899acdc35d Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Fri, 6 Jan 2023 16:21:51 +0100 Subject: [PATCH 132/398] MAINTAINERS: update Robert Foss' email address Update the email address for Robert's maintainer entries and fill in .mailmap accordingly. Link: https://lkml.kernel.org/r/20230106152151.115648-1-robert.foss@linaro.org Signed-off-by: Robert Foss Cc: Arnd Bergmann Cc: Baolin Wang Cc: Colin Ian King Cc: Kalle Valo Cc: Kirill Tkhai Cc: Qais Yousef Cc: Vasily Averin Signed-off-by: Andrew Morton --- .mailmap | 1 + MAINTAINERS | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.mailmap b/.mailmap index ccba4cf0d893..7a882bc7f376 100644 --- a/.mailmap +++ b/.mailmap @@ -371,6 +371,7 @@ Rémi Denis-Courmont Ricardo Ribalda Ricardo Ribalda Ricardo Ribalda Delgado Ricardo Ribalda +Robert Foss Roman Gushchin Roman Gushchin Roman Gushchin diff --git a/MAINTAINERS b/MAINTAINERS index a36df9ed283d..320dc090d57c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6948,7 +6948,7 @@ F: drivers/gpu/drm/atmel-hlcdc/ DRM DRIVERS FOR BRIDGE CHIPS M: Andrzej Hajda M: Neil Armstrong -M: Robert Foss +M: Robert Foss R: Laurent Pinchart R: Jonas Karlman R: Jernej Skrabec @@ -17237,7 +17237,7 @@ F: Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml F: drivers/net/wwan/qcom_bam_dmux.c QUALCOMM CAMERA SUBSYSTEM DRIVER -M: Robert Foss +M: Robert Foss M: Todor Tomov L: linux-media@vger.kernel.org S: Maintained @@ -17317,7 +17317,7 @@ F: drivers/dma/qcom/hidma* QUALCOMM I2C CCI DRIVER M: Loic Poulain -M: Robert Foss +M: Robert Foss L: linux-i2c@vger.kernel.org L: linux-arm-msm@vger.kernel.org S: Maintained From 7f31cced5724e6d414fe750aa1cd7e7b578ec22f Mon Sep 17 00:00:00 2001 From: Liam Howlett Date: Mon, 9 Jan 2023 20:55:21 +0000 Subject: [PATCH 133/398] nommu: fix memory leak in do_mmap() error path The preallocation of the maple tree nodes may leak if the error path to "error_just_free" is taken. Fix this by moving the freeing of the maple tree nodes to a shared location for all error paths. Link: https://lkml.kernel.org/r/20230109205507.955577-1-Liam.Howlett@oracle.com Fixes: 8220543df148 ("nommu: remove uses of VMA linked list") Signed-off-by: Liam R. Howlett Cc: Matthew Wilcox (Oracle) Cc: Vlastimil Babka Cc: Yu Zhao Cc: Signed-off-by: Andrew Morton --- mm/nommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/nommu.c b/mm/nommu.c index 214c70e1d059..c8252f01d5db 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1240,6 +1240,7 @@ share: error_just_free: up_write(&nommu_region_sem); error: + mas_destroy(&mas); if (region->vm_file) fput(region->vm_file); kmem_cache_free(vm_region_jar, region); @@ -1250,7 +1251,6 @@ error: sharing_violation: up_write(&nommu_region_sem); - mas_destroy(&mas); pr_warn("Attempt to share mismatched mappings\n"); ret = -EINVAL; goto error; From 80be727ec87225797771a39f3e6801baf291faaf Mon Sep 17 00:00:00 2001 From: Liam Howlett Date: Mon, 9 Jan 2023 20:57:21 +0000 Subject: [PATCH 134/398] nommu: fix do_munmap() error path When removing a VMA from the tree fails due to no memory, do not free the VMA since a reference still exists. Link: https://lkml.kernel.org/r/20230109205708.956103-1-Liam.Howlett@oracle.com Fixes: 8220543df148 ("nommu: remove uses of VMA linked list") Signed-off-by: Liam R. Howlett Cc: Matthew Wilcox (Oracle) Cc: Vlastimil Babka Cc: Yu Zhao Cc: Signed-off-by: Andrew Morton --- mm/nommu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/nommu.c b/mm/nommu.c index c8252f01d5db..844af5be7640 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1509,7 +1509,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len, struct list erase_whole_vma: if (delete_vma_from_mm(vma)) ret = -ENOMEM; - delete_vma(mm, vma); + else + delete_vma(mm, vma); return ret; } From fd9edbdbdcde6b489ce59f326755ef16a2ffadd7 Mon Sep 17 00:00:00 2001 From: Liam Howlett Date: Mon, 9 Jan 2023 20:58:20 +0000 Subject: [PATCH 135/398] nommu: fix split_vma() map_count error During the maple tree conversion of nommu, an error in counting the VMAs was introduced by counting the existing VMA again. The counting used to be decremented by one and incremented by two, but now it only increments by two. Fix the counting error by moving the increment outside the setup_vma_to_mm() function to the callers. Link: https://lkml.kernel.org/r/20230109205809.956325-1-Liam.Howlett@oracle.com Fixes: 8220543df148 ("nommu: remove uses of VMA linked list") Signed-off-by: Liam R. Howlett Cc: Matthew Wilcox (Oracle) Cc: Vlastimil Babka Cc: Yu Zhao Cc: Signed-off-by: Andrew Morton --- mm/nommu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mm/nommu.c b/mm/nommu.c index 844af5be7640..5b83938ecb67 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -559,7 +559,6 @@ void vma_mas_remove(struct vm_area_struct *vma, struct ma_state *mas) static void setup_vma_to_mm(struct vm_area_struct *vma, struct mm_struct *mm) { - mm->map_count++; vma->vm_mm = mm; /* add the VMA to the mapping */ @@ -587,6 +586,7 @@ static void mas_add_vma_to_mm(struct ma_state *mas, struct mm_struct *mm, BUG_ON(!vma->vm_region); setup_vma_to_mm(vma, mm); + mm->map_count++; /* add the VMA to the tree */ vma_mas_store(vma, mas); @@ -1347,6 +1347,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, if (vma->vm_file) return -ENOMEM; + mm = vma->vm_mm; if (mm->map_count >= sysctl_max_map_count) return -ENOMEM; @@ -1398,6 +1399,7 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, mas_set_range(&mas, vma->vm_start, vma->vm_end - 1); mas_store(&mas, vma); vma_mas_store(new, &mas); + mm->map_count++; return 0; err_mas_preallocate: From 19fa92fb72f8bc542f1673862058f3b078114004 Mon Sep 17 00:00:00 2001 From: Lizzy Fleckenstein Date: Mon, 9 Jan 2023 21:18:37 +0100 Subject: [PATCH 136/398] init/Kconfig: fix typo (usafe -> unsafe) Fix the help text for the PRINTK_SAFE_LOG_BUF_SHIFT setting. Link: https://lkml.kernel.org/r/20230109201837.23873-1-eliasfleckenstein@web.de Signed-off-by: Lizzy Fleckenstein Reviewed-by: Nick Desaulniers Cc: Masahiro Yamada Signed-off-by: Andrew Morton --- init/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/Kconfig b/init/Kconfig index 7e5c3ddc341d..57c8d224ea4c 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -776,7 +776,7 @@ config PRINTK_SAFE_LOG_BUF_SHIFT depends on PRINTK help Select the size of an alternate printk per-CPU buffer where messages - printed from usafe contexts are temporary stored. One example would + printed from unsafe contexts are temporary stored. One example would be NMI messages, another one - printk recursion. The messages are copied to the main log buffer in a safe context to avoid a deadlock. The value defines the size as a power of 2. From e6cf91b7b47ff82b624bdfe2fdcde32bb52e71dd Mon Sep 17 00:00:00 2001 From: Xingyuan Mo Date: Thu, 12 Jan 2023 00:24:53 +0800 Subject: [PATCH 137/398] NFSD: fix use-after-free in nfsd4_ssc_setup_dul() If signal_pending() returns true, schedule_timeout() will not be executed, causing the waiting task to remain in the wait queue. Fixed by adding a call to finish_wait(), which ensures that the waiting task will always be removed from the wait queue. Fixes: f4e44b393389 ("NFSD: delay unmount source's export after inter-server copy completed.") Signed-off-by: Xingyuan Mo Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever --- fs/nfsd/nfs4proc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 9b81d012666e..f189ba7995f5 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1318,6 +1318,7 @@ try_again: /* allow 20secs for mount/unmount for now - revisit */ if (signal_pending(current) || (schedule_timeout(20*HZ) == 0)) { + finish_wait(&nn->nfsd_ssc_waitq, &wait); kfree(work); return nfserr_eagain; } From f385f7d244134246f984975ed34cd75f77de479f Mon Sep 17 00:00:00 2001 From: Dai Ngo Date: Wed, 11 Jan 2023 12:17:09 -0800 Subject: [PATCH 138/398] NFSD: register/unregister of nfsd-client shrinker at nfsd startup/shutdown time Currently the nfsd-client shrinker is registered and unregistered at the time the nfsd module is loaded and unloaded. The problem with this is the shrinker is being registered before all of the relevant fields in nfsd_net are initialized when nfsd is started. This can lead to an oops when memory is low and the shrinker is called while nfsd is not running. This patch moves the register/unregister of nfsd-client shrinker from module load/unload time to nfsd startup/shutdown time. Fixes: 44df6f439a17 ("NFSD: add delegation reaper to react to low memory condition") Reported-by: Mike Galbraith Signed-off-by: Dai Ngo Signed-off-by: Chuck Lever --- fs/nfsd/nfs4state.c | 22 +++++++++++----------- fs/nfsd/nfsctl.c | 7 +------ fs/nfsd/nfsd.h | 6 ++---- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 313f666d5357..db41358bd0d3 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4421,7 +4421,7 @@ nfsd4_state_shrinker_scan(struct shrinker *shrink, struct shrink_control *sc) return SHRINK_STOP; } -int +void nfsd4_init_leases_net(struct nfsd_net *nn) { struct sysinfo si; @@ -4443,16 +4443,6 @@ nfsd4_init_leases_net(struct nfsd_net *nn) nn->nfs4_max_clients = max_t(int, max_clients, NFS4_CLIENTS_PER_GB); atomic_set(&nn->nfsd_courtesy_clients, 0); - nn->nfsd_client_shrinker.scan_objects = nfsd4_state_shrinker_scan; - nn->nfsd_client_shrinker.count_objects = nfsd4_state_shrinker_count; - nn->nfsd_client_shrinker.seeks = DEFAULT_SEEKS; - return register_shrinker(&nn->nfsd_client_shrinker, "nfsd-client"); -} - -void -nfsd4_leases_net_shutdown(struct nfsd_net *nn) -{ - unregister_shrinker(&nn->nfsd_client_shrinker); } static void init_nfs4_replay(struct nfs4_replay *rp) @@ -8069,8 +8059,17 @@ static int nfs4_state_create_net(struct net *net) INIT_DELAYED_WORK(&nn->nfsd_shrinker_work, nfsd4_state_shrinker_worker); get_net(net); + nn->nfsd_client_shrinker.scan_objects = nfsd4_state_shrinker_scan; + nn->nfsd_client_shrinker.count_objects = nfsd4_state_shrinker_count; + nn->nfsd_client_shrinker.seeks = DEFAULT_SEEKS; + + if (register_shrinker(&nn->nfsd_client_shrinker, "nfsd-client")) + goto err_shrinker; return 0; +err_shrinker: + put_net(net); + kfree(nn->sessionid_hashtbl); err_sessionid: kfree(nn->unconf_id_hashtbl); err_unconf_id: @@ -8163,6 +8162,7 @@ nfs4_state_shutdown_net(struct net *net) struct list_head *pos, *next, reaplist; struct nfsd_net *nn = net_generic(net, nfsd_net_id); + unregister_shrinker(&nn->nfsd_client_shrinker); cancel_delayed_work_sync(&nn->laundromat_work); locks_end_grace(&nn->nfsd4_manager); diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index d1e581a60480..c2577ee7ffb2 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1457,9 +1457,7 @@ static __net_init int nfsd_init_net(struct net *net) goto out_idmap_error; nn->nfsd_versions = NULL; nn->nfsd4_minorversions = NULL; - retval = nfsd4_init_leases_net(nn); - if (retval) - goto out_drc_error; + nfsd4_init_leases_net(nn); retval = nfsd_reply_cache_init(nn); if (retval) goto out_cache_error; @@ -1469,8 +1467,6 @@ static __net_init int nfsd_init_net(struct net *net) return 0; out_cache_error: - nfsd4_leases_net_shutdown(nn); -out_drc_error: nfsd_idmap_shutdown(net); out_idmap_error: nfsd_export_shutdown(net); @@ -1486,7 +1482,6 @@ static __net_exit void nfsd_exit_net(struct net *net) nfsd_idmap_shutdown(net); nfsd_export_shutdown(net); nfsd_netns_free_versions(net_generic(net, nfsd_net_id)); - nfsd4_leases_net_shutdown(nn); } static struct pernet_operations nfsd_net_ops = { diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index 93b42ef9ed91..fa0144a74267 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -504,8 +504,7 @@ extern void unregister_cld_notifier(void); extern void nfsd4_ssc_init_umount_work(struct nfsd_net *nn); #endif -extern int nfsd4_init_leases_net(struct nfsd_net *nn); -extern void nfsd4_leases_net_shutdown(struct nfsd_net *nn); +extern void nfsd4_init_leases_net(struct nfsd_net *nn); #else /* CONFIG_NFSD_V4 */ static inline int nfsd4_is_junction(struct dentry *dentry) @@ -513,8 +512,7 @@ static inline int nfsd4_is_junction(struct dentry *dentry) return 0; } -static inline int nfsd4_init_leases_net(struct nfsd_net *nn) { return 0; }; -static inline void nfsd4_leases_net_shutdown(struct nfsd_net *nn) {}; +static inline void nfsd4_init_leases_net(struct nfsd_net *nn) { }; #define register_cld_notifier() 0 #define unregister_cld_notifier() do { } while(0) From 9bfa2544dbd1133f0b0af4e967de3bb9c1e3a497 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Thu, 8 Dec 2022 13:52:41 +0200 Subject: [PATCH 139/398] ARM: dts: at91: sam9x60: fix the ddr clock for sam9x60 The 2nd DDR clock for sam9x60 DDR controller is peripheral clock with id 49. Fixes: 1e5f532c2737 ("ARM: dts: at91: sam9x60: add device tree for soc and board") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20221208115241.36312-1-claudiu.beznea@microchip.com --- arch/arm/boot/dts/sam9x60.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/sam9x60.dtsi b/arch/arm/boot/dts/sam9x60.dtsi index 8f5477e307dd..37a5d96aaf64 100644 --- a/arch/arm/boot/dts/sam9x60.dtsi +++ b/arch/arm/boot/dts/sam9x60.dtsi @@ -564,7 +564,7 @@ mpddrc: mpddrc@ffffe800 { compatible = "microchip,sam9x60-ddramc", "atmel,sama5d3-ddramc"; reg = <0xffffe800 0x200>; - clocks = <&pmc PMC_TYPE_SYSTEM 2>, <&pmc PMC_TYPE_CORE PMC_MCK>; + clocks = <&pmc PMC_TYPE_SYSTEM 2>, <&pmc PMC_TYPE_PERIPHERAL 49>; clock-names = "ddrck", "mpddr"; }; From 07a2975c65f2be2e22591d795a9c39b00f95fd11 Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Thu, 12 Jan 2023 10:12:43 +0100 Subject: [PATCH 140/398] drm/vc4: bo: Fix drmm_mutex_init memory hog Commit 374146cad469 ("drm/vc4: Switch to drmm_mutex_init") converted, among other functions, vc4_create_object() to use drmm_mutex_init(). However, that function is used to allocate a BO, and therefore the mutex needs to be freed much sooner than when the DRM device is removed from the system. For each buffer allocation we thus end up allocating a small structure as part of the DRM-managed mechanism that is never freed, eventually leading us to no longer having any free memory anymore. Let's switch back to mutex_init/mutex_destroy to deal with it properly. Fixes: 374146cad469 ("drm/vc4: Switch to drmm_mutex_init") Reviewed-by: Daniel Vetter Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20230112091243.490799-1-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_bo.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 43d9b3a6a352..29ce2fa72cc4 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -179,6 +179,7 @@ static void vc4_bo_destroy(struct vc4_bo *bo) bo->validated_shader = NULL; } + mutex_destroy(&bo->madv_lock); drm_gem_dma_free(&bo->base); } @@ -406,9 +407,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) bo->madv = VC4_MADV_WILLNEED; refcount_set(&bo->usecnt, 0); - ret = drmm_mutex_init(dev, &bo->madv_lock); - if (ret) - return ERR_PTR(ret); + mutex_init(&bo->madv_lock); mutex_lock(&vc4->bo_lock); bo->label = VC4_BO_TYPE_KERNEL; From 7c24fa225081f31bc6da6a355c1ba801889ab29a Mon Sep 17 00:00:00 2001 From: Dai Ngo Date: Wed, 11 Jan 2023 16:06:51 -0800 Subject: [PATCH 141/398] NFSD: replace delayed_work with work_struct for nfsd_client_shrinker Since nfsd4_state_shrinker_count always calls mod_delayed_work with 0 delay, we can replace delayed_work with work_struct to save some space and overhead. Also add the call to cancel_work after unregister the shrinker in nfs4_state_shutdown_net. Signed-off-by: Dai Ngo Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever --- fs/nfsd/netns.h | 2 +- fs/nfsd/nfs4state.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/nfsd/netns.h b/fs/nfsd/netns.h index 8c854ba3285b..51a4b7885cae 100644 --- a/fs/nfsd/netns.h +++ b/fs/nfsd/netns.h @@ -195,7 +195,7 @@ struct nfsd_net { atomic_t nfsd_courtesy_clients; struct shrinker nfsd_client_shrinker; - struct delayed_work nfsd_shrinker_work; + struct work_struct nfsd_shrinker_work; }; /* Simple check to find out if a given net was properly initialized */ diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index db41358bd0d3..f194d029c3d6 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -4411,7 +4411,7 @@ nfsd4_state_shrinker_count(struct shrinker *shrink, struct shrink_control *sc) if (!count) count = atomic_long_read(&num_delegations); if (count) - mod_delayed_work(laundry_wq, &nn->nfsd_shrinker_work, 0); + queue_work(laundry_wq, &nn->nfsd_shrinker_work); return (unsigned long)count; } @@ -6225,8 +6225,7 @@ deleg_reaper(struct nfsd_net *nn) static void nfsd4_state_shrinker_worker(struct work_struct *work) { - struct delayed_work *dwork = to_delayed_work(work); - struct nfsd_net *nn = container_of(dwork, struct nfsd_net, + struct nfsd_net *nn = container_of(work, struct nfsd_net, nfsd_shrinker_work); courtesy_client_reaper(nn); @@ -8056,7 +8055,7 @@ static int nfs4_state_create_net(struct net *net) INIT_LIST_HEAD(&nn->blocked_locks_lru); INIT_DELAYED_WORK(&nn->laundromat_work, laundromat_main); - INIT_DELAYED_WORK(&nn->nfsd_shrinker_work, nfsd4_state_shrinker_worker); + INIT_WORK(&nn->nfsd_shrinker_work, nfsd4_state_shrinker_worker); get_net(net); nn->nfsd_client_shrinker.scan_objects = nfsd4_state_shrinker_scan; @@ -8163,6 +8162,7 @@ nfs4_state_shutdown_net(struct net *net) struct nfsd_net *nn = net_generic(net, nfsd_net_id); unregister_shrinker(&nn->nfsd_client_shrinker); + cancel_work(&nn->nfsd_shrinker_work); cancel_delayed_work_sync(&nn->laundromat_work); locks_end_grace(&nn->nfsd4_manager); From 6d3d970b2735b967650d319be27268fedc5598d1 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 10 Jan 2023 14:56:34 +0000 Subject: [PATCH 142/398] btrfs: fix missing error handling when logging directory items When logging a directory, at log_dir_items(), if we get an error when attempting to search the subvolume tree for a dir index item, we end up returning 0 (success) from log_dir_items() because 'err' is left with a value of 0. This can lead to a few problems, specially in the case the variable 'last_offset' has a value of (u64)-1 (and it's initialized to that when it was declared): 1) By returning from log_dir_items() with success (0) and a value of (u64)-1 for '*last_offset_ret', we end up not logging any other dir index keys that follow the missing, just deleted, index key. The (u64)-1 value makes log_directory_changes() not call log_dir_items() again; 2) Before returning with success (0), log_dir_items(), will log a dir index range item covering a range from the last old dentry index (stored in the variable 'last_old_dentry_offset') to the value of 'last_offset'. If 'last_offset' has a value of (u64)-1, then it means if the log is persisted and replayed after a power failure, it will cause deletion of all the directory entries that have an index number between last_old_dentry_offset + 1 and (u64)-1; 3) We can end up returning from log_dir_items() with ctx->last_dir_item_offset having a lower value than inode->last_dir_index_offset, because the former is set to the current key we are processing at process_dir_items_leaf(), and at the end of log_directory_changes() we set inode->last_dir_index_offset to the current value of ctx->last_dir_item_offset. So if for example a deletion of a lower dir index key happened, we set ctx->last_dir_item_offset to that index value, then if we return from log_dir_items() because btrfs_search_slot() returned an error, we end up returning without any error from log_dir_items() and then log_directory_changes() sets inode->last_dir_index_offset to a lower value than it had before. This can result in unpredictable and unexpected behaviour when we need to log again the directory in the same transaction, and can result in ending up with a log tree leaf that has duplicated keys, as we do batch insertions of dir index keys into a log tree. Fix this by setting 'err' to the value of 'ret' in case btrfs_search_slot() or btrfs_previous_item() returned an error. That will result in falling back to a full transaction commit. Reported-by: David Arendt Link: https://lore.kernel.org/linux-btrfs/ae169fc6-f504-28f0-a098-6fa6a4dfb612@leemhuis.info/ Fixes: e02119d5a7b4 ("Btrfs: Add a write ahead tree log to optimize synchronous operations") CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Signed-off-by: David Sterba --- fs/btrfs/tree-log.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index fb52aa060093..3ef0266e9527 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -3826,7 +3826,10 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, path->slots[0]); if (tmp.type == BTRFS_DIR_INDEX_KEY) last_old_dentry_offset = tmp.offset; + } else if (ret < 0) { + err = ret; } + goto done; } @@ -3846,7 +3849,11 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, */ if (tmp.type == BTRFS_DIR_INDEX_KEY) last_old_dentry_offset = tmp.offset; + } else if (ret < 0) { + err = ret; + goto done; } + btrfs_release_path(path); /* @@ -3859,6 +3866,8 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, */ search: ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0); + if (ret < 0) + err = ret; if (ret != 0) goto done; From 8bb6898da6271d82d8e76d8088d66b971a7dcfa6 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 10 Jan 2023 14:56:35 +0000 Subject: [PATCH 143/398] btrfs: fix directory logging due to race with concurrent index key deletion Sometimes we log a directory without holding its VFS lock, so while we logging it, dir index entries may be added or removed. This typically happens when logging a dentry from a parent directory that points to a new directory, through log_new_dir_dentries(), or when while logging some other inode we also need to log its parent directories (through btrfs_log_all_parents()). This means that while we are at log_dir_items(), we may not find a dir index key we found before, because it was deleted in the meanwhile, so a call to btrfs_search_slot() may return 1 (key not found). In that case we return from log_dir_items() with a success value (the variable 'err' has a value of 0). This can lead to a few problems, specially in the case where the variable 'last_offset' has a value of (u64)-1 (and it's initialized to that when it was declared): 1) By returning from log_dir_items() with success (0) and a value of (u64)-1 for '*last_offset_ret', we end up not logging any other dir index keys that follow the missing, just deleted, index key. The (u64)-1 value makes log_directory_changes() not call log_dir_items() again; 2) Before returning with success (0), log_dir_items(), will log a dir index range item covering a range from the last old dentry index (stored in the variable 'last_old_dentry_offset') to the value of 'last_offset'. If 'last_offset' has a value of (u64)-1, then it means if the log is persisted and replayed after a power failure, it will cause deletion of all the directory entries that have an index number between last_old_dentry_offset + 1 and (u64)-1; 3) We can end up returning from log_dir_items() with ctx->last_dir_item_offset having a lower value than inode->last_dir_index_offset, because the former is set to the current key we are processing at process_dir_items_leaf(), and at the end of log_directory_changes() we set inode->last_dir_index_offset to the current value of ctx->last_dir_item_offset. So if for example a deletion of a lower dir index key happened, we set ctx->last_dir_item_offset to that index value, then if we return from log_dir_items() because btrfs_search_slot() returned 1, we end up returning from log_dir_items() with success (0) and then log_directory_changes() sets inode->last_dir_index_offset to a lower value than it had before. This can result in unpredictable and unexpected behaviour when we need to log again the directory in the same transaction, and can result in ending up with a log tree leaf that has duplicated keys, as we do batch insertions of dir index keys into a log tree. So fix this by making log_dir_items() move on to the next dir index key if it does not find the one it was looking for. Reported-by: David Arendt Link: https://lore.kernel.org/linux-btrfs/ae169fc6-f504-28f0-a098-6fa6a4dfb612@leemhuis.info/ CC: stable@vger.kernel.org # 4.14+ Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Signed-off-by: David Sterba --- fs/btrfs/tree-log.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 3ef0266e9527..c09daab3f19e 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -3857,17 +3857,26 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans, btrfs_release_path(path); /* - * Find the first key from this transaction again. See the note for - * log_new_dir_dentries, if we're logging a directory recursively we - * won't be holding its i_mutex, which means we can modify the directory - * while we're logging it. If we remove an entry between our first - * search and this search we'll not find the key again and can just - * bail. + * Find the first key from this transaction again or the one we were at + * in the loop below in case we had to reschedule. We may be logging the + * directory without holding its VFS lock, which happen when logging new + * dentries (through log_new_dir_dentries()) or in some cases when we + * need to log the parent directory of an inode. This means a dir index + * key might be deleted from the inode's root, and therefore we may not + * find it anymore. If we can't find it, just move to the next key. We + * can not bail out and ignore, because if we do that we will simply + * not log dir index keys that come after the one that was just deleted + * and we can end up logging a dir index range that ends at (u64)-1 + * (@last_offset is initialized to that), resulting in removing dir + * entries we should not remove at log replay time. */ search: ret = btrfs_search_slot(NULL, root, &min_key, path, 0, 0); + if (ret > 0) + ret = btrfs_next_item(root, path); if (ret < 0) err = ret; + /* If ret is 1, there are no more keys in the inode's root. */ if (ret != 0) goto done; From 94cd63ae679973edeb5ea95ec25a54467c3e54c8 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 10 Jan 2023 14:56:36 +0000 Subject: [PATCH 144/398] btrfs: add missing setup of log for full commit at add_conflicting_inode() When logging conflicting inodes, if we reach the maximum limit of inodes, we return BTRFS_LOG_FORCE_COMMIT to force a transaction commit. However we don't mark the log for full commit (with btrfs_set_log_full_commit()), which means that once we leave the log transaction and before we commit the transaction, some other task may sync the log, which is incomplete as we have not logged all conflicting inodes, leading to some inconsistent in case that log ends up being replayed. So also call btrfs_set_log_full_commit() at add_conflicting_inode(). Fixes: e09d94c9e448 ("btrfs: log conflicting inodes without holding log mutex of the initial inode") CC: stable@vger.kernel.org # 6.1 Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Signed-off-by: David Sterba --- fs/btrfs/tree-log.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index c09daab3f19e..afad44a0becf 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -5598,8 +5598,10 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans, * LOG_INODE_EXISTS mode) and slow down other fsyncs or transaction * commits. */ - if (ctx->num_conflict_inodes >= MAX_CONFLICT_INODES) + if (ctx->num_conflict_inodes >= MAX_CONFLICT_INODES) { + btrfs_set_log_full_commit(trans); return BTRFS_LOG_FORCE_COMMIT; + } inode = btrfs_iget(root->fs_info->sb, ino, root); /* From 16199ad9eb6db60a6b10794a09fc1ac6d09312ff Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 10 Jan 2023 14:56:37 +0000 Subject: [PATCH 145/398] btrfs: do not abort transaction on failure to write log tree when syncing log When syncing the log, if we fail to write log tree extent buffers, we mark the log for a full commit and abort the transaction. However we don't need to abort the transaction, all we really need to do is to make sure no one can commit a superblock pointing to new log tree roots. Just because we got a failure writing extent buffers for a log tree, it does not mean we will also fail to do a transaction commit. One particular case is if due to a bug somewhere, when writing log tree extent buffers, the tree checker detects some corruption and the writeout fails because of that. Aborting the transaction can be very disruptive for a user, specially if the issue happened on a root filesystem. One example is the scenario in the Link tag below, where an isolated corruption on log tree leaves was causing transaction aborts when syncing the log. Link: https://lore.kernel.org/linux-btrfs/ae169fc6-f504-28f0-a098-6fa6a4dfb612@leemhuis.info/ CC: stable@vger.kernel.org # 5.15+ Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Signed-off-by: David Sterba --- fs/btrfs/disk-io.c | 9 ++++++++- fs/btrfs/tree-log.c | 2 -- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8aeaada1fcae..3aa04224315e 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -367,7 +367,14 @@ error: btrfs_print_tree(eb, 0); btrfs_err(fs_info, "block=%llu write time tree block corruption detected", eb->start); - WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG)); + /* + * Be noisy if this is an extent buffer from a log tree. We don't abort + * a transaction in case there's a bad log tree extent buffer, we just + * fallback to a transaction commit. Still we want to know when there is + * a bad log tree extent buffer, as that may signal a bug somewhere. + */ + WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG) || + btrfs_header_owner(eb) == BTRFS_TREE_LOG_OBJECTID); return ret; } diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index afad44a0becf..1f70d4ebffae 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2980,7 +2980,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ret = 0; if (ret) { blk_finish_plug(&plug); - btrfs_abort_transaction(trans, ret); btrfs_set_log_full_commit(trans); mutex_unlock(&root->log_mutex); goto out; @@ -3112,7 +3111,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, goto out_wake_log_root; } else if (ret) { btrfs_set_log_full_commit(trans); - btrfs_abort_transaction(trans, ret); mutex_unlock(&log_root_tree->log_mutex); goto out_wake_log_root; } From 09e44868f1e03c7825ca4283256abedc95e249a3 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Tue, 10 Jan 2023 14:56:38 +0000 Subject: [PATCH 146/398] btrfs: do not abort transaction on failure to update log root When syncing a log, if we fail to update a log root in the log root tree, we are aborting the transaction if the failure was not -ENOSPC. This is excessive because there is a chance that a transaction commit can succeed, and therefore avoid to turn the filesystem into RO mode. All we need to be careful about is to mark the log for a full commit, which we already do, to make sure no one commits a super block pointing to an outdated log root tree. So don't abort the transaction if we fail to update a log root in the log root tree, and log an error if the failure is not -ENOSPC, so that it does not go completely unnoticed. CC: stable@vger.kernel.org # 6.0+ Reviewed-by: Josef Bacik Signed-off-by: Filipe Manana Signed-off-by: David Sterba --- fs/btrfs/tree-log.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 1f70d4ebffae..d43261545264 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -3044,15 +3044,12 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, blk_finish_plug(&plug); btrfs_set_log_full_commit(trans); - - if (ret != -ENOSPC) { - btrfs_abort_transaction(trans, ret); - mutex_unlock(&log_root_tree->log_mutex); - goto out; - } + if (ret != -ENOSPC) + btrfs_err(fs_info, + "failed to update log for root %llu ret %d", + root->root_key.objectid, ret); btrfs_wait_tree_log_extents(log, mark); mutex_unlock(&log_root_tree->log_mutex); - ret = BTRFS_LOG_FORCE_COMMIT; goto out; } From bb78654b0b46316dac687fd4b7dc7cce636f46cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duke=20Xin=28=E8=BE=9B=E5=AE=89=E6=96=87=29?= Date: Tue, 27 Dec 2022 01:28:25 -0800 Subject: [PATCH 147/398] USB: serial: option: add Quectel EM05-G (CS) modem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The EM05-G (CS) modem has 2 USB configurations that are configurable via the AT command AT+QCFG="usbnet",[ 0 | 2 ] which make the modem enumerate with the following interfaces, respectively: "RMNET" : AT + DIAG + NMEA + Modem + QMI "MBIM" : MBIM + AT + DIAG + NMEA + Modem The detailed description of the USB configuration for each mode as follows: RMNET Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 21 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=030C Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-G C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms MBIM Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 16 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=030C Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-G C:* #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Duke Xin(辛安文) Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index dee79c7d82d5..7eeca6c7b270 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -255,6 +255,7 @@ static void option_instat_callback(struct urb *urb); #define QUECTEL_PRODUCT_EP06 0x0306 #define QUECTEL_PRODUCT_EM05G 0x030a #define QUECTEL_PRODUCT_EM060K 0x030b +#define QUECTEL_PRODUCT_EM05G_CS 0x030c #define QUECTEL_PRODUCT_EM05G_SG 0x0311 #define QUECTEL_PRODUCT_EM12 0x0512 #define QUECTEL_PRODUCT_RM500Q 0x0800 @@ -1161,6 +1162,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff), .driver_info = RSVD(6) | ZLP }, + { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_CS, 0xff), + .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_SG, 0xff), .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) }, From 6c331f32e32ac71eb3e8b93fceda2802d7ecb889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duke=20Xin=28=E8=BE=9B=E5=AE=89=E6=96=87=29?= Date: Tue, 27 Dec 2022 01:44:30 -0800 Subject: [PATCH 148/398] USB: serial: option: add Quectel EM05-G (GR) modem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The EM05-G (GR) modem has 2 USB configurations that are configurable via the AT command AT+QCFG="usbnet",[ 0 | 2 ] which make the modem enumerate with the following interfaces, respectively: "RMNET" : AT + DIAG + NMEA + Modem + QMI "MBIM" : MBIM + AT + DIAG + NMEA + Modem The detailed description of the USB configuration for each mode as follows: RMNET Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 21 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0313 Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-G C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms MBIM Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 16 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0313 Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-G C:* #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Duke Xin(辛安文) Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 7eeca6c7b270..07ffff889ed1 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -257,6 +257,7 @@ static void option_instat_callback(struct urb *urb); #define QUECTEL_PRODUCT_EM060K 0x030b #define QUECTEL_PRODUCT_EM05G_CS 0x030c #define QUECTEL_PRODUCT_EM05G_SG 0x0311 +#define QUECTEL_PRODUCT_EM05G_GR 0x0313 #define QUECTEL_PRODUCT_EM12 0x0512 #define QUECTEL_PRODUCT_RM500Q 0x0800 #define QUECTEL_PRODUCT_RM520N 0x0801 @@ -1164,6 +1165,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_CS, 0xff), .driver_info = RSVD(6) | ZLP }, + { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_GR, 0xff), + .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_SG, 0xff), .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) }, From 17eee264ef386ef30a69dd70e36f29893b85c170 Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Fri, 25 Nov 2022 10:12:22 +0800 Subject: [PATCH 149/398] phy: usb: sunplus: Fix potential null-ptr-deref in sp_usb_phy_probe() sp_usb_phy_probe() will call platform_get_resource_byname() that may fail and return NULL. devm_ioremap() will use usbphy->moon4_res_mem->start as input, which may causes null-ptr-deref. Check the ret value of platform_get_resource_byname() to avoid the null-ptr-deref. Fixes: 99d9ccd97385 ("phy: usb: Add USB2.0 phy driver for Sunplus SP7021") Signed-off-by: Shang XiaoJing Link: https://lore.kernel.org/r/20221125021222.25687-1-shangxiaojing@huawei.com Signed-off-by: Vinod Koul --- drivers/phy/sunplus/phy-sunplus-usb2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/phy/sunplus/phy-sunplus-usb2.c b/drivers/phy/sunplus/phy-sunplus-usb2.c index e827b79f6d49..56de41091d63 100644 --- a/drivers/phy/sunplus/phy-sunplus-usb2.c +++ b/drivers/phy/sunplus/phy-sunplus-usb2.c @@ -254,6 +254,9 @@ static int sp_usb_phy_probe(struct platform_device *pdev) return PTR_ERR(usbphy->phy_regs); usbphy->moon4_res_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "moon4"); + if (!usbphy->moon4_res_mem) + return -EINVAL; + usbphy->moon4_regs = devm_ioremap(&pdev->dev, usbphy->moon4_res_mem->start, resource_size(usbphy->moon4_res_mem)); if (!usbphy->moon4_regs) From ec4a1d9301100c011312357ea25627b98eb293d5 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Mon, 26 Dec 2022 15:42:16 +0900 Subject: [PATCH 150/398] phy: renesas: r8a779f0-eth-serdes: Fix register setting Fix register setting which is typo in r8a779f0_eth_serdes_chan_setting(). Fixes: 742859441d44 ("phy: renesas: Add Renesas Ethernet SERDES driver for R-Car S4-8") Signed-off-by: Yoshihiro Shimoda Link: https://lore.kernel.org/r/20221226064216.3895421-1-yoshihiro.shimoda.uh@renesas.com Signed-off-by: Vinod Koul --- drivers/phy/renesas/r8a779f0-ether-serdes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/renesas/r8a779f0-ether-serdes.c b/drivers/phy/renesas/r8a779f0-ether-serdes.c index ec6594e6dc27..e7588a940d69 100644 --- a/drivers/phy/renesas/r8a779f0-ether-serdes.c +++ b/drivers/phy/renesas/r8a779f0-ether-serdes.c @@ -126,7 +126,7 @@ r8a779f0_eth_serdes_chan_setting(struct r8a779f0_eth_serdes_channel *channel) r8a779f0_eth_serdes_write32(channel->addr, 0x0160, 0x180, 0x0007); r8a779f0_eth_serdes_write32(channel->addr, 0x01ac, 0x180, 0x0000); r8a779f0_eth_serdes_write32(channel->addr, 0x00c4, 0x180, 0x0310); - r8a779f0_eth_serdes_write32(channel->addr, 0x00c8, 0x380, 0x0101); + r8a779f0_eth_serdes_write32(channel->addr, 0x00c8, 0x180, 0x0101); ret = r8a779f0_eth_serdes_reg_wait(channel, 0x00c8, 0x0180, BIT(0), 0); if (ret) return ret; From b0907cadabcae6f1248f37a32a6e777f9ff6d4aa Mon Sep 17 00:00:00 2001 From: Adrian Huang Date: Tue, 10 Jan 2023 09:45:12 +0800 Subject: [PATCH 151/398] md: fix incorrect declaration about claim_rdev in md_import_device Commit fb541ca4c365 ("md: remove lock_bdev / unlock_bdev") removes wrappers for blkdev_get/blkdev_put. However, the uninitialized local static variable of pointer type 'claim_rdev' in md_import_device() is NULL, which leads to the following warning call trace: WARNING: CPU: 22 PID: 1037 at block/bdev.c:577 bd_prepare_to_claim+0x131/0x150 CPU: 22 PID: 1037 Comm: mdadm Not tainted 6.2.0-rc3+ #69 .. RIP: 0010:bd_prepare_to_claim+0x131/0x150 .. Call Trace: ? _raw_spin_unlock+0x15/0x30 ? iput+0x6a/0x220 blkdev_get_by_dev.part.0+0x4b/0x300 md_import_device+0x126/0x1d0 new_dev_store+0x184/0x240 md_attr_store+0x80/0xf0 kernfs_fop_write_iter+0x128/0x1c0 vfs_write+0x2be/0x3c0 ksys_write+0x5f/0xe0 do_syscall_64+0x38/0x90 entry_SYSCALL_64_after_hwframe+0x72/0xdc It turns out the md device cannot be used: md: could not open device unknown-block(259,0). md: md127 stopped. Fix the issue by declaring the local static variable of struct type and passing the pointer of the variable to blkdev_get_by_dev(). Fixes: fb541ca4c365 ("md: remove lock_bdev / unlock_bdev") Cc: Christoph Hellwig Signed-off-by: Adrian Huang Reviewed-by: Christoph Hellwig Signed-off-by: Song Liu --- drivers/md/md.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/md/md.c b/drivers/md/md.c index 8af639296b3c..02b0240e7c71 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -3644,7 +3644,7 @@ EXPORT_SYMBOL_GPL(md_rdev_init); */ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int super_minor) { - static struct md_rdev *claim_rdev; /* just for claiming the bdev */ + static struct md_rdev claim_rdev; /* just for claiming the bdev */ struct md_rdev *rdev; sector_t size; int err; @@ -3662,7 +3662,7 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe rdev->bdev = blkdev_get_by_dev(newdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL, - super_format == -2 ? claim_rdev : rdev); + super_format == -2 ? &claim_rdev : rdev); if (IS_ERR(rdev->bdev)) { pr_warn("md: could not open device unknown-block(%u,%u).\n", MAJOR(newdev), MINOR(newdev)); From 9fdaca2c1e157dc0a3c0faecf3a6a68e7d8d0c7b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 11 Jan 2023 22:33:07 +0000 Subject: [PATCH 152/398] kselftest: Fix error message for unconfigured LLVM builds We are missing a ) when we attempt to complain about not having enough configuration for clang, resulting in the rather inscrutable error: ../lib.mk:23: *** unterminated call to function 'error': missing ')'. Stop. Add the required ) so we print the message we were trying to print. Signed-off-by: Mark Brown Signed-off-by: Shuah Khan --- tools/testing/selftests/lib.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index 291144c284fb..f7900e75d230 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk @@ -20,7 +20,7 @@ CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(ARCH)) ifeq ($(CROSS_COMPILE),) ifeq ($(CLANG_TARGET_FLAGS),) -$(error Specify CROSS_COMPILE or add '--target=' option to lib.mk +$(error Specify CROSS_COMPILE or add '--target=' option to lib.mk) else CLANG_FLAGS += --target=$(CLANG_TARGET_FLAGS) endif # CLANG_TARGET_FLAGS From 9f907439dc80e4a2fcfb949927b36c036468dbb3 Mon Sep 17 00:00:00 2001 From: Tonghao Zhang Date: Wed, 11 Jan 2023 17:29:01 +0800 Subject: [PATCH 153/398] bpf: hash map, avoid deadlock with suitable hash mask The deadlock still may occur while accessed in NMI and non-NMI context. Because in NMI, we still may access the same bucket but with different map_locked index. For example, on the same CPU, .max_entries = 2, we update the hash map, with key = 4, while running bpf prog in NMI nmi_handle(), to update hash map with key = 20, so it will have the same bucket index but have different map_locked index. To fix this issue, using min mask to hash again. Fixes: 20b6cc34ea74 ("bpf: Avoid hashtab deadlock with map_locked") Signed-off-by: Tonghao Zhang Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Andrii Nakryiko Cc: Martin KaFai Lau Cc: Song Liu Cc: Yonghong Song Cc: John Fastabend Cc: KP Singh Cc: Stanislav Fomichev Cc: Hao Luo Cc: Jiri Olsa Cc: Hou Tao Acked-by: Yonghong Song Acked-by: Hou Tao Link: https://lore.kernel.org/r/20230111092903.92389-1-tong@infragraf.org Signed-off-by: Martin KaFai Lau --- kernel/bpf/hashtab.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 5aa2b5525f79..66bded144377 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -152,7 +152,7 @@ static inline int htab_lock_bucket(const struct bpf_htab *htab, { unsigned long flags; - hash = hash & HASHTAB_MAP_LOCK_MASK; + hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1); preempt_disable(); if (unlikely(__this_cpu_inc_return(*(htab->map_locked[hash])) != 1)) { @@ -171,7 +171,7 @@ static inline void htab_unlock_bucket(const struct bpf_htab *htab, struct bucket *b, u32 hash, unsigned long flags) { - hash = hash & HASHTAB_MAP_LOCK_MASK; + hash = hash & min_t(u32, HASHTAB_MAP_LOCK_MASK, htab->n_buckets - 1); raw_spin_unlock_irqrestore(&b->raw_lock, flags); __this_cpu_dec(*(htab->map_locked[hash])); preempt_enable(); From 579923d84b04abb6cd4cd1fd9974096a2dd1832b Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Wed, 11 Jan 2023 22:58:51 +0530 Subject: [PATCH 154/398] amd-xgbe: TX Flow Ctrl Registers are h/w ver dependent There is difference in the TX Flow Control registers (TFCR) between the revisions of the hardware. The older revisions of hardware used to have single register per queue. Whereas, the newer revision of hardware (from ver 30H onwards) have one register per priority. Update the driver to use the TFCR based on the reported version of the hardware. Fixes: c5aa9e3b8156 ("amd-xgbe: Initial AMD 10GbE platform driver") Co-developed-by: Ajith Nayak Signed-off-by: Ajith Nayak Signed-off-by: Raju Rangoju Acked-by: Shyam Sundar S K Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c index 3936543a74d8..4030d619e84f 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c @@ -524,19 +524,28 @@ static void xgbe_disable_vxlan(struct xgbe_prv_data *pdata) netif_dbg(pdata, drv, pdata->netdev, "VXLAN acceleration disabled\n"); } +static unsigned int xgbe_get_fc_queue_count(struct xgbe_prv_data *pdata) +{ + unsigned int max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; + + /* From MAC ver 30H the TFCR is per priority, instead of per queue */ + if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) >= 0x30) + return max_q_count; + else + return min_t(unsigned int, pdata->tx_q_count, max_q_count); +} + static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata) { - unsigned int max_q_count, q_count; unsigned int reg, reg_val; - unsigned int i; + unsigned int i, q_count; /* Clear MTL flow control */ for (i = 0; i < pdata->rx_q_count; i++) XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0); /* Clear MAC flow control */ - max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; - q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count); + q_count = xgbe_get_fc_queue_count(pdata); reg = MAC_Q0TFCR; for (i = 0; i < q_count; i++) { reg_val = XGMAC_IOREAD(pdata, reg); @@ -553,9 +562,8 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata) { struct ieee_pfc *pfc = pdata->pfc; struct ieee_ets *ets = pdata->ets; - unsigned int max_q_count, q_count; unsigned int reg, reg_val; - unsigned int i; + unsigned int i, q_count; /* Set MTL flow control */ for (i = 0; i < pdata->rx_q_count; i++) { @@ -579,8 +587,7 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata) } /* Set MAC flow control */ - max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES; - q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count); + q_count = xgbe_get_fc_queue_count(pdata); reg = MAC_Q0TFCR; for (i = 0; i < q_count; i++) { reg_val = XGMAC_IOREAD(pdata, reg); From 926446ae24c03311a480fb96eb78f0ce7ea6d091 Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Wed, 11 Jan 2023 22:58:52 +0530 Subject: [PATCH 155/398] amd-xgbe: Delay AN timeout during KR training AN restart triggered during KR training not only aborts the KR training process but also move the HW to unstable state. Driver has to wait upto 500ms or until the KR training is completed before restarting AN cycle. Fixes: 7c12aa08779c ("amd-xgbe: Move the PHY support into amd-xgbe") Co-developed-by: Sudheesh Mavila Signed-off-by: Sudheesh Mavila Signed-off-by: Raju Rangoju Acked-by: Shyam Sundar S K Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 24 +++++++++++++++++++++++ drivers/net/ethernet/amd/xgbe/xgbe.h | 2 ++ 2 files changed, 26 insertions(+) diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c index 0c5c1b155683..43fdd111235a 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c @@ -496,6 +496,7 @@ static enum xgbe_an xgbe_an73_tx_training(struct xgbe_prv_data *pdata, reg |= XGBE_KR_TRAINING_ENABLE; reg |= XGBE_KR_TRAINING_START; XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg); + pdata->kr_start_time = jiffies; netif_dbg(pdata, link, pdata->netdev, "KR training initiated\n"); @@ -632,6 +633,8 @@ static enum xgbe_an xgbe_an73_incompat_link(struct xgbe_prv_data *pdata) xgbe_switch_mode(pdata); + pdata->an_result = XGBE_AN_READY; + xgbe_an_restart(pdata); return XGBE_AN_INCOMPAT_LINK; @@ -1275,9 +1278,30 @@ static bool xgbe_phy_aneg_done(struct xgbe_prv_data *pdata) static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata) { unsigned long link_timeout; + unsigned long kr_time; + int wait; link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * HZ); if (time_after(jiffies, link_timeout)) { + if ((xgbe_cur_mode(pdata) == XGBE_MODE_KR) && + pdata->phy.autoneg == AUTONEG_ENABLE) { + /* AN restart should not happen while KR training is in progress. + * The while loop ensures no AN restart during KR training, + * waits up to 500ms and AN restart is triggered only if KR + * training is failed. + */ + wait = XGBE_KR_TRAINING_WAIT_ITER; + while (wait--) { + kr_time = pdata->kr_start_time + + msecs_to_jiffies(XGBE_AN_MS_TIMEOUT); + if (time_after(jiffies, kr_time)) + break; + /* AN restart is not required, if AN result is COMPLETE */ + if (pdata->an_result == XGBE_AN_COMPLETE) + return; + usleep_range(10000, 11000); + } + } netif_dbg(pdata, link, pdata->netdev, "AN link timeout\n"); xgbe_phy_config_aneg(pdata); } diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 71f24cb47935..7a41367c437d 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -290,6 +290,7 @@ /* Auto-negotiation */ #define XGBE_AN_MS_TIMEOUT 500 #define XGBE_LINK_TIMEOUT 5 +#define XGBE_KR_TRAINING_WAIT_ITER 50 #define XGBE_SGMII_AN_LINK_STATUS BIT(1) #define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3)) @@ -1280,6 +1281,7 @@ struct xgbe_prv_data { unsigned int parallel_detect; unsigned int fec_ability; unsigned long an_start; + unsigned long kr_start_time; enum xgbe_an_mode an_mode; /* I2C support */ From 01644a1f98ff45a4044395ce2bbfd534747e0676 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 11 Jan 2023 18:07:15 +0000 Subject: [PATCH 156/398] rxrpc: Fix wrong error return in rxrpc_connect_call() Fix rxrpc_connect_call() to return -ENOMEM rather than 0 if it fails to look up a peer. This generated a smatch warning: net/rxrpc/call_object.c:303 rxrpc_connect_call() warn: missing error code 'ret' I think this also fixes a syzbot-found bug: rxrpc: Assertion failed - 1(0x1) == 11(0xb) is false ------------[ cut here ]------------ kernel BUG at net/rxrpc/call_object.c:645! where the call being put is in the wrong state - as would be the case if we failed to clear up correctly after the error in rxrpc_connect_call(). Fixes: 9d35d880e0e4 ("rxrpc: Move client call connection to the I/O thread") Reported-by: kernel test robot Reported-by: Dan Carpenter Reported-and-tested-by: syzbot+4bb6356bb29d6299360e@syzkaller.appspotmail.com Signed-off-by: David Howells Link: https://lore.kernel.org/r/202301111153.9eZRYLf1-lkp@intel.com/ Reviewed-by: Alexander Duyck Link: https://lore.kernel.org/r/2438405.1673460435@warthog.procyon.org.uk Signed-off-by: Jakub Kicinski --- net/rxrpc/call_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c index 3ded5a24627c..f3c9f0201c15 100644 --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c @@ -294,7 +294,7 @@ static void rxrpc_put_call_slot(struct rxrpc_call *call) static int rxrpc_connect_call(struct rxrpc_call *call, gfp_t gfp) { struct rxrpc_local *local = call->local; - int ret = 0; + int ret = -ENOMEM; _enter("{%d,%lx},", call->debug_id, call->user_call_ID); From ea22f4319c3409d847d70eaaf149cc480a73220d Mon Sep 17 00:00:00 2001 From: Sudheer Mogilappagari Date: Wed, 11 Jan 2023 15:56:07 -0800 Subject: [PATCH 157/398] ethtool: add netlink attr in rss get reply only if value is not null Current code for RSS_GET ethtool command includes netlink attributes in reply message to user space even if they are null. Added checks to include netlink attribute in reply message only if a value is received from driver. Drivers might return null for RSS indirection table or hash key. Instead of including attributes with empty value in the reply message, add netlink attribute only if there is content. Fixes: 7112a04664bf ("ethtool: add netlink based get rss support") Signed-off-by: Sudheer Mogilappagari Reviewed-by: Michal Kubecek Link: https://lore.kernel.org/r/20230111235607.85509-1-sudheer.mogilappagari@intel.com Signed-off-by: Jakub Kicinski --- net/ethtool/rss.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/ethtool/rss.c b/net/ethtool/rss.c index ebe6145aed3f..be260ab34e58 100644 --- a/net/ethtool/rss.c +++ b/net/ethtool/rss.c @@ -122,10 +122,13 @@ rss_fill_reply(struct sk_buff *skb, const struct ethnl_req_info *req_base, { const struct rss_reply_data *data = RSS_REPDATA(reply_base); - if (nla_put_u32(skb, ETHTOOL_A_RSS_HFUNC, data->hfunc) || - nla_put(skb, ETHTOOL_A_RSS_INDIR, - sizeof(u32) * data->indir_size, data->indir_table) || - nla_put(skb, ETHTOOL_A_RSS_HKEY, data->hkey_size, data->hkey)) + if ((data->hfunc && + nla_put_u32(skb, ETHTOOL_A_RSS_HFUNC, data->hfunc)) || + (data->indir_size && + nla_put(skb, ETHTOOL_A_RSS_INDIR, + sizeof(u32) * data->indir_size, data->indir_table)) || + (data->hkey_size && + nla_put(skb, ETHTOOL_A_RSS_HKEY, data->hkey_size, data->hkey))) return -EMSGSIZE; return 0; From aedee9e8d9224de35081e73e63333a402907c53c Mon Sep 17 00:00:00 2001 From: Peter Foley Date: Thu, 12 Jan 2023 23:23:59 -0500 Subject: [PATCH 158/398] kconfig: Update all declared targets Currently qconf-cfg.sh is the only script that touches the "-bin" target, even though all of the conf_cfg rules declare that they do. Make the recipe unconditionally touch all declared targets to avoid incompatibilities with upcoming versions of GNU make: https://lists.gnu.org/archive/html/info-gnu/2022-10/msg00008.html e.g. scripts/kconfig/Makefile:215: warning: pattern recipe did not update peer target 'scripts/kconfig/nconf-bin'. scripts/kconfig/Makefile:215: warning: pattern recipe did not update peer target 'scripts/kconfig/mconf-bin'. scripts/kconfig/Makefile:215: warning: pattern recipe did not update peer target 'scripts/kconfig/gconf-bin'. Signed-off-by: Peter Foley Signed-off-by: Masahiro Yamada --- scripts/kconfig/.gitignore | 2 +- scripts/kconfig/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore index c8a3f9cd52f0..0b2ff775b2e3 100644 --- a/scripts/kconfig/.gitignore +++ b/scripts/kconfig/.gitignore @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only /conf /[gmnq]conf +/[gmnq]conf-bin /[gmnq]conf-cflags /[gmnq]conf-libs -/qconf-bin /qconf-moc.cc diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 0b1d15efaeb0..af1c96198f49 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile @@ -209,7 +209,7 @@ $(obj)/gconf: | $(obj)/gconf-libs $(obj)/gconf.o: | $(obj)/gconf-cflags # check if necessary packages are available, and configure build flags -cmd_conf_cfg = $< $(addprefix $(obj)/$*conf-, cflags libs bin) +cmd_conf_cfg = $< $(addprefix $(obj)/$*conf-, cflags libs bin); touch $(obj)/$*conf-bin $(obj)/%conf-cflags $(obj)/%conf-libs $(obj)/%conf-bin: $(src)/%conf-cfg.sh $(call cmd,conf_cfg) From 1ed8a46256771de283772d482403691807214cf7 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 13 Jan 2023 23:08:04 +0900 Subject: [PATCH 159/398] tomoyo: Remove "select SRCU" Now that the SRCU Kconfig option is unconditionally selected, there is no longer any point in selecting it. Therefore, remove the "select SRCU" Kconfig statements. Signed-off-by: Paul E. McKenney Signed-off-by: Tetsuo Handa --- security/tomoyo/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig index 772d2ab58fd1..ee0c1f48025b 100644 --- a/security/tomoyo/Kconfig +++ b/security/tomoyo/Kconfig @@ -6,7 +6,6 @@ config SECURITY_TOMOYO select SECURITYFS select SECURITY_PATH select SECURITY_NETWORK - select SRCU default n help This selects TOMOYO Linux, pathname-based access control. From fa17087e244263627a01d6a9b76b8fdaf410de34 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa Date: Fri, 13 Jan 2023 23:11:38 +0900 Subject: [PATCH 160/398] tomoyo: Update website link SourceForge.JP was renamed to OSDN in May 2015. Signed-off-by: Tetsuo Handa --- security/tomoyo/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/tomoyo/Kconfig b/security/tomoyo/Kconfig index ee0c1f48025b..fad75be5f381 100644 --- a/security/tomoyo/Kconfig +++ b/security/tomoyo/Kconfig @@ -10,7 +10,7 @@ config SECURITY_TOMOYO help This selects TOMOYO Linux, pathname-based access control. Required userspace tools and further information may be - found at . + found at . If you are unsure how to answer this question, answer N. config SECURITY_TOMOYO_MAX_ACCEPT_ENTRY From e4f4db47794c9f474b184ee1418f42e6a07412b6 Mon Sep 17 00:00:00 2001 From: Luis Gerhorst Date: Mon, 9 Jan 2023 16:05:46 +0100 Subject: [PATCH 161/398] bpf: Fix pointer-leak due to insufficient speculative store bypass mitigation To mitigate Spectre v4, 2039f26f3aca ("bpf: Fix leakage due to insufficient speculative store bypass mitigation") inserts lfence instructions after 1) initializing a stack slot and 2) spilling a pointer to the stack. However, this does not cover cases where a stack slot is first initialized with a pointer (subject to sanitization) but then overwritten with a scalar (not subject to sanitization because the slot was already initialized). In this case, the second write may be subject to speculative store bypass (SSB) creating a speculative pointer-as-scalar type confusion. This allows the program to subsequently leak the numerical pointer value using, for example, a branch-based cache side channel. To fix this, also sanitize scalars if they write a stack slot that previously contained a pointer. Assuming that pointer-spills are only generated by LLVM on register-pressure, the performance impact on most real-world BPF programs should be small. The following unprivileged BPF bytecode drafts a minimal exploit and the mitigation: [...] // r6 = 0 or 1 (skalar, unknown user input) // r7 = accessible ptr for side channel // r10 = frame pointer (fp), to be leaked // r9 = r10 # fp alias to encourage ssb *(u64 *)(r9 - 8) = r10 // fp[-8] = ptr, to be leaked // lfence added here because of pointer spill to stack. // // Ommitted: Dummy bpf_ringbuf_output() here to train alias predictor // for no r9-r10 dependency. // *(u64 *)(r10 - 8) = r6 // fp[-8] = scalar, overwrites ptr // 2039f26f3aca: no lfence added because stack slot was not STACK_INVALID, // store may be subject to SSB // // fix: also add an lfence when the slot contained a ptr // r8 = *(u64 *)(r9 - 8) // r8 = architecturally a scalar, speculatively a ptr // // leak ptr using branch-based cache side channel: r8 &= 1 // choose bit to leak if r8 == 0 goto SLOW // no mispredict // architecturally dead code if input r6 is 0, // only executes speculatively iff ptr bit is 1 r8 = *(u64 *)(r7 + 0) # encode bit in cache (0: slow, 1: fast) SLOW: [...] After running this, the program can time the access to *(r7 + 0) to determine whether the chosen pointer bit was 0 or 1. Repeat this 64 times to recover the whole address on amd64. In summary, sanitization can only be skipped if one scalar is overwritten with another scalar. Scalar-confusion due to speculative store bypass can not lead to invalid accesses because the pointer bounds deducted during verification are enforced using branchless logic. See 979d63d50c0c ("bpf: prevent out of bounds speculation on pointer arithmetic") for details. Do not make the mitigation depend on !env->allow_{uninit_stack,ptr_leaks} because speculative leaks are likely unexpected if these were enabled. For example, leaking the address to a protected log file may be acceptable while disabling the mitigation might unintentionally leak the address into the cached-state of a map that is accessible to unprivileged processes. Fixes: 2039f26f3aca ("bpf: Fix leakage due to insufficient speculative store bypass mitigation") Signed-off-by: Luis Gerhorst Signed-off-by: Daniel Borkmann Acked-by: Henriette Hofmeier Link: https://lore.kernel.org/bpf/edc95bad-aada-9cfc-ffe2-fa9bb206583c@cs.fau.de Link: https://lore.kernel.org/bpf/20230109150544.41465-1-gerhorst@cs.fau.de --- kernel/bpf/verifier.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index c4c0985daac0..dbef0b0967ae 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -3295,7 +3295,9 @@ static int check_stack_write_fixed_off(struct bpf_verifier_env *env, bool sanitize = reg && is_spillable_regtype(reg->type); for (i = 0; i < size; i++) { - if (state->stack[spi].slot_type[i] == STACK_INVALID) { + u8 type = state->stack[spi].slot_type[i]; + + if (type != STACK_MISC && type != STACK_ZERO) { sanitize = true; break; } From 83a7f8e4899fb4cd77c787a3373f3e82b49a080f Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Fri, 13 Jan 2023 16:46:37 +0100 Subject: [PATCH 162/398] drm/vc4: bo: Fix unused variable warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 07a2975c65f2 ("drm/vc4: bo: Fix drmm_mutex_init memory hog") removed the only use of the ret variable, but didn't remove the variable itself leading to a unused variable warning. Remove that variable. Reported-by: Stephen Rothwell Fixes: 07a2975c65f2 ("drm/vc4: bo: Fix drmm_mutex_init memory hog") Reviewed-by: Maíra Canal Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20230113154637.1704116-1-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_bo.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 29ce2fa72cc4..c5947ed8cc81 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -395,7 +395,6 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) { struct vc4_dev *vc4 = to_vc4_dev(dev); struct vc4_bo *bo; - int ret; if (WARN_ON_ONCE(vc4->is_vc5)) return ERR_PTR(-ENODEV); From 5daba914da0e48950e9407ea4d75fa57029c9adc Mon Sep 17 00:00:00 2001 From: Shang XiaoJing Date: Mon, 5 Dec 2022 19:58:23 +0800 Subject: [PATCH 163/398] phy: rockchip-inno-usb2: Fix missing clk_disable_unprepare() in rockchip_usb2phy_power_on() The clk_disable_unprepare() should be called in the error handling of rockchip_usb2phy_power_on(). Fixes: 0e08d2a727e6 ("phy: rockchip-inno-usb2: add a new driver for Rockchip usb2phy") Signed-off-by: Shang XiaoJing Link: https://lore.kernel.org/r/20221205115823.16957-1-shangxiaojing@huawei.com Signed-off-by: Vinod Koul --- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index e6ededc51523..a0bc10aa7961 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -485,8 +485,10 @@ static int rockchip_usb2phy_power_on(struct phy *phy) return ret; ret = property_enable(base, &rport->port_cfg->phy_sus, false); - if (ret) + if (ret) { + clk_disable_unprepare(rphy->clk480m); return ret; + } /* waiting for the utmi_clk to become stable */ usleep_range(1500, 2000); From d60c471a8670635b65b3d67b6e7aaa263d191cc3 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Wed, 14 Dec 2022 23:37:32 +0100 Subject: [PATCH 164/398] phy: Revert "phy: qualcomm: usb28nm: Add MDM9607 init sequence" This reverts commit 557a28811c7e0286d3816842032db5eb7bb5f156. This commit introduced an init sequence from downstream DT [1] in the driver. As mentioned by the comment above the HSPHY_INIT_CFG macro for this sequence: /* * The macro is used to define an initialization sequence. Each tuple * is meant to program 'value' into phy register at 'offset' with 'delay' * in us followed. */ Instead of corresponding to offsets into the phy register, the sequence read by the downstream driver [2] is passed into ulpi_write [3] which crafts the address-value pair into a new value and writes it into the same register at USB_ULPI_VIEWPORT [4]. In other words, this init sequence is programmed into the hardware in a totally different way than downstream and is unlikely to achieve the desired result, if the hsphy is working at all. An alternative method needs to be found to write these init values at the desired location. Fortunately mdm9607 did not land upstream yet [5] and should have its compatible revised to use the generic one, instead of a compatible that writes wrong data to the wrong registers. [1]: https://android.googlesource.com/kernel/msm/+/android-7.1.0_r0.2/arch/arm/boot/dts/qcom/mdm9607.dtsi#585 [2]: https://android.googlesource.com/kernel/msm/+/android-7.1.0_r0.2/drivers/usb/phy/phy-msm-usb.c#4183 [3]: https://android.googlesource.com/kernel/msm/+/android-7.1.0_r0.2/drivers/usb/phy/phy-msm-usb.c#468 [4]: https://android.googlesource.com/kernel/msm/+/android-7.1.0_r0.2/drivers/usb/phy/phy-msm-usb.c#418 [5]: https://lore.kernel.org/linux-arm-msm/20210805222812.40731-1-konrad.dybcio@somainline.org/ Reported-by: Michael Srba Signed-off-by: Marijn Suijten Reviewed-by: Stephan Gerhold Reviewed-by: Bryan O'Donoghue Link: https://lore.kernel.org/r/20221214223733.648167-1-marijn.suijten@somainline.org Signed-off-by: Vinod Koul --- .../devicetree/bindings/phy/qcom,usb-hs-28nm.yaml | 1 - drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c | 13 ------------- 2 files changed, 14 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/qcom,usb-hs-28nm.yaml b/Documentation/devicetree/bindings/phy/qcom,usb-hs-28nm.yaml index abcc4373f39e..ca6a0836b53c 100644 --- a/Documentation/devicetree/bindings/phy/qcom,usb-hs-28nm.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,usb-hs-28nm.yaml @@ -16,7 +16,6 @@ properties: compatible: enum: - qcom,usb-hs-28nm-femtophy - - qcom,usb-hs-28nm-mdm9607 reg: maxItems: 1 diff --git a/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c b/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c index 8807e59a1162..a52a9bf13b75 100644 --- a/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c +++ b/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c @@ -401,26 +401,13 @@ static const struct hsphy_init_seq init_seq_femtophy[] = { HSPHY_INIT_CFG(0x90, 0x60, 0), }; -static const struct hsphy_init_seq init_seq_mdm9607[] = { - HSPHY_INIT_CFG(0x80, 0x44, 0), - HSPHY_INIT_CFG(0x81, 0x38, 0), - HSPHY_INIT_CFG(0x82, 0x24, 0), - HSPHY_INIT_CFG(0x83, 0x13, 0), -}; - static const struct hsphy_data hsphy_data_femtophy = { .init_seq = init_seq_femtophy, .init_seq_num = ARRAY_SIZE(init_seq_femtophy), }; -static const struct hsphy_data hsphy_data_mdm9607 = { - .init_seq = init_seq_mdm9607, - .init_seq_num = ARRAY_SIZE(init_seq_mdm9607), -}; - static const struct of_device_id qcom_snps_hsphy_match[] = { { .compatible = "qcom,usb-hs-28nm-femtophy", .data = &hsphy_data_femtophy, }, - { .compatible = "qcom,usb-hs-28nm-mdm9607", .data = &hsphy_data_mdm9607, }, { }, }; MODULE_DEVICE_TABLE(of, qcom_snps_hsphy_match); From b574baa64cf84e7793fe79f4491ae36c16e65a0b Mon Sep 17 00:00:00 2001 From: Richard Zhu Date: Mon, 19 Dec 2022 15:12:21 +0800 Subject: [PATCH 165/398] phy: freescale: imx8m-pcie: Add one missing error return There should be one error return when fail to fetch the perst reset. Add the missing error return. Fixes: dce9edff16ee ("phy: freescale: imx8m-pcie: Add i.MX8MP PCIe PHY support") Signed-off-by: Richard Zhu Reviewed-by: Marek Vasut Link: https://lore.kernel.org/r/1671433941-2037-1-git-send-email-hongxing.zhu@nxp.com Signed-off-by: Vinod Koul --- drivers/phy/freescale/phy-fsl-imx8m-pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c index 7585e8080b77..afc63552ecaf 100644 --- a/drivers/phy/freescale/phy-fsl-imx8m-pcie.c +++ b/drivers/phy/freescale/phy-fsl-imx8m-pcie.c @@ -255,7 +255,7 @@ static int imx8_pcie_phy_probe(struct platform_device *pdev) imx8_phy->perst = devm_reset_control_get_exclusive(dev, "perst"); if (IS_ERR(imx8_phy->perst)) - dev_err_probe(dev, PTR_ERR(imx8_phy->perst), + return dev_err_probe(dev, PTR_ERR(imx8_phy->perst), "Failed to get PCIE PHY PERST control\n"); } From 4bb4db7f3187c6e3de6b229ffc87cdb30a2d22b6 Mon Sep 17 00:00:00 2001 From: Jisoo Jang Date: Wed, 11 Jan 2023 22:19:14 +0900 Subject: [PATCH 166/398] net: nfc: Fix use-after-free in local_cleanup() Fix a use-after-free that occurs in kfree_skb() called from local_cleanup(). This could happen when killing nfc daemon (e.g. neard) after detaching an nfc device. When detaching an nfc device, local_cleanup() called from nfc_llcp_unregister_device() frees local->rx_pending and decreases local->ref by kref_put() in nfc_llcp_local_put(). In the terminating process, nfc daemon releases all sockets and it leads to decreasing local->ref. After the last release of local->ref, local_cleanup() called from local_release() frees local->rx_pending again, which leads to the bug. Setting local->rx_pending to NULL in local_cleanup() could prevent use-after-free when local_cleanup() is called twice. Found by a modified version of syzkaller. BUG: KASAN: use-after-free in kfree_skb() Call Trace: dump_stack_lvl (lib/dump_stack.c:106) print_address_description.constprop.0.cold (mm/kasan/report.c:306) kasan_check_range (mm/kasan/generic.c:189) kfree_skb (net/core/skbuff.c:955) local_cleanup (net/nfc/llcp_core.c:159) nfc_llcp_local_put.part.0 (net/nfc/llcp_core.c:172) nfc_llcp_local_put (net/nfc/llcp_core.c:181) llcp_sock_destruct (net/nfc/llcp_sock.c:959) __sk_destruct (net/core/sock.c:2133) sk_destruct (net/core/sock.c:2181) __sk_free (net/core/sock.c:2192) sk_free (net/core/sock.c:2203) llcp_sock_release (net/nfc/llcp_sock.c:646) __sock_release (net/socket.c:650) sock_close (net/socket.c:1365) __fput (fs/file_table.c:306) task_work_run (kernel/task_work.c:179) ptrace_notify (kernel/signal.c:2354) syscall_exit_to_user_mode_prepare (kernel/entry/common.c:278) syscall_exit_to_user_mode (kernel/entry/common.c:296) do_syscall_64 (arch/x86/entry/common.c:86) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:106) Allocated by task 4719: kasan_save_stack (mm/kasan/common.c:45) __kasan_slab_alloc (mm/kasan/common.c:325) slab_post_alloc_hook (mm/slab.h:766) kmem_cache_alloc_node (mm/slub.c:3497) __alloc_skb (net/core/skbuff.c:552) pn533_recv_response (drivers/nfc/pn533/usb.c:65) __usb_hcd_giveback_urb (drivers/usb/core/hcd.c:1671) usb_giveback_urb_bh (drivers/usb/core/hcd.c:1704) tasklet_action_common.isra.0 (kernel/softirq.c:797) __do_softirq (kernel/softirq.c:571) Freed by task 1901: kasan_save_stack (mm/kasan/common.c:45) kasan_set_track (mm/kasan/common.c:52) kasan_save_free_info (mm/kasan/genericdd.c:518) __kasan_slab_free (mm/kasan/common.c:236) kmem_cache_free (mm/slub.c:3809) kfree_skbmem (net/core/skbuff.c:874) kfree_skb (net/core/skbuff.c:931) local_cleanup (net/nfc/llcp_core.c:159) nfc_llcp_unregister_device (net/nfc/llcp_core.c:1617) nfc_unregister_device (net/nfc/core.c:1179) pn53x_unregister_nfc (drivers/nfc/pn533/pn533.c:2846) pn533_usb_disconnect (drivers/nfc/pn533/usb.c:579) usb_unbind_interface (drivers/usb/core/driver.c:458) device_release_driver_internal (drivers/base/dd.c:1279) bus_remove_device (drivers/base/bus.c:529) device_del (drivers/base/core.c:3665) usb_disable_device (drivers/usb/core/message.c:1420) usb_disconnect (drivers/usb/core.c:2261) hub_event (drivers/usb/core/hub.c:5833) process_one_work (arch/x86/include/asm/jump_label.h:27 include/linux/jump_label.h:212 include/trace/events/workqueue.h:108 kernel/workqueue.c:2281) worker_thread (include/linux/list.h:282 kernel/workqueue.c:2423) kthread (kernel/kthread.c:319) ret_from_fork (arch/x86/entry/entry_64.S:301) Fixes: 3536da06db0b ("NFC: llcp: Clean local timers and works when removing a device") Signed-off-by: Jisoo Jang Link: https://lore.kernel.org/r/20230111131914.3338838-1-jisoo.jang@yonsei.ac.kr Signed-off-by: Jakub Kicinski --- net/nfc/llcp_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c index 3364caabef8b..a27e1842b2a0 100644 --- a/net/nfc/llcp_core.c +++ b/net/nfc/llcp_core.c @@ -157,6 +157,7 @@ static void local_cleanup(struct nfc_llcp_local *local) cancel_work_sync(&local->rx_work); cancel_work_sync(&local->timeout_work); kfree_skb(local->rx_pending); + local->rx_pending = NULL; del_timer_sync(&local->sdreq_timer); cancel_work_sync(&local->sdreq_timeout_work); nfc_llcp_free_sdp_tlv_list(&local->pending_sdreqs); From 488e0bf7f34af3d42d1d5e56f7a5a7beaff188a3 Mon Sep 17 00:00:00 2001 From: Esina Ekaterina Date: Thu, 12 Jan 2023 10:47:03 +0300 Subject: [PATCH 167/398] net: wan: Add checks for NULL for utdm in undo_uhdlc_init and unmap_si_regs If uhdlc_priv_tsa != 1 then utdm is not initialized. And if ret != NULL then goto undo_uhdlc_init, where utdm is dereferenced. Same if dev == NULL. Found by Astra Linux on behalf of Linux Verification Center (linuxtesting.org) with SVACE. Fixes: 8d68100ab4ad ("soc/fsl/qe: fix err handling of ucc_of_parse_tdm") Signed-off-by: Esina Ekaterina Link: https://lore.kernel.org/r/20230112074703.13558-1-eesina@astralinux.ru Signed-off-by: Jakub Kicinski --- drivers/net/wan/fsl_ucc_hdlc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c index 22edea6ca4b8..1c53b5546927 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.c +++ b/drivers/net/wan/fsl_ucc_hdlc.c @@ -1243,9 +1243,11 @@ static int ucc_hdlc_probe(struct platform_device *pdev) free_dev: free_netdev(dev); undo_uhdlc_init: - iounmap(utdm->siram); + if (utdm) + iounmap(utdm->siram); unmap_si_regs: - iounmap(utdm->si_regs); + if (utdm) + iounmap(utdm->si_regs); free_utdm: if (uhdlc_priv->tsa) kfree(utdm); From 3c463721a73bdb57a913e0d3124677a3758886fc Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Thu, 12 Jan 2023 12:54:40 +0200 Subject: [PATCH 168/398] net: enetc: avoid deadlock in enetc_tx_onestep_tstamp() This lockdep splat says it better than I could: ================================ WARNING: inconsistent lock state 6.2.0-rc2-07010-ga9b9500ffaac-dirty #967 Not tainted -------------------------------- inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage. kworker/1:3/179 [HC0[0]:SC0[0]:HE1:SE1] takes: ffff3ec4036ce098 (_xmit_ETHER#2){+.?.}-{3:3}, at: netif_freeze_queues+0x5c/0xc0 {IN-SOFTIRQ-W} state was registered at: _raw_spin_lock+0x5c/0xc0 sch_direct_xmit+0x148/0x37c __dev_queue_xmit+0x528/0x111c ip6_finish_output2+0x5ec/0xb7c ip6_finish_output+0x240/0x3f0 ip6_output+0x78/0x360 ndisc_send_skb+0x33c/0x85c ndisc_send_rs+0x54/0x12c addrconf_rs_timer+0x154/0x260 call_timer_fn+0xb8/0x3a0 __run_timers.part.0+0x214/0x26c run_timer_softirq+0x3c/0x74 __do_softirq+0x14c/0x5d8 ____do_softirq+0x10/0x20 call_on_irq_stack+0x2c/0x5c do_softirq_own_stack+0x1c/0x30 __irq_exit_rcu+0x168/0x1a0 irq_exit_rcu+0x10/0x40 el1_interrupt+0x38/0x64 irq event stamp: 7825 hardirqs last enabled at (7825): [] exit_to_kernel_mode+0x34/0x130 hardirqs last disabled at (7823): [] __do_softirq+0x550/0x5d8 softirqs last enabled at (7824): [] __do_softirq+0x46c/0x5d8 softirqs last disabled at (7811): [] ____do_softirq+0x10/0x20 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(_xmit_ETHER#2); lock(_xmit_ETHER#2); *** DEADLOCK *** 3 locks held by kworker/1:3/179: #0: ffff3ec400004748 ((wq_completion)events){+.+.}-{0:0}, at: process_one_work+0x1f4/0x6c0 #1: ffff80000a0bbdc8 ((work_completion)(&priv->tx_onestep_tstamp)){+.+.}-{0:0}, at: process_one_work+0x1f4/0x6c0 #2: ffff3ec4036cd438 (&dev->tx_global_lock){+.+.}-{3:3}, at: netif_tx_lock+0x1c/0x34 Workqueue: events enetc_tx_onestep_tstamp Call trace: print_usage_bug.part.0+0x208/0x22c mark_lock+0x7f0/0x8b0 __lock_acquire+0x7c4/0x1ce0 lock_acquire.part.0+0xe0/0x220 lock_acquire+0x68/0x84 _raw_spin_lock+0x5c/0xc0 netif_freeze_queues+0x5c/0xc0 netif_tx_lock+0x24/0x34 enetc_tx_onestep_tstamp+0x20/0x100 process_one_work+0x28c/0x6c0 worker_thread+0x74/0x450 kthread+0x118/0x11c but I'll say it anyway: the enetc_tx_onestep_tstamp() work item runs in process context, therefore with softirqs enabled (i.o.w., it can be interrupted by a softirq). If we hold the netif_tx_lock() when there is an interrupt, and the NET_TX softirq then gets scheduled, this will take the netif_tx_lock() a second time and deadlock the kernel. To solve this, use netif_tx_lock_bh(), which blocks softirqs from running. Fixes: 7294380c5211 ("enetc: support PTP Sync packet one-step timestamping") Signed-off-by: Vladimir Oltean Reviewed-by: Alexander Duyck Link: https://lore.kernel.org/r/20230112105440.1786799-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/freescale/enetc/enetc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index 3a79ead5219a..e96449eedfb5 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -2290,14 +2290,14 @@ static void enetc_tx_onestep_tstamp(struct work_struct *work) priv = container_of(work, struct enetc_ndev_priv, tx_onestep_tstamp); - netif_tx_lock(priv->ndev); + netif_tx_lock_bh(priv->ndev); clear_bit_unlock(ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS, &priv->flags); skb = skb_dequeue(&priv->tx_skbs); if (skb) enetc_start_xmit(skb, priv->ndev); - netif_tx_unlock(priv->ndev); + netif_tx_unlock_bh(priv->ndev); } static void enetc_tx_onestep_tstamp_init(struct enetc_ndev_priv *priv) From 925f3deb45df73173a33e1e81db77575f4ffde39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20L=C3=A9ger?= Date: Thu, 12 Jan 2023 17:13:11 +0100 Subject: [PATCH 169/398] net: lan966x: add missing fwnode_handle_put() for ports node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the "ethernet-ports" node is retrieved using device_get_named_child_node(), it should be release after using it. Add missing fwnode_handle_put() and move the code that retrieved the node from device-tree to avoid complicated handling in case of error. Fixes: db8bcaad5393 ("net: lan966x: add the basic lan966x driver") Signed-off-by: Clément Léger Reviewed-by: Alexander Duyck Link: https://lore.kernel.org/r/20230112161311.495124-1-clement.leger@bootlin.com Signed-off-by: Jakub Kicinski --- .../net/ethernet/microchip/lan966x/lan966x_main.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c index cadde20505ba..580c91d24a52 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -1043,11 +1043,6 @@ static int lan966x_probe(struct platform_device *pdev) lan966x->base_mac[5] &= 0xf0; } - ports = device_get_named_child_node(&pdev->dev, "ethernet-ports"); - if (!ports) - return dev_err_probe(&pdev->dev, -ENODEV, - "no ethernet-ports child found\n"); - err = lan966x_create_targets(pdev, lan966x); if (err) return dev_err_probe(&pdev->dev, err, @@ -1125,6 +1120,11 @@ static int lan966x_probe(struct platform_device *pdev) } } + ports = device_get_named_child_node(&pdev->dev, "ethernet-ports"); + if (!ports) + return dev_err_probe(&pdev->dev, -ENODEV, + "no ethernet-ports child found\n"); + /* init switch */ lan966x_init(lan966x); lan966x_stats_init(lan966x); @@ -1162,6 +1162,8 @@ static int lan966x_probe(struct platform_device *pdev) goto cleanup_ports; } + fwnode_handle_put(ports); + lan966x_mdb_init(lan966x); err = lan966x_fdb_init(lan966x); if (err) @@ -1191,6 +1193,7 @@ cleanup_fdb: lan966x_fdb_deinit(lan966x); cleanup_ports: + fwnode_handle_put(ports); fwnode_handle_put(portnp); lan966x_cleanup_ports(lan966x); From 6bc1fe7dd748ba5e76e7917d110837cafe7b931c Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Thu, 12 Jan 2023 18:42:51 +0100 Subject: [PATCH 170/398] mptcp: explicitly specify sock family at subflow creation time Let the caller specify the to-be-created subflow family. For a given MPTCP socket created with the AF_INET6 family, the current userspace PM can already ask the kernel to create subflows in v4 and v6. If "plain" IPv4 addresses are passed to the kernel, they are automatically mapped in v6 addresses "by accident". This can be problematic because the userspace will need to pass different addresses, now the v4-mapped-v6 addresses to destroy this new subflow. On the other hand, if the MPTCP socket has been created with the AF_INET family, the command to create a subflow in v6 will be accepted but the result will not be the one as expected as new subflow will be created in IPv4 using part of the v6 addresses passed to the kernel: not creating the expected subflow then. No functional change intended for the in-kernel PM where an explicit enforcement is currently in place. This arbitrary enforcement will be leveraged by other patches in a future version. Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment") Cc: stable@vger.kernel.org Co-developed-by: Matthieu Baerts Signed-off-by: Matthieu Baerts Signed-off-by: Paolo Abeni Reviewed-by: Mat Martineau Signed-off-by: Matthieu Baerts Signed-off-by: Jakub Kicinski --- net/mptcp/protocol.c | 2 +- net/mptcp/protocol.h | 3 ++- net/mptcp/subflow.c | 9 +++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index b7ad030dfe89..8cd6cc67c2c5 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -98,7 +98,7 @@ static int __mptcp_socket_create(struct mptcp_sock *msk) struct socket *ssock; int err; - err = mptcp_subflow_create_socket(sk, &ssock); + err = mptcp_subflow_create_socket(sk, sk->sk_family, &ssock); if (err) return err; diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index a0d1658ce59e..a9e0355744b6 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -641,7 +641,8 @@ bool mptcp_addresses_equal(const struct mptcp_addr_info *a, /* called with sk socket lock held */ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, const struct mptcp_addr_info *remote); -int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock); +int mptcp_subflow_create_socket(struct sock *sk, unsigned short family, + struct socket **new_sock); void mptcp_info2sockaddr(const struct mptcp_addr_info *info, struct sockaddr_storage *addr, unsigned short family); diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index bd387d4b5a38..ec54413fb31f 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -1547,7 +1547,7 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc, if (!mptcp_is_fully_established(sk)) goto err_out; - err = mptcp_subflow_create_socket(sk, &sf); + err = mptcp_subflow_create_socket(sk, loc->family, &sf); if (err) goto err_out; @@ -1660,7 +1660,9 @@ static void mptcp_subflow_ops_undo_override(struct sock *ssk) #endif ssk->sk_prot = &tcp_prot; } -int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock) + +int mptcp_subflow_create_socket(struct sock *sk, unsigned short family, + struct socket **new_sock) { struct mptcp_subflow_context *subflow; struct net *net = sock_net(sk); @@ -1673,8 +1675,7 @@ int mptcp_subflow_create_socket(struct sock *sk, struct socket **new_sock) if (unlikely(!sk->sk_socket)) return -EINVAL; - err = sock_create_kern(net, sk->sk_family, SOCK_STREAM, IPPROTO_TCP, - &sf); + err = sock_create_kern(net, family, SOCK_STREAM, IPPROTO_TCP, &sf); if (err) return err; From fb00ee4f3343acb2b9222ca9b73b47dd1e1a8efc Mon Sep 17 00:00:00 2001 From: Matthieu Baerts Date: Thu, 12 Jan 2023 18:42:52 +0100 Subject: [PATCH 171/398] mptcp: netlink: respect v4/v6-only sockets If an MPTCP socket has been created with AF_INET6 and the IPV6_V6ONLY option has been set, the userspace PM would allow creating subflows using IPv4 addresses, e.g. mapped in v6. The kernel side of userspace PM will also accept creating subflows with local and remote addresses having different families. Depending on the subflow socket's family, different behaviours are expected: - If AF_INET is forced with a v6 address, the kernel will take the last byte of the IP and try to connect to that: a new subflow is created but to a non expected address. - If AF_INET6 is forced with a v4 address, the kernel will try to connect to a v4 address (v4-mapped-v6). A -EBADF error from the connect() part is then expected. It is then required to check the given families can be accepted. This is done by using a new helper for addresses family matching, taking care of IPv4 vs IPv4-mapped-IPv6 addresses. This helper will be re-used later by the in-kernel path-manager to use mixed IPv4 and IPv6 addresses. While at it, a clear error message is now reported if there are some conflicts with the families that have been passed by the userspace. Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment") Cc: stable@vger.kernel.org Reviewed-by: Mat Martineau Signed-off-by: Matthieu Baerts Signed-off-by: Jakub Kicinski --- net/mptcp/pm.c | 25 +++++++++++++++++++++++++ net/mptcp/pm_userspace.c | 7 +++++++ net/mptcp/protocol.h | 3 +++ 3 files changed, 35 insertions(+) diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 45e2a48397b9..70f0ced3ca86 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -420,6 +420,31 @@ void mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk) } } +/* if sk is ipv4 or ipv6_only allows only same-family local and remote addresses, + * otherwise allow any matching local/remote pair + */ +bool mptcp_pm_addr_families_match(const struct sock *sk, + const struct mptcp_addr_info *loc, + const struct mptcp_addr_info *rem) +{ + bool mptcp_is_v4 = sk->sk_family == AF_INET; + +#if IS_ENABLED(CONFIG_MPTCP_IPV6) + bool loc_is_v4 = loc->family == AF_INET || ipv6_addr_v4mapped(&loc->addr6); + bool rem_is_v4 = rem->family == AF_INET || ipv6_addr_v4mapped(&rem->addr6); + + if (mptcp_is_v4) + return loc_is_v4 && rem_is_v4; + + if (ipv6_only_sock(sk)) + return !loc_is_v4 && !rem_is_v4; + + return loc_is_v4 == rem_is_v4; +#else + return mptcp_is_v4 && loc->family == AF_INET && rem->family == AF_INET; +#endif +} + void mptcp_pm_data_reset(struct mptcp_sock *msk) { u8 pm_type = mptcp_get_pm_type(sock_net((struct sock *)msk)); diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index 65dcc55a8ad8..ea6ad9da7493 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -294,6 +294,13 @@ int mptcp_nl_cmd_sf_create(struct sk_buff *skb, struct genl_info *info) } sk = (struct sock *)msk; + + if (!mptcp_pm_addr_families_match(sk, &addr_l, &addr_r)) { + GENL_SET_ERR_MSG(info, "families mismatch"); + err = -EINVAL; + goto create_err; + } + lock_sock(sk); err = __mptcp_subflow_connect(sk, &addr_l, &addr_r); diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index a9e0355744b6..601469249da8 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -777,6 +777,9 @@ int mptcp_pm_parse_addr(struct nlattr *attr, struct genl_info *info, int mptcp_pm_parse_entry(struct nlattr *attr, struct genl_info *info, bool require_family, struct mptcp_pm_addr_entry *entry); +bool mptcp_pm_addr_families_match(const struct sock *sk, + const struct mptcp_addr_info *loc, + const struct mptcp_addr_info *rem); void mptcp_pm_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk); void mptcp_pm_nl_subflow_chk_stale(const struct mptcp_sock *msk, struct sock *ssk); void mptcp_pm_new_connection(struct mptcp_sock *msk, const struct sock *ssk, int server_side); From 4656d72c1efa495a58ad6d8b073a60907073e4e6 Mon Sep 17 00:00:00 2001 From: Matthieu Baerts Date: Thu, 12 Jan 2023 18:42:53 +0100 Subject: [PATCH 172/398] selftests: mptcp: userspace: validate v4-v6 subflows mix MPTCP protocol supports having subflows in both IPv4 and IPv6. In Linux, it is possible to have that if the MPTCP socket has been created with AF_INET6 family without the IPV6_V6ONLY option. Here, a new IPv4 subflow is being added to the initial IPv6 connection, then being removed using Netlink commands. Cc: stable@vger.kernel.org # v5.19+ Reviewed-by: Mat Martineau Signed-off-by: Matthieu Baerts Signed-off-by: Jakub Kicinski --- .../selftests/net/mptcp/userspace_pm.sh | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh index a29deb9fa024..ab2d581f28a1 100755 --- a/tools/testing/selftests/net/mptcp/userspace_pm.sh +++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh @@ -752,6 +752,52 @@ test_subflows() "$server4_token" > /dev/null 2>&1 } +test_subflows_v4_v6_mix() +{ + # Attempt to add a listener at 10.0.2.1: + ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.2.1\ + $app6_port > /dev/null 2>&1 & + local listener_pid=$! + + # ADD_ADDR4 from server to client machine reusing the subflow port on + # the established v6 connection + :>"$client_evts" + ip netns exec "$ns1" ./pm_nl_ctl ann 10.0.2.1 token "$server6_token" id\ + $server_addr_id dev ns1eth2 > /dev/null 2>&1 + stdbuf -o0 -e0 printf "ADD_ADDR4 id:%d 10.0.2.1 (ns1) => ns2, reuse port\t\t" $server_addr_id + sleep 0.5 + verify_announce_event "$client_evts" "$ANNOUNCED" "$client6_token" "10.0.2.1"\ + "$server_addr_id" "$app6_port" + + # CREATE_SUBFLOW from client to server machine + :>"$client_evts" + ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.2.2 lid 23 rip 10.0.2.1 rport\ + $app6_port token "$client6_token" > /dev/null 2>&1 + sleep 0.5 + verify_subflow_events "$client_evts" "$SUB_ESTABLISHED" "$client6_token"\ + "$AF_INET" "10.0.2.2" "10.0.2.1" "$app6_port" "23"\ + "$server_addr_id" "ns2" "ns1" + + # Delete the listener from the server ns, if one was created + kill_wait $listener_pid + + sport=$(sed --unbuffered -n 's/.*\(sport:\)\([[:digit:]]*\).*$/\2/p;q' "$client_evts") + + # DESTROY_SUBFLOW from client to server machine + :>"$client_evts" + ip netns exec "$ns2" ./pm_nl_ctl dsf lip 10.0.2.2 lport "$sport" rip 10.0.2.1 rport\ + $app6_port token "$client6_token" > /dev/null 2>&1 + sleep 0.5 + verify_subflow_events "$client_evts" "$SUB_CLOSED" "$client6_token" \ + "$AF_INET" "10.0.2.2" "10.0.2.1" "$app6_port" "23"\ + "$server_addr_id" "ns2" "ns1" + + # RM_ADDR from server to client machine + ip netns exec "$ns1" ./pm_nl_ctl rem id $server_addr_id token\ + "$server6_token" > /dev/null 2>&1 + sleep 0.5 +} + test_prio() { local count @@ -861,6 +907,7 @@ make_connection "v6" test_announce test_remove test_subflows +test_subflows_v4_v6_mix test_prio test_listener From a22b7388d658ecfcd226600c8c34ce4481e88655 Mon Sep 17 00:00:00 2001 From: Rahul Rameshbabu Date: Thu, 12 Jan 2023 16:55:29 -0800 Subject: [PATCH 173/398] sch_htb: Avoid grafting on htb_destroy_class_offload when destroying htb Peek at old qdisc and graft only when deleting a leaf class in the htb, rather than when deleting the htb itself. Do not peek at the qdisc of the netdev queue when destroying the htb. The caller may already have grafted a new qdisc that is not part of the htb structure being destroyed. This fix resolves two use cases. 1. Using tc to destroy the htb. - Netdev was being prematurely activated before the htb was fully destroyed. 2. Using tc to replace the htb with another qdisc (which also leads to the htb being destroyed). - Premature netdev activation like previous case. Newly grafted qdisc was also getting accidentally overwritten when destroying the htb. Fixes: d03b195b5aa0 ("sch_htb: Hierarchical QoS hardware offload") Signed-off-by: Rahul Rameshbabu Reviewed-by: Saeed Mahameed Reviewed-by: Maxim Mikityanskiy Reviewed-by: Jiri Pirko Link: https://lore.kernel.org/r/20230113005528.302625-1-rrameshbabu@nvidia.com Signed-off-by: Jakub Kicinski --- net/sched/sch_htb.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 2238edece1a4..f46643850df8 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1549,7 +1549,7 @@ static int htb_destroy_class_offload(struct Qdisc *sch, struct htb_class *cl, struct tc_htb_qopt_offload offload_opt; struct netdev_queue *dev_queue; struct Qdisc *q = cl->leaf.q; - struct Qdisc *old = NULL; + struct Qdisc *old; int err; if (cl->level) @@ -1557,14 +1557,17 @@ static int htb_destroy_class_offload(struct Qdisc *sch, struct htb_class *cl, WARN_ON(!q); dev_queue = htb_offload_get_queue(cl); - old = htb_graft_helper(dev_queue, NULL); - if (destroying) - /* Before HTB is destroyed, the kernel grafts noop_qdisc to - * all queues. + /* When destroying, caller qdisc_graft grafts the new qdisc and invokes + * qdisc_put for the qdisc being destroyed. htb_destroy_class_offload + * does not need to graft or qdisc_put the qdisc being destroyed. + */ + if (!destroying) { + old = htb_graft_helper(dev_queue, NULL); + /* Last qdisc grafted should be the same as cl->leaf.q when + * calling htb_delete. */ - WARN_ON(!(old->flags & TCQ_F_BUILTIN)); - else WARN_ON(old != q); + } if (cl->parent) { _bstats_update(&cl->parent->bstats_bias, @@ -1581,10 +1584,12 @@ static int htb_destroy_class_offload(struct Qdisc *sch, struct htb_class *cl, }; err = htb_offload(qdisc_dev(sch), &offload_opt); - if (!err || destroying) - qdisc_put(old); - else - htb_graft_helper(dev_queue, old); + if (!destroying) { + if (!err) + qdisc_put(old); + else + htb_graft_helper(dev_queue, old); + } if (last_child) return err; From a608da3bd730d718f2d3ebec1c26f9865f8f17ce Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Fri, 6 Jan 2023 17:43:06 +0900 Subject: [PATCH 174/398] zonefs: Detect append writes at invalid locations Using REQ_OP_ZONE_APPEND operations for synchronous writes to sequential files succeeds regardless of the zone write pointer position, as long as the target zone is not full. This means that if an external (buggy) application writes to the zone of a sequential file underneath the file system, subsequent file write() operation will succeed but the file size will not be correct and the file will contain invalid data written by another application. Modify zonefs_file_dio_append() to check the written sector of an append write (returned in bio->bi_iter.bi_sector) and return -EIO if there is a mismatch with the file zone wp offset field. This change triggers a call to zonefs_io_error() and a zone check. Modify zonefs_io_error_cb() to not expose the unexpected data after the current inode size when the errors=remount-ro mode is used. Other error modes are correctly handled already. Fixes: 02ef12a663c7 ("zonefs: use REQ_OP_ZONE_APPEND for sync DIO") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal Reviewed-by: Johannes Thumshirn --- fs/zonefs/super.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index 2c53fbb8d918..a9c5c3f720ad 100644 --- a/fs/zonefs/super.c +++ b/fs/zonefs/super.c @@ -442,6 +442,10 @@ static int zonefs_io_error_cb(struct blk_zone *zone, unsigned int idx, data_size = zonefs_check_zone_condition(inode, zone, false, false); } + } else if (sbi->s_mount_opts & ZONEFS_MNTOPT_ERRORS_RO && + data_size > isize) { + /* Do not expose garbage data */ + data_size = isize; } /* @@ -805,6 +809,24 @@ static ssize_t zonefs_file_dio_append(struct kiocb *iocb, struct iov_iter *from) ret = submit_bio_wait(bio); + /* + * If the file zone was written underneath the file system, the zone + * write pointer may not be where we expect it to be, but the zone + * append write can still succeed. So check manually that we wrote where + * we intended to, that is, at zi->i_wpoffset. + */ + if (!ret) { + sector_t wpsector = + zi->i_zsector + (zi->i_wpoffset >> SECTOR_SHIFT); + + if (bio->bi_iter.bi_sector != wpsector) { + zonefs_warn(inode->i_sb, + "Corrupted write pointer %llu for zone at %llu\n", + wpsector, zi->i_zsector); + ret = -EIO; + } + } + zonefs_file_write_dio_end_io(iocb, size, ret, 0); trace_zonefs_file_dio_append(inode, size, ret); From 216f764716f34fe68cedc7296ae2043a7727e640 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Tue, 3 Jan 2023 16:47:55 +0800 Subject: [PATCH 175/398] block, bfq: switch 'bfqg->ref' to use atomic refcount apis The updating of 'bfqg->ref' should be protected by 'bfqd->lock', however, during code review, we found that bfq_pd_free() update 'bfqg->ref' without holding the lock, which is problematic: 1) bfq_pd_free() triggered by removing cgroup is called asynchronously; 2) bfqq will grab bfqg reference, and exit bfqq will drop the reference, which can concurrent with 1). Unfortunately, 'bfqd->lock' can't be held here because 'bfqd' might already be freed in bfq_pd_free(). Fix the problem by using atomic refcount apis. Signed-off-by: Yu Kuai Reviewed-by: Jan Kara Link: https://lore.kernel.org/r/20230103084755.1256479-1-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe --- block/bfq-cgroup.c | 8 +++----- block/bfq-iosched.h | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c index 1b2829e99dad..7d9b15f0dbd5 100644 --- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -316,14 +316,12 @@ struct bfq_group *bfqq_group(struct bfq_queue *bfqq) static void bfqg_get(struct bfq_group *bfqg) { - bfqg->ref++; + refcount_inc(&bfqg->ref); } static void bfqg_put(struct bfq_group *bfqg) { - bfqg->ref--; - - if (bfqg->ref == 0) + if (refcount_dec_and_test(&bfqg->ref)) kfree(bfqg); } @@ -530,7 +528,7 @@ static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, struct request_queue *q, } /* see comments in bfq_bic_update_cgroup for why refcounting */ - bfqg_get(bfqg); + refcount_set(&bfqg->ref, 1); return &bfqg->pd; } diff --git a/block/bfq-iosched.h b/block/bfq-iosched.h index 41aa151ccc22..466e4865ace6 100644 --- a/block/bfq-iosched.h +++ b/block/bfq-iosched.h @@ -928,7 +928,7 @@ struct bfq_group { char blkg_path[128]; /* reference counter (see comments in bfq_bic_update_cgroup) */ - int ref; + refcount_t ref; /* Is bfq_group still online? */ bool online; From b72d13977689f0c717444010e108c4f20658dfee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duke=20Xin=28=E8=BE=9B=E5=AE=89=E6=96=87=29?= Date: Tue, 27 Dec 2022 01:51:27 -0800 Subject: [PATCH 176/398] USB: serial: option: add Quectel EM05-G (RS) modem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The EM05-G (RS) modem has 2 USB configurations that are configurable via the AT command AT+QCFG="usbnet",[ 0 | 2 ] which make the modem enumerate with the following interfaces, respectively: "RMNET" : AT + DIAG + NMEA + Modem + QMI "MBIM" : MBIM + AT + DIAG + NMEA + Modem The detailed description of the USB configuration for each mode as follows: RMNET Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 21 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0314 Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-G C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms MBIM Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 16 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0314 Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-G C:* #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Duke Xin(辛安文) Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 07ffff889ed1..58df076b6944 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -258,6 +258,7 @@ static void option_instat_callback(struct urb *urb); #define QUECTEL_PRODUCT_EM05G_CS 0x030c #define QUECTEL_PRODUCT_EM05G_SG 0x0311 #define QUECTEL_PRODUCT_EM05G_GR 0x0313 +#define QUECTEL_PRODUCT_EM05G_RS 0x0314 #define QUECTEL_PRODUCT_EM12 0x0512 #define QUECTEL_PRODUCT_RM500Q 0x0800 #define QUECTEL_PRODUCT_RM520N 0x0801 @@ -1167,6 +1168,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_GR, 0xff), .driver_info = RSVD(6) | ZLP }, + { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_RS, 0xff), + .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_SG, 0xff), .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) }, From d9bbb15881046bd76f8710c76e26a740eee997ef Mon Sep 17 00:00:00 2001 From: Ali Mirghasemi Date: Wed, 28 Dec 2022 15:08:47 +0330 Subject: [PATCH 177/398] USB: serial: option: add Quectel EC200U modem Add support for EC200U modem 0x0901: EC200U - AT + AP + CP + NMEA + DIAG + MOS usb-device output: T: Bus=01 Lev=02 Prnt=02 Port=02 Cnt=01 Dev#= 4 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0901 Rev= 3.18 S: Manufacturer=Android S: Product=Android C:* #Ifs= 9 Cfg#= 1 Atr=e0 MxPwr=400mA A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=06 Prot=00 I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=06 Prot=00 Driver=cdc_ether E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 512 Ivl=4096ms I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 7 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=8a(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=03(Int.) MxPS= 512 Ivl=4096ms I:* If#= 8 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=08(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Ali Mirghasemi Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 58df076b6944..f00eaff4c913 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -262,6 +262,7 @@ static void option_instat_callback(struct urb *urb); #define QUECTEL_PRODUCT_EM12 0x0512 #define QUECTEL_PRODUCT_RM500Q 0x0800 #define QUECTEL_PRODUCT_RM520N 0x0801 +#define QUECTEL_PRODUCT_EC200U 0x0901 #define QUECTEL_PRODUCT_EC200S_CN 0x6002 #define QUECTEL_PRODUCT_EC200T 0x6026 #define QUECTEL_PRODUCT_RM500K 0x7001 @@ -1189,6 +1190,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500K, 0xff, 0x00, 0x00) }, From 3f9e76e31704a325170e5aec2243c8d084d74854 Mon Sep 17 00:00:00 2001 From: Michael Adler Date: Tue, 3 Jan 2023 14:48:50 +0100 Subject: [PATCH 178/398] USB: serial: cp210x: add SCALANCE LPE-9000 device id Add the USB serial console device ID for Siemens SCALANCE LPE-9000 which have a USB port for their serial console. Signed-off-by: Michael Adler Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 67372acc2352..832ad592b7ef 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -60,6 +60,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x0846, 0x1100) }, /* NetGear Managed Switch M4100 series, M5300 series, M7100 series */ { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */ + { USB_DEVICE(0x0908, 0x0070) }, /* Siemens SCALANCE LPE-9000 USB Serial Console */ { USB_DEVICE(0x0908, 0x01FF) }, /* Siemens RUGGEDCOM USB Serial Console */ { USB_DEVICE(0x0988, 0x0578) }, /* Teraoka AD2000 */ { USB_DEVICE(0x0B00, 0x3070) }, /* Ingenico 3070 */ From 1541dd0097c0f8f470e76eddf5120fc55a7e3101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duke=20Xin=28=E8=BE=9B=E5=AE=89=E6=96=87=29?= Date: Sun, 15 Jan 2023 18:07:27 -0800 Subject: [PATCH 179/398] USB: serial: option: add Quectel EM05CN (SG) modem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The EM05CN (SG) modem has 2 USB configurations that are configurable via the AT command AT+QCFG="usbnet",[ 0 | 2 ] which make the modem enumerate with the following interfaces, respectively: "MBIM" : AT + MBIM + DIAG + NMEA + MODEM "RMNET" : AT + DIAG + NMEA + Modem + QMI The detailed description of the USB configuration for each mode as follows: MBIM Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0310 Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-CN C:* #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA A: FirstIf#= 1 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 2 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I:* If#= 2 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms RMNET Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0310 Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-CN C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Duke Xin(辛安文) Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f00eaff4c913..2b1d5472f578 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -256,6 +256,7 @@ static void option_instat_callback(struct urb *urb); #define QUECTEL_PRODUCT_EM05G 0x030a #define QUECTEL_PRODUCT_EM060K 0x030b #define QUECTEL_PRODUCT_EM05G_CS 0x030c +#define QUECTEL_PRODUCT_EM05CN_SG 0x0310 #define QUECTEL_PRODUCT_EM05G_SG 0x0311 #define QUECTEL_PRODUCT_EM05G_GR 0x0313 #define QUECTEL_PRODUCT_EM05G_RS 0x0314 @@ -1163,6 +1164,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, + { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05CN_SG, 0xff), + .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff), .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G_CS, 0xff), From 71dfd381a7c051f16a61f82fbd38a4cca563bdca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Duke=20Xin=28=E8=BE=9B=E5=AE=89=E6=96=87=29?= Date: Sun, 15 Jan 2023 18:33:28 -0800 Subject: [PATCH 180/398] USB: serial: option: add Quectel EM05CN modem MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The EM05CN modem has 2 USB configurations that are configurable via the AT command AT+QCFG="usbnet",[ 0 | 2 ] which make the modem enumerate with the following interfaces, respectively: "MBIM" : AT + MBIM + DIAG + NMEA + MODEM "RMNET" : AT + DIAG + NMEA + Modem + QMI The detailed description of the USB configuration for each mode as follows: MBIM Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0312 Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-CN C:* #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA A: FirstIf#= 1 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 2 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I:* If#= 2 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms RMNET Mode -------------- T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0312 Rev= 3.18 S: Manufacturer=Quectel S: Product=Quectel EM05-CN C:* #Ifs= 5 Cfg#= 1 Atr=a0 MxPwr=500mA I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 6 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=89(I) Atr=03(Int.) MxPS= 8 Ivl=32ms E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Duke Xin(辛安文) Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 2b1d5472f578..ee5ac4ef7e16 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -258,6 +258,7 @@ static void option_instat_callback(struct urb *urb); #define QUECTEL_PRODUCT_EM05G_CS 0x030c #define QUECTEL_PRODUCT_EM05CN_SG 0x0310 #define QUECTEL_PRODUCT_EM05G_SG 0x0311 +#define QUECTEL_PRODUCT_EM05CN 0x0312 #define QUECTEL_PRODUCT_EM05G_GR 0x0313 #define QUECTEL_PRODUCT_EM05G_RS 0x0314 #define QUECTEL_PRODUCT_EM12 0x0512 @@ -1164,6 +1165,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff), .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) }, + { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05CN, 0xff), + .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05CN_SG, 0xff), .driver_info = RSVD(6) | ZLP }, { USB_DEVICE_INTERFACE_CLASS(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM05G, 0xff), From e5464277625c1aca5c002e0f470377cdd6816dcf Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 16 Jan 2023 10:49:56 +0100 Subject: [PATCH 181/398] gpio: mxc: Protect GPIO irqchip RMW with bgpio spinlock The driver currently performs register read-modify-write without locking in its irqchip part, this could lead to a race condition when configuring interrupt mode setting. Add the missing bgpio spinlock lock/unlock around the register read-modify-write. Reviewed-by: Linus Walleij Reviewed-by: Marc Zyngier Fixes: 07bd1a6cc7cbb ("MXC arch: Add gpio support for the whole platform") Signed-off-by: Marek Vasut Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mxc.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index d5626c572d24..2d9d498727f1 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -159,6 +160,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) { struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct mxc_gpio_port *port = gc->private; + unsigned long flags; u32 bit, val; u32 gpio_idx = d->hwirq; int edge; @@ -197,6 +199,8 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) return -EINVAL; } + raw_spin_lock_irqsave(&port->gc.bgpio_lock, flags); + if (GPIO_EDGE_SEL >= 0) { val = readl(port->base + GPIO_EDGE_SEL); if (edge == GPIO_INT_BOTH_EDGES) @@ -217,15 +221,20 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) writel(1 << gpio_idx, port->base + GPIO_ISR); port->pad_type[gpio_idx] = type; + raw_spin_unlock_irqrestore(&port->gc.bgpio_lock, flags); + return 0; } static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) { void __iomem *reg = port->base; + unsigned long flags; u32 bit, val; int edge; + raw_spin_lock_irqsave(&port->gc.bgpio_lock, flags); + reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */ bit = gpio & 0xf; val = readl(reg); @@ -243,6 +252,8 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) return; } writel(val | (edge << (bit << 1)), reg); + + raw_spin_unlock_irqrestore(&port->gc.bgpio_lock, flags); } /* handle 32 interrupts in one status register */ From 8e88a0feebb241cab0253698b2f7358b6ebec802 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 16 Jan 2023 10:49:57 +0100 Subject: [PATCH 182/398] gpio: mxc: Always set GPIOs used as interrupt source to INPUT mode Always configure GPIO pins which are used as interrupt source as INPUTs. In case the default pin configuration is OUTPUT, or the prior stage does configure the pins as OUTPUT, then Linux will not reconfigure the pin as INPUT and no interrupts are received. Always configure the interrupt source GPIO pin as input to fix the above case. Reviewed-by: Linus Walleij Fixes: 07bd1a6cc7cbb ("MXC arch: Add gpio support for the whole platform") Signed-off-by: Marek Vasut Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpio-mxc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 2d9d498727f1..6f673b2f2a1b 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c @@ -223,7 +223,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type) raw_spin_unlock_irqrestore(&port->gc.bgpio_lock, flags); - return 0; + return port->gc.direction_input(&port->gc, gpio_idx); } static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio) From 8c0089882a62da2d75fb655e781cc33cc1351f6a Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 16 Jan 2023 11:45:33 +0100 Subject: [PATCH 183/398] scripts: support GNU make 4.4 in jobserver-exec Starting with GNU make 4.4, --jobserver-auth newly uses named pipe (fifo) instead of part of opened file descriptors: https://www.gnu.org/software/make/manual/html_node/POSIX-Jobserver.html Support also the new format. Signed-off-by: Martin Liska Signed-off-by: Masahiro Yamada --- scripts/jobserver-exec | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/scripts/jobserver-exec b/scripts/jobserver-exec index 4192855f5b8b..7eca035472d3 100755 --- a/scripts/jobserver-exec +++ b/scripts/jobserver-exec @@ -26,11 +26,20 @@ try: # If the MAKEFLAGS variable contains multiple instances of the # --jobserver-auth= option, the last one is relevant. fds = opts[-1].split("=", 1)[1] - reader, writer = [int(x) for x in fds.split(",", 1)] - # Open a private copy of reader to avoid setting nonblocking - # on an unexpecting process with the same reader fd. - reader = os.open("/proc/self/fd/%d" % (reader), - os.O_RDONLY | os.O_NONBLOCK) + + # Starting with GNU Make 4.4, named pipes are used for reader and writer. + # Example argument: --jobserver-auth=fifo:/tmp/GMfifo8134 + _, _, path = fds.partition('fifo:') + + if path: + reader = os.open(path, os.O_RDONLY | os.O_NONBLOCK) + writer = os.open(path, os.O_WRONLY) + else: + reader, writer = [int(x) for x in fds.split(",", 1)] + # Open a private copy of reader to avoid setting nonblocking + # on an unexpecting process with the same reader fd. + reader = os.open("/proc/self/fd/%d" % (reader), + os.O_RDONLY | os.O_NONBLOCK) # Read out as many jobserver slots as possible. while True: From e5d1ab1a73ad275c0205cbc09a0a9f9f42bbb87f Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 3 Jan 2023 13:41:15 +0100 Subject: [PATCH 184/398] wifi: brcmfmac: avoid handling disabled channels for survey dump An issue was reported in which periodically error messages are printed in the kernel log: [ 26.303445] brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43455-sdio for chip BCM4345/6 [ 26.303554] brcmfmac mmc1:0001:1: Direct firmware load for brcm/brcmfmac43455-sdio.raspberrypi,3-model-b-plus.bin failed with error -2 [ 26.516752] brcmfmac_wcc: brcmf_wcc_attach: executing [ 26.528264] brcmfmac: brcmf_c_preinit_dcmds: Firmware: BCM4345/6 wl0: Jan 4 2021 19:56:29 version 7.45.229 (617f1f5 CY) FWID 01-2dbd9d2e [ 27.076829] Bluetooth: hci0: BCM: features 0x2f [ 27.078592] Bluetooth: hci0: BCM43455 37.4MHz Raspberry Pi 3+ [ 27.078601] Bluetooth: hci0: BCM4345C0 (003.001.025) build 0342 [ 30.142104] Adding 102396k swap on /var/swap. Priority:-2 extents:1 across:102396k SS [ 30.590017] Bluetooth: MGMT ver 1.22 [ 104.897615] brcmfmac: cfg80211_set_channel: set chanspec 0x100e fail, reason -52 [ 104.897992] brcmfmac: cfg80211_set_channel: set chanspec 0xd022 fail, reason -52 [ 105.007672] brcmfmac: cfg80211_set_channel: set chanspec 0xd026 fail, reason -52 [ 105.117654] brcmfmac: cfg80211_set_channel: set chanspec 0xd02a fail, reason -52 [ 105.227636] brcmfmac: cfg80211_set_channel: set chanspec 0xd02e fail, reason -52 [ 106.987552] brcmfmac: cfg80211_set_channel: set chanspec 0xd090 fail, reason -52 [ 106.987911] brcmfmac: cfg80211_set_channel: set chanspec 0xd095 fail, reason -52 [ 106.988233] brcmfmac: cfg80211_set_channel: set chanspec 0xd099 fail, reason -52 [ 106.988565] brcmfmac: cfg80211_set_channel: set chanspec 0xd09d fail, reason -52 [ 106.988909] brcmfmac: cfg80211_set_channel: set chanspec 0xd0a1 fail, reason -52 This happens in brcmf_cfg80211_dump_survey() because we try a disabled channel. When channel is marked as disabled we do not need to fill any other info so bail out. Fixes: 6c04deae1438 ("brcmfmac: Add dump_survey cfg80211 ops for HostApd AutoChannelSelection") Reported-by: Stefan Wahren Signed-off-by: Arend van Spriel Tested-by: Stefan Wahren Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230103124117.271988-2-arend.vanspriel@broadcom.com --- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index bff3128c2f26..478ca3848c64 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -7937,6 +7937,9 @@ cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); + if (chan->flags & IEEE80211_CHAN_DISABLED) + return -EINVAL; + /* set_channel */ chspec = channel_to_chanspec(&cfg->d11inf, chan); if (chspec != INVCHANSPEC) { @@ -7961,7 +7964,6 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); struct brcmf_dump_survey survey = {}; struct ieee80211_supported_band *band; - struct ieee80211_channel *chan; struct cca_msrmnt_query req; u32 noise; int err; @@ -7987,13 +7989,10 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, } /* Setting current channel to the requested channel */ - chan = &band->channels[idx]; - err = cfg80211_set_channel(wiphy, ndev, chan, NL80211_CHAN_HT20); - if (err) { - info->channel = chan; - info->filled = 0; + info->filled = 0; + info->channel = &band->channels[idx]; + if (cfg80211_set_channel(wiphy, ndev, info->channel, NL80211_CHAN_HT20)) return 0; - } /* Disable mpc */ brcmf_set_mpc(ifp, 0); @@ -8028,7 +8027,6 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, if (err) goto exit; - info->channel = chan; info->noise = noise; info->time = ACS_MSRMNT_DELAY; info->time_busy = ACS_MSRMNT_DELAY - survey.idle; @@ -8040,7 +8038,7 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, SURVEY_INFO_TIME_TX; brcmf_dbg(INFO, "OBSS dump: channel %d: survey duration %d\n", - ieee80211_frequency_to_channel(chan->center_freq), + ieee80211_frequency_to_channel(info->channel->center_freq), ACS_MSRMNT_DELAY); brcmf_dbg(INFO, "noise(%d) busy(%llu) rx(%llu) tx(%llu)\n", info->noise, info->time_busy, info->time_rx, info->time_tx); From aadb50d1571211c73248605bcc1f4b9f8e3d1364 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 3 Jan 2023 13:41:16 +0100 Subject: [PATCH 185/398] wifi: brcmfmac: avoid NULL-deref in survey dump for 2G only device When dealing with a device for 2GHz band only the wiphy->bands for 5GHz will be NULL. This would result in a NULL-deref in the brcmf_cfg80211_dump_survey() function. Rework the code with a for-loop to make it easier to add another band. Fixes: 6c04deae1438 ("brcmfmac: Add dump_survey cfg80211 ops for HostApd AutoChannelSelection") Signed-off-by: Arend van Spriel Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230103124117.271988-3-arend.vanspriel@broadcom.com --- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 478ca3848c64..b115902eb475 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -7964,6 +7964,7 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); struct brcmf_dump_survey survey = {}; struct ieee80211_supported_band *band; + enum nl80211_band band_id; struct cca_msrmnt_query req; u32 noise; int err; @@ -7976,21 +7977,23 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev, return -EBUSY; } - band = wiphy->bands[NL80211_BAND_2GHZ]; - if (band && idx >= band->n_channels) { - idx -= band->n_channels; - band = NULL; - } + for (band_id = 0; band_id < NUM_NL80211_BANDS; band_id++) { + band = wiphy->bands[band_id]; + if (!band) + continue; + if (idx >= band->n_channels) { + idx -= band->n_channels; + continue; + } - if (!band || idx >= band->n_channels) { - band = wiphy->bands[NL80211_BAND_5GHZ]; - if (idx >= band->n_channels) - return -ENOENT; + info->channel = &band->channels[idx]; + break; } + if (band_id == NUM_NL80211_BANDS) + return -ENOENT; /* Setting current channel to the requested channel */ info->filled = 0; - info->channel = &band->channels[idx]; if (cfg80211_set_channel(wiphy, ndev, info->channel, NL80211_CHAN_HT20)) return 0; From ed05cb177ae5cd7f02f1d6e7706ba627d30f1696 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Wed, 11 Jan 2023 12:24:19 +0100 Subject: [PATCH 186/398] wifi: brcmfmac: fix regression for Broadcom PCIe wifi devices A sanity check was introduced considering maximum flowrings above 256 as insane and effectively aborting the device probe. This resulted in regression for number of users as the value turns out to be sane after all. Fixes: 2aca4f3734bd ("brcmfmac: return error when getting invalid max_flowrings from dongle") Reported-by: chainofflowers Link: https://lore.kernel.org/all/4781984.GXAFRqVoOG@luna/ Reported-by: Christian Marillat Link: https://bugzilla.kernel.org/show_bug.cgi?id=216894 Cc: stable@vger.kernel.org Signed-off-by: Arend van Spriel Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230111112419.24185-1-arend.vanspriel@broadcom.com --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index ae57a9a3ab05..b67f6d0810b6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -1228,7 +1228,7 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo) BRCMF_NROF_H2D_COMMON_MSGRINGS; max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS; } - if (max_flowrings > 256) { + if (max_flowrings > 512) { brcmf_err(bus, "invalid max_flowrings(%d)\n", max_flowrings); return -EIO; } From b870e73a56c4cccbec33224233eaf295839f228c Mon Sep 17 00:00:00 2001 From: Szymon Heidrich Date: Wed, 11 Jan 2023 18:50:31 +0100 Subject: [PATCH 187/398] wifi: rndis_wlan: Prevent buffer overflow in rndis_query_oid Since resplen and respoffs are signed integers sufficiently large values of unsigned int len and offset members of RNDIS response will result in negative values of prior variables. This may be utilized to bypass implemented security checks to either extract memory contents by manipulating offset or overflow the data buffer via memcpy by manipulating both offset and len. Additionally assure that sum of resplen and respoffs does not overflow so buffer boundaries are kept. Fixes: 80f8c5b434f9 ("rndis_wlan: copy only useful data from rndis_command respond") Signed-off-by: Szymon Heidrich Reviewed-by: Alexander Duyck Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230111175031.7049-1-szymon.heidrich@gmail.com --- drivers/net/wireless/rndis_wlan.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 82a7458e01ae..bf72e5fd39cf 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -696,8 +696,8 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len) struct rndis_query *get; struct rndis_query_c *get_c; } u; - int ret, buflen; - int resplen, respoffs, copylen; + int ret; + size_t buflen, resplen, respoffs, copylen; buflen = *len + sizeof(*u.get); if (buflen < CONTROL_BUFFER_SIZE) @@ -732,22 +732,15 @@ static int rndis_query_oid(struct usbnet *dev, u32 oid, void *data, int *len) if (respoffs > buflen) { /* Device returned data offset outside buffer, error. */ - netdev_dbg(dev->net, "%s(%s): received invalid " - "data offset: %d > %d\n", __func__, - oid_to_string(oid), respoffs, buflen); + netdev_dbg(dev->net, + "%s(%s): received invalid data offset: %zu > %zu\n", + __func__, oid_to_string(oid), respoffs, buflen); ret = -EINVAL; goto exit_unlock; } - if ((resplen + respoffs) > buflen) { - /* Device would have returned more data if buffer would - * have been big enough. Copy just the bits that we got. - */ - copylen = buflen - respoffs; - } else { - copylen = resplen; - } + copylen = min(resplen, buflen - respoffs); if (copylen > *len) copylen = *len; From 31b62a98de42cf65d76e4dcfb571af067d27d83a Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Tue, 10 Jan 2023 17:29:58 +0000 Subject: [PATCH 188/398] pinctrl: rockchip: fix reading pull type on rk3568 When reading pinconf-pins from debugfs it fails to get the configured pull type on RK3568, "unsupported pinctrl type" error messages is also reported. Fix this by adding support for RK3568 in rockchip_get_pull, including a reverse of the pull-up value swap applied in rockchip_set_pull so that pull-up is correctly reported in pinconf-pins. Also update the workaround comment to reflect affected pins, GPIO0_D3-D6. Fixes: c0dadc0e47a8 ("pinctrl: rockchip: add support for rk3568") Signed-off-by: Jonas Karlman Reviewed-by: Heiko Stuebner Reviewed-by: Jianqun Xu Link: https://lore.kernel.org/r/20230110172955.1258840-1-jonas@kwiboo.se Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index da974ff2d75d..c3b9313e5be1 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -2436,10 +2436,19 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num) case RK3308: case RK3368: case RK3399: + case RK3568: case RK3588: pull_type = bank->pull_type[pin_num / 8]; data >>= bit; data &= (1 << RK3188_PULL_BITS_PER_PIN) - 1; + /* + * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6, + * where that pull up value becomes 3. + */ + if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { + if (data == 3) + data = 1; + } return rockchip_pull_list[pull_type][data]; default: @@ -2497,7 +2506,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank, } } /* - * In the TRM, pull-up being 1 for everything except the GPIO0_D0-D6, + * In the TRM, pull-up being 1 for everything except the GPIO0_D3-D6, * where that pull up value becomes 3. */ if (ctrl->type == RK3568 && bank->bank_num == 0 && pin_num >= 27 && pin_num <= 30) { From c296c77efb66994d94d9f706446a115581226550 Mon Sep 17 00:00:00 2001 From: Kurt Kanzenbach Date: Sat, 14 Jan 2023 13:04:37 +0100 Subject: [PATCH 189/398] net: stmmac: Fix queue statistics reading Correct queue statistics reading. All queue statistics are stored as unsigned long values. The retrieval for ethtool fetches these values as u64. However, on some systems the size of the counters are 32 bit. That yields wrong queue statistic counters e.g., on arm32 systems such as the stm32mp157. Fix it by using the correct data type. Tested on Olimex STMP157-OLinuXino-LIME2 by simple running linuxptp for a short period of time: Non-patched kernel: |root@st1:~# ethtool -S eth0 | grep q0 | q0_tx_pkt_n: 3775276254951 # ??? | q0_tx_irq_n: 879 | q0_rx_pkt_n: 1194000908909 # ??? | q0_rx_irq_n: 278 Patched kernel: |root@st1:~# ethtool -S eth0 | grep q0 | q0_tx_pkt_n: 2434 | q0_tx_irq_n: 1274 | q0_rx_pkt_n: 1604 | q0_rx_irq_n: 846 Fixes: 68e9c5dee1cf ("net: stmmac: add ethtool per-queue statistic framework") Signed-off-by: Kurt Kanzenbach Cc: Vijayakannan Ayyathurai Cc: Wong Vee Khee Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index f453b0d09366..35c8dd92d369 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -551,16 +551,16 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data) p = (char *)priv + offsetof(struct stmmac_priv, xstats.txq_stats[q].tx_pkt_n); for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) { - *data++ = (*(u64 *)p); - p += sizeof(u64 *); + *data++ = (*(unsigned long *)p); + p += sizeof(unsigned long); } } for (q = 0; q < rx_cnt; q++) { p = (char *)priv + offsetof(struct stmmac_priv, xstats.rxq_stats[q].rx_pkt_n); for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) { - *data++ = (*(u64 *)p); - p += sizeof(u64 *); + *data++ = (*(unsigned long *)p); + p += sizeof(unsigned long); } } } From 3a415d59c1dbec9d772dbfab2d2520d98360caae Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 13 Jan 2023 16:48:49 +0000 Subject: [PATCH 190/398] net/sched: sch_taprio: fix possible use-after-free syzbot reported a nasty crash [1] in net_tx_action() which made little sense until we got a repro. This repro installs a taprio qdisc, but providing an invalid TCA_RATE attribute. qdisc_create() has to destroy the just initialized taprio qdisc, and taprio_destroy() is called. However, the hrtimer used by taprio had already fired, therefore advance_sched() called __netif_schedule(). Then net_tx_action was trying to use a destroyed qdisc. We can not undo the __netif_schedule(), so we must wait until one cpu serviced the qdisc before we can proceed. Many thanks to Alexander Potapenko for his help. [1] BUG: KMSAN: uninit-value in queued_spin_trylock include/asm-generic/qspinlock.h:94 [inline] BUG: KMSAN: uninit-value in do_raw_spin_trylock include/linux/spinlock.h:191 [inline] BUG: KMSAN: uninit-value in __raw_spin_trylock include/linux/spinlock_api_smp.h:89 [inline] BUG: KMSAN: uninit-value in _raw_spin_trylock+0x92/0xa0 kernel/locking/spinlock.c:138 queued_spin_trylock include/asm-generic/qspinlock.h:94 [inline] do_raw_spin_trylock include/linux/spinlock.h:191 [inline] __raw_spin_trylock include/linux/spinlock_api_smp.h:89 [inline] _raw_spin_trylock+0x92/0xa0 kernel/locking/spinlock.c:138 spin_trylock include/linux/spinlock.h:359 [inline] qdisc_run_begin include/net/sch_generic.h:187 [inline] qdisc_run+0xee/0x540 include/net/pkt_sched.h:125 net_tx_action+0x77c/0x9a0 net/core/dev.c:5086 __do_softirq+0x1cc/0x7fb kernel/softirq.c:571 run_ksoftirqd+0x2c/0x50 kernel/softirq.c:934 smpboot_thread_fn+0x554/0x9f0 kernel/smpboot.c:164 kthread+0x31b/0x430 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 Uninit was created at: slab_post_alloc_hook mm/slab.h:732 [inline] slab_alloc_node mm/slub.c:3258 [inline] __kmalloc_node_track_caller+0x814/0x1250 mm/slub.c:4970 kmalloc_reserve net/core/skbuff.c:358 [inline] __alloc_skb+0x346/0xcf0 net/core/skbuff.c:430 alloc_skb include/linux/skbuff.h:1257 [inline] nlmsg_new include/net/netlink.h:953 [inline] netlink_ack+0x5f3/0x12b0 net/netlink/af_netlink.c:2436 netlink_rcv_skb+0x55d/0x6c0 net/netlink/af_netlink.c:2507 rtnetlink_rcv+0x30/0x40 net/core/rtnetlink.c:6108 netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline] netlink_unicast+0xf3b/0x1270 net/netlink/af_netlink.c:1345 netlink_sendmsg+0x1288/0x1440 net/netlink/af_netlink.c:1921 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg net/socket.c:734 [inline] ____sys_sendmsg+0xabc/0xe90 net/socket.c:2482 ___sys_sendmsg+0x2a1/0x3f0 net/socket.c:2536 __sys_sendmsg net/socket.c:2565 [inline] __do_sys_sendmsg net/socket.c:2574 [inline] __se_sys_sendmsg net/socket.c:2572 [inline] __x64_sys_sendmsg+0x367/0x540 net/socket.c:2572 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd CPU: 0 PID: 13 Comm: ksoftirqd/0 Not tainted 6.0.0-rc2-syzkaller-47461-gac3859c02d7f #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/22/2022 Fixes: 5a781ccbd19e ("tc: Add support for configuring the taprio scheduler") Reported-by: syzbot Signed-off-by: Eric Dumazet Cc: Alexander Potapenko Cc: Vinicius Costa Gomes Signed-off-by: David S. Miller --- include/net/sch_generic.h | 7 +++++++ net/sched/sch_taprio.c | 3 +++ 2 files changed, 10 insertions(+) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index d5517719af4e..af4aa66aaa4e 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -1288,4 +1288,11 @@ void mq_change_real_num_tx(struct Qdisc *sch, unsigned int new_real_tx); int sch_frag_xmit_hook(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb)); +/* Make sure qdisc is no longer in SCHED state. */ +static inline void qdisc_synchronize(const struct Qdisc *q) +{ + while (test_bit(__QDISC_STATE_SCHED, &q->state)) + msleep(1); +} + #endif diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 570389f6cdd7..9a11a499ea2d 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1700,6 +1700,8 @@ static void taprio_reset(struct Qdisc *sch) int i; hrtimer_cancel(&q->advance_timer); + qdisc_synchronize(sch); + if (q->qdiscs) { for (i = 0; i < dev->num_tx_queues; i++) if (q->qdiscs[i]) @@ -1720,6 +1722,7 @@ static void taprio_destroy(struct Qdisc *sch) * happens in qdisc_create(), after taprio_init() has been called. */ hrtimer_cancel(&q->advance_timer); + qdisc_synchronize(sch); taprio_disable_offload(dev, q, NULL); From c4d48a58f32c5972174a1d01c33b296fe378cce0 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Fri, 13 Jan 2023 19:01:36 -0800 Subject: [PATCH 191/398] l2tp: convert l2tp_tunnel_list to idr l2tp uses l2tp_tunnel_list to track all registered tunnels and to allocate tunnel ID's. IDR can do the same job. More importantly, with IDR we can hold the ID before a successful registration so that we don't need to worry about late error handling, it is not easy to rollback socket changes. This is a preparation for the following fix. Cc: Tetsuo Handa Cc: Guillaume Nault Cc: Jakub Sitnicki Cc: Eric Dumazet Cc: Tom Parkin Signed-off-by: Cong Wang Reviewed-by: Guillaume Nault Signed-off-by: David S. Miller --- net/l2tp/l2tp_core.c | 85 ++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 43 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 9a1415fe3fa7..e9c0ce0b7972 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -104,9 +104,9 @@ static struct workqueue_struct *l2tp_wq; /* per-net private data for this module */ static unsigned int l2tp_net_id; struct l2tp_net { - struct list_head l2tp_tunnel_list; - /* Lock for write access to l2tp_tunnel_list */ - spinlock_t l2tp_tunnel_list_lock; + /* Lock for write access to l2tp_tunnel_idr */ + spinlock_t l2tp_tunnel_idr_lock; + struct idr l2tp_tunnel_idr; struct hlist_head l2tp_session_hlist[L2TP_HASH_SIZE_2]; /* Lock for write access to l2tp_session_hlist */ spinlock_t l2tp_session_hlist_lock; @@ -208,13 +208,10 @@ struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id) struct l2tp_tunnel *tunnel; rcu_read_lock_bh(); - list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { - if (tunnel->tunnel_id == tunnel_id && - refcount_inc_not_zero(&tunnel->ref_count)) { - rcu_read_unlock_bh(); - - return tunnel; - } + tunnel = idr_find(&pn->l2tp_tunnel_idr, tunnel_id); + if (tunnel && refcount_inc_not_zero(&tunnel->ref_count)) { + rcu_read_unlock_bh(); + return tunnel; } rcu_read_unlock_bh(); @@ -224,13 +221,14 @@ EXPORT_SYMBOL_GPL(l2tp_tunnel_get); struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth) { - const struct l2tp_net *pn = l2tp_pernet(net); + struct l2tp_net *pn = l2tp_pernet(net); + unsigned long tunnel_id, tmp; struct l2tp_tunnel *tunnel; int count = 0; rcu_read_lock_bh(); - list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { - if (++count > nth && + idr_for_each_entry_ul(&pn->l2tp_tunnel_idr, tunnel, tmp, tunnel_id) { + if (tunnel && ++count > nth && refcount_inc_not_zero(&tunnel->ref_count)) { rcu_read_unlock_bh(); return tunnel; @@ -1227,6 +1225,15 @@ static void l2tp_udp_encap_destroy(struct sock *sk) l2tp_tunnel_delete(tunnel); } +static void l2tp_tunnel_remove(struct net *net, struct l2tp_tunnel *tunnel) +{ + struct l2tp_net *pn = l2tp_pernet(net); + + spin_lock_bh(&pn->l2tp_tunnel_idr_lock); + idr_remove(&pn->l2tp_tunnel_idr, tunnel->tunnel_id); + spin_unlock_bh(&pn->l2tp_tunnel_idr_lock); +} + /* Workqueue tunnel deletion function */ static void l2tp_tunnel_del_work(struct work_struct *work) { @@ -1234,7 +1241,6 @@ static void l2tp_tunnel_del_work(struct work_struct *work) del_work); struct sock *sk = tunnel->sock; struct socket *sock = sk->sk_socket; - struct l2tp_net *pn; l2tp_tunnel_closeall(tunnel); @@ -1248,12 +1254,7 @@ static void l2tp_tunnel_del_work(struct work_struct *work) } } - /* Remove the tunnel struct from the tunnel list */ - pn = l2tp_pernet(tunnel->l2tp_net); - spin_lock_bh(&pn->l2tp_tunnel_list_lock); - list_del_rcu(&tunnel->list); - spin_unlock_bh(&pn->l2tp_tunnel_list_lock); - + l2tp_tunnel_remove(tunnel->l2tp_net, tunnel); /* drop initial ref */ l2tp_tunnel_dec_refcount(tunnel); @@ -1455,12 +1456,19 @@ static int l2tp_validate_socket(const struct sock *sk, const struct net *net, int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, struct l2tp_tunnel_cfg *cfg) { - struct l2tp_tunnel *tunnel_walk; - struct l2tp_net *pn; + struct l2tp_net *pn = l2tp_pernet(net); + u32 tunnel_id = tunnel->tunnel_id; struct socket *sock; struct sock *sk; int ret; + spin_lock_bh(&pn->l2tp_tunnel_idr_lock); + ret = idr_alloc_u32(&pn->l2tp_tunnel_idr, NULL, &tunnel_id, tunnel_id, + GFP_ATOMIC); + spin_unlock_bh(&pn->l2tp_tunnel_idr_lock); + if (ret) + return ret == -ENOSPC ? -EEXIST : ret; + if (tunnel->fd < 0) { ret = l2tp_tunnel_sock_create(net, tunnel->tunnel_id, tunnel->peer_tunnel_id, cfg, @@ -1481,23 +1489,13 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, rcu_assign_sk_user_data(sk, tunnel); write_unlock_bh(&sk->sk_callback_lock); - tunnel->l2tp_net = net; - pn = l2tp_pernet(net); - sock_hold(sk); tunnel->sock = sk; + tunnel->l2tp_net = net; - spin_lock_bh(&pn->l2tp_tunnel_list_lock); - list_for_each_entry(tunnel_walk, &pn->l2tp_tunnel_list, list) { - if (tunnel_walk->tunnel_id == tunnel->tunnel_id) { - spin_unlock_bh(&pn->l2tp_tunnel_list_lock); - sock_put(sk); - ret = -EEXIST; - goto err_sock; - } - } - list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list); - spin_unlock_bh(&pn->l2tp_tunnel_list_lock); + spin_lock_bh(&pn->l2tp_tunnel_idr_lock); + idr_replace(&pn->l2tp_tunnel_idr, tunnel, tunnel->tunnel_id); + spin_unlock_bh(&pn->l2tp_tunnel_idr_lock); if (tunnel->encap == L2TP_ENCAPTYPE_UDP) { struct udp_tunnel_sock_cfg udp_cfg = { @@ -1523,9 +1521,6 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, return 0; -err_sock: - write_lock_bh(&sk->sk_callback_lock); - rcu_assign_sk_user_data(sk, NULL); err_inval_sock: write_unlock_bh(&sk->sk_callback_lock); @@ -1534,6 +1529,7 @@ err_inval_sock: else sockfd_put(sock); err: + l2tp_tunnel_remove(net, tunnel); return ret; } EXPORT_SYMBOL_GPL(l2tp_tunnel_register); @@ -1647,8 +1643,8 @@ static __net_init int l2tp_init_net(struct net *net) struct l2tp_net *pn = net_generic(net, l2tp_net_id); int hash; - INIT_LIST_HEAD(&pn->l2tp_tunnel_list); - spin_lock_init(&pn->l2tp_tunnel_list_lock); + idr_init(&pn->l2tp_tunnel_idr); + spin_lock_init(&pn->l2tp_tunnel_idr_lock); for (hash = 0; hash < L2TP_HASH_SIZE_2; hash++) INIT_HLIST_HEAD(&pn->l2tp_session_hlist[hash]); @@ -1662,11 +1658,13 @@ static __net_exit void l2tp_exit_net(struct net *net) { struct l2tp_net *pn = l2tp_pernet(net); struct l2tp_tunnel *tunnel = NULL; + unsigned long tunnel_id, tmp; int hash; rcu_read_lock_bh(); - list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { - l2tp_tunnel_delete(tunnel); + idr_for_each_entry_ul(&pn->l2tp_tunnel_idr, tunnel, tmp, tunnel_id) { + if (tunnel) + l2tp_tunnel_delete(tunnel); } rcu_read_unlock_bh(); @@ -1676,6 +1674,7 @@ static __net_exit void l2tp_exit_net(struct net *net) for (hash = 0; hash < L2TP_HASH_SIZE_2; hash++) WARN_ON_ONCE(!hlist_empty(&pn->l2tp_session_hlist[hash])); + idr_destroy(&pn->l2tp_tunnel_idr); } static struct pernet_operations l2tp_net_ops = { From 0b2c59720e65885a394a017d0cf9cab118914682 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Fri, 13 Jan 2023 19:01:37 -0800 Subject: [PATCH 192/398] l2tp: close all race conditions in l2tp_tunnel_register() The code in l2tp_tunnel_register() is racy in several ways: 1. It modifies the tunnel socket _after_ publishing it. 2. It calls setup_udp_tunnel_sock() on an existing socket without locking. 3. It changes sock lock class on fly, which triggers many syzbot reports. This patch amends all of them by moving socket initialization code before publishing and under sock lock. As suggested by Jakub, the l2tp lockdep class is not necessary as we can just switch to bh_lock_sock_nested(). Fixes: 37159ef2c1ae ("l2tp: fix a lockdep splat") Fixes: 6b9f34239b00 ("l2tp: fix races in tunnel creation") Reported-by: syzbot+52866e24647f9a23403f@syzkaller.appspotmail.com Reported-by: syzbot+94cc2a66fc228b23f360@syzkaller.appspotmail.com Reported-by: Tetsuo Handa Cc: Guillaume Nault Cc: Jakub Sitnicki Cc: Eric Dumazet Cc: Tom Parkin Signed-off-by: Cong Wang Reviewed-by: Guillaume Nault Signed-off-by: David S. Miller --- net/l2tp/l2tp_core.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index e9c0ce0b7972..b6554e32bb12 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1041,7 +1041,7 @@ static int l2tp_xmit_core(struct l2tp_session *session, struct sk_buff *skb, uns IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | IPSKB_REROUTED); nf_reset_ct(skb); - bh_lock_sock(sk); + bh_lock_sock_nested(sk); if (sock_owned_by_user(sk)) { kfree_skb(skb); ret = NET_XMIT_DROP; @@ -1385,8 +1385,6 @@ out: return err; } -static struct lock_class_key l2tp_socket_class; - int l2tp_tunnel_create(int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, struct l2tp_tunnel_cfg *cfg, struct l2tp_tunnel **tunnelp) { @@ -1482,21 +1480,16 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, } sk = sock->sk; + lock_sock(sk); write_lock_bh(&sk->sk_callback_lock); ret = l2tp_validate_socket(sk, net, tunnel->encap); - if (ret < 0) + if (ret < 0) { + release_sock(sk); goto err_inval_sock; + } rcu_assign_sk_user_data(sk, tunnel); write_unlock_bh(&sk->sk_callback_lock); - sock_hold(sk); - tunnel->sock = sk; - tunnel->l2tp_net = net; - - spin_lock_bh(&pn->l2tp_tunnel_idr_lock); - idr_replace(&pn->l2tp_tunnel_idr, tunnel, tunnel->tunnel_id); - spin_unlock_bh(&pn->l2tp_tunnel_idr_lock); - if (tunnel->encap == L2TP_ENCAPTYPE_UDP) { struct udp_tunnel_sock_cfg udp_cfg = { .sk_user_data = tunnel, @@ -1510,9 +1503,16 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, tunnel->old_sk_destruct = sk->sk_destruct; sk->sk_destruct = &l2tp_tunnel_destruct; - lockdep_set_class_and_name(&sk->sk_lock.slock, &l2tp_socket_class, - "l2tp_sock"); sk->sk_allocation = GFP_ATOMIC; + release_sock(sk); + + sock_hold(sk); + tunnel->sock = sk; + tunnel->l2tp_net = net; + + spin_lock_bh(&pn->l2tp_tunnel_idr_lock); + idr_replace(&pn->l2tp_tunnel_idr, tunnel, tunnel->tunnel_id); + spin_unlock_bh(&pn->l2tp_tunnel_idr_lock); trace_register_tunnel(tunnel); From 87b93b678e95c7d93fe6a55b0e0fbda26d8c7760 Mon Sep 17 00:00:00 2001 From: Geetha sowjanya Date: Fri, 13 Jan 2023 11:49:02 +0530 Subject: [PATCH 193/398] octeontx2-pf: Avoid use of GFP_KERNEL in atomic context Using GFP_KERNEL in preemption disable context, causing below warning when CONFIG_DEBUG_ATOMIC_SLEEP is enabled. [ 32.542271] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:274 [ 32.550883] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1, name: swapper/0 [ 32.558707] preempt_count: 1, expected: 0 [ 32.562710] RCU nest depth: 0, expected: 0 [ 32.566800] CPU: 3 PID: 1 Comm: swapper/0 Tainted: G W 6.2.0-rc2-00269-gae9dcb91c606 #7 [ 32.576188] Hardware name: Marvell CN106XX board (DT) [ 32.581232] Call trace: [ 32.583670] dump_backtrace.part.0+0xe0/0xf0 [ 32.587937] show_stack+0x18/0x30 [ 32.591245] dump_stack_lvl+0x68/0x84 [ 32.594900] dump_stack+0x18/0x34 [ 32.598206] __might_resched+0x12c/0x160 [ 32.602122] __might_sleep+0x48/0xa0 [ 32.605689] __kmem_cache_alloc_node+0x2b8/0x2e0 [ 32.610301] __kmalloc+0x58/0x190 [ 32.613610] otx2_sq_aura_pool_init+0x1a8/0x314 [ 32.618134] otx2_open+0x1d4/0x9d0 To avoid use of GFP_ATOMIC for memory allocation, disable preemption after all memory allocation is done. Fixes: 4af1b64f80fb ("octeontx2-pf: Fix lmtst ID used in aura free") Signed-off-by: Geetha sowjanya Signed-off-by: Sunil Kovvuri Goutham Reviewed-by: Leon Romanovsky Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c index 88f8772a61cd..497b777b6a34 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c @@ -1370,7 +1370,6 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf) if (err) goto fail; - get_cpu(); /* Allocate pointers and free them to aura/pool */ for (qidx = 0; qidx < hw->tot_tx_queues; qidx++) { pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, qidx); @@ -1388,13 +1387,14 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf) err = otx2_alloc_rbuf(pfvf, pool, &bufptr); if (err) goto err_mem; + get_cpu(); pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr); + put_cpu(); sq->sqb_ptrs[sq->sqb_count++] = (u64)bufptr; } } err_mem: - put_cpu(); return err ? -ENOMEM : 0; fail: From b22c7b97189d461d7143052da83b36390c623b54 Mon Sep 17 00:00:00 2001 From: Jingbo Xu Date: Thu, 12 Jan 2023 14:54:30 +0800 Subject: [PATCH 194/398] erofs: add documentation for 'domain_id' mount option Since the EROFS share domain feature for fscache mode has been available since Linux v6.1, let's add documentation for 'domain_id' mount option. Cc: linux-doc@vger.kernel.org Reviewed-by: Jia Zhu Signed-off-by: Jingbo Xu Reviewed-by: Gao Xiang Reviewed-by: Chao Yu Link: https://lore.kernel.org/r/20230112065431.124926-2-jefflexu@linux.alibaba.com Signed-off-by: Gao Xiang --- Documentation/filesystems/erofs.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/filesystems/erofs.rst b/Documentation/filesystems/erofs.rst index 067fd1670b1f..a43aacf1494e 100644 --- a/Documentation/filesystems/erofs.rst +++ b/Documentation/filesystems/erofs.rst @@ -120,6 +120,8 @@ dax={always,never} Use direct access (no page cache). See dax A legacy option which is an alias for ``dax=always``. device=%s Specify a path to an extra device to be used together. fsid=%s Specify a filesystem image ID for Fscache back-end. +domain_id=%s Specify a domain ID in fscache mode so that different images + with the same blobs under a given domain ID can share storage. =================== ========================================================= Sysfs Entries From e02ac3e7329f76c5de40cba2746cbe165f571dff Mon Sep 17 00:00:00 2001 From: Jingbo Xu Date: Thu, 12 Jan 2023 14:54:31 +0800 Subject: [PATCH 195/398] erofs: clean up parsing of fscache related options ... to avoid the mess of conditional preprocessing as we are continually adding fscache related mount options. Reviewd-by: Gao Xiang Reviewed-by: Yue Hu Reviewed-by: Chao Yu Signed-off-by: Jingbo Xu Link: https://lore.kernel.org/r/20230112065431.124926-3-jefflexu@linux.alibaba.com Signed-off-by: Gao Xiang --- fs/erofs/super.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/erofs/super.c b/fs/erofs/super.c index 481788c24a68..626a615dafc2 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -577,26 +577,25 @@ static int erofs_fc_parse_param(struct fs_context *fc, } ++ctx->devs->extra_devices; break; - case Opt_fsid: #ifdef CONFIG_EROFS_FS_ONDEMAND + case Opt_fsid: kfree(ctx->fsid); ctx->fsid = kstrdup(param->string, GFP_KERNEL); if (!ctx->fsid) return -ENOMEM; -#else - errorfc(fc, "fsid option not supported"); -#endif break; case Opt_domain_id: -#ifdef CONFIG_EROFS_FS_ONDEMAND kfree(ctx->domain_id); ctx->domain_id = kstrdup(param->string, GFP_KERNEL); if (!ctx->domain_id) return -ENOMEM; -#else - errorfc(fc, "domain_id option not supported"); -#endif break; +#else + case Opt_fsid: + case Opt_domain_id: + errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name); + break; +#endif default: return -ENOPARAM; } From 1132d1c834d6185c89aef07c860fc143a6f2db93 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 13 Jan 2023 11:58:46 +0100 Subject: [PATCH 196/398] wifi: mt76: dma: do not increment queue head if mt76_dma_add_buf fails Do not increment queue head if mt76_dma_add_buf fails for Wireless Ethernet Dispatcher rx queues. Fixes: cd372b8c99c5 ("wifi: mt76: add WED RX support to mt76_dma_{add,get}_buf") Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau (cherry picked from commit fe13dad8992be0b26c1be390bcd111acf9892c17) Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230113105848.34642-1-nbd@nbd.name --- drivers/net/wireless/mediatek/mt76/dma.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index f795548562f5..c058a02e9ba5 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -212,14 +212,14 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, { struct mt76_queue_entry *entry; struct mt76_desc *desc; - u32 ctrl; int i, idx = -1; + u32 ctrl, next; for (i = 0; i < nbufs; i += 2, buf += 2) { u32 buf0 = buf[0].addr, buf1 = 0; idx = q->head; - q->head = (q->head + 1) % q->ndesc; + next = (q->head + 1) % q->ndesc; desc = &q->desc[idx]; entry = &q->entry[idx]; @@ -239,8 +239,8 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, MT_DMA_CTL_TO_HOST; } else { if (txwi) { - q->entry[q->head].txwi = DMA_DUMMY_DATA; - q->entry[q->head].skip_buf0 = true; + q->entry[next].txwi = DMA_DUMMY_DATA; + q->entry[next].skip_buf0 = true; } if (buf[0].skip_unmap) @@ -271,6 +271,7 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, WRITE_ONCE(desc->info, cpu_to_le32(info)); WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); + q->head = next; q->queued++; } From e5c3ac895750b39ef53b84ff4814617ecd69d556 Mon Sep 17 00:00:00 2001 From: Lorenzo Bianconi Date: Fri, 13 Jan 2023 11:58:47 +0100 Subject: [PATCH 197/398] wifi: mt76: handle possible mt76_rx_token_consume failures Take into account possible error conditions of mt76_rx_token_consume routine in mt7915_mmio_wed_init_rx_buf() and mt76_dma_add_buf() Fixes: cd372b8c99c5 ("wifi: mt76: add WED RX support to mt76_dma_{add,get}_buf") Fixes: 4f831d18d12d ("wifi: mt76: mt7915: enable WED RX support") Signed-off-by: Lorenzo Bianconi Signed-off-by: Felix Fietkau (cherry picked from commit 96f134dc19645be4994e89a2f68fa89309becbee) Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230113105848.34642-2-nbd@nbd.name --- drivers/net/wireless/mediatek/mt76/dma.c | 10 +++++++++- drivers/net/wireless/mediatek/mt76/mt7915/mmio.c | 7 +++++++ drivers/net/wireless/mediatek/mt76/tx.c | 7 ++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index c058a02e9ba5..61a8ab9e1db5 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -234,6 +234,9 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, rx_token = mt76_rx_token_consume(dev, (void *)skb, t, buf[0].addr); + if (rx_token < 0) + return -ENOMEM; + buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token); ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len) | MT_DMA_CTL_TO_HOST; @@ -602,7 +605,12 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) qbuf.addr = addr + offset; qbuf.len = len - offset; qbuf.skip_unmap = false; - mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t); + if (mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t) < 0) { + dma_unmap_single(dev->dma_dev, addr, len, + DMA_FROM_DEVICE); + skb_free_frag(buf); + break; + } frames++; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c index 0a95c3da241b..8388e2a65853 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mmio.c @@ -653,6 +653,13 @@ static u32 mt7915_mmio_wed_init_rx_buf(struct mtk_wed_device *wed, int size) desc->buf0 = cpu_to_le32(phy_addr); token = mt76_rx_token_consume(&dev->mt76, ptr, t, phy_addr); + if (token < 0) { + dma_unmap_single(dev->mt76.dma_dev, phy_addr, + wed->wlan.rx_size, DMA_TO_DEVICE); + skb_free_frag(ptr); + goto unmap; + } + desc->token |= cpu_to_le32(FIELD_PREP(MT_DMA_CTL_TOKEN, token)); desc++; diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c index 24568b98ed9d..1f309d05380a 100644 --- a/drivers/net/wireless/mediatek/mt76/tx.c +++ b/drivers/net/wireless/mediatek/mt76/tx.c @@ -764,11 +764,12 @@ int mt76_rx_token_consume(struct mt76_dev *dev, void *ptr, spin_lock_bh(&dev->rx_token_lock); token = idr_alloc(&dev->rx_token, t, 0, dev->rx_token_size, GFP_ATOMIC); + if (token >= 0) { + t->ptr = ptr; + t->dma_addr = phys; + } spin_unlock_bh(&dev->rx_token_lock); - t->ptr = ptr; - t->dma_addr = phys; - return token; } EXPORT_SYMBOL_GPL(mt76_rx_token_consume); From 953519b35227d5dbbb5c5724f1f539735fbf7781 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 13 Jan 2023 11:58:48 +0100 Subject: [PATCH 198/398] wifi: mt76: dma: fix a regression in adding rx buffers When adding WED support, mt76_dma_add_buf was accidentally changed to set the skip_buf0 flag for tx buffers on the wrong queue descriptor entry. Additionally, there is a rxwi leak when rx buffer allocation fails. Fix this and make the code more readable by adding a separate function for adding rx buffers. Reported-by: Mikhail Gavrilov Tested-by: Mikhail Gavrilov Link: https://lore.kernel.org/r/CABXGCsMEnQd=gYKTd1knRsWuxCb=Etv5nAre%2BXJS_s5FgVteYA@mail.gmail.com/ Reported-by: Mike Lothian Link: https://bugzilla.kernel.org/show_bug.cgi?id=216829 Reported-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/lkml/20230112171706.294550-1-angelogioacchino.delregno@collabora.com/ Fixes: cd372b8c99c5 ("wifi: mt76: add WED RX support to mt76_dma_{add,get}_buf") Signed-off-by: Felix Fietkau Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230113105848.34642-3-nbd@nbd.name --- drivers/net/wireless/mediatek/mt76/dma.c | 120 +++++++++++++---------- 1 file changed, 70 insertions(+), 50 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index 61a8ab9e1db5..06161815c180 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -205,6 +205,52 @@ mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q) mt76_dma_sync_idx(dev, q); } +static int +mt76_dma_add_rx_buf(struct mt76_dev *dev, struct mt76_queue *q, + struct mt76_queue_buf *buf, void *data) +{ + struct mt76_desc *desc = &q->desc[q->head]; + struct mt76_queue_entry *entry = &q->entry[q->head]; + struct mt76_txwi_cache *txwi = NULL; + u32 buf1 = 0, ctrl; + int idx = q->head; + int rx_token; + + ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len); + + if ((q->flags & MT_QFLAG_WED) && + FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) { + txwi = mt76_get_rxwi(dev); + if (!txwi) + return -ENOMEM; + + rx_token = mt76_rx_token_consume(dev, data, txwi, buf->addr); + if (rx_token < 0) { + mt76_put_rxwi(dev, txwi); + return -ENOMEM; + } + + buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token); + ctrl |= MT_DMA_CTL_TO_HOST; + } + + WRITE_ONCE(desc->buf0, cpu_to_le32(buf->addr)); + WRITE_ONCE(desc->buf1, cpu_to_le32(buf1)); + WRITE_ONCE(desc->ctrl, cpu_to_le32(ctrl)); + WRITE_ONCE(desc->info, 0); + + entry->dma_addr[0] = buf->addr; + entry->dma_len[0] = buf->len; + entry->txwi = txwi; + entry->buf = data; + entry->wcid = 0xffff; + entry->skip_buf1 = true; + q->head = (q->head + 1) % q->ndesc; + q->queued++; + + return idx; +} + static int mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, struct mt76_queue_buf *buf, int nbufs, u32 info, @@ -215,6 +261,11 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, int i, idx = -1; u32 ctrl, next; + if (txwi) { + q->entry[q->head].txwi = DMA_DUMMY_DATA; + q->entry[q->head].skip_buf0 = true; + } + for (i = 0; i < nbufs; i += 2, buf += 2) { u32 buf0 = buf[0].addr, buf1 = 0; @@ -224,51 +275,28 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q, desc = &q->desc[idx]; entry = &q->entry[idx]; - if ((q->flags & MT_QFLAG_WED) && - FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) { - struct mt76_txwi_cache *t = txwi; - int rx_token; + if (buf[0].skip_unmap) + entry->skip_buf0 = true; + entry->skip_buf1 = i == nbufs - 1; - if (!t) - return -ENOMEM; + entry->dma_addr[0] = buf[0].addr; + entry->dma_len[0] = buf[0].len; - rx_token = mt76_rx_token_consume(dev, (void *)skb, t, - buf[0].addr); - if (rx_token < 0) - return -ENOMEM; - - buf1 |= FIELD_PREP(MT_DMA_CTL_TOKEN, rx_token); - ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len) | - MT_DMA_CTL_TO_HOST; - } else { - if (txwi) { - q->entry[next].txwi = DMA_DUMMY_DATA; - q->entry[next].skip_buf0 = true; - } - - if (buf[0].skip_unmap) - entry->skip_buf0 = true; - entry->skip_buf1 = i == nbufs - 1; - - entry->dma_addr[0] = buf[0].addr; - entry->dma_len[0] = buf[0].len; - - ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len); - if (i < nbufs - 1) { - entry->dma_addr[1] = buf[1].addr; - entry->dma_len[1] = buf[1].len; - buf1 = buf[1].addr; - ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len); - if (buf[1].skip_unmap) - entry->skip_buf1 = true; - } - - if (i == nbufs - 1) - ctrl |= MT_DMA_CTL_LAST_SEC0; - else if (i == nbufs - 2) - ctrl |= MT_DMA_CTL_LAST_SEC1; + ctrl = FIELD_PREP(MT_DMA_CTL_SD_LEN0, buf[0].len); + if (i < nbufs - 1) { + entry->dma_addr[1] = buf[1].addr; + entry->dma_len[1] = buf[1].len; + buf1 = buf[1].addr; + ctrl |= FIELD_PREP(MT_DMA_CTL_SD_LEN1, buf[1].len); + if (buf[1].skip_unmap) + entry->skip_buf1 = true; } + if (i == nbufs - 1) + ctrl |= MT_DMA_CTL_LAST_SEC0; + else if (i == nbufs - 2) + ctrl |= MT_DMA_CTL_LAST_SEC1; + WRITE_ONCE(desc->buf0, cpu_to_le32(buf0)); WRITE_ONCE(desc->buf1, cpu_to_le32(buf1)); WRITE_ONCE(desc->info, cpu_to_le32(info)); @@ -581,17 +609,9 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) spin_lock_bh(&q->lock); while (q->queued < q->ndesc - 1) { - struct mt76_txwi_cache *t = NULL; struct mt76_queue_buf qbuf; void *buf = NULL; - if ((q->flags & MT_QFLAG_WED) && - FIELD_GET(MT_QFLAG_WED_TYPE, q->flags) == MT76_WED_Q_RX) { - t = mt76_get_rxwi(dev); - if (!t) - break; - } - buf = page_frag_alloc(rx_page, q->buf_size, GFP_ATOMIC); if (!buf) break; @@ -605,7 +625,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q) qbuf.addr = addr + offset; qbuf.len = len - offset; qbuf.skip_unmap = false; - if (mt76_dma_add_buf(dev, q, &qbuf, 1, 0, buf, t) < 0) { + if (mt76_dma_add_rx_buf(dev, q, &qbuf, buf) < 0) { dma_unmap_single(dev->dma_dev, addr, len, DMA_FROM_DEVICE); skb_free_frag(buf); From 80f8a66dede0a4b4e9e846765a97809c6fe49ce5 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 13 Jan 2023 12:43:26 +0000 Subject: [PATCH 199/398] Revert "wifi: mac80211: fix memory leak in ieee80211_if_add()" This reverts commit 13e5afd3d773c6fc6ca2b89027befaaaa1ea7293. ieee80211_if_free() is already called from free_netdev(ndev) because ndev->priv_destructor == ieee80211_if_free syzbot reported: general protection fault, probably for non-canonical address 0xdffffc0000000004: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000020-0x0000000000000027] CPU: 0 PID: 10041 Comm: syz-executor.0 Not tainted 6.2.0-rc2-syzkaller-00388-g55b98837e37d #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 RIP: 0010:pcpu_get_page_chunk mm/percpu.c:262 [inline] RIP: 0010:pcpu_chunk_addr_search mm/percpu.c:1619 [inline] RIP: 0010:free_percpu mm/percpu.c:2271 [inline] RIP: 0010:free_percpu+0x186/0x10f0 mm/percpu.c:2254 Code: 80 3c 02 00 0f 85 f5 0e 00 00 48 8b 3b 48 01 ef e8 cf b3 0b 00 48 ba 00 00 00 00 00 fc ff df 48 8d 78 20 48 89 f9 48 c1 e9 03 <80> 3c 11 00 0f 85 3b 0e 00 00 48 8b 58 20 48 b8 00 00 00 00 00 fc RSP: 0018:ffffc90004ba7068 EFLAGS: 00010002 RAX: 0000000000000000 RBX: ffff88823ffe2b80 RCX: 0000000000000004 RDX: dffffc0000000000 RSI: ffffffff81c1f4e7 RDI: 0000000000000020 RBP: ffffe8fffe8fc220 R08: 0000000000000005 R09: 0000000000000000 R10: 0000000000000000 R11: 1ffffffff2179ab2 R12: ffff8880b983d000 R13: 0000000000000003 R14: 0000607f450fc220 R15: ffff88823ffe2988 FS: 00007fcb349de700(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000001b32220000 CR3: 000000004914f000 CR4: 00000000003506f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: netdev_run_todo+0x6bf/0x1100 net/core/dev.c:10352 ieee80211_register_hw+0x2663/0x4040 net/mac80211/main.c:1411 mac80211_hwsim_new_radio+0x2537/0x4d80 drivers/net/wireless/mac80211_hwsim.c:4583 hwsim_new_radio_nl+0xa09/0x10f0 drivers/net/wireless/mac80211_hwsim.c:5176 genl_family_rcv_msg_doit.isra.0+0x1e6/0x2d0 net/netlink/genetlink.c:968 genl_family_rcv_msg net/netlink/genetlink.c:1048 [inline] genl_rcv_msg+0x4ff/0x7e0 net/netlink/genetlink.c:1065 netlink_rcv_skb+0x165/0x440 net/netlink/af_netlink.c:2564 genl_rcv+0x28/0x40 net/netlink/genetlink.c:1076 netlink_unicast_kernel net/netlink/af_netlink.c:1330 [inline] netlink_unicast+0x547/0x7f0 net/netlink/af_netlink.c:1356 netlink_sendmsg+0x91b/0xe10 net/netlink/af_netlink.c:1932 sock_sendmsg_nosec net/socket.c:714 [inline] sock_sendmsg+0xd3/0x120 net/socket.c:734 ____sys_sendmsg+0x712/0x8c0 net/socket.c:2476 ___sys_sendmsg+0x110/0x1b0 net/socket.c:2530 __sys_sendmsg+0xf7/0x1c0 net/socket.c:2559 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Reported-by: syzbot Fixes: 13e5afd3d773 ("wifi: mac80211: fix memory leak in ieee80211_if_add()") Signed-off-by: Eric Dumazet Cc: Zhengchao Shao Cc: Johannes Berg Signed-off-by: Kalle Valo Link: https://lore.kernel.org/r/20230113124326.3533978-1-edumazet@google.com --- net/mac80211/iface.c | 1 - 1 file changed, 1 deletion(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index e20c3fe9a0b1..23ed13f15067 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -2197,7 +2197,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, ret = cfg80211_register_netdevice(ndev); if (ret) { - ieee80211_if_free(ndev); free_netdev(ndev); return ret; } From 3ef5abd9b5c738bc6fa9a65e40331ef2cb03ad9c Mon Sep 17 00:00:00 2001 From: John Ogness Date: Thu, 12 Jan 2023 17:18:13 +0106 Subject: [PATCH 200/398] tty: serial: kgdboc: fix mutex locking order for configure_kgdboc() Several mutexes are taken while setting up console serial ports. In particular, the tty_port->mutex and @console_mutex are taken: serial_pnp_probe serial8250_register_8250_port uart_add_one_port (locks tty_port->mutex) uart_configure_port register_console (locks @console_mutex) In order to synchronize kgdb's tty_find_polling_driver() with register_console(), commit 6193bc90849a ("tty: serial: kgdboc: synchronize tty_find_polling_driver() and register_console()") takes the @console_mutex. However, this leads to the following call chain (with locking): platform_probe kgdboc_probe configure_kgdboc (locks @console_mutex) tty_find_polling_driver uart_poll_init (locks tty_port->mutex) uart_set_options This is clearly deadlock potential due to the reverse lock ordering. Since uart_set_options() requires holding @console_mutex in order to serialize early initialization of the serial-console lock, take the @console_mutex in uart_poll_init() instead of configure_kgdboc(). Since configure_kgdboc() was using @console_mutex for safe traversal of the console list, change it to use the SRCU iterator instead. Add comments to uart_set_options() kerneldoc mentioning that it requires holding @console_mutex (aka the console_list_lock). Fixes: 6193bc90849a ("tty: serial: kgdboc: synchronize tty_find_polling_driver() and register_console()") Signed-off-by: John Ogness Reviewed-by: Sergey Senozhatsky Reviewed-by: Petr Mladek [pmladek@suse.com: Export console_srcu_read_lock_is_held() to fix build kgdboc as a module.] Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20230112161213.1434854-1-john.ogness@linutronix.de --- drivers/tty/serial/kgdboc.c | 20 +++++--------------- drivers/tty/serial/serial_core.c | 5 +++++ kernel/printk/printk.c | 1 + 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c index a3ed9b34e2ab..7ce7bb164005 100644 --- a/drivers/tty/serial/kgdboc.c +++ b/drivers/tty/serial/kgdboc.c @@ -171,6 +171,7 @@ static int configure_kgdboc(void) int err = -ENODEV; char *cptr = config; struct console *cons; + int cookie; if (!strlen(config) || isspace(config[0])) { err = 0; @@ -189,20 +190,9 @@ static int configure_kgdboc(void) if (kgdboc_register_kbd(&cptr)) goto do_register; - /* - * tty_find_polling_driver() can call uart_set_options() - * (via poll_init) to configure the uart. Take the console_list_lock - * in order to synchronize against register_console(), which can also - * configure the uart via uart_set_options(). This also allows safe - * traversal of the console list. - */ - console_list_lock(); - p = tty_find_polling_driver(cptr, &tty_line); - if (!p) { - console_list_unlock(); + if (!p) goto noconfig; - } /* * Take console_lock to serialize device() callback with @@ -211,7 +201,8 @@ static int configure_kgdboc(void) */ console_lock(); - for_each_console(cons) { + cookie = console_srcu_read_lock(); + for_each_console_srcu(cons) { int idx; if (cons->device && cons->device(cons, &idx) == p && idx == tty_line) { @@ -219,11 +210,10 @@ static int configure_kgdboc(void) break; } } + console_srcu_read_unlock(cookie); console_unlock(); - console_list_unlock(); - kgdb_tty_driver = p; kgdb_tty_line = tty_line; diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index b9fbbee598b8..ec874f3a567c 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2212,6 +2212,9 @@ EXPORT_SYMBOL_GPL(uart_parse_options); * @parity: parity character - 'n' (none), 'o' (odd), 'e' (even) * @bits: number of data bits * @flow: flow control character - 'r' (rts) + * + * Locking: Caller must hold console_list_lock in order to serialize + * early initialization of the serial-console lock. */ int uart_set_options(struct uart_port *port, struct console *co, @@ -2619,7 +2622,9 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options) if (!ret && options) { uart_parse_options(options, &baud, &parity, &bits, &flow); + console_list_lock(); ret = uart_set_options(port, NULL, baud, parity, bits, flow); + console_list_unlock(); } out: mutex_unlock(&tport->mutex); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 9ec101766471..3f7c8ed96512 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -123,6 +123,7 @@ bool console_srcu_read_lock_is_held(void) { return srcu_read_lock_held(&console_srcu); } +EXPORT_SYMBOL(console_srcu_read_lock_is_held); #endif enum devkmsg_log_bits { From 3e9900f3bd7ba30d60f82b162b70a1dffe4e8e24 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 16 Jan 2023 08:51:05 -0700 Subject: [PATCH 201/398] pktcdvd: check for NULL returna fter calling bio_split_to_limits() The revert of the removal of this driver happened after we fixed up the split limits for NOWAIT issue, hence it got missed. Ensure that we check for a NULL bio after splitting, in case it should be retried. Marking this as fixing both commits, so that stable backport will do this correctly. Cc: stable@vger.kernel.org Fixes: 9cea62b2cbab ("block: don't allow splitting of a REQ_NOWAIT bio") Fixes: 4b83e99ee709 ("Revert "pktcdvd: remove driver."") Signed-off-by: Jens Axboe --- drivers/block/pktcdvd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 4cea3b08087e..2f1a92509271 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2400,6 +2400,8 @@ static void pkt_submit_bio(struct bio *bio) struct bio *split; bio = bio_split_to_limits(bio); + if (!bio) + return; pkt_dbg(2, pd, "start = %6llx stop = %6llx\n", (unsigned long long)bio->bi_iter.bi_sector, From 4fe59a130c112460626a6a8b9232aa580d9b8efc Mon Sep 17 00:00:00 2001 From: Anuradha Weeraman Date: Mon, 16 Jan 2023 18:26:34 +0530 Subject: [PATCH 202/398] kernel/printk/printk.c: Fix W=1 kernel-doc warning Fix W=1 kernel-doc warning: kernel/printk/printk.c: - Include function parameter in console_lock_spinning_disable_and_check() Signed-off-by: Anuradha Weeraman Reviewed-by: Petr Mladek Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/20230116125635.374567-1-anuradha@debian.org --- kernel/printk/printk.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 3f7c8ed96512..39221b0f918d 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -1892,6 +1892,7 @@ static void console_lock_spinning_enable(void) /** * console_lock_spinning_disable_and_check - mark end of code where another * thread was able to busy wait and check if there is a waiter + * @cookie: cookie returned from console_srcu_read_lock() * * This is called at the end of the section where spinning is allowed. * It has two functions. First, it is a signal that it is no longer From 0f097f08c9b3c1fdb6cc9f2dd423abc17d13f1a2 Mon Sep 17 00:00:00 2001 From: Yishai Hadas Date: Wed, 11 Jan 2023 12:10:54 +0200 Subject: [PATCH 203/398] lib/scatterlist: Fix to calculate the last_pg properly The last_pg is wrong, it is actually the first page of the last scatterlist element. To get the last page of the last scatterlist element we have to add prv->length. So it is checking mergability against the wrong page, Further, a SG element is not guaranteed to end on a page boundary, so we have to check the sub page location also for merge eligibility. Fix the above by checking physical contiguity based on PFNs, compute the actual last page and then call pages_are_mergable(). Fixes: 1567b49d1a40 ("lib/scatterlist: add check when merging zone device pages") Link: https://lore.kernel.org/r/20230111101054.188136-1-yishaih@nvidia.com Reported-by: Jason Gunthorpe Signed-off-by: Yishai Hadas Reviewed-by: Chaitanya Kulkarni Signed-off-by: Jason Gunthorpe --- lib/scatterlist.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lib/scatterlist.c b/lib/scatterlist.c index f72aa50c6654..8d7519a8f308 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -470,22 +470,27 @@ int sg_alloc_append_table_from_pages(struct sg_append_table *sgt_append, return -EOPNOTSUPP; if (sgt_append->prv) { + unsigned long next_pfn = (page_to_phys(sg_page(sgt_append->prv)) + + sgt_append->prv->offset + sgt_append->prv->length) / PAGE_SIZE; + if (WARN_ON(offset)) return -EINVAL; /* Merge contiguous pages into the last SG */ prv_len = sgt_append->prv->length; - last_pg = sg_page(sgt_append->prv); - while (n_pages && pages_are_mergeable(pages[0], last_pg)) { - if (sgt_append->prv->length + PAGE_SIZE > max_segment) - break; - sgt_append->prv->length += PAGE_SIZE; - last_pg = pages[0]; - pages++; - n_pages--; + if (page_to_pfn(pages[0]) == next_pfn) { + last_pg = pfn_to_page(next_pfn - 1); + while (n_pages && pages_are_mergeable(pages[0], last_pg)) { + if (sgt_append->prv->length + PAGE_SIZE > max_segment) + break; + sgt_append->prv->length += PAGE_SIZE; + last_pg = pages[0]; + pages++; + n_pages--; + } + if (!n_pages) + goto out; } - if (!n_pages) - goto out; } /* compute number of contiguous chunks */ From 0e0078f72be81bbb2a02b229fd2cec8ad63e4fb1 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 21 Nov 2022 18:47:48 +0100 Subject: [PATCH 204/398] btrfs: factor out scratching of one regular super block btrfs_scratch_superblocks open codes scratching super block of a non-zoned super block. Split the code to read, zero and write the superblock for regular devices into a separate helper. Reviewed-by: Johannes Thumshirn Signed-off-by: Christoph Hellwig Reviewed-by: David Sterba [ update changelog ] Signed-off-by: David Sterba --- fs/btrfs/volumes.c | 51 +++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index bf0decaac7f3..119dc26ca141 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2014,42 +2014,43 @@ static u64 btrfs_num_devices(struct btrfs_fs_info *fs_info) return num_devices; } +static void btrfs_scratch_superblock(struct btrfs_fs_info *fs_info, + struct block_device *bdev, int copy_num) +{ + struct btrfs_super_block *disk_super; + struct page *page; + int ret; + + disk_super = btrfs_read_dev_one_super(bdev, copy_num, false); + if (IS_ERR(disk_super)) + return; + + memset(&disk_super->magic, 0, sizeof(disk_super->magic)); + page = virt_to_page(disk_super); + set_page_dirty(page); + lock_page(page); + /* write_on_page() unlocks the page */ + ret = write_one_page(page); + if (ret) + btrfs_warn(fs_info, "error clearing superblock number %d (%d)", + copy_num, ret); + btrfs_release_disk_super(disk_super); +} + void btrfs_scratch_superblocks(struct btrfs_fs_info *fs_info, struct block_device *bdev, const char *device_path) { - struct btrfs_super_block *disk_super; int copy_num; if (!bdev) return; for (copy_num = 0; copy_num < BTRFS_SUPER_MIRROR_MAX; copy_num++) { - struct page *page; - int ret; - - disk_super = btrfs_read_dev_one_super(bdev, copy_num, false); - if (IS_ERR(disk_super)) - continue; - - if (bdev_is_zoned(bdev)) { + if (bdev_is_zoned(bdev)) btrfs_reset_sb_log_zones(bdev, copy_num); - continue; - } - - memset(&disk_super->magic, 0, sizeof(disk_super->magic)); - - page = virt_to_page(disk_super); - set_page_dirty(page); - lock_page(page); - /* write_on_page() unlocks the page */ - ret = write_one_page(page); - if (ret) - btrfs_warn(fs_info, - "error clearing superblock number %d (%d)", - copy_num, ret); - btrfs_release_disk_super(disk_super); - + else + btrfs_scratch_superblock(fs_info, bdev, copy_num); } /* Notify udev that device has changed */ From 26ecf243e407be54807ad67210f7e83b9fad71ea Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 21 Nov 2022 18:47:49 +0100 Subject: [PATCH 205/398] btrfs: stop using write_one_page in btrfs_scratch_superblock write_one_page is an awkward interface that expects the page locked and ->writepage to be implemented. Replace that by zeroing the signature bytes and synchronize the block device page using the proper bdev helpers. Signed-off-by: Christoph Hellwig Reviewed-by: David Sterba [ update changelog ] Signed-off-by: David Sterba --- fs/btrfs/volumes.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 119dc26ca141..bcfef75b97da 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -2018,23 +2018,22 @@ static void btrfs_scratch_superblock(struct btrfs_fs_info *fs_info, struct block_device *bdev, int copy_num) { struct btrfs_super_block *disk_super; - struct page *page; + const size_t len = sizeof(disk_super->magic); + const u64 bytenr = btrfs_sb_offset(copy_num); int ret; - disk_super = btrfs_read_dev_one_super(bdev, copy_num, false); + disk_super = btrfs_read_disk_super(bdev, bytenr, bytenr); if (IS_ERR(disk_super)) return; - memset(&disk_super->magic, 0, sizeof(disk_super->magic)); - page = virt_to_page(disk_super); - set_page_dirty(page); - lock_page(page); - /* write_on_page() unlocks the page */ - ret = write_one_page(page); + memset(&disk_super->magic, 0, len); + folio_mark_dirty(virt_to_folio(disk_super)); + btrfs_release_disk_super(disk_super); + + ret = sync_blockdev_range(bdev, bytenr, bytenr + len - 1); if (ret) btrfs_warn(fs_info, "error clearing superblock number %d (%d)", copy_num, ret); - btrfs_release_disk_super(disk_super); } void btrfs_scratch_superblocks(struct btrfs_fs_info *fs_info, From 1f55ee6d0901d915801618bda0af4e5b937e3db7 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 12 Jan 2023 14:17:20 +0000 Subject: [PATCH 206/398] btrfs: fix invalid leaf access due to inline extent during lseek During lseek, for SEEK_DATA and SEEK_HOLE modes, we access the disk_bytenr of an extent without checking its type. However inline extents have their data starting the offset of the disk_bytenr field, so accessing that field when we have an inline extent can result in either of the following: 1) Interpret the inline extent's data as a disk_bytenr value; 2) In case the inline data is less than 8 bytes, we access part of some other item in the leaf, or unused space in the leaf; 3) In case the inline data is less than 8 bytes and the extent item is the first item in the leaf, we can access beyond the leaf's limit. So fix this by not accessing the disk_bytenr field if we have an inline extent. Fixes: b6e833567ea1 ("btrfs: make hole and data seeking a lot more efficient") Reported-by: Matthias Schoepfer Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=216908 Link: https://lore.kernel.org/linux-btrfs/7f25442f-b121-2a3a-5a3d-22bcaae83cd4@leemhuis.info/ CC: stable@vger.kernel.org # 6.1 Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/file.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 834bbcb91102..af046d22300e 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -3541,6 +3541,7 @@ static loff_t find_desired_extent(struct file *file, loff_t offset, int whence) struct extent_buffer *leaf = path->nodes[0]; struct btrfs_file_extent_item *extent; u64 extent_end; + u8 type; if (path->slots[0] >= btrfs_header_nritems(leaf)) { ret = btrfs_next_leaf(root, path); @@ -3596,10 +3597,16 @@ static loff_t find_desired_extent(struct file *file, loff_t offset, int whence) extent = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_file_extent_item); + type = btrfs_file_extent_type(leaf, extent); - if (btrfs_file_extent_disk_bytenr(leaf, extent) == 0 || - btrfs_file_extent_type(leaf, extent) == - BTRFS_FILE_EXTENT_PREALLOC) { + /* + * Can't access the extent's disk_bytenr field if this is an + * inline extent, since at that offset, it's where the extent + * data starts. + */ + if (type == BTRFS_FILE_EXTENT_PREALLOC || + (type == BTRFS_FILE_EXTENT_REG && + btrfs_file_extent_disk_bytenr(leaf, extent) == 0)) { /* * Explicit hole or prealloc extent, search for delalloc. * A prealloc extent is treated like a hole. From b7adbf9ada3513d2092362c8eac5cddc5b651f5c Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Thu, 12 Jan 2023 16:31:08 +0000 Subject: [PATCH 207/398] btrfs: fix race between quota rescan and disable leading to NULL pointer deref If we have one task trying to start the quota rescan worker while another one is trying to disable quotas, we can end up hitting a race that results in the quota rescan worker doing a NULL pointer dereference. The steps for this are the following: 1) Quotas are enabled; 2) Task A calls the quota rescan ioctl and enters btrfs_qgroup_rescan(). It calls qgroup_rescan_init() which returns 0 (success) and then joins a transaction and commits it; 3) Task B calls the quota disable ioctl and enters btrfs_quota_disable(). It clears the bit BTRFS_FS_QUOTA_ENABLED from fs_info->flags and calls btrfs_qgroup_wait_for_completion(), which returns immediately since the rescan worker is not yet running. Then it starts a transaction and locks fs_info->qgroup_ioctl_lock; 4) Task A queues the rescan worker, by calling btrfs_queue_work(); 5) The rescan worker starts, and calls rescan_should_stop() at the start of its while loop, which results in 0 iterations of the loop, since the flag BTRFS_FS_QUOTA_ENABLED was cleared from fs_info->flags by task B at step 3); 6) Task B sets fs_info->quota_root to NULL; 7) The rescan worker tries to start a transaction and uses fs_info->quota_root as the root argument for btrfs_start_transaction(). This results in a NULL pointer dereference down the call chain of btrfs_start_transaction(). The stack trace is something like the one reported in Link tag below: general protection fault, probably for non-canonical address 0xdffffc0000000041: 0000 [#1] PREEMPT SMP KASAN KASAN: null-ptr-deref in range [0x0000000000000208-0x000000000000020f] CPU: 1 PID: 34 Comm: kworker/u4:2 Not tainted 6.1.0-syzkaller-13872-gb6bb9676f216 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 Workqueue: btrfs-qgroup-rescan btrfs_work_helper RIP: 0010:start_transaction+0x48/0x10f0 fs/btrfs/transaction.c:564 Code: 48 89 fb 48 (...) RSP: 0018:ffffc90000ab7ab0 EFLAGS: 00010206 RAX: 0000000000000041 RBX: 0000000000000208 RCX: ffff88801779ba80 RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000 RBP: dffffc0000000000 R08: 0000000000000001 R09: fffff52000156f5d R10: fffff52000156f5d R11: 1ffff92000156f5c R12: 0000000000000000 R13: 0000000000000001 R14: 0000000000000001 R15: 0000000000000003 FS: 0000000000000000(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f2bea75b718 CR3: 000000001d0cc000 CR4: 00000000003506e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: btrfs_qgroup_rescan_worker+0x3bb/0x6a0 fs/btrfs/qgroup.c:3402 btrfs_work_helper+0x312/0x850 fs/btrfs/async-thread.c:280 process_one_work+0x877/0xdb0 kernel/workqueue.c:2289 worker_thread+0xb14/0x1330 kernel/workqueue.c:2436 kthread+0x266/0x300 kernel/kthread.c:376 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:308 Modules linked in: So fix this by having the rescan worker function not attempt to start a transaction if it didn't do any rescan work. Reported-by: syzbot+96977faa68092ad382c4@syzkaller.appspotmail.com Link: https://lore.kernel.org/linux-btrfs/000000000000e5454b05f065a803@google.com/ Fixes: e804861bd4e6 ("btrfs: fix deadlock between quota disable and qgroup rescan worker") CC: stable@vger.kernel.org # 5.4+ Signed-off-by: Filipe Manana Signed-off-by: David Sterba --- fs/btrfs/qgroup.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 00851c86aa8a..af97413abcf4 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -3367,6 +3367,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work) int err = -ENOMEM; int ret = 0; bool stopped = false; + bool did_leaf_rescans = false; path = btrfs_alloc_path(); if (!path) @@ -3387,6 +3388,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work) } err = qgroup_rescan_leaf(trans, path); + did_leaf_rescans = true; if (err > 0) btrfs_commit_transaction(trans); @@ -3407,16 +3409,23 @@ out: mutex_unlock(&fs_info->qgroup_rescan_lock); /* - * only update status, since the previous part has already updated the - * qgroup info. + * Only update status, since the previous part has already updated the + * qgroup info, and only if we did any actual work. This also prevents + * race with a concurrent quota disable, which has already set + * fs_info->quota_root to NULL and cleared BTRFS_FS_QUOTA_ENABLED at + * btrfs_quota_disable(). */ - trans = btrfs_start_transaction(fs_info->quota_root, 1); - if (IS_ERR(trans)) { - err = PTR_ERR(trans); + if (did_leaf_rescans) { + trans = btrfs_start_transaction(fs_info->quota_root, 1); + if (IS_ERR(trans)) { + err = PTR_ERR(trans); + trans = NULL; + btrfs_err(fs_info, + "fail to start transaction for status update: %d", + err); + } + } else { trans = NULL; - btrfs_err(fs_info, - "fail to start transaction for status update: %d", - err); } mutex_lock(&fs_info->qgroup_rescan_lock); From e3ff8887e7db757360f97634e0d6f4b8e27a8c46 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Tue, 3 Jan 2023 19:28:33 +0800 Subject: [PATCH 208/398] blk-cgroup: fix missing pd_online_fn() while activating policy If the policy defines pd_online_fn(), it should be called after pd_init_fn(), like blkg_create(). Signed-off-by: Yu Kuai Acked-by: Tejun Heo Link: https://lore.kernel.org/r/20230103112833.2013432-1-yukuai1@huaweicloud.com Signed-off-by: Jens Axboe --- block/blk-cgroup.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index ce6a2b7d3dfb..4c94a6560f62 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -1455,6 +1455,10 @@ retry: list_for_each_entry_reverse(blkg, &q->blkg_list, q_node) pol->pd_init_fn(blkg->pd[pol->plid]); + if (pol->pd_online_fn) + list_for_each_entry_reverse(blkg, &q->blkg_list, q_node) + pol->pd_online_fn(blkg->pd[pol->plid]); + __set_bit(pol->plid, q->blkcg_pols); ret = 0; From d52fec86a465355b379e839fa372ead0334d62e6 Mon Sep 17 00:00:00 2001 From: Huacai Chen Date: Tue, 17 Jan 2023 11:42:16 +0800 Subject: [PATCH 209/398] LoongArch: Add HWCAP_LOONGARCH_CPUCFG to elf_hwcap HWCAP_LOONGARCH_CPUCFG is missing in elf_hwcap, so add it for glibc's later use. Cc: stable@vger.kernel.org Reported-by: Yinyu Cai Signed-off-by: Huacai Chen --- arch/loongarch/kernel/cpu-probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c index 255a09876ef2..3a3fce2d7846 100644 --- a/arch/loongarch/kernel/cpu-probe.c +++ b/arch/loongarch/kernel/cpu-probe.c @@ -94,7 +94,7 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c) c->options = LOONGARCH_CPU_CPUCFG | LOONGARCH_CPU_CSR | LOONGARCH_CPU_TLB | LOONGARCH_CPU_VINT | LOONGARCH_CPU_WATCH; - elf_hwcap |= HWCAP_LOONGARCH_CRC32; + elf_hwcap = HWCAP_LOONGARCH_CPUCFG | HWCAP_LOONGARCH_CRC32; config = read_cpucfg(LOONGARCH_CPUCFG1); if (config & CPUCFG1_UAL) { From 2959fce7fdb73fc784aefd58cc34b1ba700826aa Mon Sep 17 00:00:00 2001 From: Tiezhu Yang Date: Tue, 17 Jan 2023 11:42:16 +0800 Subject: [PATCH 210/398] LoongArch: Use common function sign_extend64() There exists a common function sign_extend64() to sign extend a 64-bit value using specified bit as sign-bit in include/linux/bitops.h, it is more efficient, let us use it and remove the arch-specific sign_extend() under arch/loongarch. Suggested-by: Jinyang He Signed-off-by: Tiezhu Yang Signed-off-by: Huacai Chen --- arch/loongarch/include/asm/inst.h | 8 -------- arch/loongarch/kernel/alternative.c | 6 +++--- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h index c00e1512d4fa..6cd994d6d9d0 100644 --- a/arch/loongarch/include/asm/inst.h +++ b/arch/loongarch/include/asm/inst.h @@ -377,14 +377,6 @@ static inline bool unsigned_imm_check(unsigned long val, unsigned int bit) return val < (1UL << bit); } -static inline unsigned long sign_extend(unsigned long val, unsigned int idx) -{ - if (!is_imm_negative(val, idx + 1)) - return ((1UL << idx) - 1) & val; - else - return ~((1UL << idx) - 1) | val; -} - #define DEF_EMIT_REG0I26_FORMAT(NAME, OP) \ static inline void emit_##NAME(union loongarch_instruction *insn, \ int offset) \ diff --git a/arch/loongarch/kernel/alternative.c b/arch/loongarch/kernel/alternative.c index c5aebeac960b..4ad13847e962 100644 --- a/arch/loongarch/kernel/alternative.c +++ b/arch/loongarch/kernel/alternative.c @@ -74,7 +74,7 @@ static void __init_or_module recompute_jump(union loongarch_instruction *buf, switch (src->reg0i26_format.opcode) { case b_op: case bl_op: - jump_addr = cur_pc + sign_extend((si_h << 16 | si_l) << 2, 27); + jump_addr = cur_pc + sign_extend64((si_h << 16 | si_l) << 2, 27); if (in_alt_jump(jump_addr, start, end)) return; offset = jump_addr - pc; @@ -93,7 +93,7 @@ static void __init_or_module recompute_jump(union loongarch_instruction *buf, fallthrough; case beqz_op: case bnez_op: - jump_addr = cur_pc + sign_extend((si_h << 16 | si_l) << 2, 22); + jump_addr = cur_pc + sign_extend64((si_h << 16 | si_l) << 2, 22); if (in_alt_jump(jump_addr, start, end)) return; offset = jump_addr - pc; @@ -112,7 +112,7 @@ static void __init_or_module recompute_jump(union loongarch_instruction *buf, case bge_op: case bltu_op: case bgeu_op: - jump_addr = cur_pc + sign_extend(si << 2, 17); + jump_addr = cur_pc + sign_extend64(si << 2, 17); if (in_alt_jump(jump_addr, start, end)) return; offset = jump_addr - pc; From 3200983fa8e2c8aa17ed911b617b4a248bcb1267 Mon Sep 17 00:00:00 2001 From: Youling Tang Date: Tue, 17 Jan 2023 11:42:16 +0800 Subject: [PATCH 211/398] LoongArch: Simplify larch_insn_gen_xxx implementation Simplify larch_insn_gen_xxx implementation by reusing emit_xxx. Signed-off-by: Youling Tang Signed-off-by: Huacai Chen --- arch/loongarch/include/asm/inst.h | 1 + arch/loongarch/kernel/inst.c | 45 +++++-------------------------- 2 files changed, 8 insertions(+), 38 deletions(-) diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h index 6cd994d6d9d0..7eedd83fd0d7 100644 --- a/arch/loongarch/include/asm/inst.h +++ b/arch/loongarch/include/asm/inst.h @@ -393,6 +393,7 @@ static inline void emit_##NAME(union loongarch_instruction *insn, \ } DEF_EMIT_REG0I26_FORMAT(b, b_op) +DEF_EMIT_REG0I26_FORMAT(bl, bl_op) #define DEF_EMIT_REG1I20_FORMAT(NAME, OP) \ static inline void emit_##NAME(union loongarch_instruction *insn, \ diff --git a/arch/loongarch/kernel/inst.c b/arch/loongarch/kernel/inst.c index 512579d79b22..badc59087042 100644 --- a/arch/loongarch/kernel/inst.c +++ b/arch/loongarch/kernel/inst.c @@ -58,7 +58,6 @@ u32 larch_insn_gen_nop(void) u32 larch_insn_gen_b(unsigned long pc, unsigned long dest) { long offset = dest - pc; - unsigned int immediate_l, immediate_h; union loongarch_instruction insn; if ((offset & 3) || offset < -SZ_128M || offset >= SZ_128M) { @@ -66,15 +65,7 @@ u32 larch_insn_gen_b(unsigned long pc, unsigned long dest) return INSN_BREAK; } - offset >>= 2; - - immediate_l = offset & 0xffff; - offset >>= 16; - immediate_h = offset & 0x3ff; - - insn.reg0i26_format.opcode = b_op; - insn.reg0i26_format.immediate_l = immediate_l; - insn.reg0i26_format.immediate_h = immediate_h; + emit_b(&insn, offset >> 2); return insn.word; } @@ -82,7 +73,6 @@ u32 larch_insn_gen_b(unsigned long pc, unsigned long dest) u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest) { long offset = dest - pc; - unsigned int immediate_l, immediate_h; union loongarch_instruction insn; if ((offset & 3) || offset < -SZ_128M || offset >= SZ_128M) { @@ -90,15 +80,7 @@ u32 larch_insn_gen_bl(unsigned long pc, unsigned long dest) return INSN_BREAK; } - offset >>= 2; - - immediate_l = offset & 0xffff; - offset >>= 16; - immediate_h = offset & 0x3ff; - - insn.reg0i26_format.opcode = bl_op; - insn.reg0i26_format.immediate_l = immediate_l; - insn.reg0i26_format.immediate_h = immediate_h; + emit_bl(&insn, offset >> 2); return insn.word; } @@ -107,10 +89,7 @@ u32 larch_insn_gen_or(enum loongarch_gpr rd, enum loongarch_gpr rj, enum loongar { union loongarch_instruction insn; - insn.reg3_format.opcode = or_op; - insn.reg3_format.rd = rd; - insn.reg3_format.rj = rj; - insn.reg3_format.rk = rk; + emit_or(&insn, rd, rj, rk); return insn.word; } @@ -124,9 +103,7 @@ u32 larch_insn_gen_lu12iw(enum loongarch_gpr rd, int imm) { union loongarch_instruction insn; - insn.reg1i20_format.opcode = lu12iw_op; - insn.reg1i20_format.rd = rd; - insn.reg1i20_format.immediate = imm; + emit_lu12iw(&insn, rd, imm); return insn.word; } @@ -135,9 +112,7 @@ u32 larch_insn_gen_lu32id(enum loongarch_gpr rd, int imm) { union loongarch_instruction insn; - insn.reg1i20_format.opcode = lu32id_op; - insn.reg1i20_format.rd = rd; - insn.reg1i20_format.immediate = imm; + emit_lu32id(&insn, rd, imm); return insn.word; } @@ -146,10 +121,7 @@ u32 larch_insn_gen_lu52id(enum loongarch_gpr rd, enum loongarch_gpr rj, int imm) { union loongarch_instruction insn; - insn.reg2i12_format.opcode = lu52id_op; - insn.reg2i12_format.rd = rd; - insn.reg2i12_format.rj = rj; - insn.reg2i12_format.immediate = imm; + emit_lu52id(&insn, rd, rj, imm); return insn.word; } @@ -158,10 +130,7 @@ u32 larch_insn_gen_jirl(enum loongarch_gpr rd, enum loongarch_gpr rj, unsigned l { union loongarch_instruction insn; - insn.reg2i16_format.opcode = jirl_op; - insn.reg2i16_format.rd = rd; - insn.reg2i16_format.rj = rj; - insn.reg2i16_format.immediate = (dest - pc) >> 2; + emit_jirl(&insn, rj, rd, (dest - pc) >> 2); return insn.word; } From e2f27392275c7ffceb4afac1567eb325722b9ae1 Mon Sep 17 00:00:00 2001 From: Jinyang He Date: Tue, 17 Jan 2023 11:42:16 +0800 Subject: [PATCH 212/398] LoongArch: Adjust PC value when unwind next frame in unwinder When state->first is not set, the PC is a return address in the previous frame. We need to adjust its value in case overflow to the next symbol. Signed-off-by: Jinyang He Signed-off-by: Huacai Chen --- arch/loongarch/kernel/unwind_prologue.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c index 0f8d1451ebb8..e98b00432c88 100644 --- a/arch/loongarch/kernel/unwind_prologue.c +++ b/arch/loongarch/kernel/unwind_prologue.c @@ -56,7 +56,7 @@ static bool unwind_by_prologue(struct unwind_state *state) { long frame_ra = -1; unsigned long frame_size = 0; - unsigned long size, offset, pc = state->pc; + unsigned long size, offset, pc; struct pt_regs *regs; struct stack_info *info = &state->stack_info; union loongarch_instruction *ip, *ip_end; @@ -78,6 +78,11 @@ static bool unwind_by_prologue(struct unwind_state *state) return true; } + /* + * When first is not set, the PC is a return address in the previous frame. + * We need to adjust its value in case overflow to the next symbol. + */ + pc = state->pc - (state->first ? 0 : LOONGARCH_INSN_SIZE); if (!kallsyms_lookup_size_offset(pc, &size, &offset)) return false; From 429a9671f235c94fc4b5d6687308714b74adc820 Mon Sep 17 00:00:00 2001 From: Jinyang He Date: Tue, 17 Jan 2023 11:42:16 +0800 Subject: [PATCH 213/398] LoongArch: Get frame info in unwind_start() when regs is not available At unwind_start(), it is better to get its frame info here rather than get them outside, even we don't have 'regs'. In this way we can simply use unwind_{start, next_frame, done} outside. Signed-off-by: Jinyang He Signed-off-by: Huacai Chen --- arch/loongarch/kernel/process.c | 12 +++--------- arch/loongarch/kernel/unwind_guess.c | 6 ++++++ arch/loongarch/kernel/unwind_prologue.c | 16 +++++++++++++--- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c index c583b1ef1f44..edfd220a3737 100644 --- a/arch/loongarch/kernel/process.c +++ b/arch/loongarch/kernel/process.c @@ -191,20 +191,14 @@ out: unsigned long __get_wchan(struct task_struct *task) { - unsigned long pc; + unsigned long pc = 0; struct unwind_state state; if (!try_get_task_stack(task)) return 0; - unwind_start(&state, task, NULL); - state.sp = thread_saved_fp(task); - get_stack_info(state.sp, state.task, &state.stack_info); - state.pc = thread_saved_ra(task); -#ifdef CONFIG_UNWINDER_PROLOGUE - state.type = UNWINDER_PROLOGUE; -#endif - for (; !unwind_done(&state); unwind_next_frame(&state)) { + for (unwind_start(&state, task, NULL); + !unwind_done(&state); unwind_next_frame(&state)) { pc = unwind_get_return_address(&state); if (!pc) break; diff --git a/arch/loongarch/kernel/unwind_guess.c b/arch/loongarch/kernel/unwind_guess.c index e2d2e4f3001f..9ef5f2a47f88 100644 --- a/arch/loongarch/kernel/unwind_guess.c +++ b/arch/loongarch/kernel/unwind_guess.c @@ -26,6 +26,12 @@ void unwind_start(struct unwind_state *state, struct task_struct *task, if (regs) { state->sp = regs->regs[3]; state->pc = regs->csr_era; + } else if (task && task != current) { + state->sp = thread_saved_fp(task); + state->pc = thread_saved_ra(task); + } else { + state->sp = (unsigned long)__builtin_frame_address(0); + state->pc = (unsigned long)__builtin_return_address(0); } state->task = task; diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c index e98b00432c88..613545ce6a97 100644 --- a/arch/loongarch/kernel/unwind_prologue.c +++ b/arch/loongarch/kernel/unwind_prologue.c @@ -146,12 +146,22 @@ void unwind_start(struct unwind_state *state, struct task_struct *task, struct pt_regs *regs) { memset(state, 0, sizeof(*state)); + state->type = UNWINDER_PROLOGUE; - if (regs && __kernel_text_address(regs->csr_era)) { - state->pc = regs->csr_era; + if (regs) { state->sp = regs->regs[3]; + state->pc = regs->csr_era; state->ra = regs->regs[1]; - state->type = UNWINDER_PROLOGUE; + if (!__kernel_text_address(state->pc)) + state->type = UNWINDER_GUESS; + } else if (task && task != current) { + state->sp = thread_saved_fp(task); + state->pc = thread_saved_ra(task); + state->ra = 0; + } else { + state->sp = (unsigned long)__builtin_frame_address(0); + state->pc = (unsigned long)__builtin_return_address(0); + state->ra = 0; } state->task = task; From 5bb8d34449c4a2eb94d657b992170afafac274f9 Mon Sep 17 00:00:00 2001 From: Jinyang He Date: Tue, 17 Jan 2023 11:42:16 +0800 Subject: [PATCH 214/398] LoongArch: Use correct sp value to get graph addr in stack unwinders The stack frame when function_graph enable like follows, --------- <- function sp_on_entry | | | FAKE_RA <- sp_on_entry - sizeof(pt_regs) + PT_R1 | --------- <- sp_on_entry - sizeof(pt_regs) So if we want to get the &FAKE_RA we should get sp_on_entry first. In the unwinder_prologue case, we can get the sp_on_entry as state->sp, because we try to calculate each CFA and the ra saved address. But in the unwinder_guess case, we cannot get it because we do not try to calculate the CFA. Although LoongArch have not fixed frame, the $ra is saved at CFA - 8 in most cases, we can try guess, too. As we store the pc in state, we not need to dereference state->sp, too. Signed-off-by: Jinyang He Signed-off-by: Huacai Chen --- arch/loongarch/include/asm/ftrace.h | 2 -- arch/loongarch/include/asm/unwind.h | 10 ++++++++++ arch/loongarch/kernel/unwind_guess.c | 11 ++++------- arch/loongarch/kernel/unwind_prologue.c | 21 ++++++--------------- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/arch/loongarch/include/asm/ftrace.h b/arch/loongarch/include/asm/ftrace.h index 90f9d3399b2a..3418d32d4fc7 100644 --- a/arch/loongarch/include/asm/ftrace.h +++ b/arch/loongarch/include/asm/ftrace.h @@ -10,8 +10,6 @@ #define FTRACE_REGS_PLT_IDX 1 #define NR_FTRACE_PLTS 2 -#define GRAPH_FAKE_OFFSET (sizeof(struct pt_regs) - offsetof(struct pt_regs, regs[1])) - #ifdef CONFIG_FUNCTION_TRACER #define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h index f2b52b9ea93d..834ba6bd15d2 100644 --- a/arch/loongarch/include/asm/unwind.h +++ b/arch/loongarch/include/asm/unwind.h @@ -8,7 +8,9 @@ #define _ASM_UNWIND_H #include +#include +#include #include enum unwinder_type { @@ -40,4 +42,12 @@ static inline bool unwind_error(struct unwind_state *state) return state->error; } +#define GRAPH_FAKE_OFFSET (sizeof(struct pt_regs) - offsetof(struct pt_regs, regs[1])) + +static inline unsigned long unwind_graph_addr(struct unwind_state *state, + unsigned long pc, unsigned long cfa) +{ + return ftrace_graph_ret_addr(state->task, &state->graph_idx, + pc, (unsigned long *)(cfa - GRAPH_FAKE_OFFSET)); +} #endif /* _ASM_UNWIND_H */ diff --git a/arch/loongarch/kernel/unwind_guess.c b/arch/loongarch/kernel/unwind_guess.c index 9ef5f2a47f88..e7e637bdba17 100644 --- a/arch/loongarch/kernel/unwind_guess.c +++ b/arch/loongarch/kernel/unwind_guess.c @@ -11,10 +11,8 @@ unsigned long unwind_get_return_address(struct unwind_state *state) { if (unwind_done(state)) return 0; - else if (state->first) - return state->pc; - return *(unsigned long *)(state->sp); + return state->pc; } EXPORT_SYMBOL_GPL(unwind_get_return_address); @@ -36,7 +34,7 @@ void unwind_start(struct unwind_state *state, struct task_struct *task, state->task = task; state->first = true; - + state->pc = unwind_graph_addr(state, state->pc, state->sp); get_stack_info(state->sp, state->task, &state->stack_info); if (!unwind_done(state) && !__kernel_text_address(state->pc)) @@ -60,9 +58,8 @@ bool unwind_next_frame(struct unwind_state *state) state->sp < info->end; state->sp += sizeof(unsigned long)) { addr = *(unsigned long *)(state->sp); - state->pc = ftrace_graph_ret_addr(state->task, &state->graph_idx, - addr, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET)); - if (__kernel_text_address(addr)) + state->pc = unwind_graph_addr(state, addr, state->sp + 8); + if (__kernel_text_address(state->pc)) return true; } diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c index 613545ce6a97..463ba2391bdf 100644 --- a/arch/loongarch/kernel/unwind_prologue.c +++ b/arch/loongarch/kernel/unwind_prologue.c @@ -21,16 +21,10 @@ static inline void unwind_state_fixup(struct unwind_state *state) unsigned long unwind_get_return_address(struct unwind_state *state) { - if (unwind_done(state)) return 0; - else if (state->type) - return state->pc; - else if (state->first) - return state->pc; - - return *(unsigned long *)(state->sp); + return state->pc; } EXPORT_SYMBOL_GPL(unwind_get_return_address); @@ -43,9 +37,8 @@ static bool unwind_by_guess(struct unwind_state *state) state->sp < info->end; state->sp += sizeof(unsigned long)) { addr = *(unsigned long *)(state->sp); - state->pc = ftrace_graph_ret_addr(state->task, &state->graph_idx, - addr, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET)); - if (__kernel_text_address(addr)) + state->pc = unwind_graph_addr(state, addr, state->sp + 8); + if (__kernel_text_address(state->pc)) return true; } @@ -166,7 +159,7 @@ void unwind_start(struct unwind_state *state, struct task_struct *task, state->task = task; state->first = true; - + state->pc = unwind_graph_addr(state, state->pc, state->sp); get_stack_info(state->sp, state->task, &state->stack_info); if (!unwind_done(state) && !__kernel_text_address(state->pc)) @@ -193,8 +186,7 @@ bool unwind_next_frame(struct unwind_state *state) case UNWINDER_PROLOGUE: if (unwind_by_prologue(state)) { - state->pc = ftrace_graph_ret_addr(state->task, &state->graph_idx, - state->pc, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET)); + state->pc = unwind_graph_addr(state, state->pc, state->sp); return true; } @@ -209,8 +201,7 @@ bool unwind_next_frame(struct unwind_state *state) state->first = true; state->ra = regs->regs[1]; state->sp = regs->regs[3]; - state->pc = ftrace_graph_ret_addr(state->task, &state->graph_idx, - pc, (unsigned long *)(state->sp - GRAPH_FAKE_OFFSET)); + state->pc = pc; get_stack_info(state->sp, state->task, info); return true; From c5ac25e0d78a6f63446b8fef4d8630ccd7a2663d Mon Sep 17 00:00:00 2001 From: Jinyang He Date: Tue, 17 Jan 2023 11:42:16 +0800 Subject: [PATCH 215/398] LoongArch: Strip guess unwinder out from prologue unwinder The prolugue unwinder rely on symbol info. When PC is not in kernel text address, it cannot find relative symbol info and it will be broken. The guess unwinder will be used in this case. And the guess unwinder code in prolugue unwinder is redundant. Strip it out and set the unwinder type in unwind_state. Make guess_unwinder::unwind_next_frame() as default way when other unwinders cannot unwind in some extreme case. Signed-off-by: Jinyang He Signed-off-by: Huacai Chen --- arch/loongarch/include/asm/unwind.h | 29 +++++ arch/loongarch/kernel/Makefile | 2 +- arch/loongarch/kernel/traps.c | 3 - arch/loongarch/kernel/unwind.c | 32 +++++ arch/loongarch/kernel/unwind_guess.c | 52 +------- arch/loongarch/kernel/unwind_prologue.c | 157 ++++++++++-------------- 6 files changed, 129 insertions(+), 146 deletions(-) create mode 100644 arch/loongarch/kernel/unwind.c diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h index 834ba6bd15d2..36584b95ef8b 100644 --- a/arch/loongarch/include/asm/unwind.h +++ b/arch/loongarch/include/asm/unwind.h @@ -27,6 +27,8 @@ struct unwind_state { unsigned long sp, pc, ra; }; +bool default_next_frame(struct unwind_state *state); + void unwind_start(struct unwind_state *state, struct task_struct *task, struct pt_regs *regs); bool unwind_next_frame(struct unwind_state *state); @@ -50,4 +52,31 @@ static inline unsigned long unwind_graph_addr(struct unwind_state *state, return ftrace_graph_ret_addr(state->task, &state->graph_idx, pc, (unsigned long *)(cfa - GRAPH_FAKE_OFFSET)); } + +static __always_inline void __unwind_start(struct unwind_state *state, + struct task_struct *task, struct pt_regs *regs) +{ + memset(state, 0, sizeof(*state)); + if (regs) { + state->sp = regs->regs[3]; + state->pc = regs->csr_era; + state->ra = regs->regs[1]; + } else if (task && task != current) { + state->sp = thread_saved_fp(task); + state->pc = thread_saved_ra(task); + state->ra = 0; + } else { + state->sp = (unsigned long)__builtin_frame_address(0); + state->pc = (unsigned long)__builtin_return_address(0); + state->ra = 0; + } + state->task = task; + get_stack_info(state->sp, state->task, &state->stack_info); + state->pc = unwind_graph_addr(state, state->pc, state->sp); +} + +static __always_inline unsigned long __unwind_get_return_address(struct unwind_state *state) +{ + return unwind_done(state) ? 0 : state->pc; +} #endif /* _ASM_UNWIND_H */ diff --git a/arch/loongarch/kernel/Makefile b/arch/loongarch/kernel/Makefile index fcaa024a685e..c8cfbd562921 100644 --- a/arch/loongarch/kernel/Makefile +++ b/arch/loongarch/kernel/Makefile @@ -8,7 +8,7 @@ extra-y := vmlinux.lds obj-y += head.o cpu-probe.o cacheinfo.o env.o setup.o entry.o genex.o \ traps.o irq.o idle.o process.o dma.o mem.o io.o reset.o switch.o \ elf.o syscall.o signal.o time.o topology.o inst.o ptrace.o vdso.o \ - alternative.o unaligned.o + alternative.o unaligned.o unwind.o obj-$(CONFIG_ACPI) += acpi.o obj-$(CONFIG_EFI) += efi.o diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c index 7ea62faeeadb..c38a146a973b 100644 --- a/arch/loongarch/kernel/traps.c +++ b/arch/loongarch/kernel/traps.c @@ -72,9 +72,6 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs, if (!task) task = current; - if (user_mode(regs)) - state.type = UNWINDER_GUESS; - printk("%sCall Trace:", loglvl); for (unwind_start(&state, task, pregs); !unwind_done(&state); unwind_next_frame(&state)) { diff --git a/arch/loongarch/kernel/unwind.c b/arch/loongarch/kernel/unwind.c new file mode 100644 index 000000000000..a463d6961344 --- /dev/null +++ b/arch/loongarch/kernel/unwind.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022-2023 Loongson Technology Corporation Limited + */ +#include +#include + +#include + +bool default_next_frame(struct unwind_state *state) +{ + struct stack_info *info = &state->stack_info; + unsigned long addr; + + if (unwind_done(state)) + return false; + + do { + for (state->sp += sizeof(unsigned long); + state->sp < info->end; state->sp += sizeof(unsigned long)) { + addr = *(unsigned long *)(state->sp); + state->pc = unwind_graph_addr(state, addr, state->sp + 8); + if (__kernel_text_address(state->pc)) + return true; + } + + state->sp = info->next_sp; + + } while (!get_stack_info(state->sp, state->task, info)); + + return false; +} diff --git a/arch/loongarch/kernel/unwind_guess.c b/arch/loongarch/kernel/unwind_guess.c index e7e637bdba17..98379b7d4147 100644 --- a/arch/loongarch/kernel/unwind_guess.c +++ b/arch/loongarch/kernel/unwind_guess.c @@ -2,41 +2,18 @@ /* * Copyright (C) 2022 Loongson Technology Corporation Limited */ -#include -#include - #include unsigned long unwind_get_return_address(struct unwind_state *state) { - if (unwind_done(state)) - return 0; - - return state->pc; + return __unwind_get_return_address(state); } EXPORT_SYMBOL_GPL(unwind_get_return_address); void unwind_start(struct unwind_state *state, struct task_struct *task, struct pt_regs *regs) { - memset(state, 0, sizeof(*state)); - - if (regs) { - state->sp = regs->regs[3]; - state->pc = regs->csr_era; - } else if (task && task != current) { - state->sp = thread_saved_fp(task); - state->pc = thread_saved_ra(task); - } else { - state->sp = (unsigned long)__builtin_frame_address(0); - state->pc = (unsigned long)__builtin_return_address(0); - } - - state->task = task; - state->first = true; - state->pc = unwind_graph_addr(state, state->pc, state->sp); - get_stack_info(state->sp, state->task, &state->stack_info); - + __unwind_start(state, task, regs); if (!unwind_done(state) && !__kernel_text_address(state->pc)) unwind_next_frame(state); } @@ -44,29 +21,6 @@ EXPORT_SYMBOL_GPL(unwind_start); bool unwind_next_frame(struct unwind_state *state) { - struct stack_info *info = &state->stack_info; - unsigned long addr; - - if (unwind_done(state)) - return false; - - if (state->first) - state->first = false; - - do { - for (state->sp += sizeof(unsigned long); - state->sp < info->end; - state->sp += sizeof(unsigned long)) { - addr = *(unsigned long *)(state->sp); - state->pc = unwind_graph_addr(state, addr, state->sp + 8); - if (__kernel_text_address(state->pc)) - return true; - } - - state->sp = info->next_sp; - - } while (!get_stack_info(state->sp, state->task, info)); - - return false; + return default_next_frame(state); } EXPORT_SYMBOL_GPL(unwind_next_frame); diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c index 463ba2391bdf..dfc352dba746 100644 --- a/arch/loongarch/kernel/unwind_prologue.c +++ b/arch/loongarch/kernel/unwind_prologue.c @@ -19,32 +19,14 @@ static inline void unwind_state_fixup(struct unwind_state *state) #endif } -unsigned long unwind_get_return_address(struct unwind_state *state) -{ - if (unwind_done(state)) - return 0; - - return state->pc; -} -EXPORT_SYMBOL_GPL(unwind_get_return_address); - -static bool unwind_by_guess(struct unwind_state *state) -{ - struct stack_info *info = &state->stack_info; - unsigned long addr; - - for (state->sp += sizeof(unsigned long); - state->sp < info->end; - state->sp += sizeof(unsigned long)) { - addr = *(unsigned long *)(state->sp); - state->pc = unwind_graph_addr(state, addr, state->sp + 8); - if (__kernel_text_address(state->pc)) - return true; - } - - return false; -} - +/* + * LoongArch function prologue is like follows, + * [instructions not use stack var] + * addi.d sp, sp, -imm + * st.d xx, sp, offset <- save callee saved regs and + * st.d yy, sp, offset save ra if function is nest. + * [others instructions] + */ static bool unwind_by_prologue(struct unwind_state *state) { long frame_ra = -1; @@ -91,6 +73,10 @@ static bool unwind_by_prologue(struct unwind_state *state) ip++; } + /* + * Can't find stack alloc action, PC may be in a leaf function. Only the + * first being true is reasonable, otherwise indicate analysis is broken. + */ if (!frame_size) { if (state->first) goto first; @@ -108,6 +94,7 @@ static bool unwind_by_prologue(struct unwind_state *state) ip++; } + /* Can't find save $ra action, PC may be in a leaf function, too. */ if (frame_ra < 0) { if (state->first) { state->sp = state->sp + frame_size; @@ -116,96 +103,48 @@ static bool unwind_by_prologue(struct unwind_state *state) return false; } - if (state->first) - state->first = false; - state->pc = *(unsigned long *)(state->sp + frame_ra); state->sp = state->sp + frame_size; goto out; first: - state->first = false; - if (state->pc == state->ra) - return false; - state->pc = state->ra; out: + state->first = false; unwind_state_fixup(state); return !!__kernel_text_address(state->pc); } -void unwind_start(struct unwind_state *state, struct task_struct *task, - struct pt_regs *regs) +static bool next_frame(struct unwind_state *state) { - memset(state, 0, sizeof(*state)); - state->type = UNWINDER_PROLOGUE; - - if (regs) { - state->sp = regs->regs[3]; - state->pc = regs->csr_era; - state->ra = regs->regs[1]; - if (!__kernel_text_address(state->pc)) - state->type = UNWINDER_GUESS; - } else if (task && task != current) { - state->sp = thread_saved_fp(task); - state->pc = thread_saved_ra(task); - state->ra = 0; - } else { - state->sp = (unsigned long)__builtin_frame_address(0); - state->pc = (unsigned long)__builtin_return_address(0); - state->ra = 0; - } - - state->task = task; - state->first = true; - state->pc = unwind_graph_addr(state, state->pc, state->sp); - get_stack_info(state->sp, state->task, &state->stack_info); - - if (!unwind_done(state) && !__kernel_text_address(state->pc)) - unwind_next_frame(state); -} -EXPORT_SYMBOL_GPL(unwind_start); - -bool unwind_next_frame(struct unwind_state *state) -{ - struct stack_info *info = &state->stack_info; - struct pt_regs *regs; unsigned long pc; + struct pt_regs *regs; + struct stack_info *info = &state->stack_info; if (unwind_done(state)) return false; do { - switch (state->type) { - case UNWINDER_GUESS: - state->first = false; - if (unwind_by_guess(state)) - return true; - break; + if (unwind_by_prologue(state)) { + state->pc = unwind_graph_addr(state, state->pc, state->sp); + return true; + } - case UNWINDER_PROLOGUE: - if (unwind_by_prologue(state)) { - state->pc = unwind_graph_addr(state, state->pc, state->sp); - return true; - } + if (info->type == STACK_TYPE_IRQ && info->end == state->sp) { + regs = (struct pt_regs *)info->next_sp; + pc = regs->csr_era; - if (info->type == STACK_TYPE_IRQ && - info->end == state->sp) { - regs = (struct pt_regs *)info->next_sp; - pc = regs->csr_era; + if (user_mode(regs) || !__kernel_text_address(pc)) + return false; - if (user_mode(regs) || !__kernel_text_address(pc)) - return false; + state->first = true; + state->pc = pc; + state->ra = regs->regs[1]; + state->sp = regs->regs[3]; + get_stack_info(state->sp, state->task, info); - state->first = true; - state->ra = regs->regs[1]; - state->sp = regs->regs[3]; - state->pc = pc; - get_stack_info(state->sp, state->task, info); - - return true; - } + return true; } state->sp = info->next_sp; @@ -214,4 +153,36 @@ bool unwind_next_frame(struct unwind_state *state) return false; } + +unsigned long unwind_get_return_address(struct unwind_state *state) +{ + return __unwind_get_return_address(state); +} +EXPORT_SYMBOL_GPL(unwind_get_return_address); + +void unwind_start(struct unwind_state *state, struct task_struct *task, + struct pt_regs *regs) +{ + __unwind_start(state, task, regs); + state->type = UNWINDER_PROLOGUE; + state->first = true; + + /* + * The current PC is not kernel text address, we cannot find its + * relative symbol. Thus, prologue analysis will be broken. Luckily, + * we can use the default_next_frame(). + */ + if (!__kernel_text_address(state->pc)) { + state->type = UNWINDER_GUESS; + if (!unwind_done(state)) + unwind_next_frame(state); + } +} +EXPORT_SYMBOL_GPL(unwind_start); + +bool unwind_next_frame(struct unwind_state *state) +{ + return state->type == UNWINDER_PROLOGUE ? + next_frame(state) : default_next_frame(state); +} EXPORT_SYMBOL_GPL(unwind_next_frame); From dc74a9e8a8c57966a563ab078ba91c8b2c0d0a72 Mon Sep 17 00:00:00 2001 From: Jinyang He Date: Tue, 17 Jan 2023 11:42:16 +0800 Subject: [PATCH 216/398] LoongArch: Add generic ex-handler unwind in prologue unwinder When exception is triggered, code flow go handle_\exception in some cases. One of stackframe in this case as follows, high -> +-------+ | REGS | <- a pt_regs | | | | <- ex trigger | REGS | <- ex pt_regs <-+ | | | | | | low -> +-------+ ->unwind-+ When unwinder unwinds to handler_\exception it cannot go on prologue analysis. Because it is an asynchronous code flow, we should get the next frame PC from regs->csr_era rather than regs->regs[1]. At init time we copy the handlers to eentry and also copy them to NUMA-affine memory named pcpu_handlers if NUMA is enabled. Thus, unwinder cannot unwind normally. To solve this, we try to give some hints in handler_\exception and fixup unwinders in unwind_next_frame(). Reported-by: Qing Zhang Signed-off-by: Jinyang He Signed-off-by: Huacai Chen --- arch/loongarch/include/asm/unwind.h | 2 +- arch/loongarch/kernel/genex.S | 3 + arch/loongarch/kernel/unwind_prologue.c | 101 +++++++++++++++++++++--- arch/loongarch/mm/tlb.c | 2 +- 4 files changed, 93 insertions(+), 15 deletions(-) diff --git a/arch/loongarch/include/asm/unwind.h b/arch/loongarch/include/asm/unwind.h index 36584b95ef8b..b9dce87afd2e 100644 --- a/arch/loongarch/include/asm/unwind.h +++ b/arch/loongarch/include/asm/unwind.h @@ -22,7 +22,7 @@ struct unwind_state { char type; /* UNWINDER_XXX */ struct stack_info stack_info; struct task_struct *task; - bool first, error, is_ftrace; + bool first, error, reset; int graph_idx; unsigned long sp, pc, ra; }; diff --git a/arch/loongarch/kernel/genex.S b/arch/loongarch/kernel/genex.S index 75e5be807a0d..7e5c293ed89f 100644 --- a/arch/loongarch/kernel/genex.S +++ b/arch/loongarch/kernel/genex.S @@ -67,14 +67,17 @@ SYM_FUNC_END(except_vec_cex) .macro BUILD_HANDLER exception handler prep .align 5 SYM_FUNC_START(handle_\exception) + 666: BACKUP_T0T1 SAVE_ALL build_prep_\prep move a0, sp la.abs t0, do_\handler jirl ra, t0, 0 + 668: RESTORE_ALL_AND_RET SYM_FUNC_END(handle_\exception) + SYM_DATA(unwind_hint_\exception, .word 668b - 666b) .endm BUILD_HANDLER ade ade badv diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c index dfc352dba746..9095fde8e55d 100644 --- a/arch/loongarch/kernel/unwind_prologue.c +++ b/arch/loongarch/kernel/unwind_prologue.c @@ -2,23 +2,103 @@ /* * Copyright (C) 2022 Loongson Technology Corporation Limited */ +#include #include #include #include +#include #include +#include #include -static inline void unwind_state_fixup(struct unwind_state *state) +extern const int unwind_hint_ade; +extern const int unwind_hint_ale; +extern const int unwind_hint_bp; +extern const int unwind_hint_fpe; +extern const int unwind_hint_fpu; +extern const int unwind_hint_lsx; +extern const int unwind_hint_lasx; +extern const int unwind_hint_lbt; +extern const int unwind_hint_ri; +extern const int unwind_hint_watch; +extern unsigned long eentry; +#ifdef CONFIG_NUMA +extern unsigned long pcpu_handlers[NR_CPUS]; +#endif + +static inline bool scan_handlers(unsigned long entry_offset) +{ + int idx, offset; + + if (entry_offset >= EXCCODE_INT_START * VECSIZE) + return false; + + idx = entry_offset / VECSIZE; + offset = entry_offset % VECSIZE; + switch (idx) { + case EXCCODE_ADE: + return offset == unwind_hint_ade; + case EXCCODE_ALE: + return offset == unwind_hint_ale; + case EXCCODE_BP: + return offset == unwind_hint_bp; + case EXCCODE_FPE: + return offset == unwind_hint_fpe; + case EXCCODE_FPDIS: + return offset == unwind_hint_fpu; + case EXCCODE_LSXDIS: + return offset == unwind_hint_lsx; + case EXCCODE_LASXDIS: + return offset == unwind_hint_lasx; + case EXCCODE_BTDIS: + return offset == unwind_hint_lbt; + case EXCCODE_INE: + return offset == unwind_hint_ri; + case EXCCODE_WATCH: + return offset == unwind_hint_watch; + default: + return false; + } +} + +static inline bool fix_exception(unsigned long pc) +{ +#ifdef CONFIG_NUMA + int cpu; + + for_each_possible_cpu(cpu) { + if (!pcpu_handlers[cpu]) + continue; + if (scan_handlers(pc - pcpu_handlers[cpu])) + return true; + } +#endif + return scan_handlers(pc - eentry); +} + +/* + * As we meet ftrace_regs_entry, reset first flag like first doing + * tracing. Prologue analysis will stop soon because PC is at entry. + */ +static inline bool fix_ftrace(unsigned long pc) { #ifdef CONFIG_DYNAMIC_FTRACE - static unsigned long ftrace = (unsigned long)ftrace_call + 4; - - if (state->pc == ftrace) - state->is_ftrace = true; + return pc == (unsigned long)ftrace_call + LOONGARCH_INSN_SIZE; +#else + return false; #endif } +static inline bool unwind_state_fixup(struct unwind_state *state) +{ + if (!fix_exception(state->pc) && !fix_ftrace(state->pc)) + return false; + + state->reset = true; + return true; +} + /* * LoongArch function prologue is like follows, * [instructions not use stack var] @@ -39,14 +119,10 @@ static bool unwind_by_prologue(struct unwind_state *state) if (state->sp >= info->end || state->sp < info->begin) return false; - if (state->is_ftrace) { - /* - * As we meet ftrace_regs_entry, reset first flag like first doing - * tracing. Prologue analysis will stop soon because PC is at entry. - */ + if (state->reset) { regs = (struct pt_regs *)state->sp; state->first = true; - state->is_ftrace = false; + state->reset = false; state->pc = regs->csr_era; state->ra = regs->regs[1]; state->sp = regs->regs[3]; @@ -112,8 +188,7 @@ first: out: state->first = false; - unwind_state_fixup(state); - return !!__kernel_text_address(state->pc); + return unwind_state_fixup(state) || __kernel_text_address(state->pc); } static bool next_frame(struct unwind_state *state) diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c index da3681f131c8..8bad6b0cff59 100644 --- a/arch/loongarch/mm/tlb.c +++ b/arch/loongarch/mm/tlb.c @@ -251,7 +251,7 @@ static void output_pgtable_bits_defines(void) } #ifdef CONFIG_NUMA -static unsigned long pcpu_handlers[NR_CPUS]; +unsigned long pcpu_handlers[NR_CPUS]; #endif extern long exception_handlers[VECSIZE * 128 / sizeof(long)]; From ecf7cf8efb59789e2b21d2f9ab926142579092b2 Mon Sep 17 00:00:00 2001 From: Szymon Heidrich Date: Sat, 14 Jan 2023 19:23:26 +0100 Subject: [PATCH 217/398] net: usb: sr9700: Handle negative len Packet len computed as difference of length word extracted from skb data and four may result in a negative value. In such case processing of the buffer should be interrupted rather than setting sr_skb->len to an unexpectedly large value (due to cast from signed to unsigned integer) and passing sr_skb to usbnet_skb_return. Fixes: e9da0b56fe27 ("sr9700: sanity check for packet length") Signed-off-by: Szymon Heidrich Link: https://lore.kernel.org/r/20230114182326.30479-1-szymon.heidrich@gmail.com Signed-off-by: Paolo Abeni --- drivers/net/usb/sr9700.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/usb/sr9700.c b/drivers/net/usb/sr9700.c index 5a53e63d33a6..3164451e1010 100644 --- a/drivers/net/usb/sr9700.c +++ b/drivers/net/usb/sr9700.c @@ -413,7 +413,7 @@ static int sr9700_rx_fixup(struct usbnet *dev, struct sk_buff *skb) /* ignore the CRC length */ len = (skb->data[1] | (skb->data[2] << 8)) - 4; - if (len > ETH_FRAME_LEN || len > skb->len) + if (len > ETH_FRAME_LEN || len > skb->len || len < 0) return 0; /* the last packet of current skb */ From 867dbe784c5010a466f00a7d1467c1c5ea569c75 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sun, 15 Jan 2023 11:54:06 +0100 Subject: [PATCH 218/398] net: mdio: validate parameter addr in mdiobus_get_phy() The caller may pass any value as addr, what may result in an out-of-bounds access to array mdio_map. One existing case is stmmac_init_phy() that may pass -1 as addr. Therefore validate addr before using it. Fixes: 7f854420fbfe ("phy: Add API for {un}registering an mdio device to a bus.") Signed-off-by: Heiner Kallweit Reviewed-by: Andrew Lunn Link: https://lore.kernel.org/r/cdf664ea-3312-e915-73f8-021678d08887@gmail.com Signed-off-by: Paolo Abeni --- drivers/net/phy/mdio_bus.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 1cd604cd1fa1..16e021b477f0 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -108,7 +108,12 @@ EXPORT_SYMBOL(mdiobus_unregister_device); struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr) { - struct mdio_device *mdiodev = bus->mdio_map[addr]; + struct mdio_device *mdiodev; + + if (addr < 0 || addr >= ARRAY_SIZE(bus->mdio_map)) + return NULL; + + mdiodev = bus->mdio_map[addr]; if (!mdiodev) return NULL; From b12fece4c64857e5fab4290bf01b2e0317a88456 Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Mon, 16 Jan 2023 11:11:24 +0000 Subject: [PATCH 219/398] HID: check empty report_list in hid_validate_values() Add a check for empty report_list in hid_validate_values(). The missing check causes a type confusion when issuing a list_entry() on an empty report_list. The problem is caused by the assumption that the device must have valid report_list. While this will be true for all normal HID devices, a suitably malicious device can violate the assumption. Fixes: 1b15d2e5b807 ("HID: core: fix validation of report id 0") Signed-off-by: Pietro Borrello Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index bd47628da6be..3e1803592bd4 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -993,8 +993,8 @@ struct hid_report *hid_validate_values(struct hid_device *hid, * Validating on id 0 means we should examine the first * report in the list. */ - report = list_entry( - hid->report_enum[type].report_list.next, + report = list_first_entry_or_null( + &hid->report_enum[type].report_list, struct hid_report, list); } else { report = hid->report_enum[type].report_id_hash[id]; From c7bf714f875531f227f2ef1fdcc8f4d44e7c7d9d Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Mon, 16 Jan 2023 11:11:25 +0000 Subject: [PATCH 220/398] HID: check empty report_list in bigben_probe() Add a check for empty report_list in bigben_probe(). The missing check causes a type confusion when issuing a list_entry() on an empty report_list. The problem is caused by the assumption that the device must have valid report_list. While this will be true for all normal HID devices, a suitably malicious device can violate the assumption. Fixes: 256a90ed9e46 ("HID: hid-bigbenff: driver for BigBen Interactive PS3OFMINIPAD gamepad") Signed-off-by: Pietro Borrello Signed-off-by: Jiri Kosina --- drivers/hid/hid-bigbenff.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hid/hid-bigbenff.c b/drivers/hid/hid-bigbenff.c index e8c5e3ac9fff..e8b16665860d 100644 --- a/drivers/hid/hid-bigbenff.c +++ b/drivers/hid/hid-bigbenff.c @@ -344,6 +344,11 @@ static int bigben_probe(struct hid_device *hid, } report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; + if (list_empty(report_list)) { + hid_err(hid, "no output report found\n"); + error = -ENODEV; + goto error_hw_stop; + } bigben->report = list_entry(report_list->next, struct hid_report, list); From 81aae5cbd36da836eb65025c798d15e5e28a019b Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 12 Jan 2023 20:53:39 +0100 Subject: [PATCH 221/398] MAINTAINERS: Update the ACPICA development list address The previous ACPICA development list address, devel@acpica.org, started to bounce some time ago and it is not likely to be restored, so replace it with a new one, acpica-devel@lists.linuxfoundation.org. Signed-off-by: Rafael J. Wysocki --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 42fc47c6edfd..439b51c5d25f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -383,7 +383,7 @@ ACPI COMPONENT ARCHITECTURE (ACPICA) M: Robert Moore M: "Rafael J. Wysocki" L: linux-acpi@vger.kernel.org -L: devel@acpica.org +L: acpica-devel@lists.linuxfoundation.org S: Supported W: https://acpica.org/ W: https://github.com/acpica/acpica/ From 8ba5fc4c154aeb3b4620f05543cce426c62ed2de Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 13 Jan 2023 12:41:26 +0100 Subject: [PATCH 222/398] ACPI: video: Add backlight=native DMI quirk for Acer Aspire 4810T The Acer Aspire 4810T predates Windows 8, so it defaults to using acpi_video# for backlight control, but this is non functional on this model. Add a DMI quirk to use the native backlight interface which does work properly. Signed-off-by: Hans de Goede Signed-off-by: Rafael J. Wysocki --- drivers/acpi/video_detect.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 8a541efc5675..65cec7bb6d96 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -515,6 +515,14 @@ static const struct dmi_system_id video_detect_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Precision 7510"), }, }, + { + .callback = video_detect_force_native, + /* Acer Aspire 4810T */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 4810T"), + }, + }, { .callback = video_detect_force_native, /* Acer Aspire 5738z */ From 1f3bd64ad921f051254591fbed04fd30b306cde6 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sun, 15 Jan 2023 18:24:08 +0100 Subject: [PATCH 223/398] net: stmmac: fix invalid call to mdiobus_get_phy() In a number of cases the driver assigns a default value of -1 to priv->plat->phy_addr. This may result in calling mdiobus_get_phy() with addr parameter being -1. Therefore check for this scenario and bail out before calling mdiobus_get_phy(). Fixes: 42e87024f727 ("net: stmmac: Fix case when PHY handle is not present") Signed-off-by: Heiner Kallweit Link: https://lore.kernel.org/r/669f9671-ecd1-a41b-2727-7b73e3003985@gmail.com Signed-off-by: Paolo Abeni --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index c6951c976f5d..b7e5af58ab75 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1150,6 +1150,11 @@ static int stmmac_init_phy(struct net_device *dev) int addr = priv->plat->phy_addr; struct phy_device *phydev; + if (addr < 0) { + netdev_err(priv->dev, "no phy found\n"); + return -ENODEV; + } + phydev = mdiobus_get_phy(priv->mii, addr); if (!phydev) { netdev_err(priv->dev, "no phy at addr %d\n", addr); From 431d1531466033909d2e8c754a7dc3704b70843f Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Tue, 10 Jan 2023 08:46:53 +0000 Subject: [PATCH 224/398] pinctrl: rockchip: fix mux route data for rk3568 IO mux selection is configured in PMU_GRF_SOC_CON4 and GRF_IOFUNC_SEL0-5 regs on RK3568. pwm0-2 is configured in PMU_GRF reg and the rest is configured in GRF_IOFUNC regs according to TRM [1]. Update mux route data to reflect this and use proper detection pin for UART1 IO mux M1. This fixes HDMITX IO mux M1 selection and makes it possible to enable HDMI CEC on my Radxa ROCK 3 Model A v1.31 board. [1] http://opensource.rock-chips.com/images/2/26/Rockchip_RK3568_TRM_Part1_V1.3-20220930P.PDF Fixes: c0dadc0e47a8 ("pinctrl: rockchip: add support for rk3568") Signed-off-by: Jonas Karlman Link: https://lore.kernel.org/r/20230110084636.1141740-1-jonas@kwiboo.se Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-rockchip.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index c3b9313e5be1..5eeac92f610a 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -926,19 +926,19 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = { RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */ RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */ RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */ - RK_MUXROUTE_PMU(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */ RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */ RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */ RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */ RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */ - RK_MUXROUTE_PMU(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ + RK_MUXROUTE_GRF(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */ RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */ RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */ - RK_MUXROUTE_PMU(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ - RK_MUXROUTE_PMU(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ + RK_MUXROUTE_GRF(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */ RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */ RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */ @@ -964,7 +964,7 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = { RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */ RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */ RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */ - RK_MUXROUTE_PMU(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */ RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */ RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */ @@ -973,8 +973,8 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = { RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */ RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */ RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */ - RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ - RK_MUXROUTE_PMU(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PD6, 4, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ + RK_MUXROUTE_GRF(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */ RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */ RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */ @@ -1004,13 +1004,13 @@ static struct rockchip_mux_route_data rk3568_mux_route_data[] = { RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */ - RK_MUXROUTE_PMU(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */ RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */ - RK_MUXROUTE_PMU(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */ RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */ - RK_MUXROUTE_PMU(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */ RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */ }; From 7ffd2266bd32d9f31a4e918443c733906cff0d19 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Mon, 12 Dec 2022 09:51:39 +0100 Subject: [PATCH 225/398] ARM: dts: stm32: Fix qspi pinctrl phandle for stm32mp15xx-dhcor-som Chip select pinctrl phandle was missing in several stm32mp15x based boards. Fixes: ea99a5a02ebc ("ARM: dts: stm32: Create separate pinmux for qspi cs pin in stm32mp15-pinctrl.dtsi") Signed-off-by: Patrice Chotard Cc: Marek Vasut Cc: Alexandre Torgue Cc: linux-stm32@st-md-mailman.stormreply.com Cc: linux-arm-kernel@lists.infradead.org Reviewed-by: Marek Vasut Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi index 134a798ad3f2..bb40fb46da81 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcor-som.dtsi @@ -247,8 +247,12 @@ &qspi { pinctrl-names = "default", "sleep"; - pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>; - pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a>; + pinctrl-0 = <&qspi_clk_pins_a + &qspi_bk1_pins_a + &qspi_cs1_pins_a>; + pinctrl-1 = <&qspi_clk_sleep_pins_a + &qspi_bk1_sleep_pins_a + &qspi_cs1_sleep_pins_a>; reg = <0x58003000 0x1000>, <0x70000000 0x200000>; #address-cells = <1>; #size-cells = <0>; From 21d83512bf2bd25ebed467151fd2bcd0cca7dc9a Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Mon, 12 Dec 2022 09:51:40 +0100 Subject: [PATCH 226/398] ARM: dts: stm32: Fix qspi pinctrl phandle for stm32mp15xx-dhcom-som Chip select pinctrl phandle was missing in several stm32mp15x based boards. Fixes: ea99a5a02ebc ("ARM: dts: stm32: Create separate pinmux for qspi cs pin in stm32mp15-pinctrl.dtsi") Signed-off-by: Patrice Chotard Cc: Marek Vasut Cc: Alexandre Torgue Cc: linux-stm32@st-md-mailman.stormreply.com Cc: linux-arm-kernel@lists.infradead.org Reviewed-by: Marek Vasut Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi index 002f221f1694..c06edd2eacb0 100644 --- a/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi +++ b/arch/arm/boot/dts/stm32mp15xx-dhcom-som.dtsi @@ -428,8 +428,12 @@ &qspi { pinctrl-names = "default", "sleep"; - pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>; - pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a>; + pinctrl-0 = <&qspi_clk_pins_a + &qspi_bk1_pins_a + &qspi_cs1_pins_a>; + pinctrl-1 = <&qspi_clk_sleep_pins_a + &qspi_bk1_sleep_pins_a + &qspi_cs1_sleep_pins_a>; reg = <0x58003000 0x1000>, <0x70000000 0x4000000>; #address-cells = <1>; #size-cells = <0>; From 732dbcf52f74b254a7ddd4226e0b9638e1e7aeff Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Mon, 12 Dec 2022 09:51:41 +0100 Subject: [PATCH 227/398] ARM: dts: stm32: Fix qspi pinctrl phandle for stm32mp157c-emstamp-argon Chip select pinctrl phandle was missing in several stm32mp15x based boards. Fixes: ea99a5a02ebc ("ARM: dts: stm32: Create separate pinmux for qspi cs pin in stm32mp15-pinctrl.dtsi") Signed-off-by: Patrice Chotard Cc: Reinhold Mueller Cc: Alexandre Torgue Cc: linux-stm32@st-md-mailman.stormreply.com Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi b/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi index aef02e6421a3..7d11c50b9e40 100644 --- a/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi +++ b/arch/arm/boot/dts/stm32mp157c-emstamp-argon.dtsi @@ -391,8 +391,12 @@ &qspi { pinctrl-names = "default", "sleep"; - pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>; - pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a>; + pinctrl-0 = <&qspi_clk_pins_a + &qspi_bk1_pins_a + &qspi_cs1_pins_a>; + pinctrl-1 = <&qspi_clk_sleep_pins_a + &qspi_bk1_sleep_pins_a + &qspi_cs1_sleep_pins_a>; reg = <0x58003000 0x1000>, <0x70000000 0x4000000>; #address-cells = <1>; #size-cells = <0>; From 175281f80695569c7f9cf062e5d0ddc4addc109f Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Mon, 12 Dec 2022 09:51:42 +0100 Subject: [PATCH 228/398] ARM: dts: stm32: Fix qspi pinctrl phandle for stm32mp151a-prtt1l Chip select pinctrl phandle was missing in several stm32mp15x based boards. Fixes: ea99a5a02ebc ("ARM: dts: stm32: Create separate pinmux for qspi cs pin in stm32mp15-pinctrl.dtsi") Signed-off-by: Patrice Chotard Cc: Oleksij Rempel Cc: Alexandre Torgue Cc: linux-stm32@st-md-mailman.stormreply.com Cc: linux-arm-kernel@lists.infradead.org Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp151a-prtt1l.dtsi | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/stm32mp151a-prtt1l.dtsi b/arch/arm/boot/dts/stm32mp151a-prtt1l.dtsi index d865ab5d866b..dd23de85100c 100644 --- a/arch/arm/boot/dts/stm32mp151a-prtt1l.dtsi +++ b/arch/arm/boot/dts/stm32mp151a-prtt1l.dtsi @@ -101,8 +101,12 @@ &qspi { pinctrl-names = "default", "sleep"; - pinctrl-0 = <&qspi_clk_pins_a &qspi_bk1_pins_a>; - pinctrl-1 = <&qspi_clk_sleep_pins_a &qspi_bk1_sleep_pins_a>; + pinctrl-0 = <&qspi_clk_pins_a + &qspi_bk1_pins_a + &qspi_cs1_pins_a>; + pinctrl-1 = <&qspi_clk_sleep_pins_a + &qspi_bk1_sleep_pins_a + &qspi_cs1_sleep_pins_a>; reg = <0x58003000 0x1000>, <0x70000000 0x4000000>; #address-cells = <1>; #size-cells = <0>; From cbf44580ce6b310272a73e3e794233fd064330bd Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 17 Jan 2023 15:41:40 +0100 Subject: [PATCH 229/398] HID: revert CHERRY_MOUSE_000C quirk This partially reverts commit f6d910a89a2391 ("HID: usbhid: Add ALWAYS_POLL quirk for some mice"), as it turns out to break reboot on some platforms for reason yet to be understood. Fixes: f6d910a89a2391 ("HID: usbhid: Add ALWAYS_POLL quirk for some mice") Reported-by: Christian Zigotzky Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 - drivers/hid/hid-quirks.c | 1 - 2 files changed, 2 deletions(-) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 82713ef3aaa6..c3735848ed5d 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -274,7 +274,6 @@ #define USB_DEVICE_ID_CH_AXIS_295 0x001c #define USB_VENDOR_ID_CHERRY 0x046a -#define USB_DEVICE_ID_CHERRY_MOUSE_000C 0x000c #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 #define USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR 0x0027 diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 0e9702c7f7d6..be3ad02573de 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -54,7 +54,6 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET }, - { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_MOUSE_000C), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS }, From 9d6033e350694a67885605674244d43c9559dc36 Mon Sep 17 00:00:00 2001 From: Guoqing Jiang Date: Fri, 30 Dec 2022 09:09:26 +0800 Subject: [PATCH 230/398] block/rnbd-clt: fix wrong max ID in ida_alloc_max We need to pass 'end - 1' to ida_alloc_max after switch from ida_simple_get to ida_alloc_max. Otherwise smatch warns. drivers/block/rnbd/rnbd-clt.c:1460 init_dev() error: Calling ida_alloc_max() with a 'max' argument which is a power of 2. -1 missing? Fixes: 24afc15dbe21 ("block/rnbd: Remove a useless mutex") Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Guoqing Jiang Acked-by: Jack Wang Link: https://lore.kernel.org/r/20221230010926.32243-1-guoqing.jiang@linux.dev Signed-off-by: Jens Axboe --- drivers/block/rnbd/rnbd-clt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c index 78334da74d8b..5eb8c7855970 100644 --- a/drivers/block/rnbd/rnbd-clt.c +++ b/drivers/block/rnbd/rnbd-clt.c @@ -1440,7 +1440,7 @@ static struct rnbd_clt_dev *init_dev(struct rnbd_clt_session *sess, goto out_alloc; } - ret = ida_alloc_max(&index_ida, 1 << (MINORBITS - RNBD_PART_BITS), + ret = ida_alloc_max(&index_ida, (1 << (MINORBITS - RNBD_PART_BITS)) - 1, GFP_KERNEL); if (ret < 0) { pr_err("Failed to initialize device '%s' from session %s, allocating idr failed, err: %d\n", From 1301c7b9f7efad2f11ef924e317c18ebd714fc9a Mon Sep 17 00:00:00 2001 From: Pawel Laszczak Date: Tue, 15 Nov 2022 05:00:39 -0500 Subject: [PATCH 231/398] usb: cdns3: remove fetched trb from cache before dequeuing After doorbell DMA fetches the TRB. If during dequeuing request driver changes NORMAL TRB to LINK TRB but doesn't delete it from controller cache then controller will handle cached TRB and packet can be lost. The example scenario for this issue looks like: 1. queue request - set doorbell 2. dequeue request 3. send OUT data packet from host 4. Device will accept this packet which is unexpected 5. queue new request - set doorbell 6. Device lost the expected packet. By setting DFLUSH controller clears DRDY bit and stop DMA transfer. Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") cc: Signed-off-by: Pawel Laszczak Acked-by: Peter Chen Link: https://lore.kernel.org/r/20221115100039.441295-1-pawell@cadence.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/cdns3-gadget.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c index 5adcb349718c..ccfaebca6faa 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -2614,6 +2614,7 @@ int cdns3_gadget_ep_dequeue(struct usb_ep *ep, u8 req_on_hw_ring = 0; unsigned long flags; int ret = 0; + int val; if (!ep || !request || !ep->desc) return -EINVAL; @@ -2649,6 +2650,13 @@ found: /* Update ring only if removed request is on pending_req_list list */ if (req_on_hw_ring && link_trb) { + /* Stop DMA */ + writel(EP_CMD_DFLUSH, &priv_dev->regs->ep_cmd); + + /* wait for DFLUSH cleared */ + readl_poll_timeout_atomic(&priv_dev->regs->ep_cmd, val, + !(val & EP_CMD_DFLUSH), 1, 1000); + link_trb->buffer = cpu_to_le32(TRB_BUFFER(priv_ep->trb_pool_dma + ((priv_req->end_trb + 1) * TRB_SIZE))); link_trb->control = cpu_to_le32((le32_to_cpu(link_trb->control) & TRB_CYCLE) | @@ -2660,6 +2668,10 @@ found: cdns3_gadget_giveback(priv_ep, priv_req, -ECONNRESET); + req = cdns3_next_request(&priv_ep->pending_req_list); + if (req) + cdns3_rearm_transfer(priv_ep, 1); + not_found: spin_unlock_irqrestore(&priv_dev->lock, flags); return ret; From d18dcfe9860e842f394e37ba01ca9440ab2178f4 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 23 Dec 2022 09:59:09 -0500 Subject: [PATCH 232/398] USB: gadgetfs: Fix race between mounting and unmounting The syzbot fuzzer and Gerald Lee have identified a use-after-free bug in the gadgetfs driver, involving processes concurrently mounting and unmounting the gadgetfs filesystem. In particular, gadgetfs_fill_super() can race with gadgetfs_kill_sb(), causing the latter to deallocate the_device while the former is using it. The output from KASAN says, in part: BUG: KASAN: use-after-free in instrument_atomic_read_write include/linux/instrumented.h:102 [inline] BUG: KASAN: use-after-free in atomic_fetch_sub_release include/linux/atomic/atomic-instrumented.h:176 [inline] BUG: KASAN: use-after-free in __refcount_sub_and_test include/linux/refcount.h:272 [inline] BUG: KASAN: use-after-free in __refcount_dec_and_test include/linux/refcount.h:315 [inline] BUG: KASAN: use-after-free in refcount_dec_and_test include/linux/refcount.h:333 [inline] BUG: KASAN: use-after-free in put_dev drivers/usb/gadget/legacy/inode.c:159 [inline] BUG: KASAN: use-after-free in gadgetfs_kill_sb+0x33/0x100 drivers/usb/gadget/legacy/inode.c:2086 Write of size 4 at addr ffff8880276d7840 by task syz-executor126/18689 CPU: 0 PID: 18689 Comm: syz-executor126 Not tainted 6.1.0-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022 Call Trace: ... atomic_fetch_sub_release include/linux/atomic/atomic-instrumented.h:176 [inline] __refcount_sub_and_test include/linux/refcount.h:272 [inline] __refcount_dec_and_test include/linux/refcount.h:315 [inline] refcount_dec_and_test include/linux/refcount.h:333 [inline] put_dev drivers/usb/gadget/legacy/inode.c:159 [inline] gadgetfs_kill_sb+0x33/0x100 drivers/usb/gadget/legacy/inode.c:2086 deactivate_locked_super+0xa7/0xf0 fs/super.c:332 vfs_get_super fs/super.c:1190 [inline] get_tree_single+0xd0/0x160 fs/super.c:1207 vfs_get_tree+0x88/0x270 fs/super.c:1531 vfs_fsconfig_locked fs/fsopen.c:232 [inline] The simplest solution is to ensure that gadgetfs_fill_super() and gadgetfs_kill_sb() are serialized by making them both acquire a new mutex. Signed-off-by: Alan Stern Reported-and-tested-by: syzbot+33d7ad66d65044b93f16@syzkaller.appspotmail.com Reported-and-tested-by: Gerald Lee Link: https://lore.kernel.org/linux-usb/CAO3qeMVzXDP-JU6v1u5Ags6Q-bb35kg3=C6d04DjzA9ffa5x1g@mail.gmail.com/ Fixes: e5d82a7360d1 ("vfs: Convert gadgetfs to use the new mount API") CC: Link: https://lore.kernel.org/r/Y6XCPXBpn3tmjdCC@rowland.harvard.edu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/legacy/inode.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 01c3ead7d1b4..d605bc2e7e8f 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -229,6 +229,7 @@ static void put_ep (struct ep_data *data) */ static const char *CHIP; +static DEFINE_MUTEX(sb_mutex); /* Serialize superblock operations */ /*----------------------------------------------------------------------*/ @@ -2010,13 +2011,20 @@ gadgetfs_fill_super (struct super_block *sb, struct fs_context *fc) { struct inode *inode; struct dev_data *dev; + int rc; - if (the_device) - return -ESRCH; + mutex_lock(&sb_mutex); + + if (the_device) { + rc = -ESRCH; + goto Done; + } CHIP = usb_get_gadget_udc_name(); - if (!CHIP) - return -ENODEV; + if (!CHIP) { + rc = -ENODEV; + goto Done; + } /* superblock */ sb->s_blocksize = PAGE_SIZE; @@ -2053,13 +2061,17 @@ gadgetfs_fill_super (struct super_block *sb, struct fs_context *fc) * from binding to a controller. */ the_device = dev; - return 0; + rc = 0; + goto Done; -Enomem: + Enomem: kfree(CHIP); CHIP = NULL; + rc = -ENOMEM; - return -ENOMEM; + Done: + mutex_unlock(&sb_mutex); + return rc; } /* "mount -t gadgetfs path /dev/gadget" ends up here */ @@ -2081,6 +2093,7 @@ static int gadgetfs_init_fs_context(struct fs_context *fc) static void gadgetfs_kill_sb (struct super_block *sb) { + mutex_lock(&sb_mutex); kill_litter_super (sb); if (the_device) { put_dev (the_device); @@ -2088,6 +2101,7 @@ gadgetfs_kill_sb (struct super_block *sb) } kfree(CHIP); CHIP = NULL; + mutex_unlock(&sb_mutex); } /*----------------------------------------------------------------------*/ From dbd24ec17b85b45f4e823d1aa5607721920f2b05 Mon Sep 17 00:00:00 2001 From: Juhyung Park Date: Tue, 17 Jan 2023 17:51:54 +0900 Subject: [PATCH 233/398] usb-storage: apply IGNORE_UAS only for HIKSEMI MD202 on RTL9210 The commit e00b488e813f ("usb-storage: Add Hiksemi USB3-FW to IGNORE_UAS") blacklists UAS for all of RTL9210 enclosures. The RTL9210 controller was advertised with UAS since its release back in 2019 and was shipped with a lot of enclosure products with different firmware combinations. Blacklist UAS only for HIKSEMI MD202. This should hopefully be replaced with more robust method than just comparing strings. But with limited information [1] provided thus far (dmesg when the device is plugged in, which includes manufacturer and product, but no lsusb -v to compare against), this is the best we can do for now. [1] https://lore.kernel.org/all/20230109115550.71688-1-qkrwngud825@gmail.com Fixes: e00b488e813f ("usb-storage: Add Hiksemi USB3-FW to IGNORE_UAS") Cc: Alan Stern Cc: Hongling Zeng Cc: stable@vger.kernel.org Signed-off-by: Juhyung Park Acked-by: Oliver Neukum Link: https://lore.kernel.org/r/20230117085154.123301-1-qkrwngud825@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/uas-detect.h | 13 +++++++++++++ drivers/usb/storage/unusual_uas.h | 7 ------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/usb/storage/uas-detect.h b/drivers/usb/storage/uas-detect.h index 3f720faa6f97..d73282c0ec50 100644 --- a/drivers/usb/storage/uas-detect.h +++ b/drivers/usb/storage/uas-detect.h @@ -116,6 +116,19 @@ static int uas_use_uas_driver(struct usb_interface *intf, if (le16_to_cpu(udev->descriptor.idVendor) == 0x0bc2) flags |= US_FL_NO_ATA_1X; + /* + * RTL9210-based enclosure from HIKSEMI, MD202 reportedly have issues + * with UAS. This isn't distinguishable with just idVendor and + * idProduct, use manufacturer and product too. + * + * Reported-by: Hongling Zeng + */ + if (le16_to_cpu(udev->descriptor.idVendor) == 0x0bda && + le16_to_cpu(udev->descriptor.idProduct) == 0x9210 && + (udev->manufacturer && !strcmp(udev->manufacturer, "HIKSEMI")) && + (udev->product && !strcmp(udev->product, "MD202"))) + flags |= US_FL_IGNORE_UAS; + usb_stor_adjust_quirks(udev, &flags); if (flags & US_FL_IGNORE_UAS) { diff --git a/drivers/usb/storage/unusual_uas.h b/drivers/usb/storage/unusual_uas.h index 251778d14e2d..c7b763d6d102 100644 --- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -83,13 +83,6 @@ UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_REPORT_LUNS), -/* Reported-by: Hongling Zeng */ -UNUSUAL_DEV(0x0bda, 0x9210, 0x0000, 0x9999, - "Hiksemi", - "External HDD", - USB_SC_DEVICE, USB_PR_DEVICE, NULL, - US_FL_IGNORE_UAS), - /* Reported-by: Benjamin Tissoires */ UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999, "Initio Corporation", From 8565c502e7c156d190d8e6d36e443f51b257f165 Mon Sep 17 00:00:00 2001 From: Drew Davenport Date: Mon, 26 Dec 2022 22:53:24 -0700 Subject: [PATCH 234/398] drm/i915/display: Check source height is > 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The error message suggests that the height of the src rect must be at least 1. Reject source with height of 0. Cc: stable@vger.kernel.org Signed-off-by: Drew Davenport Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20221226225246.1.I15dff7bb5a0e485c862eae61a69096caf12ef29f@changeid (cherry picked from commit 0fe76b198d482b41771a8d17b45fb726d13083cf) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/skl_universal_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 76490cc59d8f..7d07fa3123ec 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -1627,7 +1627,7 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state) u32 offset; int ret; - if (w > max_width || w < min_width || h > max_height) { + if (w > max_width || w < min_width || h > max_height || h < 1) { drm_dbg_kms(&dev_priv->drm, "requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n", w, h, min_width, max_width, max_height); From 93915a4170e9defd56a767a18e6c4076f3d18609 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Mon, 16 Jan 2023 16:22:10 +0200 Subject: [PATCH 235/398] xhci-pci: set the dma max_seg_size Allow devices to have dma operations beyond 64K, and avoid warnings such as: xhci_hcd 0000:00:14.0: mapping sg segment longer than device claims to support [len=98304] [max=65536] Cc: stable@vger.kernel.org Cc: Takashi Iwai Signed-off-by: Ricardo Ribalda Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20230116142216.1141605-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 79d679b3e076..2c0d7038f040 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -455,6 +455,8 @@ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) pm_runtime_allow(&dev->dev); + dma_set_max_seg_size(&dev->dev, UINT_MAX); + return 0; put_usb3_hcd: From e8fb5bc76eb86437ab87002d4a36d6da02165654 Mon Sep 17 00:00:00 2001 From: Jimmy Hu Date: Mon, 16 Jan 2023 16:22:11 +0200 Subject: [PATCH 236/398] usb: xhci: Check endpoint is valid before dereferencing it When the host controller is not responding, all URBs queued to all endpoints need to be killed. This can cause a kernel panic if we dereference an invalid endpoint. Fix this by using xhci_get_virt_ep() helper to find the endpoint and checking if the endpoint is valid before dereferencing it. [233311.853271] xhci-hcd xhci-hcd.1.auto: xHCI host controller not responding, assume dead [233311.853393] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000e8 [233311.853964] pc : xhci_hc_died+0x10c/0x270 [233311.853971] lr : xhci_hc_died+0x1ac/0x270 [233311.854077] Call trace: [233311.854085] xhci_hc_died+0x10c/0x270 [233311.854093] xhci_stop_endpoint_command_watchdog+0x100/0x1a4 [233311.854105] call_timer_fn+0x50/0x2d4 [233311.854112] expire_timers+0xac/0x2e4 [233311.854118] run_timer_softirq+0x300/0xabc [233311.854127] __do_softirq+0x148/0x528 [233311.854135] irq_exit+0x194/0x1a8 [233311.854143] __handle_domain_irq+0x164/0x1d0 [233311.854149] gic_handle_irq.22273+0x10c/0x188 [233311.854156] el1_irq+0xfc/0x1a8 [233311.854175] lpm_cpuidle_enter+0x25c/0x418 [msm_pm] [233311.854185] cpuidle_enter_state+0x1f0/0x764 [233311.854194] do_idle+0x594/0x6ac [233311.854201] cpu_startup_entry+0x7c/0x80 [233311.854209] secondary_start_kernel+0x170/0x198 Fixes: 50e8725e7c42 ("xhci: Refactor command watchdog and fix split string.") Cc: stable@vger.kernel.org Signed-off-by: Jimmy Hu Signed-off-by: Mathias Nyman Message-ID: <0fe978ed-8269-9774-1c40-f8a98c17e838@linux.intel.com> Link: https://lore.kernel.org/r/20230116142216.1141605-3-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index ddc30037f9ce..f5b0e1ce22af 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1169,7 +1169,10 @@ static void xhci_kill_endpoint_urbs(struct xhci_hcd *xhci, struct xhci_virt_ep *ep; struct xhci_ring *ring; - ep = &xhci->devs[slot_id]->eps[ep_index]; + ep = xhci_get_virt_ep(xhci, slot_id, ep_index); + if (!ep) + return; + if ((ep->ep_state & EP_HAS_STREAMS) || (ep->ep_state & EP_GETTING_NO_STREAMS)) { int stream_id; From a2bc47c43e70cf904b1af49f76d572326c08bca7 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 16 Jan 2023 16:22:12 +0200 Subject: [PATCH 237/398] xhci: Fix null pointer dereference when host dies Make sure xhci_free_dev() and xhci_kill_endpoint_urbs() do not race and cause null pointer dereference when host suddenly dies. Usb core may call xhci_free_dev() which frees the xhci->devs[slot_id] virt device at the same time that xhci_kill_endpoint_urbs() tries to loop through all the device's endpoints, checking if there are any cancelled urbs left to give back. hold the xhci spinlock while freeing the virt device Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20230116142216.1141605-4-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 79d7931c048a..50b41213e827 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3974,6 +3974,7 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_virt_device *virt_dev; struct xhci_slot_ctx *slot_ctx; + unsigned long flags; int i, ret; /* @@ -4000,7 +4001,11 @@ static void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) virt_dev->eps[i].ep_state &= ~EP_STOP_CMD_PENDING; virt_dev->udev = NULL; xhci_disable_slot(xhci, udev->slot_id); + + spin_lock_irqsave(&xhci->lock, flags); xhci_free_virt_device(xhci, udev->slot_id); + spin_unlock_irqrestore(&xhci->lock, flags); + } int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) From 23a3b8d5a2365653fd9bc5a9454d1e7f4facbf85 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 16 Jan 2023 16:22:13 +0200 Subject: [PATCH 238/398] xhci: Add update_hub_device override for PCI xHCI hosts Allow PCI hosts to check and tune roothub and port settings before the hub is up and running. This override is needed to turn off U1 and U2 LPM for some ports based on per port ACPI _DSM, _UPC, or possibly vendor specific mmio values for Intel xHC hosts. Usb core calls the host update_hub_device once it creates a hub. Entering U1 or U2 link power save state on ports with this limitation will cause link to fail, turning the usb device unusable in that setup. Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20230116142216.1141605-5-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 9 +++++++++ drivers/usb/host/xhci.c | 5 ++++- drivers/usb/host/xhci.h | 4 ++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 2c0d7038f040..b5016709b26f 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -78,9 +78,12 @@ static const char hcd_name[] = "xhci_hcd"; static struct hc_driver __read_mostly xhci_pci_hc_driver; static int xhci_pci_setup(struct usb_hcd *hcd); +static int xhci_pci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, + struct usb_tt *tt, gfp_t mem_flags); static const struct xhci_driver_overrides xhci_pci_overrides __initconst = { .reset = xhci_pci_setup, + .update_hub_device = xhci_pci_update_hub_device, }; /* called after powerup, by probe or system-pm "wakeup" */ @@ -386,6 +389,12 @@ static int xhci_pci_setup(struct usb_hcd *hcd) return xhci_pci_reinit(xhci, pdev); } +static int xhci_pci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, + struct usb_tt *tt, gfp_t mem_flags) +{ + return xhci_update_hub_device(hcd, hdev, tt, mem_flags); +} + /* * We need to register our own PCI probe function (instead of the USB core's * function) in order to create a second roothub under xHCI. diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 50b41213e827..89f92fc78bb1 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -5124,7 +5124,7 @@ static int xhci_disable_usb3_lpm_timeout(struct usb_hcd *hcd, /* Once a hub descriptor is fetched for a device, we need to update the xHC's * internal data structures for the device. */ -static int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, +int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, struct usb_tt *tt, gfp_t mem_flags) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); @@ -5224,6 +5224,7 @@ static int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, xhci_free_command(xhci, config_cmd); return ret; } +EXPORT_SYMBOL_GPL(xhci_update_hub_device); static int xhci_get_frame(struct usb_hcd *hcd) { @@ -5507,6 +5508,8 @@ void xhci_init_driver(struct hc_driver *drv, drv->check_bandwidth = over->check_bandwidth; if (over->reset_bandwidth) drv->reset_bandwidth = over->reset_bandwidth; + if (over->update_hub_device) + drv->update_hub_device = over->update_hub_device; } } EXPORT_SYMBOL_GPL(xhci_init_driver); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index c9f06c5e4e9d..3edfacb93817 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1943,6 +1943,8 @@ struct xhci_driver_overrides { struct usb_host_endpoint *ep); int (*check_bandwidth)(struct usb_hcd *, struct usb_device *); void (*reset_bandwidth)(struct usb_hcd *, struct usb_device *); + int (*update_hub_device)(struct usb_hcd *hcd, struct usb_device *hdev, + struct usb_tt *tt, gfp_t mem_flags); }; #define XHCI_CFC_DELAY 10 @@ -2122,6 +2124,8 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev); +int xhci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, + struct usb_tt *tt, gfp_t mem_flags); int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id); int xhci_ext_cap_init(struct xhci_hcd *xhci); From 0522b9a1653048440da5f21747f21e498b9220d1 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 16 Jan 2023 16:22:14 +0200 Subject: [PATCH 239/398] xhci: Add a flag to disable USB3 lpm on a xhci root port level. One USB3 roothub port may support link power management, while another root port on the same xHC can't due to different retimers used for the ports. This is the case with Intel Alder Lake, and possible future platforms where retimers used for USB4 ports cause too long exit latecy to enable native USB3 lpm U1 and U2 states. Add a flag in the xhci port structure to indicate if the port is lpm_incapable, and check it while calculating exit latency. Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20230116142216.1141605-6-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci.c | 8 ++++++++ drivers/usb/host/xhci.h | 1 + 2 files changed, 9 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 89f92fc78bb1..2b280beb0011 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -5049,6 +5049,7 @@ static int xhci_enable_usb3_lpm_timeout(struct usb_hcd *hcd, struct usb_device *udev, enum usb3_link_state state) { struct xhci_hcd *xhci; + struct xhci_port *port; u16 hub_encoded_timeout; int mel; int ret; @@ -5065,6 +5066,13 @@ static int xhci_enable_usb3_lpm_timeout(struct usb_hcd *hcd, if (xhci_check_tier_policy(xhci, udev, state) < 0) return USB3_LPM_DISABLED; + /* If connected to root port then check port can handle lpm */ + if (udev->parent && !udev->parent->parent) { + port = xhci->usb3_rhub.ports[udev->portnum - 1]; + if (port->lpm_incapable) + return USB3_LPM_DISABLED; + } + hub_encoded_timeout = xhci_calculate_lpm_timeout(hcd, udev, state); mel = calculate_max_exit_latency(udev, state, hub_encoded_timeout); if (mel < 0) { diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 3edfacb93817..dcee7f3207ad 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1735,6 +1735,7 @@ struct xhci_port { int hcd_portnum; struct xhci_hub *rhub; struct xhci_port_cap *port_cap; + unsigned int lpm_incapable:1; }; struct xhci_hub { From cd702d18c882d5a4ea44bbdb38edd5d5577ef640 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 16 Jan 2023 16:22:15 +0200 Subject: [PATCH 240/398] usb: acpi: add helper to check port lpm capability using acpi _DSM Add a helper to evaluate ACPI usb device specific method (_DSM) provided in case the USB3 port shouldn't enter U1 and U2 link states. This _DSM was added as port specific retimer configuration may lead to exit latencies growing beyond U1/U2 exit limits, and OS needs a way to find which ports can't support U1/U2 link power management states. This _DSM is also used by windows: Link: https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/usb-device-specific-method---dsm- Some patch issues found in testing resolved by Ron Lee Cc: stable@vger.kernel.org Tested-by: Ron Lee Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20230116142216.1141605-7-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/usb-acpi.c | 65 +++++++++++++++++++++++++++++++++++++ include/linux/usb.h | 3 ++ 2 files changed, 68 insertions(+) diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index 6d93428432f1..533baa85083c 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c @@ -37,6 +37,71 @@ bool usb_acpi_power_manageable(struct usb_device *hdev, int index) } EXPORT_SYMBOL_GPL(usb_acpi_power_manageable); +#define UUID_USB_CONTROLLER_DSM "ce2ee385-00e6-48cb-9f05-2edb927c4899" +#define USB_DSM_DISABLE_U1_U2_FOR_PORT 5 + +/** + * usb_acpi_port_lpm_incapable - check if lpm should be disabled for a port. + * @hdev: USB device belonging to the usb hub + * @index: zero based port index + * + * Some USB3 ports may not support USB3 link power management U1/U2 states + * due to different retimer setup. ACPI provides _DSM method which returns 0x01 + * if U1 and U2 states should be disabled. Evaluate _DSM with: + * Arg0: UUID = ce2ee385-00e6-48cb-9f05-2edb927c4899 + * Arg1: Revision ID = 0 + * Arg2: Function Index = 5 + * Arg3: (empty) + * + * Return 1 if USB3 port is LPM incapable, negative on error, otherwise 0 + */ + +int usb_acpi_port_lpm_incapable(struct usb_device *hdev, int index) +{ + union acpi_object *obj; + acpi_handle port_handle; + int port1 = index + 1; + guid_t guid; + int ret; + + ret = guid_parse(UUID_USB_CONTROLLER_DSM, &guid); + if (ret) + return ret; + + port_handle = usb_get_hub_port_acpi_handle(hdev, port1); + if (!port_handle) { + dev_dbg(&hdev->dev, "port-%d no acpi handle\n", port1); + return -ENODEV; + } + + if (!acpi_check_dsm(port_handle, &guid, 0, + BIT(USB_DSM_DISABLE_U1_U2_FOR_PORT))) { + dev_dbg(&hdev->dev, "port-%d no _DSM function %d\n", + port1, USB_DSM_DISABLE_U1_U2_FOR_PORT); + return -ENODEV; + } + + obj = acpi_evaluate_dsm(port_handle, &guid, 0, + USB_DSM_DISABLE_U1_U2_FOR_PORT, NULL); + + if (!obj) + return -ENODEV; + + if (obj->type != ACPI_TYPE_INTEGER) { + dev_dbg(&hdev->dev, "evaluate port-%d _DSM failed\n", port1); + ACPI_FREE(obj); + return -EINVAL; + } + + if (obj->integer.value == 0x01) + ret = 1; + + ACPI_FREE(obj); + + return ret; +} +EXPORT_SYMBOL_GPL(usb_acpi_port_lpm_incapable); + /** * usb_acpi_set_power_state - control usb port's power via acpi power * resource diff --git a/include/linux/usb.h b/include/linux/usb.h index 7d5325d47c45..04a7e94fb772 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -774,11 +774,14 @@ extern struct device *usb_intf_get_dma_device(struct usb_interface *intf); extern int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable); extern bool usb_acpi_power_manageable(struct usb_device *hdev, int index); +extern int usb_acpi_port_lpm_incapable(struct usb_device *hdev, int index); #else static inline int usb_acpi_set_power_state(struct usb_device *hdev, int index, bool enable) { return 0; } static inline bool usb_acpi_power_manageable(struct usb_device *hdev, int index) { return true; } +static inline int usb_acpi_port_lpm_incapable(struct usb_device *hdev, int index) + { return 0; } #endif /* USB autosuspend and autoresume */ From 74622f0a81d0c2bcfc39f9192b788124e8c7f0af Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 16 Jan 2023 16:22:16 +0200 Subject: [PATCH 241/398] xhci: Detect lpm incapable xHC USB3 roothub ports from ACPI tables USB3 ports on xHC hosts may have retimers that cause too long exit latency to work with native USB3 U1/U2 link power management states. For now only use usb_acpi_port_lpm_incapable() to evaluate if port lpm should be disabled while setting up the USB3 roothub. Other ways to identify lpm incapable ports can be added here later if ACPI _DSM does not exist. Limit this to Intel hosts for now, this is to my knowledge only an Intel issue. Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman Link: https://lore.kernel.org/r/20230116142216.1141605-8-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index b5016709b26f..fb988e4ea924 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -355,8 +355,38 @@ static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev) NULL); ACPI_FREE(obj); } + +static void xhci_find_lpm_incapable_ports(struct usb_hcd *hcd, struct usb_device *hdev) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + struct xhci_hub *rhub = &xhci->usb3_rhub; + int ret; + int i; + + /* This is not the usb3 roothub we are looking for */ + if (hcd != rhub->hcd) + return; + + if (hdev->maxchild > rhub->num_ports) { + dev_err(&hdev->dev, "USB3 roothub port number mismatch\n"); + return; + } + + for (i = 0; i < hdev->maxchild; i++) { + ret = usb_acpi_port_lpm_incapable(hdev, i); + + dev_dbg(&hdev->dev, "port-%d disable U1/U2 _DSM: %d\n", i + 1, ret); + + if (ret >= 0) { + rhub->ports[i]->lpm_incapable = ret; + continue; + } + } +} + #else static void xhci_pme_acpi_rtd3_enable(struct pci_dev *dev) { } +static void xhci_find_lpm_incapable_ports(struct usb_hcd *hcd, struct usb_device *hdev) { } #endif /* CONFIG_ACPI */ /* called during probe() after chip reset completes */ @@ -392,6 +422,10 @@ static int xhci_pci_setup(struct usb_hcd *hcd) static int xhci_pci_update_hub_device(struct usb_hcd *hcd, struct usb_device *hdev, struct usb_tt *tt, gfp_t mem_flags) { + /* Check if acpi claims some USB3 roothub ports are lpm incapable */ + if (!hdev->parent) + xhci_find_lpm_incapable_ports(hcd, hdev); + return xhci_update_hub_device(hcd, hdev, tt, mem_flags); } From f96c0384047257365371a8ac217107c0371586f1 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Thu, 15 Dec 2022 13:54:09 +0800 Subject: [PATCH 242/398] usb: chipidea: core: fix possible constant 0 if use IS_ERR(ci->role_switch) After successfully probed, ci->role_switch would only be NULL or a valid pointer. IS_ERR(ci->role_switch) will always return 0. So no need to wrap it with IS_ERR, otherwise the logic is wrong. Fixes: e1b5d2bed67c ("usb: chipidea: core: handle usb role switch in a common way") cc: Signed-off-by: Xu Yang Link: https://lore.kernel.org/r/20221215055409.3760523-1-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/chipidea/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 484b1cd23431..27c601296130 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -1294,12 +1294,12 @@ static void ci_extcon_wakeup_int(struct ci_hdrc *ci) cable_id = &ci->platdata->id_extcon; cable_vbus = &ci->platdata->vbus_extcon; - if ((!IS_ERR(cable_id->edev) || !IS_ERR(ci->role_switch)) + if ((!IS_ERR(cable_id->edev) || ci->role_switch) && ci->is_otg && (otgsc & OTGSC_IDIE) && (otgsc & OTGSC_IDIS)) ci_irq(ci); - if ((!IS_ERR(cable_vbus->edev) || !IS_ERR(ci->role_switch)) + if ((!IS_ERR(cable_vbus->edev) || ci->role_switch) && ci->is_otg && (otgsc & OTGSC_BSVIE) && (otgsc & OTGSC_BSVIS)) ci_irq(ci); From bd449ad8cee9d4b523abbdfa73e1a2a08333f331 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 30 Dec 2022 16:17:30 +0800 Subject: [PATCH 243/398] usb: musb: fix error return code in omap2430_probe() Before calling platform_get_resource() in omap2430_probe(), the 'ret' is re-assgined to 0, it can't return an error code, if platform_get_resource fails. Set the error code to -EINVAL to fix this. Fixes: ffbe2feac59b ("usb: musb: omap2430: Fix probe regression for missing resources") Cc: stable Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221230081730.1655616-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/omap2430.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 476f55d1fec3..44a21ec865fb 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -411,8 +411,10 @@ static int omap2430_probe(struct platform_device *pdev) memset(musb_res, 0, sizeof(*musb_res) * ARRAY_SIZE(musb_res)); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) + if (!res) { + ret = -EINVAL; goto err2; + } musb_res[i].start = res->start; musb_res[i].end = res->end; From fac4b8633fd682ecc8e9cff61cb3e33374a1c7e5 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Mon, 9 Jan 2023 23:12:18 -0800 Subject: [PATCH 244/398] usb: ucsi: Ensure connector delayed work items are flushed During ucsi_unregister() when destroying a connector's workqueue, there may still be pending delayed work items that haven't been scheduled yet. Because queue_delayed_work() uses a separate timer to schedule a work item, the destroy_workqueue() call is not aware of any pending items. Hence when a pending item's timer expires it would then try to queue on a dangling workqueue pointer. Fix this by keeping track of all work items in a list, so that prior to destroying the workqueue any pending items can be flushed. Do this by calling mod_delayed_work() as that will cause pending items to get queued immediately, which then allows the ensuing destroy_workqueue() to implicitly drain all currently queued items to completion and free themselves. Fixes: b9aa02ca39a4 ("usb: typec: ucsi: Add polling mechanism for partner tasks like alt mode checking") Suggested-by: Heikki Krogerus Co-developed-by: Linyu Yuan Signed-off-by: Linyu Yuan Signed-off-by: Jack Pham Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20230110071218.26261-1-quic_jackp@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/ucsi/ucsi.c | 24 +++++++++++++++++++++--- drivers/usb/typec/ucsi/ucsi.h | 1 + 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index eabe519013e7..1292241d581a 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -187,6 +187,7 @@ EXPORT_SYMBOL_GPL(ucsi_send_command); struct ucsi_work { struct delayed_work work; + struct list_head node; unsigned long delay; unsigned int count; struct ucsi_connector *con; @@ -202,6 +203,7 @@ static void ucsi_poll_worker(struct work_struct *work) mutex_lock(&con->lock); if (!con->partner) { + list_del(&uwork->node); mutex_unlock(&con->lock); kfree(uwork); return; @@ -209,10 +211,12 @@ static void ucsi_poll_worker(struct work_struct *work) ret = uwork->cb(con); - if (uwork->count-- && (ret == -EBUSY || ret == -ETIMEDOUT)) + if (uwork->count-- && (ret == -EBUSY || ret == -ETIMEDOUT)) { queue_delayed_work(con->wq, &uwork->work, uwork->delay); - else + } else { + list_del(&uwork->node); kfree(uwork); + } mutex_unlock(&con->lock); } @@ -236,6 +240,7 @@ static int ucsi_partner_task(struct ucsi_connector *con, uwork->con = con; uwork->cb = cb; + list_add_tail(&uwork->node, &con->partner_tasks); queue_delayed_work(con->wq, &uwork->work, delay); return 0; @@ -1056,6 +1061,7 @@ static int ucsi_register_port(struct ucsi *ucsi, int index) INIT_WORK(&con->work, ucsi_handle_connector_change); init_completion(&con->complete); mutex_init(&con->lock); + INIT_LIST_HEAD(&con->partner_tasks); con->num = index + 1; con->ucsi = ucsi; @@ -1420,8 +1426,20 @@ void ucsi_unregister(struct ucsi *ucsi) ucsi_unregister_altmodes(&ucsi->connector[i], UCSI_RECIPIENT_CON); ucsi_unregister_port_psy(&ucsi->connector[i]); - if (ucsi->connector[i].wq) + + if (ucsi->connector[i].wq) { + struct ucsi_work *uwork; + + mutex_lock(&ucsi->connector[i].lock); + /* + * queue delayed items immediately so they can execute + * and free themselves before the wq is destroyed + */ + list_for_each_entry(uwork, &ucsi->connector[i].partner_tasks, node) + mod_delayed_work(ucsi->connector[i].wq, &uwork->work, 0); + mutex_unlock(&ucsi->connector[i].lock); destroy_workqueue(ucsi->connector[i].wq); + } typec_unregister_port(ucsi->connector[i].port); } diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index c968474ee547..60ce9fb6e745 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -322,6 +322,7 @@ struct ucsi_connector { struct work_struct work; struct completion complete; struct workqueue_struct *wq; + struct list_head partner_tasks; struct typec_port *port; struct typec_partner *partner; From e5854355d76b8d768cea8e4fc3ce6dfdba25518a Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Tue, 10 Jan 2023 17:32:52 +0000 Subject: [PATCH 245/398] usb: misc: onboard_hub: Invert driver registration order The onboard_hub 'driver' consists of two drivers, a platform driver and a USB driver. Currently when the onboard hub driver is initialized it first registers the platform driver, then the USB driver. This results in a race condition when the 'attach' work is executed, which is scheduled when the platform device is probed. The purpose of fhe 'attach' work is to bind elegible USB hub devices to the onboard_hub USB driver. This fails if the work runs before the USB driver has been registered. Register the USB driver first, then the platform driver. This increases the chances that the onboard_hub USB devices are probed before their corresponding platform device, which the USB driver tries to locate in _probe(). The driver already handles this situation and defers probing if the onboard hub platform device doesn't exist yet. Cc: stable@vger.kernel.org Fixes: 8bc063641ceb ("usb: misc: Add onboard_usb_hub driver") Link: https://lore.kernel.org/lkml/Y6W00vQm3jfLflUJ@hovoldconsulting.com/T/#m0d64295f017942fd988f7c53425db302d61952b4 Reported-by: Alexander Stein Signed-off-by: Matthias Kaehlcke Tested-by: Stefan Wahren Link: https://lore.kernel.org/r/20230110172954.v2.1.I75494ebee7027a50235ce4b1e930fa73a578fbe2@changeid Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/onboard_usb_hub.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/onboard_usb_hub.c b/drivers/usb/misc/onboard_usb_hub.c index 94e7966e199d..db0844b30bbd 100644 --- a/drivers/usb/misc/onboard_usb_hub.c +++ b/drivers/usb/misc/onboard_usb_hub.c @@ -433,13 +433,13 @@ static int __init onboard_hub_init(void) { int ret; - ret = platform_driver_register(&onboard_hub_driver); + ret = usb_register_device_driver(&onboard_hub_usbdev_driver, THIS_MODULE); if (ret) return ret; - ret = usb_register_device_driver(&onboard_hub_usbdev_driver, THIS_MODULE); + ret = platform_driver_register(&onboard_hub_driver); if (ret) - platform_driver_unregister(&onboard_hub_driver); + usb_deregister_device_driver(&onboard_hub_usbdev_driver); return ret; } From cde37881e2e14590675d0acdfbad408300d9ca95 Mon Sep 17 00:00:00 2001 From: Matthias Kaehlcke Date: Tue, 10 Jan 2023 17:32:53 +0000 Subject: [PATCH 246/398] usb: misc: onboard_hub: Move 'attach' work to the driver Currently each onboard_hub platform device owns an 'attach' work, which is scheduled when the device probes. With this deadlocks have been reported on a Raspberry Pi 3 B+ [1], which has nested onboard hubs. The flow of the deadlock is something like this (with the onboard_hub driver built as a module) [2]: - USB root hub is instantiated - core hub driver calls onboard_hub_create_pdevs(), which creates the 'raw' platform device for the 1st level hub - 1st level hub is probed by the core hub driver - core hub driver calls onboard_hub_create_pdevs(), which creates the 'raw' platform device for the 2nd level hub - onboard_hub platform driver is registered - platform device for 1st level hub is probed - schedules 'attach' work - platform device for 2nd level hub is probed - schedules 'attach' work - onboard_hub USB driver is registered - device (and parent) lock of hub is held while the device is re-probed with the onboard_hub driver - 'attach' work (running in another thread) calls driver_attach(), which blocks on one of the hub device locks - onboard_hub_destroy_pdevs() is called by the core hub driver when one of the hubs is detached - destroying the pdevs invokes onboard_hub_remove(), which waits for the 'attach' work to complete - waits forever, since the 'attach' work can't acquire the device lock Use a single work struct for the driver instead of having a work struct per onboard hub platform driver instance. With that it isn't necessary to cancel the work in onboard_hub_remove(), which fixes the deadlock. The work is only cancelled when the driver is unloaded. [1] https://lore.kernel.org/r/d04bcc45-3471-4417-b30b-5cf9880d785d@i2se.com/ [2] https://lore.kernel.org/all/Y6OrGbqaMy2iVDWB@google.com/ Cc: stable@vger.kernel.org Fixes: 8bc063641ceb ("usb: misc: Add onboard_usb_hub driver") Link: https://lore.kernel.org/r/d04bcc45-3471-4417-b30b-5cf9880d785d@i2se.com/ Link: https://lore.kernel.org/all/Y6OrGbqaMy2iVDWB@google.com/ Reported-by: Stefan Wahren Signed-off-by: Matthias Kaehlcke Link: https://lore.kernel.org/r/20230110172954.v2.2.I16b51f32db0c32f8a8532900bfe1c70c8572881a@changeid Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/onboard_usb_hub.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/usb/misc/onboard_usb_hub.c b/drivers/usb/misc/onboard_usb_hub.c index db0844b30bbd..969c4c4f2ae9 100644 --- a/drivers/usb/misc/onboard_usb_hub.c +++ b/drivers/usb/misc/onboard_usb_hub.c @@ -27,7 +27,10 @@ #include "onboard_usb_hub.h" +static void onboard_hub_attach_usb_driver(struct work_struct *work); + static struct usb_device_driver onboard_hub_usbdev_driver; +static DECLARE_WORK(attach_usb_driver_work, onboard_hub_attach_usb_driver); /************************** Platform driver **************************/ @@ -45,7 +48,6 @@ struct onboard_hub { bool is_powered_on; bool going_away; struct list_head udev_list; - struct work_struct attach_usb_driver_work; struct mutex lock; }; @@ -271,8 +273,7 @@ static int onboard_hub_probe(struct platform_device *pdev) * This needs to be done deferred to avoid self-deadlocks on systems * with nested onboard hubs. */ - INIT_WORK(&hub->attach_usb_driver_work, onboard_hub_attach_usb_driver); - schedule_work(&hub->attach_usb_driver_work); + schedule_work(&attach_usb_driver_work); return 0; } @@ -285,9 +286,6 @@ static int onboard_hub_remove(struct platform_device *pdev) hub->going_away = true; - if (&hub->attach_usb_driver_work != current_work()) - cancel_work_sync(&hub->attach_usb_driver_work); - mutex_lock(&hub->lock); /* unbind the USB devices to avoid dangling references to this device */ @@ -449,6 +447,8 @@ static void __exit onboard_hub_exit(void) { usb_deregister_device_driver(&onboard_hub_usbdev_driver); platform_driver_unregister(&onboard_hub_driver); + + cancel_work_sync(&attach_usb_driver_work); } module_exit(onboard_hub_exit); From 6a19da111057f69214b97c62fb0ac59023970850 Mon Sep 17 00:00:00 2001 From: Udipto Goswami Date: Thu, 15 Dec 2022 10:59:05 +0530 Subject: [PATCH 247/398] usb: gadget: f_fs: Prevent race during ffs_ep0_queue_wait While performing fast composition switch, there is a possibility that the process of ffs_ep0_write/ffs_ep0_read get into a race condition due to ep0req being freed up from functionfs_unbind. Consider the scenario that the ffs_ep0_write calls the ffs_ep0_queue_wait by taking a lock &ffs->ev.waitq.lock. However, the functionfs_unbind isn't bounded so it can go ahead and mark the ep0req to NULL, and since there is no NULL check in ffs_ep0_queue_wait we will end up in use-after-free. Fix this by making a serialized execution between the two functions using a mutex_lock(ffs->mutex). Fixes: ddf8abd25994 ("USB: f_fs: the FunctionFS driver") Signed-off-by: Udipto Goswami Tested-by: Krishna Kurapati Link: https://lore.kernel.org/r/20221215052906.8993-2-quic_ugoswami@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_fs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 73dc10a77cde..bb6fe1f3a29d 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -279,6 +279,9 @@ static int __ffs_ep0_queue_wait(struct ffs_data *ffs, char *data, size_t len) struct usb_request *req = ffs->ep0req; int ret; + if (!req) + return -EINVAL; + req->zero = len < le16_to_cpu(ffs->ev.setup.wLength); spin_unlock_irq(&ffs->ev.waitq.lock); @@ -1892,10 +1895,12 @@ static void functionfs_unbind(struct ffs_data *ffs) ENTER(); if (!WARN_ON(!ffs->gadget)) { + mutex_lock(&ffs->mutex); usb_ep_free_request(ffs->gadget->ep0, ffs->ep0req); ffs->ep0req = NULL; ffs->gadget = NULL; clear_bit(FFS_FL_BOUND, &ffs->flags); + mutex_unlock(&ffs->mutex); ffs_data_put(ffs); } } From ce405d561b020e5a46340eb5146805a625dcacee Mon Sep 17 00:00:00 2001 From: Udipto Goswami Date: Thu, 15 Dec 2022 10:59:06 +0530 Subject: [PATCH 248/398] usb: gadget: f_fs: Ensure ep0req is dequeued before free_request As per the documentation, function usb_ep_free_request guarantees the request will not be queued or no longer be re-queued (or otherwise used). However, with the current implementation it doesn't make sure that the request in ep0 isn't reused. Fix this by dequeuing the ep0req on functionfs_unbind before freeing the request to align with the definition. Fixes: ddf8abd25994 ("USB: f_fs: the FunctionFS driver") Signed-off-by: Udipto Goswami Tested-by: Krishna Kurapati Link: https://lore.kernel.org/r/20221215052906.8993-3-quic_ugoswami@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_fs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index bb6fe1f3a29d..523a961b910b 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1895,6 +1895,8 @@ static void functionfs_unbind(struct ffs_data *ffs) ENTER(); if (!WARN_ON(!ffs->gadget)) { + /* dequeue before freeing ep0req */ + usb_ep_dequeue(ffs->gadget->ep0, ffs->ep0req); mutex_lock(&ffs->mutex); usb_ep_free_request(ffs->gadget->ep0, ffs->ep0req); ffs->ep0req = NULL; From 582836e3cfab4faafbdc93bbec96fce036a08ee1 Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Wed, 11 Jan 2023 02:05:41 +0000 Subject: [PATCH 249/398] usb: typec: altmodes/displayport: Add pin assignment helper The code to extract a peripheral's currently supported Pin Assignments is repeated in a couple of locations. Factor it out into a separate function. This will also make it easier to add fixes (we only need to update 1 location instead of 2). Fixes: c1e5c2f0cb8a ("usb: typec: altmodes/displayport: correct pin assignment for UFP receptacles") Cc: stable@vger.kernel.org Cc: Heikki Krogerus Signed-off-by: Prashant Malani Reviewed-by: Benson Leung Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20230111020546.3384569-1-pmalani@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/altmodes/displayport.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index de66a2949e33..5bc7a58f7f44 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -419,6 +419,18 @@ static const char * const pin_assignments[] = { [DP_PIN_ASSIGN_F] = "F", }; +/* + * Helper function to extract a peripheral's currently supported + * Pin Assignments from its DisplayPort alternate mode state. + */ +static u8 get_current_pin_assignments(struct dp_altmode *dp) +{ + if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D) + return DP_CAP_UFP_D_PIN_ASSIGN(dp->alt->vdo); + else + return DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo); +} + static ssize_t pin_assignment_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) @@ -445,10 +457,7 @@ pin_assignment_store(struct device *dev, struct device_attribute *attr, goto out_unlock; } - if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D) - assignments = DP_CAP_UFP_D_PIN_ASSIGN(dp->alt->vdo); - else - assignments = DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo); + assignments = get_current_pin_assignments(dp); if (!(DP_CONF_GET_PIN_ASSIGN(conf) & assignments)) { ret = -EINVAL; @@ -485,10 +494,7 @@ static ssize_t pin_assignment_show(struct device *dev, cur = get_count_order(DP_CONF_GET_PIN_ASSIGN(dp->data.conf)); - if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D) - assignments = DP_CAP_UFP_D_PIN_ASSIGN(dp->alt->vdo); - else - assignments = DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo); + assignments = get_current_pin_assignments(dp); for (i = 0; assignments; assignments >>= 1, i++) { if (assignments & 1) { From 9682b41e52cc9f42f5c33caf410464392adaef04 Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Wed, 11 Jan 2023 02:05:42 +0000 Subject: [PATCH 250/398] usb: typec: altmodes/displayport: Fix pin assignment calculation Commit c1e5c2f0cb8a ("usb: typec: altmodes/displayport: correct pin assignment for UFP receptacles") fixed the pin assignment calculation to take into account whether the peripheral was a plug or a receptacle. But the "pin_assignments" sysfs logic was not updated. Address this by using the macros introduced in the aforementioned commit in the sysfs logic too. Fixes: c1e5c2f0cb8a ("usb: typec: altmodes/displayport: correct pin assignment for UFP receptacles") Cc: stable@vger.kernel.org Cc: Heikki Krogerus Signed-off-by: Prashant Malani Reviewed-by: Benson Leung Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20230111020546.3384569-2-pmalani@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/altmodes/displayport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index 5bc7a58f7f44..80d8c6c3be36 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -426,9 +426,9 @@ static const char * const pin_assignments[] = { static u8 get_current_pin_assignments(struct dp_altmode *dp) { if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D) - return DP_CAP_UFP_D_PIN_ASSIGN(dp->alt->vdo); + return DP_CAP_PIN_ASSIGN_DFP_D(dp->alt->vdo); else - return DP_CAP_DFP_D_PIN_ASSIGN(dp->alt->vdo); + return DP_CAP_PIN_ASSIGN_UFP_D(dp->alt->vdo); } static ssize_t From 85af23df903ee14bfcba60c53e4f3b640f2310f8 Mon Sep 17 00:00:00 2001 From: Prashant Malani Date: Wed, 11 Jan 2023 02:05:43 +0000 Subject: [PATCH 251/398] usb: typec: altmodes/displayport: Use proper macro for pin assignment check While looking at the DP configuration VDO to determine the peripheral configuration, the spec (Table 8-5: DisplayPort Configurations, VESA DisplayPort Alt Mode Standard v2.0) lists the options as "UFP_U as a DP Source/Sink Device". So, use the correct macro while performing this check. Effectively it's the same as the existing code, but the proposed macro describes the state a little better. No functional changes introduced. Cc: Heikki Krogerus Signed-off-by: Prashant Malani Reviewed-by: Benson Leung Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20230111020546.3384569-3-pmalani@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/altmodes/displayport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index 80d8c6c3be36..9a6860285fbe 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -425,7 +425,7 @@ static const char * const pin_assignments[] = { */ static u8 get_current_pin_assignments(struct dp_altmode *dp) { - if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_DFP_D) + if (DP_CONF_CURRENTLY(dp->data.conf) == DP_CONF_UFP_U_AS_DFP_D) return DP_CAP_PIN_ASSIGN_DFP_D(dp->alt->vdo); else return DP_CAP_PIN_ASSIGN_UFP_D(dp->alt->vdo); From e95765e97d9cb93258a4840440d410fa6ff7e819 Mon Sep 17 00:00:00 2001 From: Daniel Scally Date: Fri, 16 Dec 2022 16:05:28 +0000 Subject: [PATCH 252/398] usb: gadget: g_webcam: Send color matching descriptor per frame Currently the color matching descriptor is only sent across the wire a single time, following the descriptors for each format and frame. According to the UVC 1.5 Specification 3.9.2.6 ("Color Matching Descriptors"): "Only one instance is allowed for a given format and if present, the Color Matching descriptor shall be placed following the Video and Still Image Frame descriptors for that format". Add another reference to the color matching descriptor after the yuyv frames so that it's correctly transmitted for that format too. Fixes: a9914127e834 ("USB gadget: Webcam device") Cc: stable Signed-off-by: Daniel Scally Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham Link: https://lore.kernel.org/r/20221216160528.479094-1-dan.scally@ideasonboard.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/legacy/webcam.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/legacy/webcam.c b/drivers/usb/gadget/legacy/webcam.c index 53e38f87472b..c06dd1af7a0c 100644 --- a/drivers/usb/gadget/legacy/webcam.c +++ b/drivers/usb/gadget/legacy/webcam.c @@ -293,6 +293,7 @@ static const struct uvc_descriptor_header * const uvc_fs_streaming_cls[] = { (const struct uvc_descriptor_header *) &uvc_format_yuv, (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, + (const struct uvc_descriptor_header *) &uvc_color_matching, (const struct uvc_descriptor_header *) &uvc_format_mjpg, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, @@ -305,6 +306,7 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = { (const struct uvc_descriptor_header *) &uvc_format_yuv, (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, + (const struct uvc_descriptor_header *) &uvc_color_matching, (const struct uvc_descriptor_header *) &uvc_format_mjpg, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, @@ -317,6 +319,7 @@ static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = { (const struct uvc_descriptor_header *) &uvc_format_yuv, (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p, (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p, + (const struct uvc_descriptor_header *) &uvc_color_matching, (const struct uvc_descriptor_header *) &uvc_format_mjpg, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p, (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p, From 36f78477ac2c89e9a2eed4a31404a291a3450b5d Mon Sep 17 00:00:00 2001 From: ChiYuan Huang Date: Mon, 9 Jan 2023 15:19:50 +0800 Subject: [PATCH 253/398] usb: typec: tcpm: Fix altmode re-registration causes sysfs create fail There's the altmode re-registeration issue after data role swap (DR_SWAP). Comparing to USBPD 2.0, in USBPD 3.0, it loose the limit that only DFP can initiate the VDM command to get partner identity information. For a USBPD 3.0 UFP device, it may already get the identity information from its port partner before DR_SWAP. If DR_SWAP send or receive at the mean time, 'send_discover' flag will be raised again. It causes discover identify action restart while entering ready state. And after all discover actions are done, the 'tcpm_register_altmodes' will be called. If old altmode is not unregistered, this sysfs create fail can be found. In 'DR_SWAP_CHANGE_DR' state case, only DFP will unregister altmodes. For UFP, the original altmodes keep registered. This patch fix the logic that after DR_SWAP, 'tcpm_unregister_altmodes' must be called whatever the current data role is. Reviewed-by: Macpaul Lin Fixes: ae8a2ca8a221 ("usb: typec: Group all TCPCI/TCPM code together") Reported-by: TommyYl Chen Cc: stable@vger.kernel.org Signed-off-by: ChiYuan Huang Acked-by: Heikki Krogerus Link: https://lore.kernel.org/r/1673248790-15794-1-git-send-email-cy_huang@richtek.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tcpm/tcpm.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index 904c7b4ce2f0..59b366b5c614 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -4594,14 +4594,13 @@ static void run_state_machine(struct tcpm_port *port) tcpm_set_state(port, ready_state(port), 0); break; case DR_SWAP_CHANGE_DR: - if (port->data_role == TYPEC_HOST) { - tcpm_unregister_altmodes(port); + tcpm_unregister_altmodes(port); + if (port->data_role == TYPEC_HOST) tcpm_set_roles(port, true, port->pwr_role, TYPEC_DEVICE); - } else { + else tcpm_set_roles(port, true, port->pwr_role, TYPEC_HOST); - } tcpm_ams_finish(port); tcpm_set_state(port, ready_state(port), 0); break; From 7c07553807c5125c89de242d35c10c206fd8e6bb Mon Sep 17 00:00:00 2001 From: Chanh Nguyen Date: Wed, 11 Jan 2023 13:51:05 +0700 Subject: [PATCH 254/398] USB: gadget: Add ID numbers to configfs-gadget driver names It is unable to use configfs to attach more than one gadget. When attaching the second gadget, it always fails and the kernel message prints out: Error: Driver 'configfs-gadget' is already registered, aborting... UDC core: g1: driver registration failed: -16 This commit fixes the problem by using the gadget name as a suffix to each configfs_gadget's driver name, thus making the names distinct. Fixes: fc274c1e9973 ("USB: gadget: Add a new bus for gadgets") Cc: stable Signed-off-by: Chanh Nguyen Reviewed-by: Andrzej Pietrasiewicz Tested-by: Heikki Krogerus Reviewed-by: Frank Li Link: https://lore.kernel.org/r/20230111065105.29205-1-chanh@os.amperecomputing.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/configfs.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 96121d1c8df4..0853536cbf2e 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -393,6 +393,7 @@ static void gadget_info_attr_release(struct config_item *item) WARN_ON(!list_empty(&gi->string_list)); WARN_ON(!list_empty(&gi->available_func)); kfree(gi->composite.gadget_driver.function); + kfree(gi->composite.gadget_driver.driver.name); kfree(gi); } @@ -1572,7 +1573,6 @@ static const struct usb_gadget_driver configfs_driver_template = { .max_speed = USB_SPEED_SUPER_PLUS, .driver = { .owner = THIS_MODULE, - .name = "configfs-gadget", }, .match_existing_only = 1, }; @@ -1623,13 +1623,21 @@ static struct config_group *gadgets_make( gi->composite.gadget_driver = configfs_driver_template; + gi->composite.gadget_driver.driver.name = kasprintf(GFP_KERNEL, + "configfs-gadget.%s", name); + if (!gi->composite.gadget_driver.driver.name) + goto err; + gi->composite.gadget_driver.function = kstrdup(name, GFP_KERNEL); gi->composite.name = gi->composite.gadget_driver.function; if (!gi->composite.gadget_driver.function) - goto err; + goto out_free_driver_name; return &gi->group; + +out_free_driver_name: + kfree(gi->composite.gadget_driver.driver.name); err: kfree(gi); return ERR_PTR(-ENOMEM); From c6ec929595c7443250b2a4faea988c62019d5cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Tue, 17 Jan 2023 05:18:39 -0800 Subject: [PATCH 255/398] usb: gadget: f_ncm: fix potential NULL ptr deref in ncm_bitrate() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Google internal bug 265639009 we've received an (as yet) unreproducible crash report from an aarch64 GKI 5.10.149-android13 running device. AFAICT the source code is at: https://android.googlesource.com/kernel/common/+/refs/tags/ASB-2022-12-05_13-5.10 The call stack is: ncm_close() -> ncm_notify() -> ncm_do_notify() with the crash at: ncm_do_notify+0x98/0x270 Code: 79000d0b b9000a6c f940012a f9400269 (b9405d4b) Which I believe disassembles to (I don't know ARM assembly, but it looks sane enough to me...): // halfword (16-bit) store presumably to event->wLength (at offset 6 of struct usb_cdc_notification) 0B 0D 00 79 strh w11, [x8, #6] // word (32-bit) store presumably to req->Length (at offset 8 of struct usb_request) 6C 0A 00 B9 str w12, [x19, #8] // x10 (NULL) was read here from offset 0 of valid pointer x9 // IMHO we're reading 'cdev->gadget' and getting NULL // gadget is indeed at offset 0 of struct usb_composite_dev 2A 01 40 F9 ldr x10, [x9] // loading req->buf pointer, which is at offset 0 of struct usb_request 69 02 40 F9 ldr x9, [x19] // x10 is null, crash, appears to be attempt to read cdev->gadget->max_speed 4B 5D 40 B9 ldr w11, [x10, #0x5c] which seems to line up with ncm_do_notify() case NCM_NOTIFY_SPEED code fragment: event->wLength = cpu_to_le16(8); req->length = NCM_STATUS_BYTECOUNT; /* SPEED_CHANGE data is up/down speeds in bits/sec */ data = req->buf + sizeof *event; data[0] = cpu_to_le32(ncm_bitrate(cdev->gadget)); My analysis of registers and NULL ptr deref crash offset (Unable to handle kernel NULL pointer dereference at virtual address 000000000000005c) heavily suggests that the crash is due to 'cdev->gadget' being NULL when executing: data[0] = cpu_to_le32(ncm_bitrate(cdev->gadget)); which calls: ncm_bitrate(NULL) which then calls: gadget_is_superspeed(NULL) which reads ((struct usb_gadget *)NULL)->max_speed and hits a panic. AFAICT, if I'm counting right, the offset of max_speed is indeed 0x5C. (remember there's a GKI KABI reservation of 16 bytes in struct work_struct) It's not at all clear to me how this is all supposed to work... but returning 0 seems much better than panic-ing... Cc: Felipe Balbi Cc: Lorenzo Colitti Cc: Carlos Llamas Cc: stable@vger.kernel.org Signed-off-by: Maciej Å»enczykowski Cc: stable Link: https://lore.kernel.org/r/20230117131839.1138208-1-maze@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/function/f_ncm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index c36bcfa0e9b4..424bb3b666db 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -83,7 +83,9 @@ static inline struct f_ncm *func_to_ncm(struct usb_function *f) /* peak (theoretical) bulk transfer rate in bits-per-second */ static inline unsigned ncm_bitrate(struct usb_gadget *g) { - if (gadget_is_superspeed(g) && g->speed >= USB_SPEED_SUPER_PLUS) + if (!g) + return 0; + else if (gadget_is_superspeed(g) && g->speed >= USB_SPEED_SUPER_PLUS) return 4250000000U; else if (gadget_is_superspeed(g) && g->speed == USB_SPEED_SUPER) return 3750000000U; From 11cefeb2058f9f2322713b2683be9301556705e2 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 12 Dec 2022 16:20:35 +0100 Subject: [PATCH 256/398] USB: fix misleading usb_set_intfdata() kernel doc The struct device driver-data pointer is used for any data that a driver may need in various callbacks while bound to the device. For convenience, subsystems typically provide wrappers such as usb_set_intfdata() of the generic accessor functions for use in bus callbacks. There is generally no longer any need for a driver to clear the pointer, but since commit 0998d0631001 ("device-core: Ensure drvdata = NULL when no driver is bound") the driver-data pointer is set to NULL by driver core post unbind anyway. For historical reasons, USB core also clears this pointer when an explicitly claimed interface is released. Due to a misunderstanding, a misleading kernel doc comment for usb_set_intfdata() was recently added which claimed that the driver data pointer must not be cleared during disconnect before "all actions [are] completed", which is both imprecise and incorrect. Specifically, drivers like cdc-acm which claim additional interfaces use the driver-data pointer as a flag which is cleared when the first interface is unbound. As long as a driver does not do something odd like dereference the pointer in, for example, completion callbacks, this can be done at any time during disconnect. And in any case this is no different than for any other resource, like the driver data itself, which may be freed by the disconnect callback. Note that the comment actually also claimed that the interface itself was somehow being set to NULL by driver core. Fix the kernel doc by removing incorrect, overly specific and misleading details and adding a comment about why some drivers do clear the driver-data pointer. Fixes: 27ef17849779 ("usb: add usb_set_intfdata() documentation") Signed-off-by: Johan Hovold Acked-by: Alan Stern Acked-by: Vincent Mailhol Link: https://lore.kernel.org/r/20221212152035.31806-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/include/linux/usb.h b/include/linux/usb.h index 04a7e94fb772..86d1c8e79566 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -267,16 +267,15 @@ static inline void *usb_get_intfdata(struct usb_interface *intf) } /** - * usb_set_intfdata() - associate driver-specific data with the interface - * @intf: the usb interface - * @data: pointer to the device priv structure or %NULL + * usb_set_intfdata() - associate driver-specific data with an interface + * @intf: USB interface + * @data: driver data * - * Drivers should use this function in their probe() to associate their - * driver-specific data with the usb interface. + * Drivers can use this function in their probe() callbacks to associate + * driver-specific data with an interface. * - * When disconnecting, the core will take care of setting @intf back to %NULL, - * so no actions are needed on the driver side. The interface should not be set - * to %NULL before all actions completed (e.g. no outsanding URB remaining). + * Note that there is generally no need to clear the driver-data pointer even + * if some drivers do so for historical or implementation-specific reasons. */ static inline void usb_set_intfdata(struct usb_interface *intf, void *data) { From 7171b0e261b17de96490adf053b8bb4b00061bcf Mon Sep 17 00:00:00 2001 From: Flavio Suligoi Date: Mon, 19 Dec 2022 13:47:59 +0100 Subject: [PATCH 257/398] usb: core: hub: disable autosuspend for TI TUSB8041 The Texas Instruments TUSB8041 has an autosuspend problem at high temperature. If there is not USB traffic, after a couple of ms, the device enters in autosuspend mode. In this condition the external clock stops working, to save energy. When the USB activity turns on, ther hub exits the autosuspend state, the clock starts running again and all works fine. At ambient temperature all works correctly, but at high temperature, when the USB activity turns on, the external clock doesn't restart and the hub disappears from the USB bus. Disabling the autosuspend mode for this hub solves the issue. Signed-off-by: Flavio Suligoi Cc: stable Acked-by: Alan Stern Link: https://lore.kernel.org/r/20221219124759.3207032-1-f.suligoi@asem.it Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 77e73fc8d673..9eca403af2a8 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -44,6 +44,9 @@ #define USB_PRODUCT_USB5534B 0x5534 #define USB_VENDOR_CYPRESS 0x04b4 #define USB_PRODUCT_CY7C65632 0x6570 +#define USB_VENDOR_TEXAS_INSTRUMENTS 0x0451 +#define USB_PRODUCT_TUSB8041_USB3 0x8140 +#define USB_PRODUCT_TUSB8041_USB2 0x8142 #define HUB_QUIRK_CHECK_PORT_AUTOSUSPEND 0x01 #define HUB_QUIRK_DISABLE_AUTOSUSPEND 0x02 @@ -5854,6 +5857,16 @@ static const struct usb_device_id hub_id_table[] = { .idVendor = USB_VENDOR_GENESYS_LOGIC, .bInterfaceClass = USB_CLASS_HUB, .driver_info = HUB_QUIRK_CHECK_PORT_AUTOSUSPEND}, + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT, + .idVendor = USB_VENDOR_TEXAS_INSTRUMENTS, + .idProduct = USB_PRODUCT_TUSB8041_USB2, + .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_PRODUCT, + .idVendor = USB_VENDOR_TEXAS_INSTRUMENTS, + .idProduct = USB_PRODUCT_TUSB8041_USB3, + .driver_info = HUB_QUIRK_DISABLE_AUTOSUSPEND}, { .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS, .bDeviceClass = USB_CLASS_HUB}, { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS, From 7746564793978fe2f43b18a302b22dca0ad3a0e8 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Tue, 17 Jan 2023 11:42:15 +0000 Subject: [PATCH 258/398] block: fix hctx checks for batch allocation When there are no read queues read requests will be assigned a default queue on allocation. However, blk_mq_get_cached_request() is not prepared for that and will fail all attempts to grab read requests from the cache. Worst case it doubles the number of requests allocated, roughly half of which will be returned by blk_mq_free_plug_rqs(). It only affects batched allocations and so is io_uring specific. For reference, QD8 t/io_uring benchmark improves by 20-35%. Signed-off-by: Pavel Begunkov Link: https://lore.kernel.org/r/80d4511011d7d4751b4cf6375c4e38f237d935e3.1673955390.git.asml.silence@gmail.com Signed-off-by: Jens Axboe --- block/blk-mq.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 2c49b4151da1..9d463f7563bc 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -2890,6 +2890,7 @@ static inline struct request *blk_mq_get_cached_request(struct request_queue *q, struct blk_plug *plug, struct bio **bio, unsigned int nsegs) { struct request *rq; + enum hctx_type type, hctx_type; if (!plug) return NULL; @@ -2902,7 +2903,10 @@ static inline struct request *blk_mq_get_cached_request(struct request_queue *q, return NULL; } - if (blk_mq_get_hctx_type((*bio)->bi_opf) != rq->mq_hctx->type) + type = blk_mq_get_hctx_type((*bio)->bi_opf); + hctx_type = rq->mq_hctx->type; + if (type != hctx_type && + !(type == HCTX_TYPE_READ && hctx_type == HCTX_TYPE_DEFAULT)) return NULL; if (op_is_flush(rq->cmd_flags) != op_is_flush((*bio)->bi_opf)) return NULL; From 41e1992665a2701fa025a8b76970c43b4148446f Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 17 Jan 2023 19:00:59 +0100 Subject: [PATCH 259/398] s390: workaround invalid gcc-11 out of bounds read warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC 11.1.0 and 11.2.0 generate a wrong warning when compiling the kernel e.g. with allmodconfig: arch/s390/kernel/setup.c: In function ‘setup_lowcore_dat_on’: ./include/linux/fortify-string.h:57:33: error: ‘__builtin_memcpy’ reading 128 bytes from a region of size 0 [-Werror=stringop-overread] ... arch/s390/kernel/setup.c:526:9: note: in expansion of macro ‘memcpy’ 526 | memcpy(abs_lc->cregs_save_area, S390_lowcore.cregs_save_area, | ^~~~~~ This could be addressed by using absolute_pointer() with the S390_lowcore macro, but this is not a good idea since this generates worse code for performance critical paths. Therefore simply use a for loop to copy the array in question and get rid of the warning. Reported-by: Geert Uytterhoeven Signed-off-by: Heiko Carstens --- arch/s390/kernel/setup.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 2b6091349daa..696c9e007a36 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -508,6 +508,7 @@ static void __init setup_lowcore_dat_on(void) { struct lowcore *abs_lc; unsigned long flags; + int i; __ctl_clear_bit(0, 28); S390_lowcore.external_new_psw.mask |= PSW_MASK_DAT; @@ -523,8 +524,8 @@ static void __init setup_lowcore_dat_on(void) abs_lc = get_abs_lowcore(&flags); abs_lc->restart_flags = RESTART_FLAG_CTLREGS; abs_lc->program_new_psw = S390_lowcore.program_new_psw; - memcpy(abs_lc->cregs_save_area, S390_lowcore.cregs_save_area, - sizeof(abs_lc->cregs_save_area)); + for (i = 0; i < 16; i++) + abs_lc->cregs_save_area[i] = S390_lowcore.cregs_save_area[i]; put_abs_lowcore(abs_lc, flags); } From 7d83299351fe7c812c529f5e39fe63b5312e4233 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 17 Jan 2023 17:39:32 +0100 Subject: [PATCH 260/398] staging: vchiq_arm: fix enum vchiq_status return types gcc-13 notices a type mismatch between function declaration and definition for a few functions that have been converted from returning vchiq specific status values to regular error codes: drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c:662:5: error: conflicting types for 'vchiq_initialise' due to enum/integer mismatch; have 'int(struct vchiq_instance **)' [-Werror=enum-int-mismatch] drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c:1411:1: error: conflicting types for 'vchiq_use_internal' due to enum/integer mismatch; have 'int(struct vchiq_state *, struct vchiq_service *, enum USE_TYPE_E)' [-Werror=enum-int-mismatch] drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c:1468:1: error: conflicting types for 'vchiq_release_internal' due to enum/integer mismatch; have 'int(struct vchiq_state *, struct vchiq_service *)' [-Werror=enum-int-mismatch] Change the declarations to match the actual function definition. Fixes: a9fbd828be7f ("staging: vchiq_arm: drop enum vchiq_status from vchiq_*_internal") Cc: stable Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20230117163957.1109872-1-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman --- .../staging/vc04_services/include/linux/raspberrypi/vchiq.h | 2 +- drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h index db1441c0cc66..690ab7165b2c 100644 --- a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h +++ b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h @@ -86,7 +86,7 @@ struct vchiq_service_params_kernel { struct vchiq_instance; -extern enum vchiq_status vchiq_initialise(struct vchiq_instance **pinstance); +extern int vchiq_initialise(struct vchiq_instance **pinstance); extern enum vchiq_status vchiq_shutdown(struct vchiq_instance *instance); extern enum vchiq_status vchiq_connect(struct vchiq_instance *instance); extern enum vchiq_status vchiq_open_service(struct vchiq_instance *instance, diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h index 2851ef6b9cd0..cd20eb18f275 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h @@ -100,10 +100,10 @@ vchiq_dump_platform_use_state(struct vchiq_state *state); extern void vchiq_dump_service_use_state(struct vchiq_state *state); -extern enum vchiq_status +extern int vchiq_use_internal(struct vchiq_state *state, struct vchiq_service *service, enum USE_TYPE_E use_type); -extern enum vchiq_status +extern int vchiq_release_internal(struct vchiq_state *state, struct vchiq_service *service); From 8026a31df6d59265553e7874cf3c2b560138a407 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 2 Jan 2023 11:16:22 -0300 Subject: [PATCH 261/398] tools headers UAPI: Sync linux/kvm.h with the kernel sources To pick the changes in: b0305c1e0e27ad91 ("KVM: x86/xen: Add KVM_XEN_INVALID_GPA and KVM_XEN_INVALID_GFN to uapi") That just rebuilds perf, as these patches don't add any new KVM ioctl to be harvested for the the 'perf trace' ioctl syscall argument beautifiers. This silences this perf build warning: Warning: Kernel ABI header at 'tools/include/uapi/linux/kvm.h' differs from latest version at 'include/uapi/linux/kvm.h' diff -u tools/include/uapi/linux/kvm.h include/uapi/linux/kvm.h Cc: Adrian Hunter Cc: David Woodhouse Cc: Ian Rogers Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paolo Bonzini Link: http://lore.kernel.org/lkml/Y7Loj5slB908QSXf@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/kvm.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index 20522d4ba1e0..55155e262646 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h @@ -1767,6 +1767,7 @@ struct kvm_xen_hvm_attr { __u8 runstate_update_flag; struct { __u64 gfn; +#define KVM_XEN_INVALID_GFN ((__u64)-1) } shared_info; struct { __u32 send_port; @@ -1798,6 +1799,7 @@ struct kvm_xen_hvm_attr { } u; }; + /* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_SHARED_INFO */ #define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0 #define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1 @@ -1823,6 +1825,7 @@ struct kvm_xen_vcpu_attr { __u16 pad[3]; union { __u64 gpa; +#define KVM_XEN_INVALID_GPA ((__u64)-1) __u64 pad[8]; struct { __u64 state; From effa76856f2d7111f8c44de49f15ebdfccea8ccc Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 16 Jan 2023 10:22:13 -0300 Subject: [PATCH 262/398] tools headers UAPI: Sync x86's asm/kvm.h with the kernel sources To pick the changes in: 8aff460f216753d8 ("KVM: x86: Add a VALID_MASK for the flags in kvm_msr_filter_range") c1340fe3590ebbe7 ("KVM: x86: Add a VALID_MASK for the flag in kvm_msr_filter") be83794210e7020f ("KVM: x86: Disallow the use of KVM_MSR_FILTER_DEFAULT_ALLOW in the kernel") That just rebuilds kvm-stat.c on x86, no change in functionality. This silences these perf build warning: Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/kvm.h' differs from latest version at 'arch/x86/include/uapi/asm/kvm.h' diff -u tools/arch/x86/include/uapi/asm/kvm.h arch/x86/include/uapi/asm/kvm.h Cc: Aaron Lewis Cc: Adrian Hunter Cc: Ian Rogers Cc: Jiri Olsa Cc: Namhyung Kim Cc: Paolo Bonzini Link: http://lore.kernel.org/lkml/Y8VR5wSAkd2A0HxS@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/x86/include/uapi/asm/kvm.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/arch/x86/include/uapi/asm/kvm.h b/tools/arch/x86/include/uapi/asm/kvm.h index 649e50a8f9dd..e48deab8901d 100644 --- a/tools/arch/x86/include/uapi/asm/kvm.h +++ b/tools/arch/x86/include/uapi/asm/kvm.h @@ -206,6 +206,8 @@ struct kvm_msr_list { struct kvm_msr_filter_range { #define KVM_MSR_FILTER_READ (1 << 0) #define KVM_MSR_FILTER_WRITE (1 << 1) +#define KVM_MSR_FILTER_RANGE_VALID_MASK (KVM_MSR_FILTER_READ | \ + KVM_MSR_FILTER_WRITE) __u32 flags; __u32 nmsrs; /* number of msrs in bitmap */ __u32 base; /* MSR index the bitmap starts at */ @@ -214,8 +216,11 @@ struct kvm_msr_filter_range { #define KVM_MSR_FILTER_MAX_RANGES 16 struct kvm_msr_filter { +#ifndef __KERNEL__ #define KVM_MSR_FILTER_DEFAULT_ALLOW (0 << 0) +#endif #define KVM_MSR_FILTER_DEFAULT_DENY (1 << 0) +#define KVM_MSR_FILTER_VALID_MASK (KVM_MSR_FILTER_DEFAULT_DENY) __u32 flags; struct kvm_msr_filter_range ranges[KVM_MSR_FILTER_MAX_RANGES]; }; From c410cb974f2ba562920ecb8492ee66945dcf88af Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Wed, 11 Jan 2023 14:42:32 +0100 Subject: [PATCH 263/398] netfilter: conntrack: handle tcp challenge acks during connection reuse When a connection is re-used, following can happen: [ connection starts to close, fin sent in either direction ] > syn # initator quickly reuses connection < ack # peer sends a challenge ack > rst # rst, sequence number == ack_seq of previous challenge ack > syn # this syn is expected to pass Problem is that the rst will fail window validation, so it gets tagged as invalid. If ruleset drops such packets, we get repeated syn-retransmits until initator gives up or peer starts responding with syn/ack. Before the commit indicated in the "Fixes" tag below this used to work: The challenge-ack made conntrack re-init state based on the challenge ack itself, so the following rst would pass window validation. Add challenge-ack support: If we get ack for syn, record the ack_seq, and then check if the rst sequence number matches the last ack number seen in reverse direction. Fixes: c7aab4f17021 ("netfilter: nf_conntrack_tcp: re-init for syn packets only") Reported-by: Michal Tesar Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_conntrack_proto_tcp.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 656631083177..3ac1af6f59fc 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c @@ -1068,6 +1068,13 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct, ct->proto.tcp.last_flags |= IP_CT_EXP_CHALLENGE_ACK; } + + /* possible challenge ack reply to syn */ + if (old_state == TCP_CONNTRACK_SYN_SENT && + index == TCP_ACK_SET && + dir == IP_CT_DIR_REPLY) + ct->proto.tcp.last_ack = ntohl(th->ack_seq); + spin_unlock_bh(&ct->lock); nf_ct_l4proto_log_invalid(skb, ct, state, "packet (index %d) in dir %d ignored, state %s", @@ -1193,6 +1200,14 @@ int nf_conntrack_tcp_packet(struct nf_conn *ct, * segments we ignored. */ goto in_window; } + + /* Reset in response to a challenge-ack we let through earlier */ + if (old_state == TCP_CONNTRACK_SYN_SENT && + ct->proto.tcp.last_index == TCP_ACK_SET && + ct->proto.tcp.last_dir == IP_CT_DIR_REPLY && + ntohl(th->seq) == ct->proto.tcp.last_ack) + goto in_window; + break; default: /* Keep compilers happy. */ From 2185e0fdbb2137f22a9dd9fcbf6481400d56299b Mon Sep 17 00:00:00 2001 From: Harshit Mogalapalli Date: Mon, 12 Dec 2022 05:08:28 -0800 Subject: [PATCH 264/398] Bluetooth: Fix a buffer overflow in mgmt_mesh_add() Smatch Warning: net/bluetooth/mgmt_util.c:375 mgmt_mesh_add() error: __memcpy() 'mesh_tx->param' too small (48 vs 50) Analysis: 'mesh_tx->param' is array of size 48. This is the destination. u8 param[sizeof(struct mgmt_cp_mesh_send) + 29]; // 19 + 29 = 48. But in the caller 'mesh_send' we reject only when len > 50. len > (MGMT_MESH_SEND_SIZE + 31) // 19 + 31 = 50. Fixes: b338d91703fa ("Bluetooth: Implement support for Mesh") Signed-off-by: Harshit Mogalapalli Signed-off-by: Brian Gix Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/mgmt_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bluetooth/mgmt_util.h b/net/bluetooth/mgmt_util.h index 6a8b7e84293d..bdf978605d5a 100644 --- a/net/bluetooth/mgmt_util.h +++ b/net/bluetooth/mgmt_util.h @@ -27,7 +27,7 @@ struct mgmt_mesh_tx { struct sock *sk; u8 handle; u8 instance; - u8 param[sizeof(struct mgmt_cp_mesh_send) + 29]; + u8 param[sizeof(struct mgmt_cp_mesh_send) + 31]; }; struct mgmt_pending_cmd { From 3a4d29b6d631bb00236a98887e1039bbfc1b6ab5 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 19 Dec 2022 13:32:51 -0800 Subject: [PATCH 265/398] Bluetooth: hci_sync: Fix use HCI_OP_LE_READ_BUFFER_SIZE_V2 Don't try to use HCI_OP_LE_READ_BUFFER_SIZE_V2 if controller don't support ISO channels, but in order to check if ISO channels are supported HCI_OP_LE_READ_LOCAL_FEATURES needs to be done earlier so the features bits can be checked on hci_le_read_buffer_size_sync. Link: https://bugzilla.kernel.org/show_bug.cgi?id=216817 Fixes: c1631dbc00c1 ("Bluetooth: hci_sync: Fix hci_read_buffer_size_sync") Cc: stable@vger.kernel.org # 6.1 Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_sync.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 9e2d7e4b850c..b38a097344fb 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -3572,7 +3572,7 @@ static const struct hci_init_stage hci_init2[] = { static int hci_le_read_buffer_size_sync(struct hci_dev *hdev) { /* Use Read LE Buffer Size V2 if supported */ - if (hdev->commands[41] & 0x20) + if (iso_capable(hdev) && hdev->commands[41] & 0x20) return __hci_cmd_sync_status(hdev, HCI_OP_LE_READ_BUFFER_SIZE_V2, 0, NULL, HCI_CMD_TIMEOUT); @@ -3597,10 +3597,10 @@ static int hci_le_read_supported_states_sync(struct hci_dev *hdev) /* LE Controller init stage 2 command sequence */ static const struct hci_init_stage le_init2[] = { - /* HCI_OP_LE_READ_BUFFER_SIZE */ - HCI_INIT(hci_le_read_buffer_size_sync), /* HCI_OP_LE_READ_LOCAL_FEATURES */ HCI_INIT(hci_le_read_local_features_sync), + /* HCI_OP_LE_READ_BUFFER_SIZE */ + HCI_INIT(hci_le_read_buffer_size_sync), /* HCI_OP_LE_READ_SUPPORTED_STATES */ HCI_INIT(hci_le_read_supported_states_sync), {} From 3aa21311f36d8a2730c7ccef37235e951f23927b Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Wed, 4 Jan 2023 14:46:23 +0800 Subject: [PATCH 266/398] Bluetooth: hci_conn: Fix memory leaks When hci_cmd_sync_queue() failed in hci_le_terminate_big() or hci_le_big_terminate(), the memory pointed by variable d is not freed, which will cause memory leak. Add release process to error path. Fixes: eca0ae4aea66 ("Bluetooth: Add initial implementation of BIS connections") Signed-off-by: Zhengchao Shao Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_conn.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index d3e542c2fc3e..acf563fbdfd9 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -821,6 +821,7 @@ static void terminate_big_destroy(struct hci_dev *hdev, void *data, int err) static int hci_le_terminate_big(struct hci_dev *hdev, u8 big, u8 bis) { struct iso_list_data *d; + int ret; bt_dev_dbg(hdev, "big 0x%2.2x bis 0x%2.2x", big, bis); @@ -831,8 +832,12 @@ static int hci_le_terminate_big(struct hci_dev *hdev, u8 big, u8 bis) d->big = big; d->bis = bis; - return hci_cmd_sync_queue(hdev, terminate_big_sync, d, - terminate_big_destroy); + ret = hci_cmd_sync_queue(hdev, terminate_big_sync, d, + terminate_big_destroy); + if (ret) + kfree(d); + + return ret; } static int big_terminate_sync(struct hci_dev *hdev, void *data) @@ -857,6 +862,7 @@ static int big_terminate_sync(struct hci_dev *hdev, void *data) static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, u16 sync_handle) { struct iso_list_data *d; + int ret; bt_dev_dbg(hdev, "big 0x%2.2x sync_handle 0x%4.4x", big, sync_handle); @@ -867,8 +873,12 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, u16 sync_handle) d->big = big; d->sync_handle = sync_handle; - return hci_cmd_sync_queue(hdev, big_terminate_sync, d, - terminate_big_destroy); + ret = hci_cmd_sync_queue(hdev, big_terminate_sync, d, + terminate_big_destroy); + if (ret) + kfree(d); + + return ret; } /* Cleanup BIS connection From 272970be3dabd24cbe50e393ffee8f04aec3b9a8 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Thu, 29 Dec 2022 11:28:29 +0100 Subject: [PATCH 267/398] Bluetooth: hci_qca: Fix driver shutdown on closed serdev The driver shutdown callback (which sends EDL_SOC_RESET to the device over serdev) should not be invoked when HCI device is not open (e.g. if hci_dev_open_sync() failed), because the serdev and its TTY are not open either. Also skip this step if device is powered off (qca_power_shutdown()). The shutdown callback causes use-after-free during system reboot with Qualcomm Atheros Bluetooth: Unable to handle kernel paging request at virtual address 0072662f67726fd7 ... CPU: 6 PID: 1 Comm: systemd-shutdow Tainted: G W 6.1.0-rt5-00325-g8a5f56bcfcca #8 Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) Call trace: tty_driver_flush_buffer+0x4/0x30 serdev_device_write_flush+0x24/0x34 qca_serdev_shutdown+0x80/0x130 [hci_uart] device_shutdown+0x15c/0x260 kernel_restart+0x48/0xac KASAN report: BUG: KASAN: use-after-free in tty_driver_flush_buffer+0x1c/0x50 Read of size 8 at addr ffff16270c2e0018 by task systemd-shutdow/1 CPU: 7 PID: 1 Comm: systemd-shutdow Not tainted 6.1.0-next-20221220-00014-gb85aaf97fb01-dirty #28 Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) Call trace: dump_backtrace.part.0+0xdc/0xf0 show_stack+0x18/0x30 dump_stack_lvl+0x68/0x84 print_report+0x188/0x488 kasan_report+0xa4/0xf0 __asan_load8+0x80/0xac tty_driver_flush_buffer+0x1c/0x50 ttyport_write_flush+0x34/0x44 serdev_device_write_flush+0x48/0x60 qca_serdev_shutdown+0x124/0x274 device_shutdown+0x1e8/0x350 kernel_restart+0x48/0xb0 __do_sys_reboot+0x244/0x2d0 __arm64_sys_reboot+0x54/0x70 invoke_syscall+0x60/0x190 el0_svc_common.constprop.0+0x7c/0x160 do_el0_svc+0x44/0xf0 el0_svc+0x2c/0x6c el0t_64_sync_handler+0xbc/0x140 el0t_64_sync+0x190/0x194 Fixes: 7e7bbddd029b ("Bluetooth: hci_qca: Fix qca6390 enable failure after warm reboot") Cc: Signed-off-by: Krzysztof Kozlowski Signed-off-by: Luiz Augusto von Dentz --- drivers/bluetooth/hci_qca.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 6eddc23e49d9..bbe9cf1cae27 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -2164,10 +2164,17 @@ static void qca_serdev_shutdown(struct device *dev) int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS); struct serdev_device *serdev = to_serdev_device(dev); struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); + struct hci_uart *hu = &qcadev->serdev_hu; + struct hci_dev *hdev = hu->hdev; + struct qca_data *qca = hu->priv; const u8 ibs_wake_cmd[] = { 0xFD }; const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 }; if (qcadev->btsoc_type == QCA_QCA6390) { + if (test_bit(QCA_BT_OFF, &qca->flags) || + !test_bit(HCI_RUNNING, &hdev->flags)) + return; + serdev_device_write_flush(serdev); ret = serdev_device_write_buf(serdev, ibs_wake_cmd, sizeof(ibs_wake_cmd)); From 1ed8b37cbaf14574c779064ef1372af62e8ba6aa Mon Sep 17 00:00:00 2001 From: Zhengchao Shao Date: Mon, 9 Jan 2023 09:26:51 +0800 Subject: [PATCH 268/398] Bluetooth: hci_sync: fix memory leak in hci_update_adv_data() When hci_cmd_sync_queue() failed in hci_update_adv_data(), inst_ptr is not freed, which will cause memory leak, convert to use ERR_PTR/PTR_ERR to pass the instance to callback so no memory needs to be allocated. Fixes: 651cd3d65b0f ("Bluetooth: convert hci_update_adv_data to hci_sync") Signed-off-by: Zhengchao Shao Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_sync.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index b38a097344fb..117eedb6f709 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -6187,20 +6187,13 @@ int hci_get_random_address(struct hci_dev *hdev, bool require_privacy, static int _update_adv_data_sync(struct hci_dev *hdev, void *data) { - u8 instance = *(u8 *)data; - - kfree(data); + u8 instance = PTR_ERR(data); return hci_update_adv_data_sync(hdev, instance); } int hci_update_adv_data(struct hci_dev *hdev, u8 instance) { - u8 *inst_ptr = kmalloc(1, GFP_KERNEL); - - if (!inst_ptr) - return -ENOMEM; - - *inst_ptr = instance; - return hci_cmd_sync_queue(hdev, _update_adv_data_sync, inst_ptr, NULL); + return hci_cmd_sync_queue(hdev, _update_adv_data_sync, + ERR_PTR(instance), NULL); } From 6a5ad251b7cdb990a3705428aef408433f05614a Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 10 Jan 2023 13:24:51 -0800 Subject: [PATCH 269/398] Bluetooth: ISO: Fix possible circular locking dependency This attempts to fix the following trace: kworker/u3:1/184 is trying to acquire lock: ffff888001888130 (sk_lock-AF_BLUETOOTH-BTPROTO_ISO){+.+.}-{0:0}, at: iso_connect_cfm+0x2de/0x690 but task is already holding lock: ffff8880028d1c20 (&conn->lock){+.+.}-{2:2}, at: iso_connect_cfm+0x265/0x690 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #1 (&conn->lock){+.+.}-{2:2}: lock_acquire+0x176/0x3d0 _raw_spin_lock+0x2a/0x40 __iso_sock_close+0x1dd/0x4f0 iso_sock_release+0xa0/0x1b0 sock_close+0x5e/0x120 __fput+0x102/0x410 task_work_run+0xf1/0x160 exit_to_user_mode_prepare+0x170/0x180 syscall_exit_to_user_mode+0x19/0x50 do_syscall_64+0x4e/0x90 entry_SYSCALL_64_after_hwframe+0x62/0xcc -> #0 (sk_lock-AF_BLUETOOTH-BTPROTO_ISO){+.+.}-{0:0}: check_prev_add+0xfc/0x1190 __lock_acquire+0x1e27/0x2750 lock_acquire+0x176/0x3d0 lock_sock_nested+0x32/0x80 iso_connect_cfm+0x2de/0x690 hci_cc_le_setup_iso_path+0x195/0x340 hci_cmd_complete_evt+0x1ae/0x500 hci_event_packet+0x38e/0x7c0 hci_rx_work+0x34c/0x980 process_one_work+0x5a5/0x9a0 worker_thread+0x89/0x6f0 kthread+0x14e/0x180 ret_from_fork+0x22/0x30 other info that might help us debug this: Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(&conn->lock); lock(sk_lock-AF_BLUETOOTH-BTPROTO_ISO); lock(&conn->lock); lock(sk_lock-AF_BLUETOOTH-BTPROTO_ISO); *** DEADLOCK *** Fixes: ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type") Fixes: f764a6c2c1e4 ("Bluetooth: ISO: Add broadcast support") Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/iso.c | 61 +++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 035bb5d25f85..6157bc12b373 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -289,15 +289,15 @@ static int iso_connect_bis(struct sock *sk) hci_dev_unlock(hdev); hci_dev_put(hdev); + err = iso_chan_add(conn, sk, NULL); + if (err) + return err; + lock_sock(sk); /* Update source addr of the socket */ bacpy(&iso_pi(sk)->src, &hcon->src); - err = iso_chan_add(conn, sk, NULL); - if (err) - goto release; - if (hcon->state == BT_CONNECTED) { iso_sock_clear_timer(sk); sk->sk_state = BT_CONNECTED; @@ -306,7 +306,6 @@ static int iso_connect_bis(struct sock *sk) iso_sock_set_timer(sk, sk->sk_sndtimeo); } -release: release_sock(sk); return err; @@ -372,15 +371,15 @@ static int iso_connect_cis(struct sock *sk) hci_dev_unlock(hdev); hci_dev_put(hdev); + err = iso_chan_add(conn, sk, NULL); + if (err) + return err; + lock_sock(sk); /* Update source addr of the socket */ bacpy(&iso_pi(sk)->src, &hcon->src); - err = iso_chan_add(conn, sk, NULL); - if (err) - goto release; - if (hcon->state == BT_CONNECTED) { iso_sock_clear_timer(sk); sk->sk_state = BT_CONNECTED; @@ -392,7 +391,6 @@ static int iso_connect_cis(struct sock *sk) iso_sock_set_timer(sk, sk->sk_sndtimeo); } -release: release_sock(sk); return err; @@ -1432,33 +1430,29 @@ static void iso_conn_ready(struct iso_conn *conn) struct sock *parent; struct sock *sk = conn->sk; struct hci_ev_le_big_sync_estabilished *ev; + struct hci_conn *hcon; BT_DBG("conn %p", conn); if (sk) { iso_sock_ready(conn->sk); } else { - iso_conn_lock(conn); - - if (!conn->hcon) { - iso_conn_unlock(conn); + hcon = conn->hcon; + if (!hcon) return; - } - ev = hci_recv_event_data(conn->hcon->hdev, + ev = hci_recv_event_data(hcon->hdev, HCI_EVT_LE_BIG_SYNC_ESTABILISHED); if (ev) - parent = iso_get_sock_listen(&conn->hcon->src, - &conn->hcon->dst, + parent = iso_get_sock_listen(&hcon->src, + &hcon->dst, iso_match_big, ev); else - parent = iso_get_sock_listen(&conn->hcon->src, + parent = iso_get_sock_listen(&hcon->src, BDADDR_ANY, NULL, NULL); - if (!parent) { - iso_conn_unlock(conn); + if (!parent) return; - } lock_sock(parent); @@ -1466,30 +1460,29 @@ static void iso_conn_ready(struct iso_conn *conn) BTPROTO_ISO, GFP_ATOMIC, 0); if (!sk) { release_sock(parent); - iso_conn_unlock(conn); return; } iso_sock_init(sk, parent); - bacpy(&iso_pi(sk)->src, &conn->hcon->src); - iso_pi(sk)->src_type = conn->hcon->src_type; + bacpy(&iso_pi(sk)->src, &hcon->src); + iso_pi(sk)->src_type = hcon->src_type; /* If hcon has no destination address (BDADDR_ANY) it means it * was created by HCI_EV_LE_BIG_SYNC_ESTABILISHED so we need to * initialize using the parent socket destination address. */ - if (!bacmp(&conn->hcon->dst, BDADDR_ANY)) { - bacpy(&conn->hcon->dst, &iso_pi(parent)->dst); - conn->hcon->dst_type = iso_pi(parent)->dst_type; - conn->hcon->sync_handle = iso_pi(parent)->sync_handle; + if (!bacmp(&hcon->dst, BDADDR_ANY)) { + bacpy(&hcon->dst, &iso_pi(parent)->dst); + hcon->dst_type = iso_pi(parent)->dst_type; + hcon->sync_handle = iso_pi(parent)->sync_handle; } - bacpy(&iso_pi(sk)->dst, &conn->hcon->dst); - iso_pi(sk)->dst_type = conn->hcon->dst_type; + bacpy(&iso_pi(sk)->dst, &hcon->dst); + iso_pi(sk)->dst_type = hcon->dst_type; - hci_conn_hold(conn->hcon); - __iso_chan_add(conn, sk, parent); + hci_conn_hold(hcon); + iso_chan_add(conn, sk, parent); if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) sk->sk_state = BT_CONNECT2; @@ -1500,8 +1493,6 @@ static void iso_conn_ready(struct iso_conn *conn) parent->sk_data_ready(parent); release_sock(parent); - - iso_conn_unlock(conn); } } From e9d50f76fe1f7f6f251114919247445fb5cb3734 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 10 Jan 2023 17:04:46 -0800 Subject: [PATCH 270/398] Bluetooth: hci_event: Fix Invalid wait context This fixes the following trace caused by attempting to lock cmd_sync_work_lock while holding the rcu_read_lock: kworker/u3:2/212 is trying to lock: ffff888002600910 (&hdev->cmd_sync_work_lock){+.+.}-{3:3}, at: hci_cmd_sync_queue+0xad/0x140 other info that might help us debug this: context-{4:4} 4 locks held by kworker/u3:2/212: #0: ffff8880028c6530 ((wq_completion)hci0#2){+.+.}-{0:0}, at: process_one_work+0x4dc/0x9a0 #1: ffff888001aafde0 ((work_completion)(&hdev->rx_work)){+.+.}-{0:0}, at: process_one_work+0x4dc/0x9a0 #2: ffff888002600070 (&hdev->lock){+.+.}-{3:3}, at: hci_cc_le_set_cig_params+0x64/0x4f0 #3: ffffffffa5994b00 (rcu_read_lock){....}-{1:2}, at: hci_cc_le_set_cig_params+0x2f9/0x4f0 Fixes: 26afbd826ee3 ("Bluetooth: Add initial implementation of CIS connections") Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_event.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 0594af4e37ca..ad92a4be5851 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -3848,8 +3848,11 @@ static u8 hci_cc_le_set_cig_params(struct hci_dev *hdev, void *data, conn->handle, conn->link); /* Create CIS if LE is already connected */ - if (conn->link && conn->link->state == BT_CONNECTED) + if (conn->link && conn->link->state == BT_CONNECTED) { + rcu_read_unlock(); hci_le_create_cis(conn->link); + rcu_read_lock(); + } if (i == rp->num_handles) break; From 506d9b4099a0ce8249bba16b4d0b828fdcf69d9a Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 10 Jan 2023 17:18:13 -0800 Subject: [PATCH 271/398] Bluetooth: ISO: Fix possible circular locking dependency This attempts to fix the following trace: iso-tester/52 is trying to acquire lock: ffff8880024e0070 (&hdev->lock){+.+.}-{3:3}, at: iso_sock_listen+0x29e/0x440 but task is already holding lock: ffff888001978130 (sk_lock-AF_BLUETOOTH-BTPROTO_ISO){+.+.}-{0:0}, at: iso_sock_listen+0x8b/0x440 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #2 (sk_lock-AF_BLUETOOTH-BTPROTO_ISO){+.+.}-{0:0}: lock_acquire+0x176/0x3d0 lock_sock_nested+0x32/0x80 iso_connect_cfm+0x1a3/0x630 hci_cc_le_setup_iso_path+0x195/0x340 hci_cmd_complete_evt+0x1ae/0x500 hci_event_packet+0x38e/0x7c0 hci_rx_work+0x34c/0x980 process_one_work+0x5a5/0x9a0 worker_thread+0x89/0x6f0 kthread+0x14e/0x180 ret_from_fork+0x22/0x30 -> #1 (hci_cb_list_lock){+.+.}-{3:3}: lock_acquire+0x176/0x3d0 __mutex_lock+0x13b/0xf50 hci_le_remote_feat_complete_evt+0x17e/0x320 hci_event_packet+0x38e/0x7c0 hci_rx_work+0x34c/0x980 process_one_work+0x5a5/0x9a0 worker_thread+0x89/0x6f0 kthread+0x14e/0x180 ret_from_fork+0x22/0x30 -> #0 (&hdev->lock){+.+.}-{3:3}: check_prev_add+0xfc/0x1190 __lock_acquire+0x1e27/0x2750 lock_acquire+0x176/0x3d0 __mutex_lock+0x13b/0xf50 iso_sock_listen+0x29e/0x440 __sys_listen+0xe6/0x160 __x64_sys_listen+0x25/0x30 do_syscall_64+0x42/0x90 entry_SYSCALL_64_after_hwframe+0x62/0xcc other info that might help us debug this: Chain exists of: &hdev->lock --> hci_cb_list_lock --> sk_lock-AF_BLUETOOTH-BTPROTO_ISO Possible unsafe locking scenario: CPU0 CPU1 ---- ---- lock(sk_lock-AF_BLUETOOTH-BTPROTO_ISO); lock(hci_cb_list_lock); lock(sk_lock-AF_BLUETOOTH-BTPROTO_ISO); lock(&hdev->lock); *** DEADLOCK *** 1 lock held by iso-tester/52: #0: ffff888001978130 (sk_lock-AF_BLUETOOTH-BTPROTO_ISO){+.+.}-{0:0}, at: iso_sock_listen+0x8b/0x440 Fixes: f764a6c2c1e4 ("Bluetooth: ISO: Add broadcast support") Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/iso.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 6157bc12b373..24444b502e58 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -893,13 +893,10 @@ static int iso_listen_bis(struct sock *sk) if (!hdev) return -EHOSTUNREACH; - hci_dev_lock(hdev); - err = hci_pa_create_sync(hdev, &iso_pi(sk)->dst, le_addr_type(iso_pi(sk)->dst_type), iso_pi(sk)->bc_sid); - hci_dev_unlock(hdev); hci_dev_put(hdev); return err; From 1d80d57ffcb55488f0ec0b77928d4f82d16b6a90 Mon Sep 17 00:00:00 2001 From: Ying Hsu Date: Wed, 11 Jan 2023 03:16:14 +0000 Subject: [PATCH 272/398] Bluetooth: Fix possible deadlock in rfcomm_sk_state_change syzbot reports a possible deadlock in rfcomm_sk_state_change [1]. While rfcomm_sock_connect acquires the sk lock and waits for the rfcomm lock, rfcomm_sock_release could have the rfcomm lock and hit a deadlock for acquiring the sk lock. Here's a simplified flow: rfcomm_sock_connect: lock_sock(sk) rfcomm_dlc_open: rfcomm_lock() rfcomm_sock_release: rfcomm_sock_shutdown: rfcomm_lock() __rfcomm_dlc_close: rfcomm_k_state_change: lock_sock(sk) This patch drops the sk lock before calling rfcomm_dlc_open to avoid the possible deadlock and holds sk's reference count to prevent use-after-free after rfcomm_dlc_open completes. Reported-by: syzbot+d7ce59...@syzkaller.appspotmail.com Fixes: 1804fdf6e494 ("Bluetooth: btintel: Combine setting up MSFT extension") Link: https://syzkaller.appspot.com/bug?extid=d7ce59b06b3eb14fd218 [1] Signed-off-by: Ying Hsu Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/rfcomm/sock.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 21e24da4847f..4397e14ff560 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c @@ -391,6 +391,7 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a addr->sa_family != AF_BLUETOOTH) return -EINVAL; + sock_hold(sk); lock_sock(sk); if (sk->sk_state != BT_OPEN && sk->sk_state != BT_BOUND) { @@ -410,14 +411,18 @@ static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int a d->sec_level = rfcomm_pi(sk)->sec_level; d->role_switch = rfcomm_pi(sk)->role_switch; + /* Drop sock lock to avoid potential deadlock with the RFCOMM lock */ + release_sock(sk); err = rfcomm_dlc_open(d, &rfcomm_pi(sk)->src, &sa->rc_bdaddr, sa->rc_channel); - if (!err) + lock_sock(sk); + if (!err && !sock_flag(sk, SOCK_ZAPPED)) err = bt_sock_wait_state(sk, BT_CONNECTED, sock_sndtimeo(sk, flags & O_NONBLOCK)); done: release_sock(sk); + sock_put(sk); return err; } From 9ec9b2a30853ba843b70ea16f196e5fe3327be5f Mon Sep 17 00:00:00 2001 From: Caleb Connolly Date: Sun, 15 Jan 2023 17:59:24 +0000 Subject: [PATCH 273/398] net: ipa: disable ipa interrupt during suspend The IPA interrupt can fire when pm_runtime is disabled due to it racing with the PM suspend/resume code. This causes a splat in the interrupt handler when it tries to call pm_runtime_get(). Explicitly disable the interrupt in our ->suspend callback, and re-enable it in ->resume to avoid this. If there is an interrupt pending it will be handled after resuming. The interrupt is a wake_irq, as a result even when disabled if it fires it will cause the system to wake from suspend as well as cancel any suspend transition that may be in progress. If there is an interrupt pending, the ipa_isr_thread handler will be called after resuming. Fixes: 1aac309d3207 ("net: ipa: use autosuspend") Signed-off-by: Caleb Connolly Reviewed-by: Alex Elder Link: https://lore.kernel.org/r/20230115175925.465918-1-caleb.connolly@linaro.org Signed-off-by: Jakub Kicinski --- drivers/net/ipa/ipa_interrupt.c | 10 ++++++++++ drivers/net/ipa/ipa_interrupt.h | 16 ++++++++++++++++ drivers/net/ipa/ipa_power.c | 17 +++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/drivers/net/ipa/ipa_interrupt.c b/drivers/net/ipa/ipa_interrupt.c index d458a35839cc..c1b3977e1ae4 100644 --- a/drivers/net/ipa/ipa_interrupt.c +++ b/drivers/net/ipa/ipa_interrupt.c @@ -127,6 +127,16 @@ out_power_put: return IRQ_HANDLED; } +void ipa_interrupt_irq_disable(struct ipa *ipa) +{ + disable_irq(ipa->interrupt->irq); +} + +void ipa_interrupt_irq_enable(struct ipa *ipa) +{ + enable_irq(ipa->interrupt->irq); +} + /* Common function used to enable/disable TX_SUSPEND for an endpoint */ static void ipa_interrupt_suspend_control(struct ipa_interrupt *interrupt, u32 endpoint_id, bool enable) diff --git a/drivers/net/ipa/ipa_interrupt.h b/drivers/net/ipa/ipa_interrupt.h index f31fd9965fdc..8a1bd5b89393 100644 --- a/drivers/net/ipa/ipa_interrupt.h +++ b/drivers/net/ipa/ipa_interrupt.h @@ -85,6 +85,22 @@ void ipa_interrupt_suspend_clear_all(struct ipa_interrupt *interrupt); */ void ipa_interrupt_simulate_suspend(struct ipa_interrupt *interrupt); +/** + * ipa_interrupt_irq_enable() - Enable IPA interrupts + * @ipa: IPA pointer + * + * This enables the IPA interrupt line + */ +void ipa_interrupt_irq_enable(struct ipa *ipa); + +/** + * ipa_interrupt_irq_disable() - Disable IPA interrupts + * @ipa: IPA pointer + * + * This disables the IPA interrupt line + */ +void ipa_interrupt_irq_disable(struct ipa *ipa); + /** * ipa_interrupt_config() - Configure the IPA interrupt framework * @ipa: IPA pointer diff --git a/drivers/net/ipa/ipa_power.c b/drivers/net/ipa/ipa_power.c index 8420f93128a2..8057be8cda80 100644 --- a/drivers/net/ipa/ipa_power.c +++ b/drivers/net/ipa/ipa_power.c @@ -181,6 +181,17 @@ static int ipa_suspend(struct device *dev) __set_bit(IPA_POWER_FLAG_SYSTEM, ipa->power->flags); + /* Increment the disable depth to ensure that the IRQ won't + * be re-enabled until the matching _enable call in + * ipa_resume(). We do this to ensure that the interrupt + * handler won't run whilst PM runtime is disabled. + * + * Note that disabling the IRQ is NOT the same as disabling + * irq wake. If wakeup is enabled for the IPA then the IRQ + * will still cause the system to wake up, see irq_set_irq_wake(). + */ + ipa_interrupt_irq_disable(ipa); + return pm_runtime_force_suspend(dev); } @@ -193,6 +204,12 @@ static int ipa_resume(struct device *dev) __clear_bit(IPA_POWER_FLAG_SYSTEM, ipa->power->flags); + /* Now that PM runtime is enabled again it's safe + * to turn the IRQ back on and process any data + * that was received during suspend. + */ + ipa_interrupt_irq_enable(ipa); + return ret; } From 441717b6fdf2f620475b5e410f73d55154bb6f30 Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Mon, 16 Jan 2023 14:20:15 +0530 Subject: [PATCH 274/398] MAINTAINERS: Update AMD XGBE driver maintainers Due to other additional responsibilities Tom would no longer be able to support AMD XGBE driver. Cc: Tom Lendacky Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20230116085015.443127-1-Shyam-sundar.S-k@amd.com Signed-off-by: Jakub Kicinski --- MAINTAINERS | 1 - 1 file changed, 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index e278cd5d0de0..e5c43cbffea7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1104,7 +1104,6 @@ S: Supported F: arch/arm64/boot/dts/amd/ AMD XGBE DRIVER -M: Tom Lendacky M: "Shyam Sundar S K" L: netdev@vger.kernel.org S: Supported From 13e1df09284da53ae5abdd3364c36caf8f0f8916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= Date: Tue, 17 Jan 2023 05:30:43 +0000 Subject: [PATCH 275/398] kheaders: explicitly validate existence of cpio command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the cpio command is not available the error emitted by gen_kheaders.so is not clear as all output of the call to cpio is discarded: GNU make 4.4: GEN kernel/kheaders_data.tar.xz find: 'standard output': Broken pipe find: write error make[2]: *** [kernel/Makefile:157: kernel/kheaders_data.tar.xz] Error 127 make[1]: *** [scripts/Makefile.build:504: kernel] Error 2 GNU make < 4.4: GEN kernel/kheaders_data.tar.xz make[2]: *** [kernel/Makefile:157: kernel/kheaders_data.tar.xz] Error 127 make[2]: *** Waiting for unfinished jobs.... make[1]: *** [scripts/Makefile.build:504: kernel] Error 2 Add an explicit check that will trigger a clear message about the issue: CHK kernel/kheaders_data.tar.xz ./kernel/gen_kheaders.sh: line 17: type: cpio: not found The other commands executed by gen_kheaders.sh are part of a standard installation, so they are not checked. Reported-by: Amy Parker Link: https://lore.kernel.org/lkml/CAPOgqxFva=tOuh1UitCSN38+28q3BNXKq19rEsVNPRzRqKqZ+g@mail.gmail.com/ Signed-off-by: Thomas Weißschuh Reviewed-by: Nicolas Schier Signed-off-by: Masahiro Yamada --- kernel/gen_kheaders.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/gen_kheaders.sh b/kernel/gen_kheaders.sh index 473036b43c83..81b97f0f6556 100755 --- a/kernel/gen_kheaders.sh +++ b/kernel/gen_kheaders.sh @@ -14,6 +14,8 @@ include/ arch/$SRCARCH/include/ " +type cpio > /dev/null + # Support incremental builds by skipping archive generation # if timestamps of files being archived are not changed. From 90e7cb78b81543998217b0eb446c067ce2191a79 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Thu, 5 Jan 2023 19:42:20 +0800 Subject: [PATCH 276/398] net/mlx5: fix missing mutex_unlock in mlx5_fw_fatal_reporter_err_work() Add missing mutex_unlock() before returning from mlx5_fw_fatal_reporter_err_work(). Fixes: 9078e843efec ("net/mlx5: Avoid recovery in probe flows") Reported-by: kernel test robot Reported-by: Dan Carpenter Signed-off-by: Yang Yingliang Signed-off-by: Shay Drory Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/health.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/health.c b/drivers/net/ethernet/mellanox/mlx5/core/health.c index 96417c5feed7..879555ba847d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/health.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/health.c @@ -677,6 +677,7 @@ static void mlx5_fw_fatal_reporter_err_work(struct work_struct *work) mutex_lock(&dev->intf_state_mutex); if (test_bit(MLX5_DROP_NEW_HEALTH_WORK, &health->flags)) { mlx5_core_err(dev, "health works are not permitted at this stage\n"); + mutex_unlock(&dev->intf_state_mutex); return; } mutex_unlock(&dev->intf_state_mutex); From 5aa56105930374928d567744595fd7ac525d0688 Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Thu, 15 Dec 2022 16:44:33 +0100 Subject: [PATCH 277/398] net/mlx5e: Avoid false lock dependency warning on tc_ht even more The cited commit changed class of tc_ht internal mutex in order to avoid false lock dependency with fs_core node and flow_table hash table structures. However, hash table implementation internally also includes a workqueue task with its own lockdep map which causes similar bogus lockdep splat[0]. Fix it by also adding dedicated class for hash table workqueue work structure of tc_ht. [0]: [ 1139.672465] ====================================================== [ 1139.673552] WARNING: possible circular locking dependency detected [ 1139.674635] 6.1.0_for_upstream_debug_2022_12_12_17_02 #1 Not tainted [ 1139.675734] ------------------------------------------------------ [ 1139.676801] modprobe/5998 is trying to acquire lock: [ 1139.677726] ffff88811e7b93b8 (&node->lock){++++}-{3:3}, at: down_write_ref_node+0x7c/0xe0 [mlx5_core] [ 1139.679662] but task is already holding lock: [ 1139.680703] ffff88813c1f96a0 (&tc_ht_lock_key){+.+.}-{3:3}, at: rhashtable_free_and_destroy+0x38/0x6f0 [ 1139.682223] which lock already depends on the new lock. [ 1139.683640] the existing dependency chain (in reverse order) is: [ 1139.684887] -> #2 (&tc_ht_lock_key){+.+.}-{3:3}: [ 1139.685975] __mutex_lock+0x12c/0x14b0 [ 1139.686659] rht_deferred_worker+0x35/0x1540 [ 1139.687405] process_one_work+0x7c2/0x1310 [ 1139.688134] worker_thread+0x59d/0xec0 [ 1139.688820] kthread+0x28f/0x330 [ 1139.689444] ret_from_fork+0x1f/0x30 [ 1139.690106] -> #1 ((work_completion)(&ht->run_work)){+.+.}-{0:0}: [ 1139.691250] __flush_work+0xe8/0x900 [ 1139.691915] __cancel_work_timer+0x2ca/0x3f0 [ 1139.692655] rhashtable_free_and_destroy+0x22/0x6f0 [ 1139.693472] del_sw_flow_table+0x22/0xb0 [mlx5_core] [ 1139.694592] tree_put_node+0x24c/0x450 [mlx5_core] [ 1139.695686] tree_remove_node+0x6e/0x100 [mlx5_core] [ 1139.696803] mlx5_destroy_flow_table+0x187/0x690 [mlx5_core] [ 1139.698017] mlx5e_tc_nic_cleanup+0x2f8/0x400 [mlx5_core] [ 1139.699217] mlx5e_cleanup_nic_rx+0x2b/0x210 [mlx5_core] [ 1139.700397] mlx5e_detach_netdev+0x19d/0x2b0 [mlx5_core] [ 1139.701571] mlx5e_suspend+0xdb/0x140 [mlx5_core] [ 1139.702665] mlx5e_remove+0x89/0x190 [mlx5_core] [ 1139.703756] auxiliary_bus_remove+0x52/0x70 [ 1139.704492] device_release_driver_internal+0x3c1/0x600 [ 1139.705360] bus_remove_device+0x2a5/0x560 [ 1139.706080] device_del+0x492/0xb80 [ 1139.706724] mlx5_rescan_drivers_locked+0x194/0x6a0 [mlx5_core] [ 1139.707961] mlx5_unregister_device+0x7a/0xa0 [mlx5_core] [ 1139.709138] mlx5_uninit_one+0x5f/0x160 [mlx5_core] [ 1139.710252] remove_one+0xd1/0x160 [mlx5_core] [ 1139.711297] pci_device_remove+0x96/0x1c0 [ 1139.722721] device_release_driver_internal+0x3c1/0x600 [ 1139.723590] unbind_store+0x1b1/0x200 [ 1139.724259] kernfs_fop_write_iter+0x348/0x520 [ 1139.725019] vfs_write+0x7b2/0xbf0 [ 1139.725658] ksys_write+0xf3/0x1d0 [ 1139.726292] do_syscall_64+0x3d/0x90 [ 1139.726942] entry_SYSCALL_64_after_hwframe+0x46/0xb0 [ 1139.727769] -> #0 (&node->lock){++++}-{3:3}: [ 1139.728698] __lock_acquire+0x2cf5/0x62f0 [ 1139.729415] lock_acquire+0x1c1/0x540 [ 1139.730076] down_write+0x8e/0x1f0 [ 1139.730709] down_write_ref_node+0x7c/0xe0 [mlx5_core] [ 1139.731841] mlx5_del_flow_rules+0x6f/0x610 [mlx5_core] [ 1139.732982] __mlx5_eswitch_del_rule+0xdd/0x560 [mlx5_core] [ 1139.734207] mlx5_eswitch_del_offloaded_rule+0x14/0x20 [mlx5_core] [ 1139.735491] mlx5e_tc_rule_unoffload+0x104/0x2b0 [mlx5_core] [ 1139.736716] mlx5e_tc_unoffload_fdb_rules+0x10c/0x1f0 [mlx5_core] [ 1139.738007] mlx5e_tc_del_fdb_flow+0xc3c/0xfa0 [mlx5_core] [ 1139.739213] mlx5e_tc_del_flow+0x146/0xa20 [mlx5_core] [ 1139.740377] _mlx5e_tc_del_flow+0x38/0x60 [mlx5_core] [ 1139.741534] rhashtable_free_and_destroy+0x3be/0x6f0 [ 1139.742351] mlx5e_tc_ht_cleanup+0x1b/0x30 [mlx5_core] [ 1139.743512] mlx5e_cleanup_rep_tx+0x4a/0xe0 [mlx5_core] [ 1139.744683] mlx5e_detach_netdev+0x1ca/0x2b0 [mlx5_core] [ 1139.745860] mlx5e_netdev_change_profile+0xd9/0x1c0 [mlx5_core] [ 1139.747098] mlx5e_netdev_attach_nic_profile+0x1b/0x30 [mlx5_core] [ 1139.748372] mlx5e_vport_rep_unload+0x16a/0x1b0 [mlx5_core] [ 1139.749590] __esw_offloads_unload_rep+0xb1/0xd0 [mlx5_core] [ 1139.750813] mlx5_eswitch_unregister_vport_reps+0x409/0x5f0 [mlx5_core] [ 1139.752147] mlx5e_rep_remove+0x62/0x80 [mlx5_core] [ 1139.753293] auxiliary_bus_remove+0x52/0x70 [ 1139.754028] device_release_driver_internal+0x3c1/0x600 [ 1139.754885] driver_detach+0xc1/0x180 [ 1139.755553] bus_remove_driver+0xef/0x2e0 [ 1139.756260] auxiliary_driver_unregister+0x16/0x50 [ 1139.757059] mlx5e_rep_cleanup+0x19/0x30 [mlx5_core] [ 1139.758207] mlx5e_cleanup+0x12/0x30 [mlx5_core] [ 1139.759295] mlx5_cleanup+0xc/0x49 [mlx5_core] [ 1139.760384] __x64_sys_delete_module+0x2b5/0x450 [ 1139.761166] do_syscall_64+0x3d/0x90 [ 1139.761827] entry_SYSCALL_64_after_hwframe+0x46/0xb0 [ 1139.762663] other info that might help us debug this: [ 1139.763925] Chain exists of: &node->lock --> (work_completion)(&ht->run_work) --> &tc_ht_lock_key [ 1139.765743] Possible unsafe locking scenario: [ 1139.766688] CPU0 CPU1 [ 1139.767399] ---- ---- [ 1139.768111] lock(&tc_ht_lock_key); [ 1139.768704] lock((work_completion)(&ht->run_work)); [ 1139.769869] lock(&tc_ht_lock_key); [ 1139.770770] lock(&node->lock); [ 1139.771326] *** DEADLOCK *** [ 1139.772345] 2 locks held by modprobe/5998: [ 1139.772994] #0: ffff88813c1ff0e8 (&dev->mutex){....}-{3:3}, at: device_release_driver_internal+0x8d/0x600 [ 1139.774399] #1: ffff88813c1f96a0 (&tc_ht_lock_key){+.+.}-{3:3}, at: rhashtable_free_and_destroy+0x38/0x6f0 [ 1139.775822] stack backtrace: [ 1139.776579] CPU: 3 PID: 5998 Comm: modprobe Not tainted 6.1.0_for_upstream_debug_2022_12_12_17_02 #1 [ 1139.777935] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 [ 1139.779529] Call Trace: [ 1139.779992] [ 1139.780409] dump_stack_lvl+0x57/0x7d [ 1139.781015] check_noncircular+0x278/0x300 [ 1139.781687] ? print_circular_bug+0x460/0x460 [ 1139.782381] ? rcu_read_lock_sched_held+0x3f/0x70 [ 1139.783121] ? lock_release+0x487/0x7c0 [ 1139.783759] ? orc_find.part.0+0x1f1/0x330 [ 1139.784423] ? mark_lock.part.0+0xef/0x2fc0 [ 1139.785091] __lock_acquire+0x2cf5/0x62f0 [ 1139.785754] ? register_lock_class+0x18e0/0x18e0 [ 1139.786483] lock_acquire+0x1c1/0x540 [ 1139.787093] ? down_write_ref_node+0x7c/0xe0 [mlx5_core] [ 1139.788195] ? lockdep_hardirqs_on_prepare+0x3f0/0x3f0 [ 1139.788978] ? register_lock_class+0x18e0/0x18e0 [ 1139.789715] down_write+0x8e/0x1f0 [ 1139.790292] ? down_write_ref_node+0x7c/0xe0 [mlx5_core] [ 1139.791380] ? down_write_killable+0x220/0x220 [ 1139.792080] ? find_held_lock+0x2d/0x110 [ 1139.792713] down_write_ref_node+0x7c/0xe0 [mlx5_core] [ 1139.793795] mlx5_del_flow_rules+0x6f/0x610 [mlx5_core] [ 1139.794879] __mlx5_eswitch_del_rule+0xdd/0x560 [mlx5_core] [ 1139.796032] ? __esw_offloads_unload_rep+0xd0/0xd0 [mlx5_core] [ 1139.797227] ? xa_load+0x11a/0x200 [ 1139.797800] ? __xa_clear_mark+0xf0/0xf0 [ 1139.798438] mlx5_eswitch_del_offloaded_rule+0x14/0x20 [mlx5_core] [ 1139.799660] mlx5e_tc_rule_unoffload+0x104/0x2b0 [mlx5_core] [ 1139.800821] mlx5e_tc_unoffload_fdb_rules+0x10c/0x1f0 [mlx5_core] [ 1139.802049] ? mlx5_eswitch_get_uplink_priv+0x25/0x80 [mlx5_core] [ 1139.803260] mlx5e_tc_del_fdb_flow+0xc3c/0xfa0 [mlx5_core] [ 1139.804398] ? __cancel_work_timer+0x1c2/0x3f0 [ 1139.805099] ? mlx5e_tc_unoffload_from_slow_path+0x460/0x460 [mlx5_core] [ 1139.806387] mlx5e_tc_del_flow+0x146/0xa20 [mlx5_core] [ 1139.807481] _mlx5e_tc_del_flow+0x38/0x60 [mlx5_core] [ 1139.808564] rhashtable_free_and_destroy+0x3be/0x6f0 [ 1139.809336] ? mlx5e_tc_del_flow+0xa20/0xa20 [mlx5_core] [ 1139.809336] ? mlx5e_tc_del_flow+0xa20/0xa20 [mlx5_core] [ 1139.810455] mlx5e_tc_ht_cleanup+0x1b/0x30 [mlx5_core] [ 1139.811552] mlx5e_cleanup_rep_tx+0x4a/0xe0 [mlx5_core] [ 1139.812655] mlx5e_detach_netdev+0x1ca/0x2b0 [mlx5_core] [ 1139.813768] mlx5e_netdev_change_profile+0xd9/0x1c0 [mlx5_core] [ 1139.814952] mlx5e_netdev_attach_nic_profile+0x1b/0x30 [mlx5_core] [ 1139.816166] mlx5e_vport_rep_unload+0x16a/0x1b0 [mlx5_core] [ 1139.817336] __esw_offloads_unload_rep+0xb1/0xd0 [mlx5_core] [ 1139.818507] mlx5_eswitch_unregister_vport_reps+0x409/0x5f0 [mlx5_core] [ 1139.819788] ? mlx5_eswitch_uplink_get_proto_dev+0x30/0x30 [mlx5_core] [ 1139.821051] ? kernfs_find_ns+0x137/0x310 [ 1139.821705] mlx5e_rep_remove+0x62/0x80 [mlx5_core] [ 1139.822778] auxiliary_bus_remove+0x52/0x70 [ 1139.823449] device_release_driver_internal+0x3c1/0x600 [ 1139.824240] driver_detach+0xc1/0x180 [ 1139.824842] bus_remove_driver+0xef/0x2e0 [ 1139.825504] auxiliary_driver_unregister+0x16/0x50 [ 1139.826245] mlx5e_rep_cleanup+0x19/0x30 [mlx5_core] [ 1139.827322] mlx5e_cleanup+0x12/0x30 [mlx5_core] [ 1139.828345] mlx5_cleanup+0xc/0x49 [mlx5_core] [ 1139.829382] __x64_sys_delete_module+0x2b5/0x450 [ 1139.830119] ? module_flags+0x300/0x300 [ 1139.830750] ? task_work_func_match+0x50/0x50 [ 1139.831440] ? task_work_cancel+0x20/0x20 [ 1139.832088] ? lockdep_hardirqs_on_prepare+0x273/0x3f0 [ 1139.832873] ? syscall_enter_from_user_mode+0x1d/0x50 [ 1139.833661] ? trace_hardirqs_on+0x2d/0x100 [ 1139.834328] do_syscall_64+0x3d/0x90 [ 1139.834922] entry_SYSCALL_64_after_hwframe+0x46/0xb0 [ 1139.835700] RIP: 0033:0x7f153e71288b [ 1139.836302] Code: 73 01 c3 48 8b 0d 9d 75 0e 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 b0 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 6d 75 0e 00 f7 d8 64 89 01 48 [ 1139.838866] RSP: 002b:00007ffe0a3ed938 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0 [ 1139.840020] RAX: ffffffffffffffda RBX: 0000564c2cbf8220 RCX: 00007f153e71288b [ 1139.841043] RDX: 0000000000000000 RSI: 0000000000000800 RDI: 0000564c2cbf8288 [ 1139.842072] RBP: 0000564c2cbf8220 R08: 0000000000000000 R09: 0000000000000000 [ 1139.843094] R10: 00007f153e7a3ac0 R11: 0000000000000206 R12: 0000564c2cbf8288 [ 1139.844118] R13: 0000000000000000 R14: 0000564c2cbf7ae8 R15: 00007ffe0a3efcb8 Fixes: 9ba33339c043 ("net/mlx5e: Avoid false lock depenency warning on tc_ht") Signed-off-by: Vlad Buslov Reviewed-by: Eli Cohen Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index dbadaf166487..243d5d7750be 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -166,6 +166,7 @@ struct mlx5_fs_chains *mlx5e_nic_chains(struct mlx5e_tc_table *tc) * it's different than the ht->mutex here. */ static struct lock_class_key tc_ht_lock_key; +static struct lock_class_key tc_ht_wq_key; static void mlx5e_put_flow_tunnel_id(struct mlx5e_tc_flow *flow); static void free_flow_post_acts(struct mlx5e_tc_flow *flow); @@ -5182,6 +5183,7 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv) return err; lockdep_set_class(&tc->ht.mutex, &tc_ht_lock_key); + lockdep_init_map(&tc->ht.run_work.lockdep_map, "tc_ht_wq_key", &tc_ht_wq_key, 0); mapping_id = mlx5_query_nic_system_image_guid(dev); @@ -5288,6 +5290,7 @@ int mlx5e_tc_ht_init(struct rhashtable *tc_ht) return err; lockdep_set_class(&tc_ht->mutex, &tc_ht_lock_key); + lockdep_init_map(&tc_ht->run_work.lockdep_map, "tc_ht_wq_key", &tc_ht_wq_key, 0); return 0; } From 6624bfeecf019de114f8100f1468d025d13b77a1 Mon Sep 17 00:00:00 2001 From: Adham Faris Date: Thu, 12 Jan 2023 11:15:00 +0200 Subject: [PATCH 278/398] net/mlx5e: Remove redundant xsk pointer check in mlx5e_mpwrq_validate_xsk This validation function is relevant only for XSK cases, hence it assumes to be called only with xsk != NULL. Thus checking for invalid xsk pointer is redundant and misleads static code analyzers. This commit removes redundant xsk pointer check. This solves the following smatch warning: drivers/net/ethernet/mellanox/mlx5/core/en/params.c:481 mlx5e_mpwrq_validate_xsk() error: we previously assumed 'xsk' could be null (see line 478) Fixes: 6470d2e7e8ed ("net/mlx5e: xsk: Use KSM for unaligned XSK") Signed-off-by: Adham Faris Reported-by: kernel test robot Reported-by: Dan Carpenter Reviewed-by: Tariq Toukan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en/params.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c index 585bdc8383ee..4ad19c981294 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/params.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/params.c @@ -578,7 +578,6 @@ int mlx5e_mpwrq_validate_xsk(struct mlx5_core_dev *mdev, struct mlx5e_params *pa { enum mlx5e_mpwrq_umr_mode umr_mode = mlx5e_mpwrq_umr_mode(mdev, xsk); u8 page_shift = mlx5e_mpwrq_page_shift(mdev, xsk); - bool unaligned = xsk ? xsk->unaligned : false; u16 max_mtu_pkts; if (!mlx5e_check_fragmented_striding_rq_cap(mdev, page_shift, umr_mode)) @@ -591,7 +590,7 @@ int mlx5e_mpwrq_validate_xsk(struct mlx5_core_dev *mdev, struct mlx5e_params *pa * needed number of WQEs exceeds the maximum. */ max_mtu_pkts = min_t(u8, MLX5E_PARAMS_MAXIMUM_LOG_RQ_SIZE, - mlx5e_mpwrq_max_log_rq_pkts(mdev, page_shift, unaligned)); + mlx5e_mpwrq_max_log_rq_pkts(mdev, page_shift, xsk->unaligned)); if (params->log_rq_mtu_frames > max_mtu_pkts) { mlx5_core_err(mdev, "Current RQ length %d is too big for XSK with given frame size %u\n", 1 << params->log_rq_mtu_frames, xsk->chunk_size); From f51471d1935ce1f504fce6c115ce3bfbc32032b0 Mon Sep 17 00:00:00 2001 From: Maor Dickman Date: Tue, 27 Dec 2022 10:22:41 +0200 Subject: [PATCH 279/398] net/mlx5: E-switch, Fix setting of reserved fields on MODIFY_SCHEDULING_ELEMENT According to HW spec element_type, element_attributes and parent_element_id fields should be reserved (0x0) when calling MODIFY_SCHEDULING_ELEMENT command. This patch remove initialization of these fields when calling the command. Fixes: bd77bf1cb595 ("net/mlx5: Add SRIOV VF max rate configuration support") Signed-off-by: Maor Dickman Reviewed-by: Eli Cohen Signed-off-by: Saeed Mahameed --- .../net/ethernet/mellanox/mlx5/core/esw/qos.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c index 4f8a24d84a86..75015d370922 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c @@ -22,15 +22,13 @@ struct mlx5_esw_rate_group { }; static int esw_qos_tsar_config(struct mlx5_core_dev *dev, u32 *sched_ctx, - u32 parent_ix, u32 tsar_ix, - u32 max_rate, u32 bw_share) + u32 tsar_ix, u32 max_rate, u32 bw_share) { u32 bitmask = 0; if (!MLX5_CAP_GEN(dev, qos) || !MLX5_CAP_QOS(dev, esw_scheduling)) return -EOPNOTSUPP; - MLX5_SET(scheduling_context, sched_ctx, parent_element_id, parent_ix); MLX5_SET(scheduling_context, sched_ctx, max_average_bw, max_rate); MLX5_SET(scheduling_context, sched_ctx, bw_share, bw_share); bitmask |= MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_MAX_AVERAGE_BW; @@ -51,7 +49,7 @@ static int esw_qos_group_config(struct mlx5_eswitch *esw, struct mlx5_esw_rate_g int err; err = esw_qos_tsar_config(dev, sched_ctx, - esw->qos.root_tsar_ix, group->tsar_ix, + group->tsar_ix, max_rate, bw_share); if (err) NL_SET_ERR_MSG_MOD(extack, "E-Switch modify group TSAR element failed"); @@ -67,23 +65,13 @@ static int esw_qos_vport_config(struct mlx5_eswitch *esw, struct netlink_ext_ack *extack) { u32 sched_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {}; - struct mlx5_esw_rate_group *group = vport->qos.group; struct mlx5_core_dev *dev = esw->dev; - u32 parent_tsar_ix; - void *vport_elem; int err; if (!vport->qos.enabled) return -EIO; - parent_tsar_ix = group ? group->tsar_ix : esw->qos.root_tsar_ix; - MLX5_SET(scheduling_context, sched_ctx, element_type, - SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT); - vport_elem = MLX5_ADDR_OF(scheduling_context, sched_ctx, - element_attributes); - MLX5_SET(vport_element, vport_elem, vport_number, vport->vport); - - err = esw_qos_tsar_config(dev, sched_ctx, parent_tsar_ix, vport->qos.esw_tsar_ix, + err = esw_qos_tsar_config(dev, sched_ctx, vport->qos.esw_tsar_ix, max_rate, bw_share); if (err) { esw_warn(esw->dev, From 4ddf77f9bc76092d268bd3af447d60d9cc62b652 Mon Sep 17 00:00:00 2001 From: Maor Dickman Date: Tue, 27 Dec 2022 10:51:38 +0200 Subject: [PATCH 280/398] net/mlx5e: QoS, Fix wrongfully setting parent_element_id on MODIFY_SCHEDULING_ELEMENT According to HW spec parent_element_id field should be reserved (0x0) when calling MODIFY_SCHEDULING_ELEMENT command. This patch remove the wrong initialization of reserved field, parent_element_id, on mlx5_qos_update_node. Fixes: 214baf22870c ("net/mlx5e: Support HTB offload") Signed-off-by: Maor Dickman Reviewed-by: Eli Cohen Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en/htb.c | 4 ++-- drivers/net/ethernet/mellanox/mlx5/core/qos.c | 3 +-- drivers/net/ethernet/mellanox/mlx5/core/qos.h | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/htb.c b/drivers/net/ethernet/mellanox/mlx5/core/en/htb.c index 6dac76fa58a3..09d441ecb9f6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/htb.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/htb.c @@ -637,7 +637,7 @@ mlx5e_htb_update_children(struct mlx5e_htb *htb, struct mlx5e_qos_node *node, if (child->bw_share == old_bw_share) continue; - err_one = mlx5_qos_update_node(htb->mdev, child->hw_id, child->bw_share, + err_one = mlx5_qos_update_node(htb->mdev, child->bw_share, child->max_average_bw, child->hw_id); if (!err && err_one) { err = err_one; @@ -671,7 +671,7 @@ mlx5e_htb_node_modify(struct mlx5e_htb *htb, u16 classid, u64 rate, u64 ceil, mlx5e_htb_convert_rate(htb, rate, node->parent, &bw_share); mlx5e_htb_convert_ceil(htb, ceil, &max_average_bw); - err = mlx5_qos_update_node(htb->mdev, node->parent->hw_id, bw_share, + err = mlx5_qos_update_node(htb->mdev, bw_share, max_average_bw, node->hw_id); if (err) { NL_SET_ERR_MSG_MOD(extack, "Firmware error when modifying a node."); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/qos.c index 0777be24a307..8bce730b5c5b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/qos.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/qos.c @@ -62,13 +62,12 @@ int mlx5_qos_create_root_node(struct mlx5_core_dev *mdev, u32 *id) return mlx5_qos_create_inner_node(mdev, MLX5_QOS_DEFAULT_DWRR_UID, 0, 0, id); } -int mlx5_qos_update_node(struct mlx5_core_dev *mdev, u32 parent_id, +int mlx5_qos_update_node(struct mlx5_core_dev *mdev, u32 bw_share, u32 max_avg_bw, u32 id) { u32 sched_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {0}; u32 bitmask = 0; - MLX5_SET(scheduling_context, sched_ctx, parent_element_id, parent_id); MLX5_SET(scheduling_context, sched_ctx, bw_share, bw_share); MLX5_SET(scheduling_context, sched_ctx, max_average_bw, max_avg_bw); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qos.h b/drivers/net/ethernet/mellanox/mlx5/core/qos.h index 125e4e47e6f7..624ce822b7f5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/qos.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/qos.h @@ -23,7 +23,7 @@ int mlx5_qos_create_leaf_node(struct mlx5_core_dev *mdev, u32 parent_id, int mlx5_qos_create_inner_node(struct mlx5_core_dev *mdev, u32 parent_id, u32 bw_share, u32 max_avg_bw, u32 *id); int mlx5_qos_create_root_node(struct mlx5_core_dev *mdev, u32 *id); -int mlx5_qos_update_node(struct mlx5_core_dev *mdev, u32 parent_id, u32 bw_share, +int mlx5_qos_update_node(struct mlx5_core_dev *mdev, u32 bw_share, u32 max_avg_bw, u32 id); int mlx5_qos_destroy_node(struct mlx5_core_dev *mdev, u32 id); From ffa99b534732f90077f346c62094cab3d1ccddce Mon Sep 17 00:00:00 2001 From: Chris Mi Date: Thu, 12 Jan 2023 04:30:27 +0200 Subject: [PATCH 281/398] net/mlx5e: Set decap action based on attr for sample Currently decap action is set based on tunnel_id. That means it is set unconditionally. But for decap, ct and sample actions, decap is done before ct. No need to decap again in sample. And the actions are set correctly when parsing. So set decap action based on attr instead of tunnel_id. Fixes: 2741f2230905 ("net/mlx5e: TC, Support sample offload action for tunneled traffic") Signed-off-by: Chris Mi Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c index 1cbd2eb9d04f..f2c2c752bd1c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c @@ -477,7 +477,6 @@ mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample, struct mlx5e_sample_flow *sample_flow; struct mlx5e_sample_attr *sample_attr; struct mlx5_flow_attr *pre_attr; - u32 tunnel_id = attr->tunnel_id; struct mlx5_eswitch *esw; u32 default_tbl_id; u32 obj_id; @@ -522,7 +521,7 @@ mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample, restore_obj.sample.group_id = sample_attr->group_num; restore_obj.sample.rate = sample_attr->rate; restore_obj.sample.trunc_size = sample_attr->trunc_size; - restore_obj.sample.tunnel_id = tunnel_id; + restore_obj.sample.tunnel_id = attr->tunnel_id; err = mapping_add(esw->offloads.reg_c0_obj_pool, &restore_obj, &obj_id); if (err) goto err_obj_id; @@ -548,7 +547,7 @@ mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample, /* For decap action, do decap in the original flow table instead of the * default flow table. */ - if (tunnel_id) + if (attr->action & MLX5_FLOW_CONTEXT_ACTION_DECAP) pre_attr->action |= MLX5_FLOW_CONTEXT_ACTION_DECAP; pre_attr->modify_hdr = sample_flow->restore->modify_hdr; pre_attr->flags = MLX5_ATTR_FLAG_SAMPLE; From 16bccbaa00b6127ed0ebfd77bd1f10341df8d498 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Mon, 9 Jan 2023 10:43:13 +0200 Subject: [PATCH 282/398] net/mlx5e: Remove optimization which prevented update of ESN state aso->use_cache variable introduced in commit 8c582ddfbb47 ("net/mlx5e: Handle hardware IPsec limits events") was an optimization to skip recurrent calls to mlx5e_ipsec_aso_query(). Such calls are possible when lifetime event is generated: -> mlx5e_ipsec_handle_event() -> mlx5e_ipsec_aso_query() - first call -> xfrm_state_check_expire() -> mlx5e_xfrm_update_curlft() -> mlx5e_ipsec_aso_query() - second call However, such optimization not really effective as mlx5e_ipsec_aso_query() is needed to be called for update ESN anyway, which was missed due to misplaced use_cache assignment. Fixes: cee137a63431 ("net/mlx5e: Handle ESN update events") Reviewed-by: Jianbo Liu Signed-off-by: Leon Romanovsky Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h | 5 ----- .../net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c | 5 ----- 2 files changed, 10 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h index a92e19c4c499..160f8883b93e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h @@ -122,11 +122,6 @@ struct mlx5e_ipsec_aso { u8 ctx[MLX5_ST_SZ_BYTES(ipsec_aso)]; dma_addr_t dma_addr; struct mlx5_aso *aso; - /* IPsec ASO caches data on every query call, - * so in nested calls, we can use this boolean to save - * recursive calls to mlx5e_ipsec_aso_query() - */ - u8 use_cache : 1; }; struct mlx5e_ipsec { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c index 8e3614218fc4..aafbd7b244ee 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c @@ -320,7 +320,6 @@ static void mlx5e_ipsec_handle_event(struct work_struct *_work) if (ret) goto unlock; - aso->use_cache = true; if (attrs->esn_trigger && !MLX5_GET(ipsec_aso, aso->ctx, esn_event_arm)) { u32 mode_param = MLX5_GET(ipsec_aso, aso->ctx, mode_parameter); @@ -333,7 +332,6 @@ static void mlx5e_ipsec_handle_event(struct work_struct *_work) !MLX5_GET(ipsec_aso, aso->ctx, hard_lft_arm) || !MLX5_GET(ipsec_aso, aso->ctx, remove_flow_enable)) xfrm_state_check_expire(sa_entry->x); - aso->use_cache = false; unlock: spin_unlock(&sa_entry->x->lock); @@ -458,9 +456,6 @@ int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry, u8 ds_cnt; lockdep_assert_held(&sa_entry->x->lock); - if (aso->use_cache) - return 0; - res = &mdev->mlx5e_res.hw_objs; memset(aso->ctx, 0, sizeof(aso->ctx)); From e4d38c454ae57e649f09a354d5a9dae063a26ee3 Mon Sep 17 00:00:00 2001 From: Leon Romanovsky Date: Mon, 9 Jan 2023 10:34:25 +0200 Subject: [PATCH 283/398] net/mlx5e: Protect global IPsec ASO ASO operations are global to whole IPsec as they share one DMA address for all operations. As such all WQE operations need to be protected with lock. In this case, it must be spinlock to allow mlx5e_ipsec_aso_query() operate in atomic context. Fixes: 1ed78fc03307 ("net/mlx5e: Update IPsec soft and hard limits") Reviewed-by: Jianbo Liu Signed-off-by: Leon Romanovsky Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h | 2 ++ .../ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h index 160f8883b93e..8bed9c361075 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h @@ -122,6 +122,8 @@ struct mlx5e_ipsec_aso { u8 ctx[MLX5_ST_SZ_BYTES(ipsec_aso)]; dma_addr_t dma_addr; struct mlx5_aso *aso; + /* Protect ASO WQ access, as it is global to whole IPsec */ + spinlock_t lock; }; struct mlx5e_ipsec { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c index aafbd7b244ee..2461462b7b99 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c @@ -396,6 +396,7 @@ int mlx5e_ipsec_aso_init(struct mlx5e_ipsec *ipsec) goto err_aso_create; } + spin_lock_init(&aso->lock); ipsec->nb.notifier_call = mlx5e_ipsec_event; mlx5_notifier_register(mdev, &ipsec->nb); @@ -454,10 +455,12 @@ int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry, struct mlx5e_hw_objs *res; struct mlx5_aso_wqe *wqe; u8 ds_cnt; + int ret; lockdep_assert_held(&sa_entry->x->lock); res = &mdev->mlx5e_res.hw_objs; + spin_lock_bh(&aso->lock); memset(aso->ctx, 0, sizeof(aso->ctx)); wqe = mlx5_aso_get_wqe(aso->aso); ds_cnt = DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS); @@ -472,7 +475,9 @@ int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry, mlx5e_ipsec_aso_copy(ctrl, data); mlx5_aso_post_wqe(aso->aso, false, &wqe->ctrl); - return mlx5_aso_poll_cq(aso->aso, false); + ret = mlx5_aso_poll_cq(aso->aso, false); + spin_unlock_bh(&aso->lock); + return ret; } void mlx5e_ipsec_aso_update_curlft(struct mlx5e_ipsec_sa_entry *sa_entry, From 7c83d1f4c5adae9583e7fca1e3e830d6b061522d Mon Sep 17 00:00:00 2001 From: Chris Mi Date: Wed, 21 Dec 2022 11:14:37 +0200 Subject: [PATCH 284/398] net/mlx5: E-switch, Fix switchdev mode after devlink reload The cited commit removes eswitch mode none. So after devlink reload in switchdev mode, eswitch mode is not changed. But actually eswitch is disabled during devlink reload. Fix it by setting eswitch mode to legacy when disabling eswitch which is called by reload_down. Fixes: f019679ea5f2 ("net/mlx5: E-switch, Remove dependency between sriov and eswitch mode") Signed-off-by: Chris Mi Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 0dfd5742c6fe..9daf55e90367 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -1464,6 +1464,7 @@ void mlx5_eswitch_disable(struct mlx5_eswitch *esw) mlx5_lag_disable_change(esw->dev); down_write(&esw->mode_lock); mlx5_eswitch_disable_locked(esw); + esw->mode = MLX5_ESWITCH_LEGACY; up_write(&esw->mode_lock); mlx5_lag_enable_change(esw->dev); } From 2c1e1b949024989e20907b84e11a731a50778416 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 30 Aug 2022 20:12:29 -0700 Subject: [PATCH 285/398] net: mlx5: eliminate anonymous module_init & module_exit Eliminate anonymous module_init() and module_exit(), which can lead to confusion or ambiguity when reading System.map, crashes/oops/bugs, or an initcall_debug log. Give each of these init and exit functions unique driver-specific names to eliminate the anonymous names. Example 1: (System.map) ffffffff832fc78c t init ffffffff832fc79e t init ffffffff832fc8f8 t init Example 2: (initcall_debug log) calling init+0x0/0x12 @ 1 initcall init+0x0/0x12 returned 0 after 15 usecs calling init+0x0/0x60 @ 1 initcall init+0x0/0x60 returned 0 after 2 usecs calling init+0x0/0x9a @ 1 initcall init+0x0/0x9a returned 0 after 74 usecs Fixes: e126ba97dba9 ("mlx5: Add driver for Mellanox Connect-IB adapters") Signed-off-by: Randy Dunlap Cc: Eli Cohen Cc: Saeed Mahameed Cc: Leon Romanovsky Cc: linux-rdma@vger.kernel.org Reviewed-by: Ira Weiny Reviewed-by: Leon Romanovsky Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index df134f6d32dc..3d5f2a4b1fed 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -2098,7 +2098,7 @@ static void mlx5_core_verify_params(void) } } -static int __init init(void) +static int __init mlx5_init(void) { int err; @@ -2133,7 +2133,7 @@ err_debug: return err; } -static void __exit cleanup(void) +static void __exit mlx5_cleanup(void) { mlx5e_cleanup(); mlx5_sf_driver_unregister(); @@ -2141,5 +2141,5 @@ static void __exit cleanup(void) mlx5_unregister_debugfs(); } -module_init(init); -module_exit(cleanup); +module_init(mlx5_init); +module_exit(mlx5_cleanup); From febb2c0d7c69c0396aa32d5ab425a4163473961a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Exp=C3=B3sito?= Date: Mon, 26 Dec 2022 13:34:56 +0100 Subject: [PATCH 286/398] HID: uclogic: Add support for XP-PEN Deco 01 V2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The XP-PEN Deco 01 V2 is a UGEE v2 device with a frame with 8 buttons. Its pen has 2 buttons, supports tilt and pressure. Add its ID in order to support the device. Link: https://gitlab.freedesktop.org/libinput/libinput/-/issues/839 Tested-by: Mark Waddoups Signed-off-by: José Expósito Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 1 + drivers/hid/hid-uclogic-core.c | 2 ++ drivers/hid/hid-uclogic-params.c | 2 ++ 3 files changed, 5 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index c3735848ed5d..0f8c11842a3a 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -1294,6 +1294,7 @@ #define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540 0x0075 #define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640 0x0094 #define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01 0x0042 +#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01_V2 0x0905 #define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L 0x0935 #define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S 0x0909 #define USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06 0x0078 diff --git a/drivers/hid/hid-uclogic-core.c b/drivers/hid/hid-uclogic-core.c index 7fa6fe04f1b2..cfbbc39807a6 100644 --- a/drivers/hid/hid-uclogic-core.c +++ b/drivers/hid/hid-uclogic-core.c @@ -525,6 +525,8 @@ static const struct hid_device_id uclogic_devices[] = { USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640) }, { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01) }, + { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, + USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01_V2) }, { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) }, { HID_USB_DEVICE(USB_VENDOR_ID_UGEE, diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c index cd1233d7e253..3c5eea3df328 100644 --- a/drivers/hid/hid-uclogic-params.c +++ b/drivers/hid/hid-uclogic-params.c @@ -1655,6 +1655,8 @@ int uclogic_params_init(struct uclogic_params *params, break; case VID_PID(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_PARBLO_A610_PRO): + case VID_PID(USB_VENDOR_ID_UGEE, + USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01_V2): case VID_PID(USB_VENDOR_ID_UGEE, USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L): case VID_PID(USB_VENDOR_ID_UGEE, From 74cb485f68eb3dff6802ee446a602607b03f4fc9 Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander Date: Thu, 5 Jan 2023 17:59:07 -0800 Subject: [PATCH 287/398] HID: playstation: sanity check DualShock4 calibration data. Some DualShock4 devices report invalid calibration data resulting in kernel oopses due to division by zero during report handling. The devices affected generally appear to be clone devices, which don't implement all reports properly and don't populate proper calibration data. The issue may have been seen on an official device with erased calibration reports. This patch prevents the crashes by essentially disabling calibration when invalid values are detected. Signed-off-by: Roderick Colenbrander Tested-by: Alain Carlucci Signed-off-by: Jiri Kosina --- drivers/hid/hid-playstation.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c index f399bf0d3c8c..1eba50b45cb1 100644 --- a/drivers/hid/hid-playstation.c +++ b/drivers/hid/hid-playstation.c @@ -1737,6 +1737,7 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) int speed_2x; int range_2g; int ret = 0; + int i; uint8_t *buf; if (ds4->base.hdev->bus == BUS_USB) { @@ -1830,6 +1831,21 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) ds4->gyro_calib_data[2].sens_numer = speed_2x*DS4_GYRO_RES_PER_DEG_S; ds4->gyro_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus; + /* + * Sanity check gyro calibration data. This is needed to prevent crashes + * during report handling of virtual, clone or broken devices not implementing + * calibration data properly. + */ + for (i = 0; i < ARRAY_SIZE(ds4->gyro_calib_data); i++) { + if (ds4->gyro_calib_data[i].sens_denom == 0) { + hid_warn(hdev, "Invalid gyro calibration data for axis (%d), disabling calibration.", + ds4->gyro_calib_data[i].abs_code); + ds4->gyro_calib_data[i].bias = 0; + ds4->gyro_calib_data[i].sens_numer = DS4_GYRO_RANGE; + ds4->gyro_calib_data[i].sens_denom = S16_MAX; + } + } + /* * Set accelerometer calibration and normalization parameters. * Data values will be normalized to 1/DS4_ACC_RES_PER_G g. @@ -1852,6 +1868,21 @@ static int dualshock4_get_calibration_data(struct dualshock4 *ds4) ds4->accel_calib_data[2].sens_numer = 2*DS4_ACC_RES_PER_G; ds4->accel_calib_data[2].sens_denom = range_2g; + /* + * Sanity check accelerometer calibration data. This is needed to prevent crashes + * during report handling of virtual, clone or broken devices not implementing calibration + * data properly. + */ + for (i = 0; i < ARRAY_SIZE(ds4->accel_calib_data); i++) { + if (ds4->accel_calib_data[i].sens_denom == 0) { + hid_warn(hdev, "Invalid accelerometer calibration data for axis (%d), disabling calibration.", + ds4->accel_calib_data[i].abs_code); + ds4->accel_calib_data[i].bias = 0; + ds4->accel_calib_data[i].sens_numer = DS4_ACC_RANGE; + ds4->accel_calib_data[i].sens_denom = S16_MAX; + } + } + err_free: kfree(buf); return ret; From ccf1e1626d37745d0a697db67407beec9ae9d4b8 Mon Sep 17 00:00:00 2001 From: Roderick Colenbrander Date: Thu, 5 Jan 2023 17:59:08 -0800 Subject: [PATCH 288/398] HID: playstation: sanity check DualSense calibration data. Make sure calibration values are defined to prevent potential kernel crashes. This fixes a hypothetical issue for virtual or clone devices inspired by a similar fix for DS4. Signed-off-by: Roderick Colenbrander Signed-off-by: Jiri Kosina --- drivers/hid/hid-playstation.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c index 1eba50b45cb1..27c40894acab 100644 --- a/drivers/hid/hid-playstation.c +++ b/drivers/hid/hid-playstation.c @@ -944,6 +944,7 @@ ATTRIBUTE_GROUPS(ps_device); static int dualsense_get_calibration_data(struct dualsense *ds) { + struct hid_device *hdev = ds->base.hdev; short gyro_pitch_bias, gyro_pitch_plus, gyro_pitch_minus; short gyro_yaw_bias, gyro_yaw_plus, gyro_yaw_minus; short gyro_roll_bias, gyro_roll_plus, gyro_roll_minus; @@ -954,6 +955,7 @@ static int dualsense_get_calibration_data(struct dualsense *ds) int speed_2x; int range_2g; int ret = 0; + int i; uint8_t *buf; buf = kzalloc(DS_FEATURE_REPORT_CALIBRATION_SIZE, GFP_KERNEL); @@ -1005,6 +1007,21 @@ static int dualsense_get_calibration_data(struct dualsense *ds) ds->gyro_calib_data[2].sens_numer = speed_2x*DS_GYRO_RES_PER_DEG_S; ds->gyro_calib_data[2].sens_denom = gyro_roll_plus - gyro_roll_minus; + /* + * Sanity check gyro calibration data. This is needed to prevent crashes + * during report handling of virtual, clone or broken devices not implementing + * calibration data properly. + */ + for (i = 0; i < ARRAY_SIZE(ds->gyro_calib_data); i++) { + if (ds->gyro_calib_data[i].sens_denom == 0) { + hid_warn(hdev, "Invalid gyro calibration data for axis (%d), disabling calibration.", + ds->gyro_calib_data[i].abs_code); + ds->gyro_calib_data[i].bias = 0; + ds->gyro_calib_data[i].sens_numer = DS_GYRO_RANGE; + ds->gyro_calib_data[i].sens_denom = S16_MAX; + } + } + /* * Set accelerometer calibration and normalization parameters. * Data values will be normalized to 1/DS_ACC_RES_PER_G g. @@ -1027,6 +1044,21 @@ static int dualsense_get_calibration_data(struct dualsense *ds) ds->accel_calib_data[2].sens_numer = 2*DS_ACC_RES_PER_G; ds->accel_calib_data[2].sens_denom = range_2g; + /* + * Sanity check accelerometer calibration data. This is needed to prevent crashes + * during report handling of virtual, clone or broken devices not implementing calibration + * data properly. + */ + for (i = 0; i < ARRAY_SIZE(ds->accel_calib_data); i++) { + if (ds->accel_calib_data[i].sens_denom == 0) { + hid_warn(hdev, "Invalid accelerometer calibration data for axis (%d), disabling calibration.", + ds->accel_calib_data[i].abs_code); + ds->accel_calib_data[i].bias = 0; + ds->accel_calib_data[i].sens_numer = DS_ACC_RANGE; + ds->accel_calib_data[i].sens_denom = S16_MAX; + } + } + err_free: kfree(buf); return ret; From 96b3bb18f6cbe259ef4e0bed3135911b7e8d2af5 Mon Sep 17 00:00:00 2001 From: Peter Harliman Liem Date: Thu, 5 Jan 2023 11:05:51 +0800 Subject: [PATCH 289/398] dmaengine: lgm: Move DT parsing after initialization ldma_cfg_init() will parse DT to retrieve certain configs. However, that is called before ldma_dma_init_vXX(), which will make some initialization to channel configs. It will thus incorrectly overwrite certain configs that are declared in DT. To fix that, we move DT parsing after initialization. Function name is renamed to better represent what it does. Fixes: 32d31c79a1a4 ("dmaengine: Add Intel LGM SoC DMA support.") Signed-off-by: Peter Harliman Liem Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/afef6fc1ed20098b684e0d53737d69faf63c125f.1672887183.git.pliem@maxlinear.com Signed-off-by: Vinod Koul --- drivers/dma/lgm/lgm-dma.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/dma/lgm/lgm-dma.c b/drivers/dma/lgm/lgm-dma.c index 9b9184f964be..1709d159af7e 100644 --- a/drivers/dma/lgm/lgm-dma.c +++ b/drivers/dma/lgm/lgm-dma.c @@ -914,7 +914,7 @@ static void ldma_dev_init(struct ldma_dev *d) } } -static int ldma_cfg_init(struct ldma_dev *d) +static int ldma_parse_dt(struct ldma_dev *d) { struct fwnode_handle *fwnode = dev_fwnode(d->dev); struct ldma_port *p; @@ -1661,10 +1661,6 @@ static int intel_ldma_probe(struct platform_device *pdev) p->ldev = d; } - ret = ldma_cfg_init(d); - if (ret) - return ret; - dma_dev->dev = &pdev->dev; ch_mask = (unsigned long)d->channels_mask; @@ -1675,6 +1671,10 @@ static int intel_ldma_probe(struct platform_device *pdev) ldma_dma_init_v3X(j, d); } + ret = ldma_parse_dt(d); + if (ret) + return ret; + dma_dev->device_alloc_chan_resources = ldma_alloc_chan_resources; dma_dev->device_free_chan_resources = ldma_free_chan_resources; dma_dev->device_terminate_all = ldma_terminate_all; From 6437a549ae178a3f5a5c03e983f291ebcdc2bbc7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 17 Jan 2023 17:44:43 +0100 Subject: [PATCH 290/398] drm/panfrost: fix GENERIC_ATOMIC64 dependency On ARMv5 and earlier, a randconfig build can still run into WARNING: unmet direct dependencies detected for IOMMU_IO_PGTABLE_LPAE Depends on [n]: IOMMU_SUPPORT [=y] && (ARM [=y] || ARM64 || COMPILE_TEST [=y]) && !GENERIC_ATOMIC64 [=y] Selected by [y]: - DRM_PANFROST [=y] && HAS_IOMEM [=y] && DRM [=y] && (ARM [=y] || ARM64 || COMPILE_TEST [=y] && !GENERIC_ATOMIC64 [=y]) && MMU [=y] Rework the dependencies to always require a working cmpxchg64. Fixes: db594ba3fcf9 ("drm/panfrost: depend on !GENERIC_ATOMIC64 when using COMPILE_TEST") Signed-off-by: Arnd Bergmann Reviewed-by: Steven Price Signed-off-by: Steven Price Link: https://patchwork.freedesktop.org/patch/msgid/20230117164456.1591901-1-arnd@kernel.org --- drivers/gpu/drm/panfrost/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/panfrost/Kconfig b/drivers/gpu/drm/panfrost/Kconfig index 079600328be1..e6403a9d66ad 100644 --- a/drivers/gpu/drm/panfrost/Kconfig +++ b/drivers/gpu/drm/panfrost/Kconfig @@ -3,7 +3,8 @@ config DRM_PANFROST tristate "Panfrost (DRM support for ARM Mali Midgard/Bifrost GPUs)" depends on DRM - depends on ARM || ARM64 || (COMPILE_TEST && !GENERIC_ATOMIC64) + depends on ARM || ARM64 || COMPILE_TEST + depends on !GENERIC_ATOMIC64 # for IOMMU_IO_PGTABLE_LPAE depends on MMU select DRM_SCHED select IOMMU_SUPPORT From 57054fe516d59d03a7bcf1888e82479ccc244f87 Mon Sep 17 00:00:00 2001 From: "Shawn.Shao" Date: Thu, 12 Jan 2023 13:58:02 +0800 Subject: [PATCH 291/398] Add exception protection processing for vd in axi_chan_handle_err function Since there is no protection for vd, a kernel panic will be triggered here in exceptional cases. You can refer to the processing of axi_chan_block_xfer_complete function The triggered kernel panic is as follows: [ 67.848444] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000060 [ 67.848447] Mem abort info: [ 67.848449] ESR = 0x96000004 [ 67.848451] EC = 0x25: DABT (current EL), IL = 32 bits [ 67.848454] SET = 0, FnV = 0 [ 67.848456] EA = 0, S1PTW = 0 [ 67.848458] Data abort info: [ 67.848460] ISV = 0, ISS = 0x00000004 [ 67.848462] CM = 0, WnR = 0 [ 67.848465] user pgtable: 4k pages, 48-bit VAs, pgdp=00000800c4c0b000 [ 67.848468] [0000000000000060] pgd=0000000000000000, p4d=0000000000000000 [ 67.848472] Internal error: Oops: 96000004 [#1] SMP [ 67.848475] Modules linked in: dmatest [ 67.848479] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.10.100-emu_x2rc+ #11 [ 67.848483] pstate: 62000085 (nZCv daIf -PAN -UAO +TCO BTYPE=--) [ 67.848487] pc : axi_chan_handle_err+0xc4/0x230 [ 67.848491] lr : axi_chan_handle_err+0x30/0x230 [ 67.848493] sp : ffff0803fe55ae50 [ 67.848495] x29: ffff0803fe55ae50 x28: ffff800011212200 [ 67.848500] x27: ffff0800c42c0080 x26: ffff0800c097c080 [ 67.848504] x25: ffff800010d33880 x24: ffff80001139d850 [ 67.848508] x23: ffff0800c097c168 x22: 0000000000000000 [ 67.848512] x21: 0000000000000080 x20: 0000000000002000 [ 67.848517] x19: ffff0800c097c080 x18: 0000000000000000 [ 67.848521] x17: 0000000000000000 x16: 0000000000000000 [ 67.848525] x15: 0000000000000000 x14: 0000000000000000 [ 67.848529] x13: 0000000000000000 x12: 0000000000000040 [ 67.848533] x11: ffff0800c0400248 x10: ffff0800c040024a [ 67.848538] x9 : ffff800010576cd4 x8 : ffff0800c0400270 [ 67.848542] x7 : 0000000000000000 x6 : ffff0800c04003e0 [ 67.848546] x5 : ffff0800c0400248 x4 : ffff0800c4294480 [ 67.848550] x3 : dead000000000100 x2 : dead000000000122 [ 67.848555] x1 : 0000000000000100 x0 : ffff0800c097c168 [ 67.848559] Call trace: [ 67.848562] axi_chan_handle_err+0xc4/0x230 [ 67.848566] dw_axi_dma_interrupt+0xf4/0x590 [ 67.848569] __handle_irq_event_percpu+0x60/0x220 [ 67.848573] handle_irq_event+0x64/0x120 [ 67.848576] handle_fasteoi_irq+0xc4/0x220 [ 67.848580] __handle_domain_irq+0x80/0xe0 [ 67.848583] gic_handle_irq+0xc0/0x138 [ 67.848585] el1_irq+0xc8/0x180 [ 67.848588] arch_cpu_idle+0x14/0x2c [ 67.848591] default_idle_call+0x40/0x16c [ 67.848594] do_idle+0x1f0/0x250 [ 67.848597] cpu_startup_entry+0x2c/0x60 [ 67.848600] rest_init+0xc0/0xcc [ 67.848603] arch_call_rest_init+0x14/0x1c [ 67.848606] start_kernel+0x4cc/0x500 [ 67.848610] Code: eb0002ff 9a9f12d6 f2fbd5a2 f2fbd5a3 (a94602c1) [ 67.848613] ---[ end trace 585a97036f88203a ]--- Signed-off-by: Shawn.Shao Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230112055802.1764-1-shawn.shao@jaguarmicro.com Signed-off-by: Vinod Koul --- drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c index a183d93bd7e2..bf85aa0979ec 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -1018,6 +1018,11 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status) /* The bad descriptor currently is in the head of vc list */ vd = vchan_next_desc(&chan->vc); + if (!vd) { + dev_err(chan2dev(chan), "BUG: %s, IRQ with no descriptors\n", + axi_chan_name(chan)); + goto out; + } /* Remove the completed descriptor from issued list */ list_del(&vd->node); @@ -1032,6 +1037,7 @@ static noinline void axi_chan_handle_err(struct axi_dma_chan *chan, u32 status) /* Try to restart the controller */ axi_chan_start_first_queued(chan); +out: spin_unlock_irqrestore(&chan->vc.lock, flags); } From 9c7e355ccbb33d239360c876dbe49ad5ade65b47 Mon Sep 17 00:00:00 2001 From: Mohan Kumar Date: Mon, 2 Jan 2023 12:18:44 +0530 Subject: [PATCH 292/398] dmaengine: tegra210-adma: fix global intr clear The current global interrupt clear programming register offset was not correct. Fix the programming with right offset Fixes: ded1f3db4cd6 ("dmaengine: tegra210-adma: prepare for supporting newer Tegra chips") Cc: stable@vger.kernel.org Signed-off-by: Mohan Kumar Link: https://lore.kernel.org/r/20230102064844.31306-1-mkumard@nvidia.com Signed-off-by: Vinod Koul --- drivers/dma/tegra210-adma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index ae39b52012b2..79da93cc77b6 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -221,7 +221,7 @@ static int tegra_adma_init(struct tegra_adma *tdma) int ret; /* Clear any interrupts */ - tdma_write(tdma, tdma->cdata->global_int_clear, 0x1); + tdma_write(tdma, tdma->cdata->ch_base_offset + tdma->cdata->global_int_clear, 0x1); /* Assert soft reset */ tdma_write(tdma, ADMA_GLOBAL_SOFT_RESET, 0x1); From f3dc1b3b4750851a94212dba249703dd0e50bb20 Mon Sep 17 00:00:00 2001 From: Koba Ko Date: Thu, 1 Dec 2022 11:00:50 +0800 Subject: [PATCH 293/398] dmaengine: Fix double increment of client_count in dma_chan_get() The first time dma_chan_get() is called for a channel the channel client_count is incorrectly incremented twice for public channels, first in balance_ref_count(), and again prior to returning. This results in an incorrect client count which will lead to the channel resources not being freed when they should be. A simple test of repeated module load and unload of async_tx on a Dell Power Edge R7425 also shows this resulting in a kref underflow warning. [ 124.329662] async_tx: api initialized (async) [ 129.000627] async_tx: api initialized (async) [ 130.047839] ------------[ cut here ]------------ [ 130.052472] refcount_t: underflow; use-after-free. [ 130.057279] WARNING: CPU: 3 PID: 19364 at lib/refcount.c:28 refcount_warn_saturate+0xba/0x110 [ 130.065811] Modules linked in: async_tx(-) rfkill intel_rapl_msr intel_rapl_common amd64_edac edac_mce_amd ipmi_ssif kvm_amd dcdbas kvm mgag200 drm_shmem_helper acpi_ipmi irqbypass drm_kms_helper ipmi_si syscopyarea sysfillrect rapl pcspkr ipmi_devintf sysimgblt fb_sys_fops k10temp i2c_piix4 ipmi_msghandler acpi_power_meter acpi_cpufreq vfat fat drm fuse xfs libcrc32c sd_mod t10_pi sg ahci crct10dif_pclmul libahci crc32_pclmul crc32c_intel ghash_clmulni_intel igb megaraid_sas i40e libata i2c_algo_bit ccp sp5100_tco dca dm_mirror dm_region_hash dm_log dm_mod [last unloaded: async_tx] [ 130.117361] CPU: 3 PID: 19364 Comm: modprobe Kdump: loaded Not tainted 5.14.0-185.el9.x86_64 #1 [ 130.126091] Hardware name: Dell Inc. PowerEdge R7425/02MJ3T, BIOS 1.18.0 01/17/2022 [ 130.133806] RIP: 0010:refcount_warn_saturate+0xba/0x110 [ 130.139041] Code: 01 01 e8 6d bd 55 00 0f 0b e9 72 9d 8a 00 80 3d 26 18 9c 01 00 75 85 48 c7 c7 f8 a3 03 9d c6 05 16 18 9c 01 01 e8 4a bd 55 00 <0f> 0b e9 4f 9d 8a 00 80 3d 01 18 9c 01 00 0f 85 5e ff ff ff 48 c7 [ 130.157807] RSP: 0018:ffffbf98898afe68 EFLAGS: 00010286 [ 130.163036] RAX: 0000000000000000 RBX: ffff9da06028e598 RCX: 0000000000000000 [ 130.170172] RDX: ffff9daf9de26480 RSI: ffff9daf9de198a0 RDI: ffff9daf9de198a0 [ 130.177316] RBP: ffff9da7cddf3970 R08: 0000000000000000 R09: 00000000ffff7fff [ 130.184459] R10: ffffbf98898afd00 R11: ffffffff9d9e8c28 R12: ffff9da7cddf1970 [ 130.191596] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 [ 130.198739] FS: 00007f646435c740(0000) GS:ffff9daf9de00000(0000) knlGS:0000000000000000 [ 130.206832] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 130.212586] CR2: 00007f6463b214f0 CR3: 00000008ab98c000 CR4: 00000000003506e0 [ 130.219729] Call Trace: [ 130.222192] [ 130.224305] dma_chan_put+0x10d/0x110 [ 130.227988] dmaengine_put+0x7a/0xa0 [ 130.231575] __do_sys_delete_module.constprop.0+0x178/0x280 [ 130.237157] ? syscall_trace_enter.constprop.0+0x145/0x1d0 [ 130.242652] do_syscall_64+0x5c/0x90 [ 130.246240] ? exc_page_fault+0x62/0x150 [ 130.250178] entry_SYSCALL_64_after_hwframe+0x63/0xcd [ 130.255243] RIP: 0033:0x7f6463a3f5ab [ 130.258830] Code: 73 01 c3 48 8b 0d 75 a8 1b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 b0 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 45 a8 1b 00 f7 d8 64 89 01 48 [ 130.277591] RSP: 002b:00007fff22f972c8 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0 [ 130.285164] RAX: ffffffffffffffda RBX: 000055b6786edd40 RCX: 00007f6463a3f5ab [ 130.292303] RDX: 0000000000000000 RSI: 0000000000000800 RDI: 000055b6786edda8 [ 130.299443] RBP: 000055b6786edd40 R08: 0000000000000000 R09: 0000000000000000 [ 130.306584] R10: 00007f6463b9eac0 R11: 0000000000000206 R12: 000055b6786edda8 [ 130.313731] R13: 0000000000000000 R14: 000055b6786edda8 R15: 00007fff22f995f8 [ 130.320875] [ 130.323081] ---[ end trace eff7156d56b5cf25 ]--- cat /sys/class/dma/dma0chan*/in_use would get the wrong result. 2 2 2 Fixes: d2f4f99db3e9 ("dmaengine: Rework dma_chan_get") Signed-off-by: Koba Ko Reviewed-by: Jie Hai Test-by: Jie Hai Reviewed-by: Jerry Snitselaar Reviewed-by: Dave Jiang Tested-by: Joel Savitz Link: https://lore.kernel.org/r/20221201030050.978595-1-koba.ko@canonical.com Signed-off-by: Vinod Koul --- drivers/dma/dmaengine.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index c741b6431958..8a6e6b60d66f 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -451,7 +451,8 @@ static int dma_chan_get(struct dma_chan *chan) /* The channel is already in use, update client count */ if (chan->client_count) { __module_get(owner); - goto out; + chan->client_count++; + return 0; } if (!try_module_get(owner)) @@ -470,11 +471,11 @@ static int dma_chan_get(struct dma_chan *chan) goto err_out; } + chan->client_count++; + if (!dma_has_cap(DMA_PRIVATE, chan->device->cap_mask)) balance_ref_count(chan); -out: - chan->client_count++; return 0; err_out: From 1417f59ac0b02130ee56c0c50794b9b257be3d17 Mon Sep 17 00:00:00 2001 From: Hui Wang Date: Wed, 30 Nov 2022 17:08:00 +0800 Subject: [PATCH 294/398] dmaengine: imx-sdma: Fix a possible memory leak in sdma_transfer_init If the function sdma_load_context() fails, the sdma_desc will be freed, but the allocated desc->bd is forgot to be freed. We already met the sdma_load_context() failure case and the log as below: [ 450.699064] imx-sdma 30bd0000.dma-controller: Timeout waiting for CH0 ready ... In this case, the desc->bd will not be freed without this change. Signed-off-by: Hui Wang Reviewed-by: Sascha Hauer Link: https://lore.kernel.org/r/20221130090800.102035-1-hui.wang@canonical.com Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index fbea5f62dd98..b926abe4fa43 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1521,10 +1521,12 @@ static struct sdma_desc *sdma_transfer_init(struct sdma_channel *sdmac, sdma_config_ownership(sdmac, false, true, false); if (sdma_load_context(sdmac)) - goto err_desc_out; + goto err_bd_out; return desc; +err_bd_out: + sdma_free_bd(desc); err_desc_out: kfree(desc); err_out: From 7f2d4cdd2f32b66c452c958698fc287de4f68283 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 16 Jan 2023 10:33:22 -0300 Subject: [PATCH 295/398] tools kvm headers arm64: Update KVM header from the kernel sources To pick the changes from: 9cb1096f8590bc59 ("KVM: arm64: Enable ring-based dirty memory tracking") That doesn't result in any changes in tooling (built on a Libre Computer Firefly ROC-RK3399-PC-V1.1-A running Ubuntu 22.04), only addresses this perf build warning: Warning: Kernel ABI header at 'tools/arch/arm64/include/uapi/asm/kvm.h' differs from latest version at 'arch/arm64/include/uapi/asm/kvm.h' diff -u tools/arch/arm64/include/uapi/asm/kvm.h arch/arm64/include/uapi/asm/kvm.h Cc: Adrian Hunter Cc: Gavin Shan Cc: Ian Rogers Cc: Jiri Olsa Cc: Marc Zyngier Cc: Namhyung Kim Link: http://lore.kernel.org/lkml/Y8fmIT5PIfGaZuwa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/arm64/include/uapi/asm/kvm.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index 316917b98707..a7a857f1784d 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -43,6 +43,7 @@ #define __KVM_HAVE_VCPU_EVENTS #define KVM_COALESCED_MMIO_PAGE_OFFSET 1 +#define KVM_DIRTY_LOG_PAGE_OFFSET 64 #define KVM_REG_SIZE(id) \ (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT)) From 8c51e8f4e9ec6b404a10c84055b8454eba9f42fb Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 18 Jan 2023 09:38:16 -0300 Subject: [PATCH 296/398] tools headers arm64: Sync arm64's cputype.h with the kernel sources To get the changes in: decb17aeb8fa2148 ("KVM: arm64: vgic: Add Apple M2 cpus to the list of broken SEIS implementations") 07e39e60bbf0ccd5 ("arm64: Add Cortex-715 CPU part definition") 8ec8490a1950efec ("arm64: Fix bit-shifting UB in the MIDR_CPU_MODEL() macro") That addresses this perf build warning: Warning: Kernel ABI header at 'tools/arch/arm64/include/asm/cputype.h' differs from latest version at 'arch/arm64/include/asm/cputype.h' diff -u tools/arch/arm64/include/asm/cputype.h arch/arm64/include/asm/cputype.h Cc: Ali Saidi Cc: Anshuman Khandual Cc: Catalin Marinas Cc: D Scott Phillips Cc: German Gomez Cc: Leo Yan Cc: Marc Zyngier Cc: Will Deacon Link: http://lore.kernel.org/lkml/Y8fvEGCGn+227qW0@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/arm64/include/asm/cputype.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/arch/arm64/include/asm/cputype.h b/tools/arch/arm64/include/asm/cputype.h index abc418650fec..683ca3af4084 100644 --- a/tools/arch/arm64/include/asm/cputype.h +++ b/tools/arch/arm64/include/asm/cputype.h @@ -41,7 +41,7 @@ (((midr) & MIDR_IMPLEMENTOR_MASK) >> MIDR_IMPLEMENTOR_SHIFT) #define MIDR_CPU_MODEL(imp, partnum) \ - (((imp) << MIDR_IMPLEMENTOR_SHIFT) | \ + ((_AT(u32, imp) << MIDR_IMPLEMENTOR_SHIFT) | \ (0xf << MIDR_ARCHITECTURE_SHIFT) | \ ((partnum) << MIDR_PARTNUM_SHIFT)) @@ -80,6 +80,7 @@ #define ARM_CPU_PART_CORTEX_X1 0xD44 #define ARM_CPU_PART_CORTEX_A510 0xD46 #define ARM_CPU_PART_CORTEX_A710 0xD47 +#define ARM_CPU_PART_CORTEX_A715 0xD4D #define ARM_CPU_PART_CORTEX_X2 0xD48 #define ARM_CPU_PART_NEOVERSE_N2 0xD49 #define ARM_CPU_PART_CORTEX_A78C 0xD4B @@ -123,6 +124,8 @@ #define APPLE_CPU_PART_M1_FIRESTORM_PRO 0x025 #define APPLE_CPU_PART_M1_ICESTORM_MAX 0x028 #define APPLE_CPU_PART_M1_FIRESTORM_MAX 0x029 +#define APPLE_CPU_PART_M2_BLIZZARD 0x032 +#define APPLE_CPU_PART_M2_AVALANCHE 0x033 #define AMPERE_CPU_PART_AMPERE1 0xAC3 @@ -142,6 +145,7 @@ #define MIDR_CORTEX_X1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X1) #define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) +#define MIDR_CORTEX_A715 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A715) #define MIDR_CORTEX_X2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_X2) #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) #define MIDR_CORTEX_A78C MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A78C) @@ -175,6 +179,8 @@ #define MIDR_APPLE_M1_FIRESTORM_PRO MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO) #define MIDR_APPLE_M1_ICESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX) #define MIDR_APPLE_M1_FIRESTORM_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX) +#define MIDR_APPLE_M2_BLIZZARD MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD) +#define MIDR_APPLE_M2_AVALANCHE MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE) #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */ From d352588bbc990ba51f925f124946c42e604c502e Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 18 Jan 2023 10:12:23 -0300 Subject: [PATCH 297/398] perf beauty: Update copy of linux/socket.h with the kernel sources To pick the changes in: b5f0de6df6dce8d6 ("net: dev: Convert sa_data to flexible array in struct sockaddr") That don't result in any changes in the tables generated from that header. This silences this perf build warning: Warning: Kernel ABI header at 'tools/perf/trace/beauty/include/linux/socket.h' differs from latest version at 'include/linux/socket.h' diff -u tools/perf/trace/beauty/include/linux/socket.h include/linux/socket.h Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/trace/beauty/include/linux/socket.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/perf/trace/beauty/include/linux/socket.h b/tools/perf/trace/beauty/include/linux/socket.h index de3701a2a212..13c3a237b9c9 100644 --- a/tools/perf/trace/beauty/include/linux/socket.h +++ b/tools/perf/trace/beauty/include/linux/socket.h @@ -33,7 +33,10 @@ typedef __kernel_sa_family_t sa_family_t; struct sockaddr { sa_family_t sa_family; /* address family, AF_xxx */ - char sa_data[14]; /* 14 bytes of protocol address */ + union { + char sa_data_min[14]; /* Minimum 14 bytes of protocol address */ + DECLARE_FLEX_ARRAY(char, sa_data); + }; }; struct linger { From c905ecfbb8e5d54bbcdd2a1706b925baf1728cfe Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 18 Jan 2023 10:27:48 -0300 Subject: [PATCH 298/398] tools headers: Syncronize linux/build_bug.h with the kernel sources To pick up the changes in: 07a368b3f55a79d3 ("bug: introduce ASSERT_STRUCT_OFFSET") This cset only introduces a build time assert macro, that may be useful at some point for tooling, for now it silences this perf build warning: Warning: Kernel ABI header at 'tools/include/linux/build_bug.h' differs from latest version at 'include/linux/build_bug.h' diff -u tools/include/linux/build_bug.h include/linux/build_bug.h Cc: Adrian Hunter Cc: Ian Rogers Cc: Jiri Olsa Cc: Maxim Levitsky Cc: Namhyung Kim Cc: Paolo Bonzini Link: http://lore.kernel.org/lkml/Y8f0jqQFYDAOBkHx@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/linux/build_bug.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/include/linux/build_bug.h b/tools/include/linux/build_bug.h index cc7070c7439b..b4898ff085de 100644 --- a/tools/include/linux/build_bug.h +++ b/tools/include/linux/build_bug.h @@ -79,4 +79,13 @@ #define __static_assert(expr, msg, ...) _Static_assert(expr, msg) #endif // static_assert + +/* + * Compile time check that field has an expected offset + */ +#define ASSERT_STRUCT_OFFSET(type, field, expected_offset) \ + BUILD_BUG_ON_MSG(offsetof(type, field) != (expected_offset), \ + "Offset of " #field " in " #type " has changed.") + + #endif /* _LINUX_BUILD_BUG_H */ From 85c44913969bd27f15229c39383da1291800d7e9 Mon Sep 17 00:00:00 2001 From: Sohom Datta Date: Sun, 4 Dec 2022 16:28:35 +0530 Subject: [PATCH 299/398] perf expr: Prevent normalize() from reading into undefined memory in the expression lexer The current implementation does not account for a trailing backslash followed by a null-byte. If a null-byte is encountered following a backslash, normalize() will continue reading (and potentially writing) into garbage memory ignoring the EOS null-byte. Signed-off-by: Sohom Datta Acked-by: Ian Rogers Acked-by: Jiri Olsa Cc: Alexander Shishkin Cc: Ingo Molnar Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: https://lore.kernel.org/r/20221204105836.1012885-1-sohomdatta1+git@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/expr.l | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/expr.l b/tools/perf/util/expr.l index 0168a9637330..d47de5f270a8 100644 --- a/tools/perf/util/expr.l +++ b/tools/perf/util/expr.l @@ -42,8 +42,11 @@ static char *normalize(char *str, int runtime) char *dst = str; while (*str) { - if (*str == '\\') + if (*str == '\\') { *dst++ = *++str; + if (!*str) + break; + } else if (*str == '?') { char *paramval; int i = 0; From 4b21b3e7ef86aff7ff961bf28b2c17ee4204da16 Mon Sep 17 00:00:00 2001 From: Athira Rajeev Date: Mon, 16 Jan 2023 10:31:30 +0530 Subject: [PATCH 300/398] perf buildid-cache: Fix the file mode with copyfile() while adding file to build-id cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test "build id cache operations" fails on powerpc as below: Adding 5a0fd882b53084224ba47b624c55a469 ./tests/shell/../pe-file.exe: Ok build id: 5a0fd882b53084224ba47b624c55a469 link: /tmp/perf.debug.ZTu/.build-id/5a/0fd882b53084224ba47b624c55a469 file: /tmp/perf.debug.ZTu/.build-id/5a/../../root/linux/tools/perf/tests/pe-file.exe/5a0fd882b53084224ba47b624c55a469/elf failed: file /tmp/perf.debug.ZTu/.build-id/5a/../../root/linux/tools/perf/tests/pe-file.exe/5a0fd882b53084224ba47b624c55a469/elf does not exist test child finished with -1 ---- end ---- build id cache operations: FAILED! The failing test is when trying to add pe-file.exe to build id cache. 'perf buildid-cache' can be used to add/remove/manage files from the build-id cache. "-a" option is used to add a file to the build-id cache. Simple command to do so for a PE exe file: # ls -ltr tests/pe-file.exe -rw-r--r--. 1 root root 75595 Jan 10 23:35 tests/pe-file.exe The file is in home directory. # mkdir /tmp/perf.debug.TeY1 # perf --buildid-dir /tmp/perf.debug.TeY1 buildid-cache -v -a tests/pe-file.exe The above will create ".build-id" folder in build id directory, which is /tmp/perf.debug.TeY1. Also adds file to this folder under build id. Example: # ls -ltr /tmp/perf.debug.TeY1/.build-id/5a/0fd882b53084224ba47b624c55a469/ total 76 -rw-r--r--. 1 root root 0 Jan 11 00:38 probes -rwxr-xr-x. 1 root root 75595 Jan 11 00:38 elf We can see in the results that file mode for original file and file in build id directory is different. ie, build id file has executable permission whereas original file doesn’t have. The code path and function (build_id_cache__add to add a file to the cache is in "util/build-id.c". In build_id_cache__add() function, it first attempts to link the original file to destination cache folder. If linking the file fails (which can happen if the destination and source is on a different mount points), it will copy the file to destination. Here copyfile() routine explicitly uses mode as "755" and hence file in the destination will have executable permission. Code snippet: if (link(realname, filename) && errno != EEXIST && copyfile(name, filename)) strace logs: 172285 link("/home//linux/tools/perf/tests/pe-file.exe", "/tmp/perf.debug.TeY1/home//linux/tools/perf/tests/pe-file.exe/5a0fd882b53084224ba47b624c55a469/elf") = -1 EXDEV (Invalid cross-device link) 172285 newfstatat(AT_FDCWD, "tests/pe-file.exe", {st_mode=S_IFREG|0644, st_size=75595, ...}, 0) = 0 172285 openat(AT_FDCWD, "/tmp/perf.debug.TeY1/home//linux/tools/perf/tests/pe-file.exe/5a0fd882b53084224ba47b624c55a469/.elf.KbAnsl", O_RDWR|O_CREAT|O_EXCL, 0600) = 3 172285 fchmod(3, 0755) = 0 172285 openat(AT_FDCWD, "tests/pe-file.exe", O_RDONLY) = 4 172285 mmap(NULL, 75595, PROT_READ, MAP_PRIVATE, 4, 0) = 0x7fffa5cd0000 172285 pwrite64(3, "MZ\220\0\3\0\0\0\4\0\0\0\377\377\0\0\270\0\0\0\0\0\0\0@\0\0\0\0\0\0\0"..., 75595, 0) = 75595 Whereas if the link succeeds, it succeeds in the first attempt itself and the file in the build-id dir will have same permission as original file. Example, above uses /tmp. Instead if we use "--buildid-dir /home/build", linking will work here since mount points are same. Hence the destination file will not have executable permission. Since the testcase "tests/shell/buildid.sh" always looks for executable file, test fails in powerpc environment when test is run from /root. The patch adds a change in build_id_cache__add() to use copyfile_mode() which also passes the file’s original mode as argument. This way the destination file mode also will be same as original file. Signed-off-by: Athira Jajeev Cc: Andi Kleen Cc: Disha Goel Cc: Ian Rogers Cc: James Clark Cc: Jiri Olsa Cc: Kajol Jain Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Nageswara R Sastry Cc: Namhyung Kim Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/r/20230116050131.17221-1-atrajeev@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/build-id.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index a839b30c981b..ea9c083ab1e3 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -715,9 +715,13 @@ build_id_cache__add(const char *sbuild_id, const char *name, const char *realnam } else if (nsi && nsinfo__need_setns(nsi)) { if (copyfile_ns(name, filename, nsi)) goto out_free; - } else if (link(realname, filename) && errno != EEXIST && - copyfile(name, filename)) - goto out_free; + } else if (link(realname, filename) && errno != EEXIST) { + struct stat f_stat; + + if (!(stat(name, &f_stat) < 0) && + copyfile_mode(name, filename, f_stat.st_mode)) + goto out_free; + } } /* Some binaries are stripped, but have .debug files with their symbol From 3d9c07c4cfc06cf7927cd00c04dffd1165d03c53 Mon Sep 17 00:00:00 2001 From: Athira Rajeev Date: Mon, 16 Jan 2023 10:31:31 +0530 Subject: [PATCH 301/398] perf test build-id: Fix test check for PE file Perf test "build id cache operations" fails for PE executable. Logs below from powerpc system. Same is observed on x86 as well. <<>> Adding 5a0fd882b53084224ba47b624c55a469 ./tests/shell/../pe-file.exe: Ok build id: 5a0fd882b53084224ba47b624c55a469 link: /tmp/perf.debug.w0V/.build-id/5a/0fd882b53084224ba47b624c55a469 file: /tmp/perf.debug.w0V/.build-id/5a/../../root//linux/tools/perf/tests/pe-file.exe/5a0fd882b53084224ba47b624c55a469/elf failed: file /tmp/perf.debug.w0V/.build-id/5a/../../root//linux/tools/perf/tests/pe-file.exe/5a0fd882b53084224ba47b624c55a469/elf does not exist test child finished with -1 ---- end ---- build id cache operations: FAILED! <<>> The test tries to do: <<>> mkdir /tmp/perf.debug.TeY1 perf --buildid-dir /tmp/perf.debug.TeY1 buildid-cache -v -a ./tests/shell/../pe-file.exe <<>> The option "--buildid-dir" sets the build id cache directory as /tmp/perf.debug.TeY1. The option given to buildid-cahe, ie "-a ./tests/shell/../pe-file.exe", is to add the pe-file.exe to the cache. The testcase, sets buildid-dir and adds the file: pe-file.exe to build id cache. To check if the command is run successfully, "check" function looks for presence of the file in buildid cache directory. But the check here expects the added file to be executable. Snippet below: <<>> if [ ! -x $file ]; then echo "failed: file ${file} does not exist" exit 1 fi <<>> The buildid test is done for sha1 binary, md5 binary and also for PE file. The first two binaries are created at runtime by compiling with "--build-id" option and hence the check for sha1/md5 test should use [ ! -x ]. But in case of PE file, the permission for this input file is rw-r--r-- Hence the file added to build id cache has same permissoin Original file: ls tests/pe-file.exe | xargs stat --printf "%n %A \n" tests/pe-file.exe -rw-r--r-- buildid cache file: ls /tmp/perf.debug.w0V/.build-id/5a/../../root//linux/tools/perf/tests/pe-file.exe/5a0fd882b53084224ba47b624c55a469/elf | xargs stat --printf "%n %A \n" /tmp/perf.debug.w0V/.build-id/5a/../../root//linux/tools/perf/tests/pe-file.exe/5a0fd882b53084224ba47b624c55a469/elf -rw-r--r-- Fix the test to match with the permission of original file in case of FE file. ie if the "tests/pe-file.exe" file is not having exec permission, just check for existence of the buildid file using [ ! -e ] Signed-off-by: Athira Jajeev Cc: Andi Kleen Cc: Disha Goel Cc: Ian Rogers Cc: James Clark Cc: Jiri Olsa Cc: Kajol Jain Cc: Madhavan Srinivasan Cc: Michael Ellerman Cc: Nageswara R Sastry Cc: Namhyung Kim Cc: linuxppc-dev@lists.ozlabs.org Link: https://lore.kernel.org/r/20230116050131.17221-2-atrajeev@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/tests/shell/buildid.sh | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/perf/tests/shell/buildid.sh b/tools/perf/tests/shell/buildid.sh index f05670d1e39e..aaf851108ca3 100755 --- a/tools/perf/tests/shell/buildid.sh +++ b/tools/perf/tests/shell/buildid.sh @@ -77,7 +77,20 @@ check() file=${build_id_dir}/.build-id/${id:0:2}/`readlink ${link}`/elf echo "file: ${file}" - if [ ! -x $file ]; then + # Check for file permission of original file + # in case of pe-file.exe file + echo $1 | grep ".exe" + if [ $? -eq 0 ]; then + if [ -x $1 -a ! -x $file ]; then + echo "failed: file ${file} executable does not exist" + exit 1 + fi + + if [ ! -x $file -a ! -e $file ]; then + echo "failed: file ${file} does not exist" + exit 1 + fi + elif [ ! -x $file ]; then echo "failed: file ${file} does not exist" exit 1 fi From 7b90f5a665acd46efbbfa677a3a3a18d01ad6487 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Mon, 16 Jan 2023 15:41:33 -0600 Subject: [PATCH 302/398] net: macb: fix PTP TX timestamp failure due to packet padding PTP TX timestamp handling was observed to be broken with this driver when using the raw Layer 2 PTP encapsulation. ptp4l was not receiving the expected TX timestamp after transmitting a packet, causing it to enter a failure state. The problem appears to be due to the way that the driver pads packets which are smaller than the Ethernet minimum of 60 bytes. If headroom space was available in the SKB, this caused the driver to move the data back to utilize it. However, this appears to cause other data references in the SKB to become inconsistent. In particular, this caused the ptp_one_step_sync function to later (in the TX completion path) falsely detect the packet as a one-step SYNC packet, even when it was not, which caused the TX timestamp to not be processed when it should be. Using the headroom for this purpose seems like an unnecessary complexity as this is not a hot path in the driver, and in most cases it appears that there is sufficient tailroom to not require using the headroom anyway. Remove this usage of headroom to prevent this inconsistency from occurring and causing other problems. Fixes: 653e92a9175e ("net: macb: add support for padding and fcs computation") Signed-off-by: Robert Hancock Reviewed-by: Jacob Keller Tested-by: Claudiu Beznea # on SAMA7G5 Reviewed-by: Claudiu Beznea Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb_main.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 95667b979fab..72e42820713d 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -2187,7 +2187,6 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev) bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb) || skb_is_nonlinear(*skb); int padlen = ETH_ZLEN - (*skb)->len; - int headroom = skb_headroom(*skb); int tailroom = skb_tailroom(*skb); struct sk_buff *nskb; u32 fcs; @@ -2201,9 +2200,6 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev) /* FCS could be appeded to tailroom. */ if (tailroom >= ETH_FCS_LEN) goto add_fcs; - /* FCS could be appeded by moving data to headroom. */ - else if (!cloned && headroom + tailroom >= ETH_FCS_LEN) - padlen = 0; /* No room for FCS, need to reallocate skb. */ else padlen = ETH_FCS_LEN; @@ -2212,10 +2208,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev) padlen += ETH_FCS_LEN; } - if (!cloned && headroom + tailroom >= padlen) { - (*skb)->data = memmove((*skb)->head, (*skb)->data, (*skb)->len); - skb_set_tail_pointer(*skb, (*skb)->len); - } else { + if (cloned || tailroom < padlen) { nskb = skb_copy_expand(*skb, 0, padlen, GFP_ATOMIC); if (!nskb) return -ENOMEM; From d71ebe8114b4bf622804b810f5e274069060a174 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 17 Jan 2023 11:47:07 +0800 Subject: [PATCH 303/398] virtio-net: correctly enable callback during start_xmit Commit a7766ef18b33("virtio_net: disable cb aggressively") enables virtqueue callback via the following statement: do { if (use_napi) virtqueue_disable_cb(sq->vq); free_old_xmit_skbs(sq, false); } while (use_napi && kick && unlikely(!virtqueue_enable_cb_delayed(sq->vq))); When NAPI is used and kick is false, the callback won't be enabled here. And when the virtqueue is about to be full, the tx will be disabled, but we still don't enable tx interrupt which will cause a TX hang. This could be observed when using pktgen with burst enabled. TO be consistent with the logic that tries to disable cb only for NAPI, fixing this by trying to enable delayed callback only when NAPI is enabled when the queue is about to be full. Fixes: a7766ef18b33 ("virtio_net: disable cb aggressively") Signed-off-by: Jason Wang Tested-by: Laurent Vivier Signed-off-by: David S. Miller --- drivers/net/virtio_net.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 7723b2a49d8e..18b3de854aeb 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -1877,8 +1877,10 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) */ if (sq->vq->num_free < 2+MAX_SKB_FRAGS) { netif_stop_subqueue(dev, qnum); - if (!use_napi && - unlikely(!virtqueue_enable_cb_delayed(sq->vq))) { + if (use_napi) { + if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) + virtqueue_napi_schedule(&sq->napi, sq->vq); + } else if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) { /* More just got used, free them then recheck. */ free_old_xmit_skbs(sq, false); if (sq->vq->num_free >= 2+MAX_SKB_FRAGS) { From 0e3b175f079247f0d40d2ab695999c309d3a7498 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 16 Jan 2023 13:37:01 -0600 Subject: [PATCH 304/398] gpiolib: acpi: Allow ignoring wake capability on pins that aren't in _AEI Using the `ignore_wake` quirk or module parameter doesn't work for any pin that has been specified in the _CRS instead of _AEI. Extend the `acpi_gpio_irq_is_wake` check to cover both places. Suggested-by: Raul Rangel Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1722335 Signed-off-by: Mario Limonciello Reviewed-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-acpi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index bed0380c5136..4287555a1240 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -385,7 +385,7 @@ err: } static bool acpi_gpio_irq_is_wake(struct device *parent, - struct acpi_resource_gpio *agpio) + const struct acpi_resource_gpio *agpio) { unsigned int pin = agpio->pin_table[0]; @@ -778,7 +778,7 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) lookup->info.pin_config = agpio->pin_config; lookup->info.debounce = agpio->debounce_timeout; lookup->info.gpioint = gpioint; - lookup->info.wake_capable = agpio->wake_capable == ACPI_WAKE_CAPABLE; + lookup->info.wake_capable = acpi_gpio_irq_is_wake(&lookup->info.adev->dev, agpio); /* * Polarity and triggering are only specified for GpioInt From 4cb786180dfb5258ff3111181b5e4ecb1d4a297b Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Mon, 16 Jan 2023 13:37:02 -0600 Subject: [PATCH 305/398] gpiolib: acpi: Add a ignore wakeup quirk for Clevo NL5xRU commit 1796f808e4bb ("HID: i2c-hid: acpi: Stop setting wakeup_capable") changed the policy such that I2C touchpads may be able to wake up the system by default if the system is configured as such. However on Clevo NL5xRU there is a mistake in the ACPI tables that the TP_ATTN# signal connected to GPIO 9 is configured as ActiveLow and level triggered but connected to a pull up. As soon as the system suspends the touchpad loses power and then the system wakes up. To avoid this problem, introduce a quirk for this model that will prevent the wakeup capability for being set for GPIO 9. Fixes: 1796f808e4bb ("HID: i2c-hid: acpi: Stop setting wakeup_capable") Reported-by: Werner Sembach Link: https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627 Co-developed-by: Werner Sembach Signed-off-by: Werner Sembach Signed-off-by: Mario Limonciello Reviewed-by: Andy Shevchenko Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib-acpi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c index 4287555a1240..9ef0f5641b52 100644 --- a/drivers/gpio/gpiolib-acpi.c +++ b/drivers/gpio/gpiolib-acpi.c @@ -1623,6 +1623,19 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { .ignore_interrupt = "AMDI0030:00@18", }, }, + { + /* + * Spurious wakeups from TP_ATTN# pin + * Found in BIOS 1.7.8 + * https://gitlab.freedesktop.org/drm/amd/-/issues/1722#note_1720627 + */ + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "NL5xRU"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "ELAN0415:00@9", + }, + }, {} /* Terminating entry */ }; From b9fb10d131b8c84af9bb14e2078d5c63600c7dea Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 17 Jan 2023 11:01:31 +0000 Subject: [PATCH 306/398] l2tp: prevent lockdep issue in l2tp_tunnel_register() lockdep complains with the following lock/unlock sequence: lock_sock(sk); write_lock_bh(&sk->sk_callback_lock); [1] release_sock(sk); [2] write_unlock_bh(&sk->sk_callback_lock); We need to swap [1] and [2] to fix this issue. Fixes: 0b2c59720e65 ("l2tp: close all race conditions in l2tp_tunnel_register()") Reported-by: syzbot+bbd35b345c7cab0d9a08@syzkaller.appspotmail.com Signed-off-by: Eric Dumazet Link: https://lore.kernel.org/netdev/20230114030137.672706-1-xiyou.wangcong@gmail.com/T/#m1164ff20628671b0f326a24cb106ab3239c70ce3 Cc: Cong Wang Cc: Guillaume Nault Reviewed-by: Guillaume Nault Signed-off-by: David S. Miller --- net/l2tp/l2tp_core.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index b6554e32bb12..03608d3ded4b 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -1483,10 +1483,8 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, lock_sock(sk); write_lock_bh(&sk->sk_callback_lock); ret = l2tp_validate_socket(sk, net, tunnel->encap); - if (ret < 0) { - release_sock(sk); + if (ret < 0) goto err_inval_sock; - } rcu_assign_sk_user_data(sk, tunnel); write_unlock_bh(&sk->sk_callback_lock); @@ -1523,6 +1521,7 @@ int l2tp_tunnel_register(struct l2tp_tunnel *tunnel, struct net *net, err_inval_sock: write_unlock_bh(&sk->sk_callback_lock); + release_sock(sk); if (tunnel->fd < 0) sock_release(sock); From 3782c0d6edf658b71354a64d60aa7a296188fc90 Mon Sep 17 00:00:00 2001 From: Pietro Borrello Date: Wed, 11 Jan 2023 18:12:16 +0000 Subject: [PATCH 307/398] HID: betop: check shape of output reports betopff_init() only checks the total sum of the report counts for each report field to be at least 4, but hid_betopff_play() expects 4 report fields. A device advertising an output report with one field and 4 report counts would pass the check but crash the kernel with a NULL pointer dereference in hid_betopff_play(). Fixes: 52cd7785f3cd ("HID: betop: add drivers/hid/hid-betopff.c") Signed-off-by: Pietro Borrello Signed-off-by: Jiri Kosina --- drivers/hid/hid-betopff.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/hid/hid-betopff.c b/drivers/hid/hid-betopff.c index 467d789f9bc2..25ed7b9a917e 100644 --- a/drivers/hid/hid-betopff.c +++ b/drivers/hid/hid-betopff.c @@ -60,7 +60,6 @@ static int betopff_init(struct hid_device *hid) struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; struct input_dev *dev; - int field_count = 0; int error; int i, j; @@ -86,19 +85,21 @@ static int betopff_init(struct hid_device *hid) * ----------------------------------------- * Do init them with default value. */ + if (report->maxfield < 4) { + hid_err(hid, "not enough fields in the report: %d\n", + report->maxfield); + return -ENODEV; + } for (i = 0; i < report->maxfield; i++) { + if (report->field[i]->report_count < 1) { + hid_err(hid, "no values in the field\n"); + return -ENODEV; + } for (j = 0; j < report->field[i]->report_count; j++) { report->field[i]->value[j] = 0x00; - field_count++; } } - if (field_count < 4) { - hid_err(hid, "not enough fields in the report: %d\n", - field_count); - return -ENODEV; - } - betopff = kzalloc(sizeof(*betopff), GFP_KERNEL); if (!betopff) return -ENOMEM; From 67b0b4ed259e425b7eed09da75b42c80682ca003 Mon Sep 17 00:00:00 2001 From: Sasa Dragic Date: Mon, 19 Dec 2022 18:29:27 +0100 Subject: [PATCH 308/398] drm/i915: re-disable RC6p on Sandy Bridge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RC6p on Sandy Bridge got re-enabled over time, causing visual glitches and GPU hangs. Disabled originally in commit 1c8ecf80fdee ("drm/i915: do not enable RC6p on Sandy Bridge"). Signed-off-by: Sasa Dragic Signed-off-by: Ville Syrjälä Link: https://patchwork.freedesktop.org/patch/msgid/20221219172927.9603-2-sasa.dragic@gmail.com Fixes: fb6db0f5bf1d ("drm/i915: Remove unsafe i915.enable_rc6") Fixes: 13c5a577b342 ("drm/i915/gt: Select the deepest available parking mode for rc6") Cc: stable@vger.kernel.org Reviewed-by: Rodrigo Vivi (cherry picked from commit 0c8a6e9ea232c221976a0670256bd861408d9917) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_pci.c b/drivers/gpu/drm/i915/i915_pci.c index ccd1f864aa19..4fada7ebe8d8 100644 --- a/drivers/gpu/drm/i915/i915_pci.c +++ b/drivers/gpu/drm/i915/i915_pci.c @@ -423,7 +423,8 @@ static const struct intel_device_info ilk_m_info = { .has_coherent_ggtt = true, \ .has_llc = 1, \ .has_rc6 = 1, \ - .has_rc6p = 1, \ + /* snb does support rc6p, but enabling it causes various issues */ \ + .has_rc6p = 0, \ .has_rps = true, \ .dma_mask_size = 40, \ .__runtime.ppgtt_type = INTEL_PPGTT_ALIASING, \ From 93eea624526fc7d070cdae463408665824075f54 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 17 Jan 2023 13:32:34 +0100 Subject: [PATCH 309/398] drm/i915/selftests: Unwind hugepages to drop wakeref on error Make sure that upon error after we have acquired the wakeref we do release it again. v2: add another missing "goto out_wf"(Andi). Fixes: 027c38b4121e ("drm/i915/selftests: Grab the runtime pm in shrink_thp") Cc: Andi Shyti Reviewed-by: Matthew Auld Reviewed-by: Andrzej Hajda Signed-off-by: Chris Wilson Signed-off-by: Nirmoy Das Reviewed-by: Andi Shyti Reviewed-by: Nirmoy Das Signed-off-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/20230117123234.26487-1-nirmoy.das@intel.com (cherry picked from commit 14ec40a88210151296fff3e981c1a7196ad9bf55) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index beaf27e09e8a..977dead10ab5 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -1847,7 +1847,7 @@ static int igt_shrink_thp(void *arg) I915_SHRINK_ACTIVE); i915_vma_unpin(vma); if (err) - goto out_put; + goto out_wf; /* * Now that the pages are *unpinned* shrinking should invoke @@ -1863,19 +1863,19 @@ static int igt_shrink_thp(void *arg) pr_err("unexpected pages mismatch, should_swap=%s\n", str_yes_no(should_swap)); err = -EINVAL; - goto out_put; + goto out_wf; } if (should_swap == (obj->mm.page_sizes.sg || obj->mm.page_sizes.phys)) { pr_err("unexpected residual page-size bits, should_swap=%s\n", str_yes_no(should_swap)); err = -EINVAL; - goto out_put; + goto out_wf; } err = i915_vma_pin(vma, 0, 0, flags); if (err) - goto out_put; + goto out_wf; while (n--) { err = cpu_check(obj, n, 0xdeadbeaf); From a273e95721e96885971a05f1b34cb6d093904d9d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 16 Jan 2023 12:54:23 +0100 Subject: [PATCH 310/398] drm/i915: Allow switching away via vga-switcheroo if uninitialized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Always allow switching away via vga-switcheroo if the display is uninitalized. Instead prevent switching to i915 if the device has not been initialized. This issue was introduced by commit 5df7bd130818 ("drm/i915: skip display initialization when there is no display") protected, which protects code paths from being executed on uninitialized devices. In the case of vga-switcheroo, we want to allow a switch away from i915's device. So run vga_switcheroo_process_delayed_switch() and test in the switcheroo callbacks if the i915 device is available. Fixes: 5df7bd130818 ("drm/i915: skip display initialization when there is no display") Signed-off-by: Thomas Zimmermann Reviewed-by: Alex Deucher Cc: Radhakrishna Sripada Cc: Lucas De Marchi Cc: José Roberto de Souza Cc: Jani Nikula Cc: Ville Syrjälä Cc: Jani Nikula Cc: Joonas Lahtinen Cc: Rodrigo Vivi Cc: Tvrtko Ursulin Cc: "Ville Syrjälä" Cc: Manasi Navare Cc: Stanislav Lisovskiy Cc: Imre Deak Cc: "Jouni Högander" Cc: Uma Shankar Cc: Ankit Nautiyal Cc: "Jason A. Donenfeld" Cc: Matt Roper Cc: Ramalingam C Cc: Thomas Zimmermann Cc: Andi Shyti Cc: Andrzej Hajda Cc: "José Roberto de Souza" Cc: Julia Lawall Cc: intel-gfx@lists.freedesktop.org Cc: # v5.14+ Link: https://patchwork.freedesktop.org/patch/msgid/20230116115425.13484-2-tzimmermann@suse.de --- drivers/gpu/drm/i915/i915_driver.c | 3 +-- drivers/gpu/drm/i915/i915_switcheroo.c | 6 +++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 69103ae37779..b5700681432d 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1073,8 +1073,7 @@ static void i915_driver_lastclose(struct drm_device *dev) intel_fbdev_restore_mode(dev); - if (HAS_DISPLAY(i915)) - vga_switcheroo_process_delayed_switch(); + vga_switcheroo_process_delayed_switch(); } static void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) diff --git a/drivers/gpu/drm/i915/i915_switcheroo.c b/drivers/gpu/drm/i915/i915_switcheroo.c index 23777d500cdf..f45bd6b6cede 100644 --- a/drivers/gpu/drm/i915/i915_switcheroo.c +++ b/drivers/gpu/drm/i915/i915_switcheroo.c @@ -19,6 +19,10 @@ static void i915_switcheroo_set_state(struct pci_dev *pdev, dev_err(&pdev->dev, "DRM not initialized, aborting switch.\n"); return; } + if (!HAS_DISPLAY(i915)) { + dev_err(&pdev->dev, "Device state not initialized, aborting switch.\n"); + return; + } if (state == VGA_SWITCHEROO_ON) { drm_info(&i915->drm, "switched on\n"); @@ -44,7 +48,7 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) * locking inversion with the driver load path. And the access here is * completely racy anyway. So don't bother with locking for now. */ - return i915 && atomic_read(&i915->drm.open_count) == 0; + return i915 && HAS_DISPLAY(i915) && atomic_read(&i915->drm.open_count) == 0; } static const struct vga_switcheroo_client_ops i915_switcheroo_ops = { From d1d5101452ab04e5a3f010bdd200971d78956e5a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 16 Jan 2023 12:54:24 +0100 Subject: [PATCH 311/398] drm/fb-helper: Set framebuffer for vga-switcheroo clients MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Set the framebuffer info for drivers that support VGA switcheroo. Only affects the amdgpu and nouveau drivers, which use VGA switcheroo and generic fbdev emulation. For other drivers, this does nothing. This fixes a potential regression in the console code. Both, amdgpu and nouveau, invoked vga_switcheroo_client_fb_set() from their internal fbdev code. But the call got lost when the drivers switched to the generic emulation. Fixes: 087451f372bf ("drm/amdgpu: use generic fb helpers instead of setting up AMD own's.") Fixes: 4a16dd9d18a0 ("drm/nouveau/kms: switch to drm fbdev helpers") Signed-off-by: Thomas Zimmermann Reviewed-by: Daniel Vetter Reviewed-by: Alex Deucher Cc: Ben Skeggs Cc: Karol Herbst Cc: Lyude Paul Cc: Thomas Zimmermann Cc: Javier Martinez Canillas Cc: Laurent Pinchart Cc: Jani Nikula Cc: Dave Airlie Cc: Evan Quan Cc: Christian König Cc: Alex Deucher Cc: Hawking Zhang Cc: Likun Gao Cc: "Christian König" Cc: Stanley Yang Cc: "Tianci.Yin" Cc: Xiaojian Du Cc: Andrey Grodzovsky Cc: YiPeng Chai Cc: Somalapuram Amaranath Cc: Bokun Zhang Cc: Guchun Chen Cc: Hamza Mahfooz Cc: Aurabindo Pillai Cc: Mario Limonciello Cc: Solomon Chiu Cc: Kai-Heng Feng Cc: Felix Kuehling Cc: Daniel Vetter Cc: "Marek Olšák" Cc: Sam Ravnborg Cc: Hans de Goede Cc: "Ville Syrjälä" Cc: dri-devel@lists.freedesktop.org Cc: nouveau@lists.freedesktop.org Cc: # v5.17+ Link: https://patchwork.freedesktop.org/patch/msgid/20230116115425.13484-3-tzimmermann@suse.de --- drivers/gpu/drm/drm_fb_helper.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index b3a731b9170a..0d0c26ebab90 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -30,7 +30,9 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include #include +#include #include #include @@ -1909,6 +1911,11 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, return ret; strcpy(fb_helper->fb->comm, "[fbcon]"); + + /* Set the fb info for vgaswitcheroo clients. Does nothing otherwise. */ + if (dev_is_pci(dev->dev)) + vga_switcheroo_client_fb_set(to_pci_dev(dev->dev), fb_helper->info); + return 0; } From 9fb0db40513e27537fde63287aea920b60557a69 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Tue, 17 Jan 2023 19:00:37 -0300 Subject: [PATCH 312/398] cifs: fix potential deadlock in cache_refresh_path() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid getting DFS referral from an exclusive lock in cache_refresh_path() because the tcon IPC used for getting the referral could be disconnected and thus causing a deadlock as shown below: task A task B ====== ====== cifs_demultiplex_thread() dfs_cache_find() cifs_handle_standard() cache_refresh_path() reconnect_dfs_server() down_write() dfs_cache_noreq_find() get_dfs_referral() down_read() <- deadlock smb2_get_dfs_refer() SMB2_ioctl() cifs_send_recv() compound_send_recv() wait_for_response() where task A cannot wake up task B because it is blocked on down_read() due to the exclusive lock held in cache_refresh_path() and therefore not being able to make progress. Fixes: c9f711039905 ("cifs: keep referral server sessions alive") Reviewed-by: Aurélien Aptel Signed-off-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/dfs_cache.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index e20f8880363f..a6d7ae5f49a4 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -770,26 +770,27 @@ static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const */ static int cache_refresh_path(const unsigned int xid, struct cifs_ses *ses, const char *path) { - int rc; - struct cache_entry *ce; struct dfs_info3_param *refs = NULL; + struct cache_entry *ce; int numrefs = 0; - bool newent = false; + int rc; cifs_dbg(FYI, "%s: search path: %s\n", __func__, path); - down_write(&htable_rw_lock); + down_read(&htable_rw_lock); ce = lookup_cache_entry(path); - if (!IS_ERR(ce)) { - if (!cache_entry_expired(ce)) { - dump_ce(ce); - up_write(&htable_rw_lock); - return 0; - } - } else { - newent = true; + if (!IS_ERR(ce) && !cache_entry_expired(ce)) { + up_read(&htable_rw_lock); + return 0; } + /* + * Unlock shared access as we don't want to hold any locks while getting + * a new referral. The @ses used for performing the I/O could be + * reconnecting and it acquires @htable_rw_lock to look up the dfs cache + * in order to failover -- if necessary. + */ + up_read(&htable_rw_lock); /* * Either the entry was not found, or it is expired. @@ -797,19 +798,22 @@ static int cache_refresh_path(const unsigned int xid, struct cifs_ses *ses, cons */ rc = get_dfs_referral(xid, ses, path, &refs, &numrefs); if (rc) - goto out_unlock; + goto out; dump_refs(refs, numrefs); - if (!newent) { - rc = update_cache_entry_locked(ce, refs, numrefs); - goto out_unlock; + down_write(&htable_rw_lock); + /* Re-check as another task might have it added or refreshed already */ + ce = lookup_cache_entry(path); + if (!IS_ERR(ce)) { + if (cache_entry_expired(ce)) + rc = update_cache_entry_locked(ce, refs, numrefs); + } else { + rc = add_cache_entry_locked(refs, numrefs); } - rc = add_cache_entry_locked(refs, numrefs); - -out_unlock: up_write(&htable_rw_lock); +out: free_dfs_info_array(refs, numrefs); return rc; } From 48d240bf00af943db6f069a53f090e444e85f760 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Tue, 17 Jan 2023 19:00:38 -0300 Subject: [PATCH 313/398] cifs: avoid re-lookups in dfs_cache_find() Simply downgrade the write lock on cache updates from cache_refresh_path() and avoid unnecessary re-lookup in dfs_cache_find(). Signed-off-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/dfs_cache.c | 58 ++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index a6d7ae5f49a4..755a00c4cba1 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -558,7 +558,8 @@ static void remove_oldest_entry_locked(void) } /* Add a new DFS cache entry */ -static int add_cache_entry_locked(struct dfs_info3_param *refs, int numrefs) +static struct cache_entry *add_cache_entry_locked(struct dfs_info3_param *refs, + int numrefs) { int rc; struct cache_entry *ce; @@ -573,11 +574,11 @@ static int add_cache_entry_locked(struct dfs_info3_param *refs, int numrefs) rc = cache_entry_hash(refs[0].path_name, strlen(refs[0].path_name), &hash); if (rc) - return rc; + return ERR_PTR(rc); ce = alloc_cache_entry(refs, numrefs); if (IS_ERR(ce)) - return PTR_ERR(ce); + return ce; spin_lock(&cache_ttl_lock); if (!cache_ttl) { @@ -594,7 +595,7 @@ static int add_cache_entry_locked(struct dfs_info3_param *refs, int numrefs) atomic_inc(&cache_count); - return 0; + return ce; } /* Check if two DFS paths are equal. @s1 and @s2 are expected to be in @cache_cp's charset */ @@ -767,8 +768,12 @@ static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const * * For interlinks, cifs_mount() and expand_dfs_referral() are supposed to * handle them properly. + * + * On success, return entry with acquired lock for reading, otherwise error ptr. */ -static int cache_refresh_path(const unsigned int xid, struct cifs_ses *ses, const char *path) +static struct cache_entry *cache_refresh_path(const unsigned int xid, + struct cifs_ses *ses, + const char *path) { struct dfs_info3_param *refs = NULL; struct cache_entry *ce; @@ -780,10 +785,9 @@ static int cache_refresh_path(const unsigned int xid, struct cifs_ses *ses, cons down_read(&htable_rw_lock); ce = lookup_cache_entry(path); - if (!IS_ERR(ce) && !cache_entry_expired(ce)) { - up_read(&htable_rw_lock); - return 0; - } + if (!IS_ERR(ce) && !cache_entry_expired(ce)) + return ce; + /* * Unlock shared access as we don't want to hold any locks while getting * a new referral. The @ses used for performing the I/O could be @@ -797,8 +801,10 @@ static int cache_refresh_path(const unsigned int xid, struct cifs_ses *ses, cons * Request a new DFS referral in order to create or update a cache entry. */ rc = get_dfs_referral(xid, ses, path, &refs, &numrefs); - if (rc) + if (rc) { + ce = ERR_PTR(rc); goto out; + } dump_refs(refs, numrefs); @@ -806,16 +812,24 @@ static int cache_refresh_path(const unsigned int xid, struct cifs_ses *ses, cons /* Re-check as another task might have it added or refreshed already */ ce = lookup_cache_entry(path); if (!IS_ERR(ce)) { - if (cache_entry_expired(ce)) + if (cache_entry_expired(ce)) { rc = update_cache_entry_locked(ce, refs, numrefs); + if (rc) + ce = ERR_PTR(rc); + } } else { - rc = add_cache_entry_locked(refs, numrefs); + ce = add_cache_entry_locked(refs, numrefs); } - up_write(&htable_rw_lock); + if (IS_ERR(ce)) { + up_write(&htable_rw_lock); + goto out; + } + + downgrade_write(&htable_rw_lock); out: free_dfs_info_array(refs, numrefs); - return rc; + return ce; } /* @@ -935,15 +949,8 @@ int dfs_cache_find(const unsigned int xid, struct cifs_ses *ses, const struct nl if (IS_ERR(npath)) return PTR_ERR(npath); - rc = cache_refresh_path(xid, ses, npath); - if (rc) - goto out_free_path; - - down_read(&htable_rw_lock); - - ce = lookup_cache_entry(npath); + ce = cache_refresh_path(xid, ses, npath); if (IS_ERR(ce)) { - up_read(&htable_rw_lock); rc = PTR_ERR(ce); goto out_free_path; } @@ -1039,10 +1046,13 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses, cifs_dbg(FYI, "%s: update target hint - path: %s\n", __func__, npath); - rc = cache_refresh_path(xid, ses, npath); - if (rc) + ce = cache_refresh_path(xid, ses, npath); + if (IS_ERR(ce)) { + rc = PTR_ERR(ce); goto out_free_path; + } + up_read(&htable_rw_lock); down_write(&htable_rw_lock); ce = lookup_cache_entry(npath); From 11c8b3f8493cb5253da42fcd178d9b4630063f96 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Tue, 17 Jan 2023 19:00:39 -0300 Subject: [PATCH 314/398] cifs: don't take exclusive lock for updating target hints Avoid contention while updating dfs target hints. This should be perfectly fine to update them under shared locks. Signed-off-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/dfs_cache.c | 47 +++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index 755a00c4cba1..19847f9114ba 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -269,7 +269,7 @@ static int dfscache_proc_show(struct seq_file *m, void *v) list_for_each_entry(t, &ce->tlist, list) { seq_printf(m, " %s%s\n", t->name, - ce->tgthint == t ? " (target hint)" : ""); + READ_ONCE(ce->tgthint) == t ? " (target hint)" : ""); } } } @@ -321,7 +321,7 @@ static inline void dump_tgts(const struct cache_entry *ce) cifs_dbg(FYI, "target list:\n"); list_for_each_entry(t, &ce->tlist, list) { cifs_dbg(FYI, " %s%s\n", t->name, - ce->tgthint == t ? " (target hint)" : ""); + READ_ONCE(ce->tgthint) == t ? " (target hint)" : ""); } } @@ -427,7 +427,7 @@ static int cache_entry_hash(const void *data, int size, unsigned int *hash) /* Return target hint of a DFS cache entry */ static inline char *get_tgt_name(const struct cache_entry *ce) { - struct cache_dfs_tgt *t = ce->tgthint; + struct cache_dfs_tgt *t = READ_ONCE(ce->tgthint); return t ? t->name : ERR_PTR(-ENOENT); } @@ -470,6 +470,7 @@ static struct cache_dfs_tgt *alloc_target(const char *name, int path_consumed) static int copy_ref_data(const struct dfs_info3_param *refs, int numrefs, struct cache_entry *ce, const char *tgthint) { + struct cache_dfs_tgt *target; int i; ce->ttl = max_t(int, refs[0].ttl, CACHE_MIN_TTL); @@ -496,8 +497,9 @@ static int copy_ref_data(const struct dfs_info3_param *refs, int numrefs, ce->numtgts++; } - ce->tgthint = list_first_entry_or_null(&ce->tlist, - struct cache_dfs_tgt, list); + target = list_first_entry_or_null(&ce->tlist, struct cache_dfs_tgt, + list); + WRITE_ONCE(ce->tgthint, target); return 0; } @@ -712,14 +714,15 @@ void dfs_cache_destroy(void) static int update_cache_entry_locked(struct cache_entry *ce, const struct dfs_info3_param *refs, int numrefs) { + struct cache_dfs_tgt *target; + char *th = NULL; int rc; - char *s, *th = NULL; WARN_ON(!rwsem_is_locked(&htable_rw_lock)); - if (ce->tgthint) { - s = ce->tgthint->name; - th = kstrdup(s, GFP_ATOMIC); + target = READ_ONCE(ce->tgthint); + if (target) { + th = kstrdup(target->name, GFP_ATOMIC); if (!th) return -ENOMEM; } @@ -896,7 +899,7 @@ static int get_targets(struct cache_entry *ce, struct dfs_cache_tgt_list *tl) } it->it_path_consumed = t->path_consumed; - if (ce->tgthint == t) + if (READ_ONCE(ce->tgthint) == t) list_add(&it->it_list, head); else list_add_tail(&it->it_list, head); @@ -1052,23 +1055,14 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses, goto out_free_path; } - up_read(&htable_rw_lock); - down_write(&htable_rw_lock); - - ce = lookup_cache_entry(npath); - if (IS_ERR(ce)) { - rc = PTR_ERR(ce); - goto out_unlock; - } - - t = ce->tgthint; + t = READ_ONCE(ce->tgthint); if (likely(!strcasecmp(it->it_name, t->name))) goto out_unlock; list_for_each_entry(t, &ce->tlist, list) { if (!strcasecmp(t->name, it->it_name)) { - ce->tgthint = t; + WRITE_ONCE(ce->tgthint, t); cifs_dbg(FYI, "%s: new target hint: %s\n", __func__, it->it_name); break; @@ -1076,7 +1070,7 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses, } out_unlock: - up_write(&htable_rw_lock); + up_read(&htable_rw_lock); out_free_path: kfree(npath); return rc; @@ -1106,21 +1100,20 @@ void dfs_cache_noreq_update_tgthint(const char *path, const struct dfs_cache_tgt cifs_dbg(FYI, "%s: path: %s\n", __func__, path); - if (!down_write_trylock(&htable_rw_lock)) - return; + down_read(&htable_rw_lock); ce = lookup_cache_entry(path); if (IS_ERR(ce)) goto out_unlock; - t = ce->tgthint; + t = READ_ONCE(ce->tgthint); if (unlikely(!strcasecmp(it->it_name, t->name))) goto out_unlock; list_for_each_entry(t, &ce->tlist, list) { if (!strcasecmp(t->name, it->it_name)) { - ce->tgthint = t; + WRITE_ONCE(ce->tgthint, t); cifs_dbg(FYI, "%s: new target hint: %s\n", __func__, it->it_name); break; @@ -1128,7 +1121,7 @@ void dfs_cache_noreq_update_tgthint(const char *path, const struct dfs_cache_tgt } out_unlock: - up_write(&htable_rw_lock); + up_read(&htable_rw_lock); } /** From 8064f711c6a4614a848009b5a773e8d7f055a4c5 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Tue, 17 Jan 2023 19:00:40 -0300 Subject: [PATCH 315/398] cifs: remove duplicate code in __refresh_tcon() The logic for creating or updating a cache entry in __refresh_tcon() could be simply done with cache_refresh_path(), so use it instead. Signed-off-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/dfs_cache.c | 69 +++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 37 deletions(-) diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index 19847f9114ba..58d11be9d020 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -776,7 +776,8 @@ static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const */ static struct cache_entry *cache_refresh_path(const unsigned int xid, struct cifs_ses *ses, - const char *path) + const char *path, + bool force_refresh) { struct dfs_info3_param *refs = NULL; struct cache_entry *ce; @@ -788,7 +789,7 @@ static struct cache_entry *cache_refresh_path(const unsigned int xid, down_read(&htable_rw_lock); ce = lookup_cache_entry(path); - if (!IS_ERR(ce) && !cache_entry_expired(ce)) + if (!IS_ERR(ce) && !force_refresh && !cache_entry_expired(ce)) return ce; /* @@ -800,7 +801,8 @@ static struct cache_entry *cache_refresh_path(const unsigned int xid, up_read(&htable_rw_lock); /* - * Either the entry was not found, or it is expired. + * Either the entry was not found, or it is expired, or it is a forced + * refresh. * Request a new DFS referral in order to create or update a cache entry. */ rc = get_dfs_referral(xid, ses, path, &refs, &numrefs); @@ -815,7 +817,7 @@ static struct cache_entry *cache_refresh_path(const unsigned int xid, /* Re-check as another task might have it added or refreshed already */ ce = lookup_cache_entry(path); if (!IS_ERR(ce)) { - if (cache_entry_expired(ce)) { + if (force_refresh || cache_entry_expired(ce)) { rc = update_cache_entry_locked(ce, refs, numrefs); if (rc) ce = ERR_PTR(rc); @@ -952,7 +954,7 @@ int dfs_cache_find(const unsigned int xid, struct cifs_ses *ses, const struct nl if (IS_ERR(npath)) return PTR_ERR(npath); - ce = cache_refresh_path(xid, ses, npath); + ce = cache_refresh_path(xid, ses, npath, false); if (IS_ERR(ce)) { rc = PTR_ERR(ce); goto out_free_path; @@ -1049,7 +1051,7 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses, cifs_dbg(FYI, "%s: update target hint - path: %s\n", __func__, npath); - ce = cache_refresh_path(xid, ses, npath); + ce = cache_refresh_path(xid, ses, npath, false); if (IS_ERR(ce)) { rc = PTR_ERR(ce); goto out_free_path; @@ -1327,35 +1329,37 @@ static bool target_share_equal(struct TCP_Server_Info *server, const char *s1, c * Mark dfs tcon for reconnecting when the currently connected tcon does not match any of the new * target shares in @refs. */ -static void mark_for_reconnect_if_needed(struct cifs_tcon *tcon, struct dfs_cache_tgt_list *tl, - const struct dfs_info3_param *refs, int numrefs) +static void mark_for_reconnect_if_needed(struct TCP_Server_Info *server, + struct dfs_cache_tgt_list *old_tl, + struct dfs_cache_tgt_list *new_tl) { - struct dfs_cache_tgt_iterator *it; - int i; + struct dfs_cache_tgt_iterator *oit, *nit; - for (it = dfs_cache_get_tgt_iterator(tl); it; it = dfs_cache_get_next_tgt(tl, it)) { - for (i = 0; i < numrefs; i++) { - if (target_share_equal(tcon->ses->server, dfs_cache_get_tgt_name(it), - refs[i].node_name)) + for (oit = dfs_cache_get_tgt_iterator(old_tl); oit; + oit = dfs_cache_get_next_tgt(old_tl, oit)) { + for (nit = dfs_cache_get_tgt_iterator(new_tl); nit; + nit = dfs_cache_get_next_tgt(new_tl, nit)) { + if (target_share_equal(server, + dfs_cache_get_tgt_name(oit), + dfs_cache_get_tgt_name(nit))) return; } } cifs_dbg(FYI, "%s: no cached or matched targets. mark dfs share for reconnect.\n", __func__); - cifs_signal_cifsd_for_reconnect(tcon->ses->server, true); + cifs_signal_cifsd_for_reconnect(server, true); } /* Refresh dfs referral of tcon and mark it for reconnect if needed */ static int __refresh_tcon(const char *path, struct cifs_tcon *tcon, bool force_refresh) { - struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT(tl); + struct dfs_cache_tgt_list old_tl = DFS_CACHE_TGT_LIST_INIT(old_tl); + struct dfs_cache_tgt_list new_tl = DFS_CACHE_TGT_LIST_INIT(new_tl); struct cifs_ses *ses = CIFS_DFS_ROOT_SES(tcon->ses); struct cifs_tcon *ipc = ses->tcon_ipc; - struct dfs_info3_param *refs = NULL; bool needs_refresh = false; struct cache_entry *ce; unsigned int xid; - int numrefs = 0; int rc = 0; xid = get_xid(); @@ -1364,9 +1368,8 @@ static int __refresh_tcon(const char *path, struct cifs_tcon *tcon, bool force_r ce = lookup_cache_entry(path); needs_refresh = force_refresh || IS_ERR(ce) || cache_entry_expired(ce); if (!IS_ERR(ce)) { - rc = get_targets(ce, &tl); - if (rc) - cifs_dbg(FYI, "%s: could not get dfs targets: %d\n", __func__, rc); + rc = get_targets(ce, &old_tl); + cifs_dbg(FYI, "%s: get_targets: %d\n", __func__, rc); } up_read(&htable_rw_lock); @@ -1383,26 +1386,18 @@ static int __refresh_tcon(const char *path, struct cifs_tcon *tcon, bool force_r } spin_unlock(&ipc->tc_lock); - rc = get_dfs_referral(xid, ses, path, &refs, &numrefs); - if (!rc) { - /* Create or update a cache entry with the new referral */ - dump_refs(refs, numrefs); - - down_write(&htable_rw_lock); - ce = lookup_cache_entry(path); - if (IS_ERR(ce)) - add_cache_entry_locked(refs, numrefs); - else if (force_refresh || cache_entry_expired(ce)) - update_cache_entry_locked(ce, refs, numrefs); - up_write(&htable_rw_lock); - - mark_for_reconnect_if_needed(tcon, &tl, refs, numrefs); + ce = cache_refresh_path(xid, ses, path, true); + if (!IS_ERR(ce)) { + rc = get_targets(ce, &new_tl); + up_read(&htable_rw_lock); + cifs_dbg(FYI, "%s: get_targets: %d\n", __func__, rc); + mark_for_reconnect_if_needed(tcon->ses->server, &old_tl, &new_tl); } out: free_xid(xid); - dfs_cache_free_tgts(&tl); - free_dfs_info_array(refs, numrefs); + dfs_cache_free_tgts(&old_tl); + dfs_cache_free_tgts(&new_tl); return rc; } From 3deddb77fdd932df92f3b6a27a9cffed82c4fe1a Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Tue, 17 Jan 2023 19:00:41 -0300 Subject: [PATCH 316/398] cifs: handle cache lookup errors different than -ENOENT lookup_cache_entry() might return an error different than -ENOENT (e.g. from ->char2uni), so handle those as well in cache_refresh_path(). Signed-off-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/dfs_cache.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index 58d11be9d020..308101d90006 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -644,7 +644,9 @@ static struct cache_entry *__lookup_cache_entry(const char *path, unsigned int h * * Use whole path components in the match. Must be called with htable_rw_lock held. * + * Return cached entry if successful. * Return ERR_PTR(-ENOENT) if the entry is not found. + * Return error ptr otherwise. */ static struct cache_entry *lookup_cache_entry(const char *path) { @@ -789,8 +791,13 @@ static struct cache_entry *cache_refresh_path(const unsigned int xid, down_read(&htable_rw_lock); ce = lookup_cache_entry(path); - if (!IS_ERR(ce) && !force_refresh && !cache_entry_expired(ce)) + if (!IS_ERR(ce)) { + if (!force_refresh && !cache_entry_expired(ce)) + return ce; + } else if (PTR_ERR(ce) != -ENOENT) { + up_read(&htable_rw_lock); return ce; + } /* * Unlock shared access as we don't want to hold any locks while getting @@ -822,7 +829,7 @@ static struct cache_entry *cache_refresh_path(const unsigned int xid, if (rc) ce = ERR_PTR(rc); } - } else { + } else if (PTR_ERR(ce) == -ENOENT) { ce = add_cache_entry_locked(refs, numrefs); } From 596b53ccc36a546ab28e8897315c5b4d1d5a0200 Mon Sep 17 00:00:00 2001 From: Liu Shixin Date: Tue, 22 Nov 2022 10:16:12 +0800 Subject: [PATCH 317/398] dmaengine: xilinx_dma: call of_node_put() when breaking out of for_each_child_of_node() Since for_each_child_of_node() will increase the refcount of node, we need to call of_node_put() manually when breaking out of the iteration. Fixes: 9cd4360de609 ("dma: Add Xilinx AXI Video Direct Memory Access Engine driver support") Signed-off-by: Liu Shixin Acked-by: Peter Korsgaard Link: https://lore.kernel.org/r/20221122021612.1908866-1-liushixin2@huawei.com Signed-off-by: Vinod Koul --- drivers/dma/xilinx/xilinx_dma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index a8d23cdf883e..ac09f0e5f58d 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -3143,8 +3143,10 @@ static int xilinx_dma_probe(struct platform_device *pdev) /* Initialize the channels */ for_each_child_of_node(node, child) { err = xilinx_dma_child_probe(xdev, child); - if (err < 0) + if (err < 0) { + of_node_put(child); goto error; + } } if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) { From a7a7ee6f5a019ad72852c001abbce50d35e992f2 Mon Sep 17 00:00:00 2001 From: Akhil R Date: Wed, 18 Jan 2023 17:28:01 +0530 Subject: [PATCH 318/398] dmaengine: tegra: Fix memory leak in terminate_all() Terminate vdesc when terminating an ongoing transfer. This will ensure that the vdesc is present in the desc_terminated list The descriptor will be freed later in desc_free_list(). This fixes the memory leaks which can happen when terminating an ongoing transfer. Fixes: ee17028009d4 ("dmaengine: tegra: Add tegra gpcdma driver") Signed-off-by: Akhil R Link: https://lore.kernel.org/r/20230118115801.15210-1-akhilrajeev@nvidia.com Signed-off-by: Vinod Koul --- drivers/dma/tegra186-gpc-dma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/dma/tegra186-gpc-dma.c b/drivers/dma/tegra186-gpc-dma.c index 1d1180db6d4e..8f67f453a492 100644 --- a/drivers/dma/tegra186-gpc-dma.c +++ b/drivers/dma/tegra186-gpc-dma.c @@ -711,6 +711,7 @@ static int tegra_dma_terminate_all(struct dma_chan *dc) return err; } + vchan_terminate_vdesc(&tdc->dma_desc->vd); tegra_dma_disable(tdc); tdc->dma_desc = NULL; } From ce38cb84c3e8d953f4e9beaa6ba270938242c72f Mon Sep 17 00:00:00 2001 From: Matt Atwood Date: Wed, 23 Nov 2022 10:36:47 -0800 Subject: [PATCH 319/398] drm/i915/dg2: Introduce Wa_18018764978 Wa_18018764978 applies to specific steppings of DG2 (G10 C0+, G11 and G12 A0+). Clean up style in function at the same time. Bspec: 66622 Signed-off-by: Matt Atwood Reviewed-by: Gustavo Sousa Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20221123183648.407058-1-matthew.s.atwood@intel.com (cherry picked from commit 468a4e630c7da8cf586f85cc498d6097aed1ab4b) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/intel_gt_regs.h | 3 +++ drivers/gpu/drm/i915/gt/intel_workarounds.c | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h index 4a14f87e441e..a7dc1c54785f 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h @@ -457,6 +457,9 @@ #define GEN8_L3CNTLREG _MMIO(0x7034) #define GEN8_ERRDETBCTRL (1 << 9) +#define PSS_MODE2 _MMIO(0x703c) +#define SCOREBOARD_STALL_FLUSH_CONTROL REG_BIT(5) + #define GEN7_SC_INSTDONE _MMIO(0x7100) #define GEN12_SC_INSTDONE_EXTRA _MMIO(0x7104) #define GEN12_SC_INSTDONE_EXTRA2 _MMIO(0x7108) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index 5be2f91801fb..c99a3e7ef878 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -771,9 +771,14 @@ static void dg2_ctx_workarounds_init(struct intel_engine_cs *engine, /* Wa_14014947963:dg2 */ if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_B0, STEP_FOREVER) || - IS_DG2_G11(engine->i915) || IS_DG2_G12(engine->i915)) + IS_DG2_G11(engine->i915) || IS_DG2_G12(engine->i915)) wa_masked_field_set(wal, VF_PREEMPTION, PREEMPTION_VERTEX_COUNT, 0x4000); + /* Wa_18018764978:dg2 */ + if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_C0, STEP_FOREVER) || + IS_DG2_G11(engine->i915) || IS_DG2_G12(engine->i915)) + wa_masked_en(wal, PSS_MODE2, SCOREBOARD_STALL_FLUSH_CONTROL); + /* Wa_15010599737:dg2 */ wa_mcr_masked_en(wal, CHICKEN_RASTER_1, DIS_SF_ROUND_NEAREST_EVEN); } From afdecb232740ae40b9384fa0ac8ed799d6546516 Mon Sep 17 00:00:00 2001 From: Matt Atwood Date: Wed, 23 Nov 2022 10:36:48 -0800 Subject: [PATCH 320/398] drm/i915/dg2: Introduce Wa_18019271663 Wa_18019271663 applies to all DG2 steppings and skus. Bspec: 66622 Signed-off-by: Matt Atwood Reviewed-by: Gustavo Sousa Signed-off-by: Matt Roper Link: https://patchwork.freedesktop.org/patch/msgid/20221123183648.407058-2-matthew.s.atwood@intel.com (cherry picked from commit 900a80c5836587d95db32742f66e1f34f7b40fcb) Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/gt/intel_gt_regs.h | 7 ++++--- drivers/gpu/drm/i915/gt/intel_workarounds.c | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h b/drivers/gpu/drm/i915/gt/intel_gt_regs.h index a7dc1c54785f..a5454af2a9cf 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h +++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h @@ -429,9 +429,10 @@ #define RC_OP_FLUSH_ENABLE (1 << 0) #define HIZ_RAW_STALL_OPT_DISABLE (1 << 2) #define CACHE_MODE_1 _MMIO(0x7004) /* IVB+ */ -#define PIXEL_SUBSPAN_COLLECT_OPT_DISABLE (1 << 6) -#define GEN8_4x4_STC_OPTIMIZATION_DISABLE (1 << 6) -#define GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE (1 << 1) +#define MSAA_OPTIMIZATION_REDUC_DISABLE REG_BIT(11) +#define PIXEL_SUBSPAN_COLLECT_OPT_DISABLE REG_BIT(6) +#define GEN8_4x4_STC_OPTIMIZATION_DISABLE REG_BIT(6) +#define GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE REG_BIT(1) #define GEN7_GT_MODE _MMIO(0x7008) #define GEN9_IZ_HASHING_MASK(slice) (0x3 << ((slice) * 2)) diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index c99a3e7ef878..949c19339015 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -781,6 +781,9 @@ static void dg2_ctx_workarounds_init(struct intel_engine_cs *engine, /* Wa_15010599737:dg2 */ wa_mcr_masked_en(wal, CHICKEN_RASTER_1, DIS_SF_ROUND_NEAREST_EVEN); + + /* Wa_18019271663:dg2 */ + wa_masked_en(wal, CACHE_MODE_1, MSAA_OPTIMIZATION_REDUC_DISABLE); } static void fakewa_disable_nestedbb_mode(struct intel_engine_cs *engine, From d6a49e8c4ca4d399ed65ac219585187fc8c2e2b1 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Wed, 18 Jan 2023 13:36:31 -0300 Subject: [PATCH 321/398] cifs: fix return of uninitialized rc in dfs_cache_update_tgthint() Fix this by initializing rc to 0 as cache_refresh_path() would not set it in case of success. Reported-by: kernel test robot Link: https://lore.kernel.org/all/202301190004.bEHvbKG6-lkp@intel.com/ Signed-off-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/dfs_cache.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index 308101d90006..e16c63997133 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -1047,10 +1047,10 @@ int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses, const struct nls_table *cp, int remap, const char *path, const struct dfs_cache_tgt_iterator *it) { - int rc; - const char *npath; - struct cache_entry *ce; struct cache_dfs_tgt *t; + struct cache_entry *ce; + const char *npath; + int rc = 0; npath = dfs_cache_canonical_path(path, cp, remap); if (IS_ERR(npath)) From e181119046a0ec16126b682163040e8e33f310c1 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Mon, 16 Jan 2023 21:19:03 +0100 Subject: [PATCH 322/398] dt-bindings: phy: g12a-usb3-pcie-phy: fix compatible string documentation The compatible string in the driver doesn't have the meson prefix. Fix this in the documentation and rename the file accordingly. Fixes: 87a55485f2fc ("dt-bindings: phy: meson-g12a-usb3-pcie-phy: convert to yaml") Cc: stable@vger.kernel.org Signed-off-by: Heiner Kallweit Reviewed-by: Martin Blumenstingl Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/0a82be92-ce85-da34-9d6f-4b33034473e5@gmail.com Signed-off-by: Vinod Koul --- ...a-usb3-pcie-phy.yaml => amlogic,g12a-usb3-pcie-phy.yaml} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename Documentation/devicetree/bindings/phy/{amlogic,meson-g12a-usb3-pcie-phy.yaml => amlogic,g12a-usb3-pcie-phy.yaml} (82%) diff --git a/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml similarity index 82% rename from Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml rename to Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml index 868b4e6fde71..129d26e99776 100644 --- a/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml +++ b/Documentation/devicetree/bindings/phy/amlogic,g12a-usb3-pcie-phy.yaml @@ -2,7 +2,7 @@ # Copyright 2019 BayLibre, SAS %YAML 1.2 --- -$id: "http://devicetree.org/schemas/phy/amlogic,meson-g12a-usb3-pcie-phy.yaml#" +$id: "http://devicetree.org/schemas/phy/amlogic,g12a-usb3-pcie-phy.yaml#" $schema: "http://devicetree.org/meta-schemas/core.yaml#" title: Amlogic G12A USB3 + PCIE Combo PHY @@ -13,7 +13,7 @@ maintainers: properties: compatible: enum: - - amlogic,meson-g12a-usb3-pcie-phy + - amlogic,g12a-usb3-pcie-phy reg: maxItems: 1 @@ -49,7 +49,7 @@ additionalProperties: false examples: - | phy@46000 { - compatible = "amlogic,meson-g12a-usb3-pcie-phy"; + compatible = "amlogic,g12a-usb3-pcie-phy"; reg = <0x46000 0x2000>; clocks = <&ref_clk>; clock-names = "ref_clk"; From c63835bf1c750c9b3aec1d5c23d811d6375fc23d Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Mon, 16 Jan 2023 21:17:39 +0100 Subject: [PATCH 323/398] dt-bindings: phy: g12a-usb2-phy: fix compatible string documentation The compatible strings in the driver don't have the meson prefix. Fix this in the documentation and rename the file accordingly. Fixes: da86d286cce8 ("dt-bindings: phy: meson-g12a-usb2-phy: convert to yaml") Cc: stable@vger.kernel.org Signed-off-by: Heiner Kallweit Reviewed-by: Martin Blumenstingl Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/8d960029-e94d-224b-911f-03e5deb47ebc@gmail.com Signed-off-by: Vinod Koul --- ...eson-g12a-usb2-phy.yaml => amlogic,g12a-usb2-phy.yaml} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename Documentation/devicetree/bindings/phy/{amlogic,meson-g12a-usb2-phy.yaml => amlogic,g12a-usb2-phy.yaml} (85%) diff --git a/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb2-phy.yaml b/Documentation/devicetree/bindings/phy/amlogic,g12a-usb2-phy.yaml similarity index 85% rename from Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb2-phy.yaml rename to Documentation/devicetree/bindings/phy/amlogic,g12a-usb2-phy.yaml index f3a5fbabbbb5..bb01c6b34dab 100644 --- a/Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/amlogic,g12a-usb2-phy.yaml @@ -2,7 +2,7 @@ # Copyright 2019 BayLibre, SAS %YAML 1.2 --- -$id: "http://devicetree.org/schemas/phy/amlogic,meson-g12a-usb2-phy.yaml#" +$id: "http://devicetree.org/schemas/phy/amlogic,g12a-usb2-phy.yaml#" $schema: "http://devicetree.org/meta-schemas/core.yaml#" title: Amlogic G12A USB2 PHY @@ -13,8 +13,8 @@ maintainers: properties: compatible: enum: - - amlogic,meson-g12a-usb2-phy - - amlogic,meson-a1-usb2-phy + - amlogic,g12a-usb2-phy + - amlogic,a1-usb2-phy reg: maxItems: 1 @@ -68,7 +68,7 @@ additionalProperties: false examples: - | phy@36000 { - compatible = "amlogic,meson-g12a-usb2-phy"; + compatible = "amlogic,g12a-usb2-phy"; reg = <0x36000 0x2000>; clocks = <&xtal>; clock-names = "xtal"; From bc30c15f275484f9b9fe27c2fa0895f3022d9943 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 18 Jan 2023 11:29:58 +0100 Subject: [PATCH 324/398] phy: phy-can-transceiver: Skip warning if no "max-bitrate" According to the DT bindings, the "max-bitrate" property is optional. However, when it is not present, a warning is printed. Fix this by adding a missing check for -EINVAL. Fixes: a4a86d273ff1b6f7 ("phy: phy-can-transceiver: Add support for generic CAN transceiver driver") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/88e158f97dd52ebaa7126cd9631f34764b9c0795.1674037334.git.geert+renesas@glider.be Signed-off-by: Vinod Koul --- drivers/phy/phy-can-transceiver.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/phy/phy-can-transceiver.c b/drivers/phy/phy-can-transceiver.c index 95c6dbb52da7..ce511ad5d369 100644 --- a/drivers/phy/phy-can-transceiver.c +++ b/drivers/phy/phy-can-transceiver.c @@ -99,6 +99,7 @@ static int can_transceiver_phy_probe(struct platform_device *pdev) struct gpio_desc *standby_gpio; struct gpio_desc *enable_gpio; u32 max_bitrate = 0; + int err; can_transceiver_phy = devm_kzalloc(dev, sizeof(struct can_transceiver_phy), GFP_KERNEL); if (!can_transceiver_phy) @@ -124,8 +125,8 @@ static int can_transceiver_phy_probe(struct platform_device *pdev) return PTR_ERR(phy); } - device_property_read_u32(dev, "max-bitrate", &max_bitrate); - if (!max_bitrate) + err = device_property_read_u32(dev, "max-bitrate", &max_bitrate); + if ((err != -EINVAL) && !max_bitrate) dev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit\n"); phy->attrs.max_link_rate = max_bitrate; From 2293a73ad4f3b6c37c06713ff1b67659d92ef43d Mon Sep 17 00:00:00 2001 From: Nirmoy Das Date: Wed, 18 Jan 2023 18:06:24 +0100 Subject: [PATCH 325/398] drm/i915: Remove unused variable Removed unused i915 var. Fixes: a273e95721e9 ("drm/i915: Allow switching away via vga-switcheroo if uninitialized") Signed-off-by: Nirmoy Das Reviewed-by: Rodrigo Vivi Signed-off-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20230118170624.9326-1-nirmoy.das@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/i915_driver.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index b5700681432d..61c38fc734cf 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1069,8 +1069,6 @@ static int i915_driver_open(struct drm_device *dev, struct drm_file *file) */ static void i915_driver_lastclose(struct drm_device *dev) { - struct drm_i915_private *i915 = to_i915(dev); - intel_fbdev_restore_mode(dev); vga_switcheroo_process_delayed_switch(); From 182da6f2b81a78709c58021542fb694f8ed80774 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Thu, 12 Jan 2023 14:33:19 +0100 Subject: [PATCH 326/398] ACPI: PRM: Check whether EFI runtime is available The ACPI PRM address space handler calls efi_call_virt_pointer() to execute PRM firmware code, but doing so is only permitted when the EFI runtime environment is available. Otherwise, such calls are guaranteed to result in a crash, and must therefore be avoided. Given that the EFI runtime services may become unavailable after a crash occurring in the firmware, we need to check this each time the PRM address space handler is invoked. If the EFI runtime services were not available at registration time to being with, don't install the address space handler at all. Fixes: cefc7ca46235 ("ACPI: PRM: implement OperationRegion handler for the PlatformRtMechanism subtype") Signed-off-by: Ard Biesheuvel Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/acpi/prmt.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c index 998101cf16e4..3d4c4620f9f9 100644 --- a/drivers/acpi/prmt.c +++ b/drivers/acpi/prmt.c @@ -236,6 +236,11 @@ static acpi_status acpi_platformrt_space_handler(u32 function, efi_status_t status; struct prm_context_buffer context; + if (!efi_enabled(EFI_RUNTIME_SERVICES)) { + pr_err_ratelimited("PRM: EFI runtime services no longer available\n"); + return AE_NO_HANDLER; + } + /* * The returned acpi_status will always be AE_OK. Error values will be * saved in the first byte of the PRM message buffer to be used by ASL. @@ -325,6 +330,11 @@ void __init init_prmt(void) pr_info("PRM: found %u modules\n", mc); + if (!efi_enabled(EFI_RUNTIME_SERVICES)) { + pr_err("PRM: EFI runtime services unavailable\n"); + return; + } + status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT, ACPI_ADR_SPACE_PLATFORM_RT, &acpi_platformrt_space_handler, From 30b2b2196d6e4cc24cbec633535a2404f258ce69 Mon Sep 17 00:00:00 2001 From: Enzo Matsumiya Date: Wed, 18 Jan 2023 14:06:57 -0300 Subject: [PATCH 327/398] cifs: do not include page data when checking signature On async reads, page data is allocated before sending. When the response is received but it has no data to fill (e.g. STATUS_END_OF_FILE), __calc_signature() will still include the pages in its computation, leading to an invalid signature check. This patch fixes this by not setting the async read smb_rqst page data (zeroed by default) if its got_bytes is 0. This can be reproduced/verified with xfstests generic/465. Cc: Signed-off-by: Enzo Matsumiya Reviewed-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/smb2pdu.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 4b71f4a92f76..2c9ffa921e6f 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -4163,12 +4163,15 @@ smb2_readv_callback(struct mid_q_entry *mid) (struct smb2_hdr *)rdata->iov[0].iov_base; struct cifs_credits credits = { .value = 0, .instance = 0 }; struct smb_rqst rqst = { .rq_iov = &rdata->iov[1], - .rq_nvec = 1, - .rq_pages = rdata->pages, - .rq_offset = rdata->page_offset, - .rq_npages = rdata->nr_pages, - .rq_pagesz = rdata->pagesz, - .rq_tailsz = rdata->tailsz }; + .rq_nvec = 1, }; + + if (rdata->got_bytes) { + rqst.rq_pages = rdata->pages; + rqst.rq_offset = rdata->page_offset; + rqst.rq_npages = rdata->nr_pages; + rqst.rq_pagesz = rdata->pagesz; + rqst.rq_tailsz = rdata->tailsz; + } WARN_ONCE(rdata->server != mid->server, "rdata server %p != mid server %p", From a1b7c8457ecc062f612a1aca174c2e1c21f9ac10 Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Wed, 18 Jan 2023 13:55:01 -0300 Subject: [PATCH 328/398] cifs: remove unused function Remove dfs_cache_update_tgthint() as it is not used anywhere. Signed-off-by: Paulo Alcantara (SUSE) Signed-off-by: Steve French --- fs/cifs/dfs_cache.c | 60 --------------------------------------------- fs/cifs/dfs_cache.h | 3 --- 2 files changed, 63 deletions(-) diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c index e16c63997133..ac86bd0ebd63 100644 --- a/fs/cifs/dfs_cache.c +++ b/fs/cifs/dfs_cache.c @@ -1025,66 +1025,6 @@ out_unlock: return rc; } -/** - * dfs_cache_update_tgthint - update target hint of a DFS cache entry - * - * If it doesn't find the cache entry, then it will get a DFS referral for @path - * and create a new entry. - * - * In case the cache entry exists but expired, it will get a DFS referral - * for @path and then update the respective cache entry. - * - * @xid: syscall id - * @ses: smb session - * @cp: codepage - * @remap: type of character remapping for paths - * @path: path to lookup in DFS referral cache - * @it: DFS target iterator - * - * Return zero if the target hint was updated successfully, otherwise non-zero. - */ -int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses, - const struct nls_table *cp, int remap, const char *path, - const struct dfs_cache_tgt_iterator *it) -{ - struct cache_dfs_tgt *t; - struct cache_entry *ce; - const char *npath; - int rc = 0; - - npath = dfs_cache_canonical_path(path, cp, remap); - if (IS_ERR(npath)) - return PTR_ERR(npath); - - cifs_dbg(FYI, "%s: update target hint - path: %s\n", __func__, npath); - - ce = cache_refresh_path(xid, ses, npath, false); - if (IS_ERR(ce)) { - rc = PTR_ERR(ce); - goto out_free_path; - } - - t = READ_ONCE(ce->tgthint); - - if (likely(!strcasecmp(it->it_name, t->name))) - goto out_unlock; - - list_for_each_entry(t, &ce->tlist, list) { - if (!strcasecmp(t->name, it->it_name)) { - WRITE_ONCE(ce->tgthint, t); - cifs_dbg(FYI, "%s: new target hint: %s\n", __func__, - it->it_name); - break; - } - } - -out_unlock: - up_read(&htable_rw_lock); -out_free_path: - kfree(npath); - return rc; -} - /** * dfs_cache_noreq_update_tgthint - update target hint of a DFS cache entry * without sending any requests to the currently connected server. diff --git a/fs/cifs/dfs_cache.h b/fs/cifs/dfs_cache.h index f7cff0be9327..be3b5a44cf82 100644 --- a/fs/cifs/dfs_cache.h +++ b/fs/cifs/dfs_cache.h @@ -35,9 +35,6 @@ int dfs_cache_find(const unsigned int xid, struct cifs_ses *ses, const struct nl struct dfs_cache_tgt_list *tgt_list); int dfs_cache_noreq_find(const char *path, struct dfs_info3_param *ref, struct dfs_cache_tgt_list *tgt_list); -int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses, - const struct nls_table *cp, int remap, const char *path, - const struct dfs_cache_tgt_iterator *it); void dfs_cache_noreq_update_tgthint(const char *path, const struct dfs_cache_tgt_iterator *it); int dfs_cache_get_tgt_referral(const char *path, const struct dfs_cache_tgt_iterator *it, struct dfs_info3_param *ref); From 040625ab82ce6dca7772cb3867fe5c9eb279a344 Mon Sep 17 00:00:00 2001 From: hongao Date: Tue, 22 Nov 2022 19:20:34 +0800 Subject: [PATCH 329/398] drm/amd/display: Fix set scaling doesn's work [Why] Setting scaling does not correctly update CRTC state. As a result dc stream state's src (composition area) && dest (addressable area) was not calculated as expected. This causes set scaling doesn's work. [How] Correctly update CRTC state when setting scaling property. Reviewed-by: Harry Wentland Tested-by: Rodrigo Siqueira Signed-off-by: hongao Signed-off-by: Rodrigo Siqueira Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 1b7f20a9d4ae..74f624ec55e7 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -9530,8 +9530,8 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, goto fail; } - if (dm_old_con_state->abm_level != - dm_new_con_state->abm_level) + if (dm_old_con_state->abm_level != dm_new_con_state->abm_level || + dm_old_con_state->scaling != dm_new_con_state->scaling) new_crtc_state->connectors_changed = true; } From c7bae4aaa5609c1fa9761c35dbcc5fcc92915222 Mon Sep 17 00:00:00 2001 From: jie1zhan Date: Fri, 13 Jan 2023 10:39:13 +0800 Subject: [PATCH 330/398] drm/amdgpu: Correct the power calcultion for Renior/Cezanne. From smu firmware,the value of power is transferred in units of watts. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2321 Fixes: 137aac26a2ed ("drm/amdgpu/smu12: fix power reporting on renoir") Acked-by: Alex Deucher Signed-off-by: Jesse Zhang Reviewed-by: Aaron Liu Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c index 85e22210963f..5cdc07165480 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -1171,6 +1171,7 @@ static int renoir_get_smu_metrics_data(struct smu_context *smu, int ret = 0; uint32_t apu_percent = 0; uint32_t dgpu_percent = 0; + struct amdgpu_device *adev = smu->adev; ret = smu_cmn_get_metrics_table(smu, @@ -1196,7 +1197,11 @@ static int renoir_get_smu_metrics_data(struct smu_context *smu, *value = metrics->AverageUvdActivity / 100; break; case METRICS_AVERAGE_SOCKETPOWER: - *value = (metrics->CurrentSocketPower << 8) / 1000; + if (((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 1)) && (adev->pm.fw_version >= 0x40000f)) || + ((adev->ip_versions[MP1_HWIP][0] == IP_VERSION(12, 0, 0)) && (adev->pm.fw_version >= 0x373200))) + *value = metrics->CurrentSocketPower << 8; + else + *value = (metrics->CurrentSocketPower << 8) / 1000; break; case METRICS_TEMPERATURE_EDGE: *value = (metrics->GfxTemperature / 100) * From 4463b1eea28ad733ca5cb53d89371132a57b1db3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 13 Jan 2023 17:32:45 +0100 Subject: [PATCH 331/398] drm/amdgpu: fix cleaning up reserved VMID on release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to reset this or otherwise run into list corruption later on. Fixes: e44a0fe630c5 ("drm/amdgpu: rework reserved VMID handling") Signed-off-by: Christian König Reviewed-by: Alex Deucher Tested-by: Candice Li Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c index fcb711a11a5b..3f07b1a2ce47 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c @@ -497,6 +497,7 @@ void amdgpu_vmid_free_reserved(struct amdgpu_device *adev, !--id_mgr->reserved_use_count) { /* give the reserved ID back to normal round robin */ list_add(&id_mgr->reserved->list, &id_mgr->ids_lru); + id_mgr->reserved = NULL; } vm->reserved_vmid[vmhub] = false; mutex_unlock(&id_mgr->lock); From 79601b894849cb6f6d6122e6590f1887ac4a66b3 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 10 Jan 2023 20:12:21 +0000 Subject: [PATCH 332/398] drm/amd/display: Calculate output_color_space after pixel encoding adjustment Code in get_output_color_space depends on knowing the pixel encoding to determine whether to pick between eg. COLOR_SPACE_SRGB or COLOR_SPACE_YCBCR709 for transparent RGB -> YCbCr 4:4:4 in the driver. v2: Fixed patch being accidentally based on a personal feature branch, oops! Fixes: ea117312ea9f ("drm/amd/display: Reduce HDMI pixel encoding if max clock is exceeded") Reviewed-by: Melissa Wen Signed-off-by: Joshua Ashton Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 74f624ec55e7..c994a5d8c3f5 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5311,8 +5311,6 @@ static void fill_stream_properties_from_drm_display_mode( timing_out->aspect_ratio = get_aspect_ratio(mode_in); - stream->output_color_space = get_output_color_space(timing_out); - stream->out_transfer_func->type = TF_TYPE_PREDEFINED; stream->out_transfer_func->tf = TRANSFER_FUNCTION_SRGB; if (stream->signal == SIGNAL_TYPE_HDMI_TYPE_A) { @@ -5323,6 +5321,8 @@ static void fill_stream_properties_from_drm_display_mode( adjust_colour_depth_from_display_info(timing_out, info); } } + + stream->output_color_space = get_output_color_space(timing_out); } static void fill_audio_info(struct audio_info *audio_info, From 973a9c810c785ac270a6d50d8cf862b0c1643a10 Mon Sep 17 00:00:00 2001 From: Joshua Ashton Date: Tue, 10 Jan 2023 22:50:42 +0000 Subject: [PATCH 333/398] drm/amd/display: Fix COLOR_SPACE_YCBCR2020_TYPE matrix The YCC conversion matrix for RGB -> COLOR_SPACE_YCBCR2020_TYPE is missing the values for the fourth column of the matrix. The fourth column of the matrix is essentially just a value that is added given that the color is 3 components in size. These values are needed to bias the chroma from the [-1, 1] -> [0, 1] range. This fixes color being very green when using Gamescope HDR on HDMI output which prefers YCC 4:4:4. Fixes: 40df2f809e8f ("drm/amd/display: color space ycbcr709 support") Reviewed-by: Melissa Wen Signed-off-by: Joshua Ashton Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c index 471078fc3900..652270a0b498 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c @@ -90,8 +90,8 @@ static const struct out_csc_color_matrix_type output_csc_matrix[] = { { 0xE00, 0xF349, 0xFEB7, 0x1000, 0x6CE, 0x16E3, 0x24F, 0x200, 0xFCCB, 0xF535, 0xE00, 0x1000} }, { COLOR_SPACE_YCBCR2020_TYPE, - { 0x1000, 0xF149, 0xFEB7, 0x0000, 0x0868, 0x15B2, - 0x01E6, 0x0000, 0xFB88, 0xF478, 0x1000, 0x0000} }, + { 0x1000, 0xF149, 0xFEB7, 0x1004, 0x0868, 0x15B2, + 0x01E6, 0x201, 0xFB88, 0xF478, 0x1000, 0x1004} }, { COLOR_SPACE_YCBCR709_BLACK_TYPE, { 0x0000, 0x0000, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x1000} }, From 74ea8e78ab349514c9f4df0be1189d91267d750d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 12 Jan 2023 14:46:00 +0100 Subject: [PATCH 334/398] drm/amdgpu: fix amdgpu_job_free_resources v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It can be that neither fence were initialized when we run out of UVD streams for example. v2: fix typo breaking compile Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2324 Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 6.1.x --- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 9e549923622b..c3d9d75143f4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -161,8 +161,14 @@ void amdgpu_job_free_resources(struct amdgpu_job *job) struct dma_fence *f; unsigned i; - /* use sched fence if available */ - f = job->base.s_fence ? &job->base.s_fence->finished : &job->hw_fence; + /* Check if any fences where initialized */ + if (job->base.s_fence && job->base.s_fence->finished.ops) + f = &job->base.s_fence->finished; + else if (job->hw_fence.ops) + f = &job->hw_fence; + else + f = NULL; + for (i = 0; i < job->num_ibs; ++i) amdgpu_ib_free(ring->adev, &job->ibs[i], f); } From e433adc60f7f847e734c56246b09291532f29b6d Mon Sep 17 00:00:00 2001 From: Hamza Mahfooz Date: Tue, 17 Jan 2023 15:12:49 -0500 Subject: [PATCH 335/398] drm/amd/display: fix issues with driver unload Currently, we run into a number of WARN()s when attempting to unload the amdgpu driver (e.g. using "modprobe -r amdgpu"). These all stem from calling drm_encoder_cleanup() too early. So, to fix this we can stop calling drm_encoder_cleanup() from amdgpu_dm_fini() and instead have it be called from amdgpu_dm_encoder_destroy(). Also, we don't need to free in amdgpu_dm_encoder_destroy() since mst_encoders[] isn't explicitly allocated by the slab allocator. Fixes: f74367e492ba ("drm/amdgpu/display: create fake mst encoders ahead of time (v4)") Reviewed-by: Alex Deucher Signed-off-by: Hamza Mahfooz Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ---- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 1 - 2 files changed, 5 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index c994a5d8c3f5..36483a1bf6e3 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1730,10 +1730,6 @@ static void amdgpu_dm_fini(struct amdgpu_device *adev) adev->dm.vblank_control_workqueue = NULL; } - for (i = 0; i < adev->dm.display_indexes_num; i++) { - drm_encoder_cleanup(&adev->dm.mst_encoders[i].base); - } - amdgpu_dm_destroy_drm_device(&adev->dm); #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 1edf7385f8d8..d7a044e79730 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -468,7 +468,6 @@ static const struct drm_connector_helper_funcs dm_dp_mst_connector_helper_funcs static void amdgpu_dm_encoder_destroy(struct drm_encoder *encoder) { drm_encoder_cleanup(encoder); - kfree(encoder); } static const struct drm_encoder_funcs amdgpu_dm_encoder_funcs = { From 0ddadc3a2208aedb1b27dbb76d0b4e722b5b527a Mon Sep 17 00:00:00 2001 From: Lang Yu Date: Wed, 11 Jan 2023 09:52:11 +0800 Subject: [PATCH 336/398] drm/amdgpu: correct MEC number for gfx11 APUs There is only one MEC on these APUs. Signed-off-by: Lang Yu Reviewed-by: Aaron Liu Reviewed-by: Yifan Zhang Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 6.1.x --- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index a56c6e106d00..b9b57a66e113 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -1287,10 +1287,8 @@ static int gfx_v11_0_sw_init(void *handle) switch (adev->ip_versions[GC_HWIP][0]) { case IP_VERSION(11, 0, 0): - case IP_VERSION(11, 0, 1): case IP_VERSION(11, 0, 2): case IP_VERSION(11, 0, 3): - case IP_VERSION(11, 0, 4): adev->gfx.me.num_me = 1; adev->gfx.me.num_pipe_per_me = 1; adev->gfx.me.num_queue_per_pipe = 1; @@ -1298,6 +1296,15 @@ static int gfx_v11_0_sw_init(void *handle) adev->gfx.mec.num_pipe_per_mec = 4; adev->gfx.mec.num_queue_per_pipe = 4; break; + case IP_VERSION(11, 0, 1): + case IP_VERSION(11, 0, 4): + adev->gfx.me.num_me = 1; + adev->gfx.me.num_pipe_per_me = 1; + adev->gfx.me.num_queue_per_pipe = 1; + adev->gfx.mec.num_mec = 1; + adev->gfx.mec.num_pipe_per_mec = 4; + adev->gfx.mec.num_queue_per_pipe = 4; + break; default: adev->gfx.me.num_me = 1; adev->gfx.me.num_pipe_per_me = 1; From dc88063b87775971be564d79dc1b05f7b8b5c135 Mon Sep 17 00:00:00 2001 From: Lang Yu Date: Wed, 11 Jan 2023 09:32:15 +0800 Subject: [PATCH 337/398] drm/amdgpu: allow multipipe policy on ASICs with one MEC Always enable multipipe policy on ASICs with GC VERSION > 9.0.0 instead of MEC number > 1. This will allow multipipe policy on ASICs with one MEC, e.g., gfx11 APUs. Signed-off-by: Lang Yu Reviewed-by: Aaron Liu Reviewed-by: Yifan Zhang Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 6.1.x --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index 23692e5d4d13..3380daf42da8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -156,6 +156,9 @@ static bool amdgpu_gfx_is_compute_multipipe_capable(struct amdgpu_device *adev) return amdgpu_compute_multipipe == 1; } + if (adev->ip_versions[GC_HWIP][0] > IP_VERSION(9, 0, 0)) + return true; + /* FIXME: spreading the queues across pipes causes perf regressions * on POLARIS11 compute workloads */ if (adev->asic_type == CHIP_POLARIS11) From e78cc6a4c7486f50c2786d91dd7d9649a87d1dcb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 18 Jan 2023 09:19:21 -0500 Subject: [PATCH 338/398] drm/amd/display: disable S/G display on DCN 3.1.5 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Causes flickering or white screens in some configurations. Disable it for now until we can fix the issue. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/2354 Cc: roman.li@amd.com Cc: yifan1.zhang@amd.com Acked-by: Christian König Reviewed-by: Yifan Zhang Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 6.1.x --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 36483a1bf6e3..649bdd5be951 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1504,7 +1504,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) case IP_VERSION(3, 1, 2): case IP_VERSION(3, 1, 3): case IP_VERSION(3, 1, 4): - case IP_VERSION(3, 1, 5): case IP_VERSION(3, 1, 6): init_data.flags.gpu_vm_support = true; break; From a52287d66dfa1cca32e6273623b63ba39d87f126 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 18 Jan 2023 09:21:22 -0500 Subject: [PATCH 339/398] drm/amd/display: disable S/G display on DCN 3.1.4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Causes flickering or white screens in some configurations. Disable it for now until we can fix the issue. Cc: roman.li@amd.com Cc: yifan1.zhang@amd.com Acked-by: Christian König Reviewed-by: Roman Li Reviewed-by: Yifan Zhang Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org # 6.1.x --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 649bdd5be951..4d42033a703f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -1503,7 +1503,6 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) case IP_VERSION(3, 0, 1): case IP_VERSION(3, 1, 2): case IP_VERSION(3, 1, 3): - case IP_VERSION(3, 1, 4): case IP_VERSION(3, 1, 6): init_data.flags.gpu_vm_support = true; break; From 339346d49ae0859fe19b860998867861d37f1a76 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 12 Jan 2023 20:41:37 -0800 Subject: [PATCH 340/398] net: sched: gred: prevent races when adding offloads to stats Naresh reports seeing a warning that gred is calling u64_stats_update_begin() with preemption enabled. Arnd points out it's coming from _bstats_update(). We should be holding the qdisc lock when writing to stats, they are also updated from the datapath. Reported-by: Linux Kernel Functional Testing Link: https://lore.kernel.org/all/CA+G9fYsTr9_r893+62u6UGD3dVaCE-kN9C-Apmb2m=hxjc1Cqg@mail.gmail.com/ Fixes: e49efd5288bd ("net: sched: gred: support reporting stats from offloads") Link: https://lore.kernel.org/r/20230113044137.1383067-1-kuba@kernel.org Signed-off-by: Jakub Kicinski --- net/sched/sch_gred.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index a661b062cca8..872d127c9db4 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -377,6 +377,7 @@ static int gred_offload_dump_stats(struct Qdisc *sch) /* Even if driver returns failure adjust the stats - in case offload * ended but driver still wants to adjust the values. */ + sch_tree_lock(sch); for (i = 0; i < MAX_DPs; i++) { if (!table->tab[i]) continue; @@ -393,6 +394,7 @@ static int gred_offload_dump_stats(struct Qdisc *sch) sch->qstats.overlimits += hw_stats->stats.qstats[i].overlimits; } _bstats_update(&sch->bstats, bytes, packets); + sch_tree_unlock(sch); kfree(hw_stats); return ret; From e0be11a833e8447f51f428b213c91a9b05601815 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Tue, 17 Jan 2023 11:01:41 -0800 Subject: [PATCH 341/398] MAINTAINERS: add networking entries for Willem We often have to ping Willem asking for reviews of patches because he doesn't get included in the CC list. Add MAINTAINERS entries for some of the areas he covers so that ./scripts/ will know to add him. Acked-by: Willem de Bruijn Link: https://lore.kernel.org/r/20230117190141.60795-1-kuba@kernel.org Signed-off-by: Jakub Kicinski --- MAINTAINERS | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e5c43cbffea7..180c18f936b7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15748,6 +15748,12 @@ S: Maintained W: https://wireless.wiki.kernel.org/en/users/Drivers/p54 F: drivers/net/wireless/intersil/p54/ +PACKET SOCKETS +M: Willem de Bruijn +S: Maintained +F: include/uapi/linux/if_packet.h +F: net/packet/af_packet.c + PACKING M: Vladimir Oltean L: netdev@vger.kernel.org @@ -19324,6 +19330,13 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Orphan F: sound/soc/uniphier/ +SOCKET TIMESTAMPING +M: Willem de Bruijn +S: Maintained +F: Documentation/networking/timestamping.rst +F: include/uapi/linux/net_tstamp.h +F: tools/testing/selftests/net/so_txtime.c + SOEKRIS NET48XX LED SUPPORT M: Chris Boot S: Maintained @@ -21744,6 +21757,13 @@ T: git git://linuxtv.org/media_tree.git F: Documentation/admin-guide/media/zr364xx* F: drivers/staging/media/deprecated/zr364xx/ +USER DATAGRAM PROTOCOL (UDP) +M: Willem de Bruijn +S: Maintained +F: include/linux/udp.h +F: net/ipv4/udp.c +F: net/ipv6/udp.c + USER-MODE LINUX (UML) M: Richard Weinberger M: Anton Ivanov From 4fb58ac3368c6058e61194ec047a5503059d90ae Mon Sep 17 00:00:00 2001 From: Xin Long Date: Tue, 17 Jan 2023 13:42:12 -0500 Subject: [PATCH 342/398] Revert "net: team: use IFF_NO_ADDRCONF flag to prevent ipv6 addrconf" This reverts commit 0aa64df30b382fc71d4fb1827d528e0eb3eff854. Currently IFF_NO_ADDRCONF is used to prevent all ipv6 addrconf for the slave ports of team, bonding and failover devices and it means no ipv6 packets can be sent out through these slave ports. However, for team device, "nsna_ping" link_watch requires ipv6 addrconf. Otherwise, the link will be marked failure. This patch removes the IFF_NO_ADDRCONF flag set for team port, and we will fix the original issue in another patch, as Jakub suggested. Fixes: 0aa64df30b38 ("net: team: use IFF_NO_ADDRCONF flag to prevent ipv6 addrconf") Signed-off-by: Xin Long Link: https://lore.kernel.org/r/63e09531fc47963d2e4eff376653d3db21b97058.1673980932.git.lucien.xin@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/team/team.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index fcd43d62d86b..d10606f257c4 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1044,7 +1044,6 @@ static int team_port_enter(struct team *team, struct team_port *port) goto err_port_enter; } } - port->dev->priv_flags |= IFF_NO_ADDRCONF; return 0; @@ -1058,7 +1057,6 @@ static void team_port_leave(struct team *team, struct team_port *port) { if (team->ops.port_leave) team->ops.port_leave(team, port); - port->dev->priv_flags &= ~IFF_NO_ADDRCONF; dev_put(team->dev); } From c06ba7b892a50b48522ad441a40053f483dfee9e Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Tue, 17 Jan 2023 19:25:00 +0100 Subject: [PATCH 343/398] nvme-apple: reset controller during shutdown This is a functional revert of c76b8308e4c9 ("nvme-apple: fix controller shutdown in apple_nvme_disable"). The commit broke suspend/resume since apple_nvme_reset_work() tries to disable the controller on resume. This does not work for the apple NVMe controller since register access only works while the co-processor firmware is running. Disabling the NVMe controller in the shutdown path is also required for shutting the co-processor down. The original code was appropriate for this hardware. Add a comment to prevent a similar breaking changes in the future. Fixes: c76b8308e4c9 ("nvme-apple: fix controller shutdown in apple_nvme_disable") Reported-by: Janne Grunau Link: https://lore.kernel.org/all/20230110174745.GA3576@jannau.net/ Signed-off-by: Janne Grunau [hch: updated with a more descriptive comment from Hector Martin] Signed-off-by: Christoph Hellwig --- drivers/nvme/host/apple.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c index bf1c60edb7f9..146c9e63ce77 100644 --- a/drivers/nvme/host/apple.c +++ b/drivers/nvme/host/apple.c @@ -829,7 +829,23 @@ static void apple_nvme_disable(struct apple_nvme *anv, bool shutdown) apple_nvme_remove_cq(anv); } - nvme_disable_ctrl(&anv->ctrl, shutdown); + /* + * Always disable the NVMe controller after shutdown. + * We need to do this to bring it back up later anyway, and we + * can't do it while the firmware is not running (e.g. in the + * resume reset path before RTKit is initialized), so for Apple + * controllers it makes sense to unconditionally do it here. + * Additionally, this sequence of events is reliable, while + * others (like disabling after bringing back the firmware on + * resume) seem to run into trouble under some circumstances. + * + * Both U-Boot and m1n1 also use this convention (i.e. an ANS + * NVMe controller is handed off with firmware shut down, in an + * NVMe disabled state, after a clean shutdown). + */ + if (shutdown) + nvme_disable_ctrl(&anv->ctrl, shutdown); + nvme_disable_ctrl(&anv->ctrl, false); } WRITE_ONCE(anv->ioq.enabled, false); From c0a4a1eafbd48e02829045bba3e6163c03037276 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Tue, 17 Jan 2023 19:25:01 +0100 Subject: [PATCH 344/398] nvme-apple: only reset the controller when RTKit is running NVMe controller register access hangs indefinitely when the co-processor is not running. A missed reset is preferable over a hanging thread since it could be recoverable. Signed-off-by: Janne Grunau Signed-off-by: Christoph Hellwig --- drivers/nvme/host/apple.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c index 146c9e63ce77..b317ce6c4ec3 100644 --- a/drivers/nvme/host/apple.c +++ b/drivers/nvme/host/apple.c @@ -1001,11 +1001,11 @@ static void apple_nvme_reset_work(struct work_struct *work) goto out; } - if (anv->ctrl.ctrl_config & NVME_CC_ENABLE) - apple_nvme_disable(anv, false); - /* RTKit must be shut down cleanly for the (soft)-reset to work */ if (apple_rtkit_is_running(anv->rtk)) { + /* reset the controller if it is enabled */ + if (anv->ctrl.ctrl_config & NVME_CC_ENABLE) + apple_nvme_disable(anv, false); dev_dbg(anv->dev, "Trying to shut down RTKit before reset."); ret = apple_rtkit_shutdown(anv->rtk); if (ret) From 1c5842085851f786eba24a39ecd02650ad892064 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 18 Jan 2023 08:44:16 -0800 Subject: [PATCH 345/398] nvme-pci: fix timeout request state check Polling the completion can progress the request state to IDLE, either inline with the completion, or through softirq. Either way, the state may not be COMPLETED, so don't check for that. We only care if the state isn't IN_FLIGHT. This is fixing an issue where the driver aborts an IO that we just completed. Seeing the "aborting" message instead of "polled" is very misleading as to where the timeout problem resides. Fixes: bf392a5dc02a9b ("nvme-pci: Remove tag from process cq") Signed-off-by: Keith Busch Signed-off-by: Christoph Hellwig --- drivers/nvme/host/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index a2553b7d9bb8..1ff8843bc4b3 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -1362,7 +1362,7 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req) else nvme_poll_irqdisable(nvmeq); - if (blk_mq_request_completed(req)) { + if (blk_mq_rq_state(req) != MQ_RQ_IN_FLIGHT) { dev_warn(dev->ctrl.device, "I/O %d QID %d timeout, completion polled\n", req->tag, nvmeq->qid); From 3f4ca5fafc08881d7a57daa20449d171f2887043 Mon Sep 17 00:00:00 2001 From: Jason Xing Date: Wed, 18 Jan 2023 09:59:41 +0800 Subject: [PATCH 346/398] tcp: avoid the lookup process failing to get sk in ehash table While one cpu is working on looking up the right socket from ehash table, another cpu is done deleting the request socket and is about to add (or is adding) the big socket from the table. It means that we could miss both of them, even though it has little chance. Let me draw a call trace map of the server side. CPU 0 CPU 1 ----- ----- tcp_v4_rcv() syn_recv_sock() inet_ehash_insert() -> sk_nulls_del_node_init_rcu(osk) __inet_lookup_established() -> __sk_nulls_add_node_rcu(sk, list) Notice that the CPU 0 is receiving the data after the final ack during 3-way shakehands and CPU 1 is still handling the final ack. Why could this be a real problem? This case is happening only when the final ack and the first data receiving by different CPUs. Then the server receiving data with ACK flag tries to search one proper established socket from ehash table, but apparently it fails as my map shows above. After that, the server fetches a listener socket and then sends a RST because it finds a ACK flag in the skb (data), which obeys RST definition in RFC 793. Besides, Eric pointed out there's one more race condition where it handles tw socket hashdance. Only by adding to the tail of the list before deleting the old one can we avoid the race if the reader has already begun the bucket traversal and it would possibly miss the head. Many thanks to Eric for great help from beginning to end. Fixes: 5e0724d027f0 ("tcp/dccp: fix hashdance race for passive sessions") Suggested-by: Eric Dumazet Signed-off-by: Jason Xing Reviewed-by: Eric Dumazet Reviewed-by: Kuniyuki Iwashima Link: https://lore.kernel.org/lkml/20230112065336.41034-1-kerneljasonxing@gmail.com/ Link: https://lore.kernel.org/r/20230118015941.1313-1-kerneljasonxing@gmail.com Signed-off-by: Paolo Abeni --- net/ipv4/inet_hashtables.c | 17 +++++++++++++++-- net/ipv4/inet_timewait_sock.c | 8 ++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 24a38b56fab9..f58d73888638 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -650,8 +650,20 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) spin_lock(lock); if (osk) { WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); - ret = sk_nulls_del_node_init_rcu(osk); - } else if (found_dup_sk) { + ret = sk_hashed(osk); + if (ret) { + /* Before deleting the node, we insert a new one to make + * sure that the look-up-sk process would not miss either + * of them and that at least one node would exist in ehash + * table all the time. Otherwise there's a tiny chance + * that lookup process could find nothing in ehash table. + */ + __sk_nulls_add_node_tail_rcu(sk, list); + sk_nulls_del_node_init_rcu(osk); + } + goto unlock; + } + if (found_dup_sk) { *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); if (*found_dup_sk) ret = false; @@ -660,6 +672,7 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) if (ret) __sk_nulls_add_node_rcu(sk, list); +unlock: spin_unlock(lock); return ret; diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index 1d77d992e6e7..beed32fff484 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c @@ -91,10 +91,10 @@ void inet_twsk_put(struct inet_timewait_sock *tw) } EXPORT_SYMBOL_GPL(inet_twsk_put); -static void inet_twsk_add_node_rcu(struct inet_timewait_sock *tw, - struct hlist_nulls_head *list) +static void inet_twsk_add_node_tail_rcu(struct inet_timewait_sock *tw, + struct hlist_nulls_head *list) { - hlist_nulls_add_head_rcu(&tw->tw_node, list); + hlist_nulls_add_tail_rcu(&tw->tw_node, list); } static void inet_twsk_add_bind_node(struct inet_timewait_sock *tw, @@ -147,7 +147,7 @@ void inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, spin_lock(lock); - inet_twsk_add_node_rcu(tw, &ehead->chain); + inet_twsk_add_node_tail_rcu(tw, &ehead->chain); /* Step 3: Remove SK from hash chain */ if (__sk_nulls_del_node_init_rcu(sk)) From 55ba18dc62deff5910c0fa64486dea1ff20832ff Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Wed, 18 Jan 2023 15:13:00 +0800 Subject: [PATCH 347/398] octeontx2-pf: Fix the use of GFP_KERNEL in atomic context on rt The commit 4af1b64f80fb ("octeontx2-pf: Fix lmtst ID used in aura free") uses the get/put_cpu() to protect the usage of percpu pointer in ->aura_freeptr() callback, but it also unnecessarily disable the preemption for the blockable memory allocation. The commit 87b93b678e95 ("octeontx2-pf: Avoid use of GFP_KERNEL in atomic context") tried to fix these sleep inside atomic warnings. But it only fix the one for the non-rt kernel. For the rt kernel, we still get the similar warnings like below. BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:46 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1, name: swapper/0 preempt_count: 1, expected: 0 RCU nest depth: 0, expected: 0 3 locks held by swapper/0/1: #0: ffff800009fc5fe8 (rtnl_mutex){+.+.}-{3:3}, at: rtnl_lock+0x24/0x30 #1: ffff000100c276c0 (&mbox->lock){+.+.}-{3:3}, at: otx2_init_hw_resources+0x8c/0x3a4 #2: ffffffbfef6537e0 (&cpu_rcache->lock){+.+.}-{2:2}, at: alloc_iova_fast+0x1ac/0x2ac Preemption disabled at: [] otx2_rq_aura_pool_init+0x14c/0x284 CPU: 20 PID: 1 Comm: swapper/0 Tainted: G W 6.2.0-rc3-rt1-yocto-preempt-rt #1 Hardware name: Marvell OcteonTX CN96XX board (DT) Call trace: dump_backtrace.part.0+0xe8/0xf4 show_stack+0x20/0x30 dump_stack_lvl+0x9c/0xd8 dump_stack+0x18/0x34 __might_resched+0x188/0x224 rt_spin_lock+0x64/0x110 alloc_iova_fast+0x1ac/0x2ac iommu_dma_alloc_iova+0xd4/0x110 __iommu_dma_map+0x80/0x144 iommu_dma_map_page+0xe8/0x260 dma_map_page_attrs+0xb4/0xc0 __otx2_alloc_rbuf+0x90/0x150 otx2_rq_aura_pool_init+0x1c8/0x284 otx2_init_hw_resources+0xe4/0x3a4 otx2_open+0xf0/0x610 __dev_open+0x104/0x224 __dev_change_flags+0x1e4/0x274 dev_change_flags+0x2c/0x7c ic_open_devs+0x124/0x2f8 ip_auto_config+0x180/0x42c do_one_initcall+0x90/0x4dc do_basic_setup+0x10c/0x14c kernel_init_freeable+0x10c/0x13c kernel_init+0x2c/0x140 ret_from_fork+0x10/0x20 Of course, we can shuffle the get/put_cpu() to only wrap the invocation of ->aura_freeptr() as what commit 87b93b678e95 does. But there are only two ->aura_freeptr() callbacks, otx2_aura_freeptr() and cn10k_aura_freeptr(). There is no usage of perpcu variable in the otx2_aura_freeptr() at all, so the get/put_cpu() seems redundant to it. We can move the get/put_cpu() into the corresponding callback which really has the percpu variable usage and avoid the sprinkling of get/put_cpu() in several places. Fixes: 4af1b64f80fb ("octeontx2-pf: Fix lmtst ID used in aura free") Signed-off-by: Kevin Hao Link: https://lore.kernel.org/r/20230118071300.3271125-1-haokexin@gmail.com Signed-off-by: Paolo Abeni --- .../net/ethernet/marvell/octeontx2/nic/otx2_common.c | 11 ++--------- .../net/ethernet/marvell/octeontx2/nic/otx2_common.h | 2 ++ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c index 497b777b6a34..8a41ad8ca04f 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c @@ -1012,7 +1012,6 @@ static void otx2_pool_refill_task(struct work_struct *work) rbpool = cq->rbpool; free_ptrs = cq->pool_ptrs; - get_cpu(); while (cq->pool_ptrs) { if (otx2_alloc_rbuf(pfvf, rbpool, &bufptr)) { /* Schedule a WQ if we fails to free atleast half of the @@ -1032,7 +1031,6 @@ static void otx2_pool_refill_task(struct work_struct *work) pfvf->hw_ops->aura_freeptr(pfvf, qidx, bufptr + OTX2_HEAD_ROOM); cq->pool_ptrs--; } - put_cpu(); cq->refill_task_sched = false; } @@ -1387,9 +1385,7 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf) err = otx2_alloc_rbuf(pfvf, pool, &bufptr); if (err) goto err_mem; - get_cpu(); pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr); - put_cpu(); sq->sqb_ptrs[sq->sqb_count++] = (u64)bufptr; } } @@ -1435,21 +1431,18 @@ int otx2_rq_aura_pool_init(struct otx2_nic *pfvf) if (err) goto fail; - get_cpu(); /* Allocate pointers and free them to aura/pool */ for (pool_id = 0; pool_id < hw->rqpool_cnt; pool_id++) { pool = &pfvf->qset.pool[pool_id]; for (ptr = 0; ptr < num_ptrs; ptr++) { err = otx2_alloc_rbuf(pfvf, pool, &bufptr); if (err) - goto err_mem; + return -ENOMEM; pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr + OTX2_HEAD_ROOM); } } -err_mem: - put_cpu(); - return err ? -ENOMEM : 0; + return 0; fail: otx2_mbox_reset(&pfvf->mbox.mbox, 0); otx2_aura_pool_free(pfvf); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h index 5bee3c3a7ce4..3d22cc6a2804 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h @@ -736,8 +736,10 @@ static inline void cn10k_aura_freeptr(void *dev, int aura, u64 buf) u64 ptrs[2]; ptrs[1] = buf; + get_cpu(); /* Free only one buffer at time during init and teardown */ __cn10k_aura_freeptr(pfvf, aura, ptrs, 2); + put_cpu(); } /* Alloc pointer from pool/aura */ From 7d80dbd708c18c683dd34f79b600a05307707ce8 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 18 Jan 2023 10:01:41 +0100 Subject: [PATCH 348/398] usb: dwc3: fix extcon dependency The dwc3 core support now links against the extcon subsystem, so it cannot be built-in when extcon is a loadable module: arm-linux-gnueabi-ld: drivers/usb/dwc3/core.o: in function `dwc3_get_extcon': core.c:(.text+0x572): undefined reference to `extcon_get_edev_by_phandle' arm-linux-gnueabi-ld: core.c:(.text+0x596): undefined reference to `extcon_get_extcon_dev' arm-linux-gnueabi-ld: core.c:(.text+0x5ea): undefined reference to `extcon_find_edev_by_node' There was already a Kconfig dependency in the dual-role support, but this is now needed for the entire dwc3 driver. It is still possible to build dwc3 without extcon, but this prevents it from being set to built-in when extcon is a loadable module. Fixes: d182c2e1bc92 ("usb: dwc3: Don't switch OTG -> peripheral if extcon is present") Signed-off-by: Arnd Bergmann Reviewed-by: Andy Shevchenko Acked-by: Thinh Nguyen Link: https://lore.kernel.org/r/20230118090147.2126563-1-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index b2f72b0e75c6..be954a9abbe0 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -3,6 +3,7 @@ config USB_DWC3 tristate "DesignWare USB3 DRD Core Support" depends on (USB || USB_GADGET) && HAS_DMA + depends on (EXTCON || EXTCON=n) select USB_XHCI_PLATFORM if USB_XHCI_HCD select USB_ROLE_SWITCH if USB_DWC3_DUAL_ROLE help @@ -44,7 +45,6 @@ config USB_DWC3_GADGET config USB_DWC3_DUAL_ROLE bool "Dual Role mode" depends on ((USB=y || USB=USB_DWC3) && (USB_GADGET=y || USB_GADGET=USB_DWC3)) - depends on (EXTCON=y || EXTCON=USB_DWC3) help This is the default mode of working of DWC3 controller where both host and gadget features are enabled. From 95e5fda3b5f9ed8239b145da3fa01e641cf5d53c Mon Sep 17 00:00:00 2001 From: Eric Pilmore Date: Wed, 18 Jan 2023 19:39:08 -0800 Subject: [PATCH 349/398] ptdma: pt_core_execute_cmd() should use spinlock The interrupt handler (pt_core_irq_handler()) of the ptdma driver can be called from interrupt context. The code flow in this function can lead down to pt_core_execute_cmd() which will attempt to grab a mutex, which is not appropriate in interrupt context and ultimately leads to a kernel panic. The fix here changes this mutex to a spinlock, which has been verified to resolve the issue. Fixes: fa5d823b16a9 ("dmaengine: ptdma: Initial driver for the AMD PTDMA") Signed-off-by: Eric Pilmore Link: https://lore.kernel.org/r/20230119033907.35071-1-epilmore@gigaio.com Signed-off-by: Vinod Koul --- drivers/dma/ptdma/ptdma-dev.c | 7 ++++--- drivers/dma/ptdma/ptdma.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/dma/ptdma/ptdma-dev.c b/drivers/dma/ptdma/ptdma-dev.c index 377da23012ac..a2bf13ff18b6 100644 --- a/drivers/dma/ptdma/ptdma-dev.c +++ b/drivers/dma/ptdma/ptdma-dev.c @@ -71,12 +71,13 @@ static int pt_core_execute_cmd(struct ptdma_desc *desc, struct pt_cmd_queue *cmd bool soc = FIELD_GET(DWORD0_SOC, desc->dw0); u8 *q_desc = (u8 *)&cmd_q->qbase[cmd_q->qidx]; u32 tail; + unsigned long flags; if (soc) { desc->dw0 |= FIELD_PREP(DWORD0_IOC, desc->dw0); desc->dw0 &= ~DWORD0_SOC; } - mutex_lock(&cmd_q->q_mutex); + spin_lock_irqsave(&cmd_q->q_lock, flags); /* Copy 32-byte command descriptor to hw queue. */ memcpy(q_desc, desc, 32); @@ -91,7 +92,7 @@ static int pt_core_execute_cmd(struct ptdma_desc *desc, struct pt_cmd_queue *cmd /* Turn the queue back on using our cached control register */ pt_start_queue(cmd_q); - mutex_unlock(&cmd_q->q_mutex); + spin_unlock_irqrestore(&cmd_q->q_lock, flags); return 0; } @@ -199,7 +200,7 @@ int pt_core_init(struct pt_device *pt) cmd_q->pt = pt; cmd_q->dma_pool = dma_pool; - mutex_init(&cmd_q->q_mutex); + spin_lock_init(&cmd_q->q_lock); /* Page alignment satisfies our needs for N <= 128 */ cmd_q->qsize = Q_SIZE(Q_DESC_SIZE); diff --git a/drivers/dma/ptdma/ptdma.h b/drivers/dma/ptdma/ptdma.h index d093c43b7d13..21b4bf895200 100644 --- a/drivers/dma/ptdma/ptdma.h +++ b/drivers/dma/ptdma/ptdma.h @@ -196,7 +196,7 @@ struct pt_cmd_queue { struct ptdma_desc *qbase; /* Aligned queue start address (per requirement) */ - struct mutex q_mutex ____cacheline_aligned; + spinlock_t q_lock ____cacheline_aligned; unsigned int qidx; unsigned int qsize; From 39af728649b05e88a2b40e714feeee6451c3f18e Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Wed, 23 Nov 2022 10:25:42 +0800 Subject: [PATCH 350/398] device property: fix of node refcount leak in fwnode_graph_get_next_endpoint() The 'parent' returned by fwnode_graph_get_port_parent() with refcount incremented when 'prev' is not NULL, it needs be put when finish using it. Because the parent is const, introduce a new variable to store the returned fwnode, then put it before returning from fwnode_graph_get_next_endpoint(). Fixes: b5b41ab6b0c1 ("device property: Check fwnode->secondary in fwnode_graph_get_next_endpoint()") Signed-off-by: Yang Yingliang Reviewed-by: Sakari Ailus Reviewed-by: Andy Shevchenko Reviewed-and-tested-by: Daniel Scally Link: https://lore.kernel.org/r/20221123022542.2999510-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/property.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/base/property.c b/drivers/base/property.c index bbb3e499ff4a..083a95791d3b 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -997,26 +997,32 @@ struct fwnode_handle * fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode, struct fwnode_handle *prev) { + struct fwnode_handle *ep, *port_parent = NULL; const struct fwnode_handle *parent; - struct fwnode_handle *ep; /* * If this function is in a loop and the previous iteration returned * an endpoint from fwnode->secondary, then we need to use the secondary * as parent rather than @fwnode. */ - if (prev) - parent = fwnode_graph_get_port_parent(prev); - else + if (prev) { + port_parent = fwnode_graph_get_port_parent(prev); + parent = port_parent; + } else { parent = fwnode; + } if (IS_ERR_OR_NULL(parent)) return NULL; ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev); if (ep) - return ep; + goto out_put_port_parent; - return fwnode_graph_get_next_endpoint(parent->secondary, NULL); + ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL); + +out_put_port_parent: + fwnode_handle_put(port_parent); + return ep; } EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint); From b8caf69a6946e18ffebad49847e258f5b6d52ac2 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 21 Dec 2022 17:40:22 +0100 Subject: [PATCH 351/398] tty: serial: qcom-geni-serial: fix slab-out-of-bounds on RX FIFO buffer Driver's probe allocates memory for RX FIFO (port->rx_fifo) based on default RX FIFO depth, e.g. 16. Later during serial startup the qcom_geni_serial_port_setup() updates the RX FIFO depth (port->rx_fifo_depth) to match real device capabilities, e.g. to 32. The RX UART handle code will read "port->rx_fifo_depth" number of words into "port->rx_fifo" buffer, thus exceeding the bounds. This can be observed in certain configurations with Qualcomm Bluetooth HCI UART device and KASAN: Bluetooth: hci0: QCA Product ID :0x00000010 Bluetooth: hci0: QCA SOC Version :0x400a0200 Bluetooth: hci0: QCA ROM Version :0x00000200 Bluetooth: hci0: QCA Patch Version:0x00000d2b Bluetooth: hci0: QCA controller version 0x02000200 Bluetooth: hci0: QCA Downloading qca/htbtfw20.tlv bluetooth hci0: Direct firmware load for qca/htbtfw20.tlv failed with error -2 Bluetooth: hci0: QCA Failed to request file: qca/htbtfw20.tlv (-2) Bluetooth: hci0: QCA Failed to download patch (-2) ================================================================== BUG: KASAN: slab-out-of-bounds in handle_rx_uart+0xa8/0x18c Write of size 4 at addr ffff279347d578c0 by task swapper/0/0 CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.1.0-rt5-00350-gb2450b7e00be-dirty #26 Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) Call trace: dump_backtrace.part.0+0xe0/0xf0 show_stack+0x18/0x40 dump_stack_lvl+0x8c/0xb8 print_report+0x188/0x488 kasan_report+0xb4/0x100 __asan_store4+0x80/0xa4 handle_rx_uart+0xa8/0x18c qcom_geni_serial_handle_rx+0x84/0x9c qcom_geni_serial_isr+0x24c/0x760 __handle_irq_event_percpu+0x108/0x500 handle_irq_event+0x6c/0x110 handle_fasteoi_irq+0x138/0x2cc generic_handle_domain_irq+0x48/0x64 If the RX FIFO depth changes after probe, be sure to resize the buffer. Fixes: f9d690b6ece7 ("tty: serial: qcom_geni_serial: Allocate port->rx_fifo buffer in probe") Cc: Signed-off-by: Krzysztof Kozlowski Reviewed-by: Jiri Slaby Link: https://lore.kernel.org/r/20221221164022.1087814-1-krzysztof.kozlowski@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index b487823f0e61..49b9ffeae676 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -864,9 +864,10 @@ out_unlock: return IRQ_HANDLED; } -static void get_tx_fifo_size(struct qcom_geni_serial_port *port) +static int setup_fifos(struct qcom_geni_serial_port *port) { struct uart_port *uport; + u32 old_rx_fifo_depth = port->rx_fifo_depth; uport = &port->uport; port->tx_fifo_depth = geni_se_get_tx_fifo_depth(&port->se); @@ -874,6 +875,16 @@ static void get_tx_fifo_size(struct qcom_geni_serial_port *port) port->rx_fifo_depth = geni_se_get_rx_fifo_depth(&port->se); uport->fifosize = (port->tx_fifo_depth * port->tx_fifo_width) / BITS_PER_BYTE; + + if (port->rx_fifo && (old_rx_fifo_depth != port->rx_fifo_depth) && port->rx_fifo_depth) { + port->rx_fifo = devm_krealloc(uport->dev, port->rx_fifo, + port->rx_fifo_depth * sizeof(u32), + GFP_KERNEL); + if (!port->rx_fifo) + return -ENOMEM; + } + + return 0; } @@ -888,6 +899,7 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) u32 rxstale = DEFAULT_BITS_PER_CHAR * STALE_TIMEOUT; u32 proto; u32 pin_swap; + int ret; proto = geni_se_read_proto(&port->se); if (proto != GENI_SE_UART) { @@ -897,7 +909,9 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) qcom_geni_serial_stop_rx(uport); - get_tx_fifo_size(port); + ret = setup_fifos(port); + if (ret) + return ret; writel(rxstale, uport->membase + SE_UART_RX_STALE_CNT); From e8914b52e5b024e4af3d810a935fe0805eee8a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Tue, 3 Jan 2023 11:34:35 +0200 Subject: [PATCH 352/398] serial: pch_uart: Pass correct sg to dma_unmap_sg() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A local variable sg is used to store scatterlist pointer in pch_dma_tx_complete(). The for loop doing Tx byte accounting before dma_unmap_sg() alters sg in its increment statement. Therefore, the pointer passed into dma_unmap_sg() won't match to the one given to dma_map_sg(). To fix the problem, use priv->sg_tx_p directly in dma_unmap_sg() instead of the local variable. Fixes: da3564ee027e ("pch_uart: add multi-scatter processing") Cc: stable@vger.kernel.org Signed-off-by: Ilpo Järvinen Link: https://lore.kernel.org/r/20230103093435.4396-1-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/pch_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 3d54a43768cd..9576ba8bbc40 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -749,7 +749,7 @@ static void pch_dma_tx_complete(void *arg) uart_xmit_advance(port, sg_dma_len(sg)); async_tx_ack(priv->desc_tx); - dma_unmap_sg(port->dev, sg, priv->orig_nent, DMA_TO_DEVICE); + dma_unmap_sg(port->dev, priv->sg_tx_p, priv->orig_nent, DMA_TO_DEVICE); priv->tx_dma_use = 0; priv->nent = 0; priv->orig_nent = 0; From 4f39aca2360c82dccd2f5179d77e94aab665bea6 Mon Sep 17 00:00:00 2001 From: Lino Sanfilippo Date: Sun, 8 Jan 2023 19:17:35 +0100 Subject: [PATCH 353/398] serial: amba-pl011: fix high priority character transmission in rs486 mode In RS485 mode the transmission of a high priority character fails since it is written to the data register before the transmitter is enabled. Fix this in pl011_tx_chars() by enabling RS485 transmission before writing the character. Fixes: 8d479237727c ("serial: amba-pl011: add RS485 support") Cc: stable@vger.kernel.org Signed-off-by: Lino Sanfilippo Link: https://lore.kernel.org/r/20230108181735.10937-1-LinoSanfilippo@gmx.de Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/amba-pl011.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d75c39f4622b..d8c2f3455eeb 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c @@ -1466,6 +1466,10 @@ static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) struct circ_buf *xmit = &uap->port.state->xmit; int count = uap->fifosize >> 1; + if ((uap->port.rs485.flags & SER_RS485_ENABLED) && + !uap->rs485_tx_started) + pl011_rs485_tx_start(uap); + if (uap->port.x_char) { if (!pl011_tx_char(uap, uap->port.x_char, from_irq)) return true; @@ -1477,10 +1481,6 @@ static bool pl011_tx_chars(struct uart_amba_port *uap, bool from_irq) return false; } - if ((uap->port.rs485.flags & SER_RS485_ENABLED) && - !uap->rs485_tx_started) - pl011_rs485_tx_start(uap); - /* If we are using DMA mode, try to send some characters. */ if (pl011_dma_tx_irq(uap)) return true; From f24771b62a83239f0dce816bddf0f6807f436235 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Thu, 12 Jan 2023 19:04:17 +0100 Subject: [PATCH 354/398] serial: stm32: Merge hard IRQ and threaded IRQ handling into single IRQ handler Requesting an interrupt with IRQF_ONESHOT will run the primary handler in the hard-IRQ context even in the force-threaded mode. The force-threaded mode is used by PREEMPT_RT in order to avoid acquiring sleeping locks (spinlock_t) in hard-IRQ context. This combination makes it impossible and leads to "sleeping while atomic" warnings. Use one interrupt handler for both handlers (primary and secondary) and drop the IRQF_ONESHOT flag which is not needed. Fixes: e359b4411c283 ("serial: stm32: fix threaded interrupt handling") Reviewed-by: Sebastian Andrzej Siewior Tested-by: Valentin Caron # V3 Signed-off-by: Marek Vasut Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20230112180417.25595-1-marex@denx.de Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index a1490033aa16..1e24bee2b0ef 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -797,23 +797,9 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) spin_unlock(&port->lock); } - if (stm32_usart_rx_dma_enabled(port)) - return IRQ_WAKE_THREAD; - else - return IRQ_HANDLED; -} - -static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr) -{ - struct uart_port *port = ptr; - struct tty_port *tport = &port->state->port; - struct stm32_port *stm32_port = to_stm32_port(port); - unsigned int size; - unsigned long flags; - /* Receiver timeout irq for DMA RX */ - if (!stm32_port->throttled) { - spin_lock_irqsave(&port->lock, flags); + if (stm32_usart_rx_dma_enabled(port) && !stm32_port->throttled) { + spin_lock(&port->lock); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq_irqrestore(port, flags); if (size) @@ -1015,10 +1001,8 @@ static int stm32_usart_startup(struct uart_port *port) u32 val; int ret; - ret = request_threaded_irq(port->irq, stm32_usart_interrupt, - stm32_usart_threaded_interrupt, - IRQF_ONESHOT | IRQF_NO_SUSPEND, - name, port); + ret = request_irq(port->irq, stm32_usart_interrupt, + IRQF_NO_SUSPEND, name, port); if (ret) return ret; @@ -1601,13 +1585,6 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, struct dma_slave_config config; int ret; - /* - * Using DMA and threaded handler for the console could lead to - * deadlocks. - */ - if (uart_console(port)) - return -ENODEV; - stm32port->rx_buf = dma_alloc_coherent(dev, RX_BUF_L, &stm32port->rx_dma_buf, GFP_KERNEL); From 5abbeebd8296c2301023b8dc4b5a6c0d5229b4f5 Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Fri, 2 Dec 2022 14:06:33 +0800 Subject: [PATCH 355/398] tty: fix possible null-ptr-defer in spk_ttyio_release Run the following tests on the qemu platform: syzkaller:~# modprobe speakup_audptr input: Speakup as /devices/virtual/input/input4 initialized device: /dev/synth, node (MAJOR 10, MINOR 125) speakup 3.1.6: initialized synth name on entry is: (null) synth probe spk_ttyio_initialise_ldisc failed because tty_kopen_exclusive returned failed (errno -16), then remove the module, we will get a null-ptr-defer problem, as follow: syzkaller:~# modprobe -r speakup_audptr releasing synth audptr BUG: kernel NULL pointer dereference, address: 0000000000000080 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page PGD 0 P4D 0 Oops: 0002 [#1] PREEMPT SMP PTI CPU: 2 PID: 204 Comm: modprobe Not tainted 6.1.0-rc6-dirty #1 RIP: 0010:mutex_lock+0x14/0x30 Call Trace: spk_ttyio_release+0x19/0x70 [speakup] synth_release.part.6+0xac/0xc0 [speakup] synth_remove+0x56/0x60 [speakup] __x64_sys_delete_module+0x156/0x250 ? fpregs_assert_state_consistent+0x1d/0x50 do_syscall_64+0x37/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd Modules linked in: speakup_audptr(-) speakup Dumping ftrace buffer: in_synth->dev was not initialized during modprobe, so we add check for in_synth->dev to fix this bug. Fixes: 4f2a81f3a882 ("speakup: Reference synth from tty and tty from synth") Cc: stable Signed-off-by: Gaosheng Cui Link: https://lore.kernel.org/r/20221202060633.217364-1-cuigaosheng1@huawei.com Reviewed-by: Samuel Thibault Signed-off-by: Greg Kroah-Hartman --- drivers/accessibility/speakup/spk_ttyio.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/accessibility/speakup/spk_ttyio.c b/drivers/accessibility/speakup/spk_ttyio.c index 08cf8a17754b..07373b3debd1 100644 --- a/drivers/accessibility/speakup/spk_ttyio.c +++ b/drivers/accessibility/speakup/spk_ttyio.c @@ -354,6 +354,9 @@ void spk_ttyio_release(struct spk_synth *in_synth) { struct tty_struct *tty = in_synth->dev; + if (tty == NULL) + return; + tty_lock(tty); if (tty->ops->close) From 5bfdd3c654bd879bff50c2e85e42f85ae698b42f Mon Sep 17 00:00:00 2001 From: Tobias Schramm Date: Mon, 9 Jan 2023 08:29:40 +0100 Subject: [PATCH 356/398] serial: atmel: fix incorrect baudrate setup Commit ba47f97a18f2 ("serial: core: remove baud_rates when serial console setup") changed uart_set_options to select the correct baudrate configuration based on the absolute error between requested baudrate and available standard baudrate settings. Prior to that commit the baudrate was selected based on which predefined standard baudrate did not exceed the requested baudrate. This change of selection logic was never reflected in the atmel serial driver. Thus the comment left in the atmel serial driver is no longer accurate. Additionally the manual rounding up described in that comment and applied via (quot - 1) requests an incorrect baudrate. Since uart_set_options uses tty_termios_encode_baud_rate to determine the appropriate baudrate flags this can cause baudrate selection to fail entirely because tty_termios_encode_baud_rate will only select a baudrate if relative error between requested and selected baudrate does not exceed +/-2%. Fix that by requesting actual, exact baudrate used by the serial. Fixes: ba47f97a18f2 ("serial: core: remove baud_rates when serial console setup") Cc: stable Signed-off-by: Tobias Schramm Acked-by: Richard Genoud Link: https://lore.kernel.org/r/20230109072940.202936-1-t.schramm@manjaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index f1c06e12efa0..9cd7479b03c0 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -2657,13 +2657,7 @@ static void __init atmel_console_get_options(struct uart_port *port, int *baud, else if (mr == ATMEL_US_PAR_ODD) *parity = 'o'; - /* - * The serial core only rounds down when matching this to a - * supported baud rate. Make sure we don't end up slightly - * lower than one of those, as it would make us fall through - * to a much lower baud rate than we really want. - */ - *baud = port->uartclk / (16 * (quot - 1)); + *baud = port->uartclk / (16 * quot); } static int __init atmel_console_setup(struct console *co, char *options) From 5342ab0af45064cbdc773645b93ab70c24ee161f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 15 Dec 2022 17:54:24 +0100 Subject: [PATCH 357/398] tty: serial: qcom_geni: avoid duplicate struct member init When -Woverride-init is enabled in a build, gcc points out that qcom_geni_serial_pm_ops contains conflicting initializers: drivers/tty/serial/qcom_geni_serial.c:1586:20: error: initialized field overwritten [-Werror=override-init] 1586 | .restore = qcom_geni_serial_sys_hib_resume, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/tty/serial/qcom_geni_serial.c:1586:20: note: (near initialization for 'qcom_geni_serial_pm_ops.restore') drivers/tty/serial/qcom_geni_serial.c:1587:17: error: initialized field overwritten [-Werror=override-init] 1587 | .thaw = qcom_geni_serial_sys_hib_resume, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Open-code the initializers with the version that was already used, and use the pm_sleep_ptr() method to deal with unused ones, in place of the __maybe_unused annotation. Fixes: 35781d8356a2 ("tty: serial: qcom-geni-serial: Add support for Hibernation feature") Signed-off-by: Arnd Bergmann Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/20221215165453.1864836-1-arnd@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/qcom_geni_serial.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 49b9ffeae676..57f04f8bf504 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1530,7 +1530,7 @@ static int qcom_geni_serial_remove(struct platform_device *pdev) return 0; } -static int __maybe_unused qcom_geni_serial_sys_suspend(struct device *dev) +static int qcom_geni_serial_sys_suspend(struct device *dev) { struct qcom_geni_serial_port *port = dev_get_drvdata(dev); struct uart_port *uport = &port->uport; @@ -1547,7 +1547,7 @@ static int __maybe_unused qcom_geni_serial_sys_suspend(struct device *dev) return uart_suspend_port(private_data->drv, uport); } -static int __maybe_unused qcom_geni_serial_sys_resume(struct device *dev) +static int qcom_geni_serial_sys_resume(struct device *dev) { int ret; struct qcom_geni_serial_port *port = dev_get_drvdata(dev); @@ -1595,10 +1595,12 @@ static int qcom_geni_serial_sys_hib_resume(struct device *dev) } static const struct dev_pm_ops qcom_geni_serial_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_sys_suspend, - qcom_geni_serial_sys_resume) - .restore = qcom_geni_serial_sys_hib_resume, - .thaw = qcom_geni_serial_sys_hib_resume, + .suspend = pm_sleep_ptr(qcom_geni_serial_sys_suspend), + .resume = pm_sleep_ptr(qcom_geni_serial_sys_resume), + .freeze = pm_sleep_ptr(qcom_geni_serial_sys_suspend), + .poweroff = pm_sleep_ptr(qcom_geni_serial_sys_suspend), + .restore = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume), + .thaw = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume), }; static const struct of_device_id qcom_geni_serial_match_table[] = { From 423d5081d0451faa59a707e57373801da5b40141 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 19 Jan 2023 09:01:27 -0700 Subject: [PATCH 358/398] io_uring/msg_ring: move double lock/unlock helpers higher up In preparation for needing them somewhere else, move them and get rid of the unused 'issue_flags' for the unlock side. No functional changes in this patch. Signed-off-by: Jens Axboe --- io_uring/msg_ring.c | 47 ++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c index 2d3cd945a531..321f5eafef99 100644 --- a/io_uring/msg_ring.c +++ b/io_uring/msg_ring.c @@ -25,6 +25,28 @@ struct io_msg { u32 flags; }; +static void io_double_unlock_ctx(struct io_ring_ctx *octx) +{ + mutex_unlock(&octx->uring_lock); +} + +static int io_double_lock_ctx(struct io_ring_ctx *octx, + unsigned int issue_flags) +{ + /* + * To ensure proper ordering between the two ctxs, we can only + * attempt a trylock on the target. If that fails and we already have + * the source ctx lock, punt to io-wq. + */ + if (!(issue_flags & IO_URING_F_UNLOCKED)) { + if (!mutex_trylock(&octx->uring_lock)) + return -EAGAIN; + return 0; + } + mutex_lock(&octx->uring_lock); + return 0; +} + void io_msg_ring_cleanup(struct io_kiocb *req) { struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); @@ -77,29 +99,6 @@ static int io_msg_ring_data(struct io_kiocb *req) return -EOVERFLOW; } -static void io_double_unlock_ctx(struct io_ring_ctx *octx, - unsigned int issue_flags) -{ - mutex_unlock(&octx->uring_lock); -} - -static int io_double_lock_ctx(struct io_ring_ctx *octx, - unsigned int issue_flags) -{ - /* - * To ensure proper ordering between the two ctxs, we can only - * attempt a trylock on the target. If that fails and we already have - * the source ctx lock, punt to io-wq. - */ - if (!(issue_flags & IO_URING_F_UNLOCKED)) { - if (!mutex_trylock(&octx->uring_lock)) - return -EAGAIN; - return 0; - } - mutex_lock(&octx->uring_lock); - return 0; -} - static struct file *io_msg_grab_file(struct io_kiocb *req, unsigned int issue_flags) { struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); @@ -148,7 +147,7 @@ static int io_msg_install_complete(struct io_kiocb *req, unsigned int issue_flag if (!io_post_aux_cqe(target_ctx, msg->user_data, msg->len, 0)) ret = -EOVERFLOW; out_unlock: - io_double_unlock_ctx(target_ctx, issue_flags); + io_double_unlock_ctx(target_ctx); return ret; } From 2efb6edd52dc50273f5e68ad863dd1b1fb2f2d1c Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 3 Jan 2023 14:37:54 +0000 Subject: [PATCH 359/398] comedi: adv_pci1760: Fix PWM instruction handling (Actually, this is fixing the "Read the Current Status" command sent to the device's outgoing mailbox, but it is only currently used for the PWM instructions.) The PCI-1760 is operated mostly by sending commands to a set of Outgoing Mailbox registers, waiting for the command to complete, and reading the result from the Incoming Mailbox registers. One of these commands is the "Read the Current Status" command. The number of this command is 0x07 (see the User's Manual for the PCI-1760 at . The `PCI1760_CMD_GET_STATUS` macro defined in the driver should expand to this command number 0x07, but unfortunately it currently expands to 0x03. (Command number 0x03 is not defined in the User's Manual.) Correct the definition of the `PCI1760_CMD_GET_STATUS` macro to fix it. This is used by all the PWM subdevice related instructions handled by `pci1760_pwm_insn_config()` which are probably all broken. The effect of sending the undefined command number 0x03 is not known. Fixes: 14b93bb6bbf0 ("staging: comedi: adv_pci_dio: separate out PCI-1760 support") Cc: # v4.5+ Signed-off-by: Ian Abbott Link: https://lore.kernel.org/r/20230103143754.17564-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman --- drivers/comedi/drivers/adv_pci1760.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/comedi/drivers/adv_pci1760.c b/drivers/comedi/drivers/adv_pci1760.c index fcfc2e299110..27f3890f471d 100644 --- a/drivers/comedi/drivers/adv_pci1760.c +++ b/drivers/comedi/drivers/adv_pci1760.c @@ -58,7 +58,7 @@ #define PCI1760_CMD_CLR_IMB2 0x00 /* Clears IMB2 */ #define PCI1760_CMD_SET_DO 0x01 /* Set output state */ #define PCI1760_CMD_GET_DO 0x02 /* Read output status */ -#define PCI1760_CMD_GET_STATUS 0x03 /* Read current status */ +#define PCI1760_CMD_GET_STATUS 0x07 /* Read current status */ #define PCI1760_CMD_GET_FW_VER 0x0e /* Read firmware version */ #define PCI1760_CMD_GET_HW_VER 0x0f /* Read hardware version */ #define PCI1760_CMD_SET_PWM_HI(x) (0x10 + (x) * 2) /* Set "hi" period */ From 25d5648802f12ae486076ceca5d7ddf1fef792b2 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 5 Dec 2022 16:04:34 +0800 Subject: [PATCH 360/398] w1: fix deadloop in __w1_remove_master_device() I got a deadloop report while doing device(ds2482) add/remove test: [ 162.241881] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1. [ 163.272251] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1. [ 164.296157] w1_master_driver w1_bus_master1: Waiting for w1_bus_master1 to become free: refcnt=1. ... __w1_remove_master_device() can't return, because the dev->refcnt is not zero. w1_add_master_device() | w1_alloc_dev() | atomic_set(&dev->refcnt, 2) | kthread_run() | |__w1_remove_master_device() | kthread_stop() // KTHREAD_SHOULD_STOP is set, | // threadfn(w1_process) won't be | // called. | kthread() | | // refcnt will never be 0, it's deadloop. | while (atomic_read(&dev->refcnt)) {...} After calling w1_add_master_device(), w1_process() is not really invoked, before w1_process() starting, if kthread_stop() is called in __w1_remove_master_device(), w1_process() will never be called, the refcnt can not be decreased, then it causes deadloop in remove function because of non-zero refcnt. We need to make sure w1_process() is really started, so move the set refcnt into w1_process() to fix this problem. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221205080434.3149205-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/w1/w1.c | 2 ++ drivers/w1/w1_int.c | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index f2ae2e563dc5..8b35fae4cd61 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -1166,6 +1166,8 @@ int w1_process(void *data) /* remainder if it woke up early */ unsigned long jremain = 0; + atomic_inc(&dev->refcnt); + for (;;) { if (!jremain && dev->search_count) { diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index b3e1792d9c49..3a71c5eb2f83 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c @@ -51,10 +51,9 @@ static struct w1_master *w1_alloc_dev(u32 id, int slave_count, int slave_ttl, dev->search_count = w1_search_count; dev->enable_pullup = w1_enable_pullup; - /* 1 for w1_process to decrement - * 1 for __w1_remove_master_device to decrement + /* For __w1_remove_master_device to decrement */ - atomic_set(&dev->refcnt, 2); + atomic_set(&dev->refcnt, 1); INIT_LIST_HEAD(&dev->slist); INIT_LIST_HEAD(&dev->async_list); From 36225a7c72e9e3e1ce4001b6ce72849f5c9a2d3b Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Mon, 5 Dec 2022 18:15:58 +0800 Subject: [PATCH 361/398] w1: fix WARNING after calling w1_process() I got the following WARNING message while removing driver(ds2482): ------------[ cut here ]------------ do not call blocking ops when !TASK_RUNNING; state=1 set at [<000000002d50bfb6>] w1_process+0x9e/0x1d0 [wire] WARNING: CPU: 0 PID: 262 at kernel/sched/core.c:9817 __might_sleep+0x98/0xa0 CPU: 0 PID: 262 Comm: w1_bus_master1 Tainted: G N 6.1.0-rc3+ #307 RIP: 0010:__might_sleep+0x98/0xa0 Call Trace: exit_signals+0x6c/0x550 do_exit+0x2b4/0x17e0 kthread_exit+0x52/0x60 kthread+0x16d/0x1e0 ret_from_fork+0x1f/0x30 The state of task is set to TASK_INTERRUPTIBLE in loop in w1_process(), set it to TASK_RUNNING when it breaks out of the loop to avoid the warning. Fixes: 3c52e4e62789 ("W1: w1_process, block or sleep") Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20221205101558.3599162-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/w1/w1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 8b35fae4cd61..4a2ddf730a3a 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -1195,8 +1195,10 @@ int w1_process(void *data) */ mutex_unlock(&dev->list_mutex); - if (kthread_should_stop()) + if (kthread_should_stop()) { + __set_current_state(TASK_RUNNING); break; + } /* Only sleep when the search is active. */ if (dev->search_count) { From 9be182da0a7526f1b9a3777a336f83baa2e64d23 Mon Sep 17 00:00:00 2001 From: Chen Zhongjin Date: Fri, 25 Nov 2022 14:35:41 +0800 Subject: [PATCH 362/398] driver core: Fix test_async_probe_init saves device in wrong array In test_async_probe_init, second set of asynchronous devices are saved in sync_dev[sync_id], which should be async_dev[async_id]. This makes these devices not unregistered when exit. > modprobe test_async_driver_probe && \ > modprobe -r test_async_driver_probe && \ > modprobe test_async_driver_probe ... > sysfs: cannot create duplicate filename '/devices/platform/test_async_driver.4' > kobject_add_internal failed for test_async_driver.4 with -EEXIST, don't try to register things with the same name in the same directory. Fixes: 57ea974fb871 ("driver core: Rewrite test_async_driver_probe to cover serialization and NUMA affinity") Signed-off-by: Chen Zhongjin Link: https://lore.kernel.org/r/20221125063541.241328-1-chenzhongjin@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/base/test/test_async_driver_probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/test/test_async_driver_probe.c b/drivers/base/test/test_async_driver_probe.c index 4d1976ca5072..929410d0dd6f 100644 --- a/drivers/base/test/test_async_driver_probe.c +++ b/drivers/base/test/test_async_driver_probe.c @@ -145,7 +145,7 @@ static int __init test_async_probe_init(void) calltime = ktime_get(); for_each_online_cpu(cpu) { nid = cpu_to_node(cpu); - pdev = &sync_dev[sync_id]; + pdev = &async_dev[async_id]; *pdev = test_platform_device_register_node("test_async_driver", async_id, From 8ccc99362b60c6f27bb46f36fdaaccf4ef0303de Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Wed, 18 Jan 2023 13:24:12 +0100 Subject: [PATCH 363/398] net/ulp: use consistent error code when blocking ULP The referenced commit changed the error code returned by the kernel when preventing a non-established socket from attaching the ktls ULP. Before to such a commit, the user-space got ENOTCONN instead of EINVAL. The existing self-tests depend on such error code, and the change caused a failure: RUN global.non_established ... tls.c:1673:non_established:Expected errno (22) == ENOTCONN (107) non_established: Test failed at step #3 FAIL global.non_established In the unlikely event existing applications do the same, address the issue by restoring the prior error code in the above scenario. Note that the only other ULP performing similar checks at init time - smc_ulp_ops - also fails with ENOTCONN when trying to attach the ULP to a non-established socket. Reported-by: Sabrina Dubroca Fixes: 2c02d41d71f9 ("net/ulp: prevent ULP without clone op from entering the LISTEN status") Signed-off-by: Paolo Abeni Reviewed-by: Sabrina Dubroca Link: https://lore.kernel.org/r/7bb199e7a93317fb6f8bf8b9b2dc71c18f337cde.1674042685.git.pabeni@redhat.com Signed-off-by: Jakub Kicinski --- net/ipv4/tcp_ulp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_ulp.c b/net/ipv4/tcp_ulp.c index 05b6077b9f2c..2aa442128630 100644 --- a/net/ipv4/tcp_ulp.c +++ b/net/ipv4/tcp_ulp.c @@ -139,7 +139,7 @@ static int __tcp_set_ulp(struct sock *sk, const struct tcp_ulp_ops *ulp_ops) if (sk->sk_socket) clear_bit(SOCK_SUPPORT_ZC, &sk->sk_socket->flags); - err = -EINVAL; + err = -ENOTCONN; if (!ulp_ops->clone && sk->sk_state == TCP_LISTEN) goto out_err; From 903848249a781d76d59561d51676c95b3a4d7162 Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Wed, 18 Jan 2023 10:18:47 -0500 Subject: [PATCH 364/398] selftests/net: toeplitz: fix race on tpacket_v3 block close Avoid race between process wakeup and tpacket_v3 block timeout. The test waits for cfg_timeout_msec for packets to arrive. Packets arrive in tpacket_v3 rings, which pass packets ("frames") to the process in batches ("blocks"). The sk waits for req3.tp_retire_blk_tov msec to release a block. Set the block timeout lower than the process waiting time, else the process may find that no block has been released by the time it scans the socket list. Convert to a ring of more than one, smaller, blocks with shorter timeouts. Blocks must be page aligned, so >= 64KB. Fixes: 5ebfb4cc3048 ("selftests/net: toeplitz test") Signed-off-by: Willem de Bruijn Link: https://lore.kernel.org/r/20230118151847.4124260-1-willemdebruijn.kernel@gmail.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/toeplitz.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/net/toeplitz.c b/tools/testing/selftests/net/toeplitz.c index 90026a27eac0..9ba03164d73a 100644 --- a/tools/testing/selftests/net/toeplitz.c +++ b/tools/testing/selftests/net/toeplitz.c @@ -215,7 +215,7 @@ static char *recv_frame(const struct ring_state *ring, char *frame) } /* A single TPACKET_V3 block can hold multiple frames */ -static void recv_block(struct ring_state *ring) +static bool recv_block(struct ring_state *ring) { struct tpacket_block_desc *block; char *frame; @@ -223,7 +223,7 @@ static void recv_block(struct ring_state *ring) block = (void *)(ring->mmap + ring->idx * ring_block_sz); if (!(block->hdr.bh1.block_status & TP_STATUS_USER)) - return; + return false; frame = (char *)block; frame += block->hdr.bh1.offset_to_first_pkt; @@ -235,6 +235,8 @@ static void recv_block(struct ring_state *ring) block->hdr.bh1.block_status = TP_STATUS_KERNEL; ring->idx = (ring->idx + 1) % ring_block_nr; + + return true; } /* simple test: sleep once unconditionally and then process all rings */ @@ -245,7 +247,7 @@ static void process_rings(void) usleep(1000 * cfg_timeout_msec); for (i = 0; i < num_cpus; i++) - recv_block(&rings[i]); + do {} while (recv_block(&rings[i])); fprintf(stderr, "count: pass=%u nohash=%u fail=%u\n", frames_received - frames_nohash - frames_error, @@ -257,12 +259,12 @@ static char *setup_ring(int fd) struct tpacket_req3 req3 = {0}; void *ring; - req3.tp_retire_blk_tov = cfg_timeout_msec; + req3.tp_retire_blk_tov = cfg_timeout_msec / 8; req3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH; req3.tp_frame_size = 2048; req3.tp_frame_nr = 1 << 10; - req3.tp_block_nr = 2; + req3.tp_block_nr = 16; req3.tp_block_size = req3.tp_frame_size * req3.tp_frame_nr; req3.tp_block_size /= req3.tp_block_nr; From 6c977c5c2e4c5d8ad1b604724cc344e38f96fe9b Mon Sep 17 00:00:00 2001 From: Rakesh Sankaranarayanan Date: Wed, 18 Jan 2023 23:17:35 +0530 Subject: [PATCH 365/398] net: dsa: microchip: ksz9477: port map correction in ALU table entry register ALU table entry 2 register in KSZ9477 have bit positions reserved for forwarding port map. This field is referred in ksz9477_fdb_del() for clearing forward port map and alu table. But current fdb_del refer ALU table entry 3 register for accessing forward port map. Update ksz9477_fdb_del() to get forward port map from correct alu table entry register. With this bug, issue can be observed while deleting static MAC entries. Delete any specific MAC entry using "bridge fdb del" command. This should clear all the specified MAC entries. But it is observed that entries with self static alone are retained. Tested on LAN9370 EVB since ksz9477_fdb_del() is used common across LAN937x and KSZ series. Fixes: b987e98e50ab ("dsa: add DSA switch driver for Microchip KSZ9477") Signed-off-by: Rakesh Sankaranarayanan Reviewed-by: Vladimir Oltean Link: https://lore.kernel.org/r/20230118174735.702377-1-rakesh.sankaranarayanan@microchip.com Signed-off-by: Jakub Kicinski --- drivers/net/dsa/microchip/ksz9477.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index 47b54ecf2c6f..6178a96e389f 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -540,10 +540,10 @@ int ksz9477_fdb_del(struct ksz_device *dev, int port, ksz_read32(dev, REG_SW_ALU_VAL_D, &alu_table[3]); /* clear forwarding port */ - alu_table[2] &= ~BIT(port); + alu_table[1] &= ~BIT(port); /* if there is no port to forward, clear table */ - if ((alu_table[2] & ALU_V_PORT_MAP) == 0) { + if ((alu_table[1] & ALU_V_PORT_MAP) == 0) { alu_table[0] = 0; alu_table[1] = 0; alu_table[2] = 0; From e12d7a46f65ae4b7d58a5e0c1cbfa825cf8d830d Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 19 Jan 2023 09:04:40 -0700 Subject: [PATCH 366/398] io_uring/msg_ring: fix missing lock on overflow for IOPOLL If the target ring is configured with IOPOLL, then we always need to hold the target ring uring_lock before posting CQEs. We could just grab it unconditionally, but since we don't expect many target rings to be of this type, make grabbing the uring_lock conditional on the ring type. Link: https://lore.kernel.org/io-uring/Y8krlYa52%2F0YGqkg@ip-172-31-85-199.ec2.internal/ Reported-by: Xingyuan Mo Signed-off-by: Jens Axboe --- io_uring/msg_ring.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c index 321f5eafef99..a333781565d3 100644 --- a/io_uring/msg_ring.c +++ b/io_uring/msg_ring.c @@ -65,20 +65,33 @@ static void io_msg_tw_complete(struct callback_head *head) struct io_ring_ctx *target_ctx = req->file->private_data; int ret = 0; - if (current->flags & PF_EXITING) + if (current->flags & PF_EXITING) { ret = -EOWNERDEAD; - else if (!io_post_aux_cqe(target_ctx, msg->user_data, msg->len, 0)) - ret = -EOVERFLOW; + } else { + /* + * If the target ring is using IOPOLL mode, then we need to be + * holding the uring_lock for posting completions. Other ring + * types rely on the regular completion locking, which is + * handled while posting. + */ + if (target_ctx->flags & IORING_SETUP_IOPOLL) + mutex_lock(&target_ctx->uring_lock); + if (!io_post_aux_cqe(target_ctx, msg->user_data, msg->len, 0)) + ret = -EOVERFLOW; + if (target_ctx->flags & IORING_SETUP_IOPOLL) + mutex_unlock(&target_ctx->uring_lock); + } if (ret < 0) req_set_fail(req); io_req_queue_tw_complete(req, ret); } -static int io_msg_ring_data(struct io_kiocb *req) +static int io_msg_ring_data(struct io_kiocb *req, unsigned int issue_flags) { struct io_ring_ctx *target_ctx = req->file->private_data; struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); + int ret; if (msg->src_fd || msg->dst_fd || msg->flags) return -EINVAL; @@ -93,10 +106,18 @@ static int io_msg_ring_data(struct io_kiocb *req) return IOU_ISSUE_SKIP_COMPLETE; } - if (io_post_aux_cqe(target_ctx, msg->user_data, msg->len, 0)) - return 0; - - return -EOVERFLOW; + ret = -EOVERFLOW; + if (target_ctx->flags & IORING_SETUP_IOPOLL) { + if (unlikely(io_double_lock_ctx(target_ctx, issue_flags))) + return -EAGAIN; + if (io_post_aux_cqe(target_ctx, msg->user_data, msg->len, 0)) + ret = 0; + io_double_unlock_ctx(target_ctx); + } else { + if (io_post_aux_cqe(target_ctx, msg->user_data, msg->len, 0)) + ret = 0; + } + return ret; } static struct file *io_msg_grab_file(struct io_kiocb *req, unsigned int issue_flags) @@ -223,7 +244,7 @@ int io_msg_ring(struct io_kiocb *req, unsigned int issue_flags) switch (msg->cmd) { case IORING_MSG_DATA: - ret = io_msg_ring_data(req); + ret = io_msg_ring_data(req, issue_flags); break; case IORING_MSG_SEND_FD: ret = io_msg_send_fd(req, issue_flags); From 6c54b7bc8a31ce0f7cc7f8deef05067df414f1d8 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Wed, 18 Jan 2023 14:08:24 +0530 Subject: [PATCH 367/398] thermal: core: call put_device() only after device_register() fails put_device() shouldn't be called before a prior call to device_register(). __thermal_cooling_device_register() doesn't follow that properly and needs fixing. Also thermal_cooling_device_destroy_sysfs() is getting called unnecessarily on few error paths. Fix all this by placing the calls at the right place. Based on initial work done by Caleb Connolly. Fixes: 4748f9687caa ("thermal: core: fix some possible name leaks in error paths") Fixes: c408b3d1d9bb ("thermal: Validate new state in cur_state_store()") Reported-by: Caleb Connolly Signed-off-by: Viresh Kumar Tested-by: Frank Rowand Reviewed-by: Yang Yingliang Tested-by: Caleb Connolly Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index f17ab2316dbd..77bd47d976a2 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -909,15 +909,20 @@ __thermal_cooling_device_register(struct device_node *np, cdev->devdata = devdata; ret = cdev->ops->get_max_state(cdev, &cdev->max_state); - if (ret) - goto out_kfree_type; + if (ret) { + kfree(cdev->type); + goto out_ida_remove; + } thermal_cooling_device_setup_sysfs(cdev); + ret = dev_set_name(&cdev->device, "cooling_device%d", cdev->id); if (ret) { + kfree(cdev->type); thermal_cooling_device_destroy_sysfs(cdev); - goto out_kfree_type; + goto out_ida_remove; } + ret = device_register(&cdev->device); if (ret) goto out_kfree_type; @@ -943,6 +948,8 @@ out_kfree_type: thermal_cooling_device_destroy_sysfs(cdev); kfree(cdev->type); put_device(&cdev->device); + + /* thermal_release() takes care of the rest */ cdev = NULL; out_ida_remove: ida_free(&thermal_cdev_ida, id); From 07ea567d84cdf0add274d66db7c02b55b818d517 Mon Sep 17 00:00:00 2001 From: Srujana Challa Date: Wed, 18 Jan 2023 17:33:48 +0530 Subject: [PATCH 368/398] octeontx2-af: recover CPT engine when it gets fault When CPT engine has uncorrectable errors, it will get halted and must be disabled and re-enabled. This patch adds code for the same. Signed-off-by: Srujana Challa Signed-off-by: David S. Miller --- .../ethernet/marvell/octeontx2/af/rvu_cpt.c | 108 +++++++++++++----- 1 file changed, 79 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index 38bbae5d9ae0..1ed16ce515bb 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c @@ -37,34 +37,60 @@ (_rsp)->free_sts_##etype = free_sts; \ }) -static irqreturn_t rvu_cpt_af_flt_intr_handler(int irq, void *ptr) +static irqreturn_t cpt_af_flt_intr_handler(int vec, void *ptr) { struct rvu_block *block = ptr; struct rvu *rvu = block->rvu; int blkaddr = block->addr; - u64 reg0, reg1, reg2; + u64 reg, val; + int i, eng; + u8 grp; - reg0 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(0)); - reg1 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(1)); - if (!is_rvu_otx2(rvu)) { - reg2 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(2)); - dev_err_ratelimited(rvu->dev, - "Received CPTAF FLT irq : 0x%llx, 0x%llx, 0x%llx", - reg0, reg1, reg2); - } else { - dev_err_ratelimited(rvu->dev, - "Received CPTAF FLT irq : 0x%llx, 0x%llx", - reg0, reg1); + reg = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(vec)); + dev_err_ratelimited(rvu->dev, "Received CPTAF FLT%d irq : 0x%llx", vec, reg); + + i = -1; + while ((i = find_next_bit((unsigned long *)®, 64, i + 1)) < 64) { + switch (vec) { + case 0: + eng = i; + break; + case 1: + eng = i + 64; + break; + case 2: + eng = i + 128; + break; + } + grp = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng)) & 0xFF; + /* Disable and enable the engine which triggers fault */ + rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng), 0x0); + val = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng)); + rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng), val & ~1ULL); + + rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng), grp); + rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng), val | 1ULL); } - - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(0), reg0); - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(1), reg1); - if (!is_rvu_otx2(rvu)) - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(2), reg2); + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(vec), reg); return IRQ_HANDLED; } +static irqreturn_t rvu_cpt_af_flt0_intr_handler(int irq, void *ptr) +{ + return cpt_af_flt_intr_handler(CPT_AF_INT_VEC_FLT0, ptr); +} + +static irqreturn_t rvu_cpt_af_flt1_intr_handler(int irq, void *ptr) +{ + return cpt_af_flt_intr_handler(CPT_AF_INT_VEC_FLT1, ptr); +} + +static irqreturn_t rvu_cpt_af_flt2_intr_handler(int irq, void *ptr) +{ + return cpt_af_flt_intr_handler(CPT_10K_AF_INT_VEC_FLT2, ptr); +} + static irqreturn_t rvu_cpt_af_rvu_intr_handler(int irq, void *ptr) { struct rvu_block *block = ptr; @@ -119,8 +145,10 @@ static void cpt_10k_unregister_interrupts(struct rvu_block *block, int off) int i; /* Disable all CPT AF interrupts */ - for (i = 0; i < CPT_10K_AF_INT_VEC_RVU; i++) - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1); + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(0), ~0ULL); + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(1), ~0ULL); + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(2), 0xFFFF); + rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1); rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1); @@ -151,7 +179,7 @@ static void cpt_unregister_interrupts(struct rvu *rvu, int blkaddr) /* Disable all CPT AF interrupts */ for (i = 0; i < CPT_AF_INT_VEC_RVU; i++) - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1); + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), ~0ULL); rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1); rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1); @@ -172,16 +200,31 @@ static int cpt_10k_register_interrupts(struct rvu_block *block, int off) { struct rvu *rvu = block->rvu; int blkaddr = block->addr; + irq_handler_t flt_fn; int i, ret; for (i = CPT_10K_AF_INT_VEC_FLT0; i < CPT_10K_AF_INT_VEC_RVU; i++) { sprintf(&rvu->irq_name[(off + i) * NAME_SIZE], "CPTAF FLT%d", i); + + switch (i) { + case CPT_10K_AF_INT_VEC_FLT0: + flt_fn = rvu_cpt_af_flt0_intr_handler; + break; + case CPT_10K_AF_INT_VEC_FLT1: + flt_fn = rvu_cpt_af_flt1_intr_handler; + break; + case CPT_10K_AF_INT_VEC_FLT2: + flt_fn = rvu_cpt_af_flt2_intr_handler; + break; + } ret = rvu_cpt_do_register_interrupt(block, off + i, - rvu_cpt_af_flt_intr_handler, - &rvu->irq_name[(off + i) * NAME_SIZE]); + flt_fn, &rvu->irq_name[(off + i) * NAME_SIZE]); if (ret) goto err; - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1); + if (i == CPT_10K_AF_INT_VEC_FLT2) + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0xFFFF); + else + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), ~0ULL); } ret = rvu_cpt_do_register_interrupt(block, off + CPT_10K_AF_INT_VEC_RVU, @@ -208,8 +251,8 @@ static int cpt_register_interrupts(struct rvu *rvu, int blkaddr) { struct rvu_hwinfo *hw = rvu->hw; struct rvu_block *block; + irq_handler_t flt_fn; int i, offs, ret = 0; - char irq_name[16]; if (!is_block_implemented(rvu->hw, blkaddr)) return 0; @@ -226,13 +269,20 @@ static int cpt_register_interrupts(struct rvu *rvu, int blkaddr) return cpt_10k_register_interrupts(block, offs); for (i = CPT_AF_INT_VEC_FLT0; i < CPT_AF_INT_VEC_RVU; i++) { - snprintf(irq_name, sizeof(irq_name), "CPTAF FLT%d", i); + sprintf(&rvu->irq_name[(offs + i) * NAME_SIZE], "CPTAF FLT%d", i); + switch (i) { + case CPT_AF_INT_VEC_FLT0: + flt_fn = rvu_cpt_af_flt0_intr_handler; + break; + case CPT_AF_INT_VEC_FLT1: + flt_fn = rvu_cpt_af_flt1_intr_handler; + break; + } ret = rvu_cpt_do_register_interrupt(block, offs + i, - rvu_cpt_af_flt_intr_handler, - irq_name); + flt_fn, &rvu->irq_name[(offs + i) * NAME_SIZE]); if (ret) goto err; - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1); + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), ~0ULL); } ret = rvu_cpt_do_register_interrupt(block, offs + CPT_AF_INT_VEC_RVU, From f58cf765e8f5f4860ea094aa12c156d9195a4c28 Mon Sep 17 00:00:00 2001 From: Srujana Challa Date: Wed, 18 Jan 2023 17:33:49 +0530 Subject: [PATCH 369/398] octeontx2-af: add mbox for CPT LF reset On OcteonTX2 SoC, the admin function (AF) is the only one with all priviliges to configure HW and alloc resources, PFs and it's VFs have to request AF via mailbox for all their needs. This patch adds a new mailbox for CPT VFs to request for CPT LF reset. Signed-off-by: Srujana Challa Signed-off-by: David S. Miller --- .../net/ethernet/marvell/octeontx2/af/mbox.h | 8 +++++ .../ethernet/marvell/octeontx2/af/rvu_cpt.c | 33 +++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h index d2584ebb7a70..b121e3d9f561 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -195,6 +195,7 @@ M(CPT_STATS, 0xA05, cpt_sts, cpt_sts_req, cpt_sts_rsp) \ M(CPT_RXC_TIME_CFG, 0xA06, cpt_rxc_time_cfg, cpt_rxc_time_cfg_req, \ msg_rsp) \ M(CPT_CTX_CACHE_SYNC, 0xA07, cpt_ctx_cache_sync, msg_req, msg_rsp) \ +M(CPT_LF_RESET, 0xA08, cpt_lf_reset, cpt_lf_rst_req, msg_rsp) \ /* SDP mbox IDs (range 0x1000 - 0x11FF) */ \ M(SET_SDP_CHAN_INFO, 0x1000, set_sdp_chan_info, sdp_chan_info_msg, msg_rsp) \ M(GET_SDP_CHAN_INFO, 0x1001, get_sdp_chan_info, msg_req, sdp_get_chan_info_msg) \ @@ -1692,6 +1693,13 @@ struct cpt_inst_lmtst_req { u64 rsvd; }; +/* Mailbox message format to request for CPT LF reset */ +struct cpt_lf_rst_req { + struct mbox_msghdr hdr; + u32 slot; + u32 rsvd; +}; + struct sdp_node_info { /* Node to which this PF belons to */ u8 node_id; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index 1ed16ce515bb..1cd34914cb86 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c @@ -851,6 +851,39 @@ int rvu_mbox_handler_cpt_ctx_cache_sync(struct rvu *rvu, struct msg_req *req, return rvu_cpt_ctx_flush(rvu, req->hdr.pcifunc); } +int rvu_mbox_handler_cpt_lf_reset(struct rvu *rvu, struct cpt_lf_rst_req *req, + struct msg_rsp *rsp) +{ + u16 pcifunc = req->hdr.pcifunc; + struct rvu_block *block; + int cptlf, blkaddr, ret; + u16 actual_slot; + u64 ctl, ctl2; + + blkaddr = rvu_get_blkaddr_from_slot(rvu, BLKTYPE_CPT, pcifunc, + req->slot, &actual_slot); + if (blkaddr < 0) + return CPT_AF_ERR_LF_INVALID; + + block = &rvu->hw->block[blkaddr]; + + cptlf = rvu_get_lf(rvu, block, pcifunc, actual_slot); + if (cptlf < 0) + return CPT_AF_ERR_LF_INVALID; + ctl = rvu_read64(rvu, blkaddr, CPT_AF_LFX_CTL(cptlf)); + ctl2 = rvu_read64(rvu, blkaddr, CPT_AF_LFX_CTL2(cptlf)); + + ret = rvu_lf_reset(rvu, block, cptlf); + if (ret) + dev_err(rvu->dev, "Failed to reset blkaddr %d LF%d\n", + block->addr, cptlf); + + rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL(cptlf), ctl); + rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL2(cptlf), ctl2); + + return 0; +} + static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr) { struct cpt_rxc_time_cfg_req req; From 1286c50ae9e0f5025b165c8f2321b3ce3b558002 Mon Sep 17 00:00:00 2001 From: Srujana Challa Date: Wed, 18 Jan 2023 17:33:50 +0530 Subject: [PATCH 370/398] octeontx2-af: modify FLR sequence for CPT On OcteonTX2 platform CPT instruction enqueue is only possible via LMTST operations. The existing FLR sequence mentioned in HRM requires a dummy LMTST to CPT but LMTST can't be submitted from AF driver. So, HW team provided a new sequence to avoid dummy LMTST. This patch adds code for the same. Signed-off-by: Srujana Challa Signed-off-by: David S. Miller --- .../net/ethernet/marvell/octeontx2/af/rvu.h | 12 +++ .../ethernet/marvell/octeontx2/af/rvu_cpt.c | 90 +++++++++---------- .../ethernet/marvell/octeontx2/af/rvu_reg.h | 2 + 3 files changed, 55 insertions(+), 49 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h index 7f0a64731c67..20c75d7c962e 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -459,6 +459,7 @@ struct rvu { struct rvu_pfvf *pf; struct rvu_pfvf *hwvf; struct mutex rsrc_lock; /* Serialize resource alloc/free */ + struct mutex alias_lock; /* Serialize bar2 alias access */ int vfs; /* Number of VFs attached to RVU */ int nix_blkaddr[MAX_NIX_BLKS]; @@ -546,6 +547,17 @@ static inline u64 rvupf_read64(struct rvu *rvu, u64 offset) return readq(rvu->pfreg_base + offset); } +static inline void rvu_bar2_sel_write64(struct rvu *rvu, u64 block, u64 offset, u64 val) +{ + /* HW requires read back of RVU_AF_BAR2_SEL register to make sure completion of + * write operation. + */ + rvu_write64(rvu, block, offset, val); + rvu_read64(rvu, block, offset); + /* Barrier to ensure read completes before accessing LF registers */ + mb(); +} + /* Silicon revisions */ static inline bool is_rvu_pre_96xx_C0(struct rvu *rvu) { diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index 1cd34914cb86..e8973294c4f8 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c @@ -930,68 +930,63 @@ static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr) dev_warn(rvu->dev, "Poll for RXC zombie count hits hard loop counter\n"); } -#define INPROG_INFLIGHT(reg) ((reg) & 0x1FF) -#define INPROG_GRB_PARTIAL(reg) ((reg) & BIT_ULL(31)) -#define INPROG_GRB(reg) (((reg) >> 32) & 0xFF) -#define INPROG_GWB(reg) (((reg) >> 40) & 0xFF) +#define INFLIGHT GENMASK_ULL(8, 0) +#define GRB_CNT GENMASK_ULL(39, 32) +#define GWB_CNT GENMASK_ULL(47, 40) +#define XQ_XOR GENMASK_ULL(63, 63) +#define DQPTR GENMASK_ULL(19, 0) +#define NQPTR GENMASK_ULL(51, 32) static void cpt_lf_disable_iqueue(struct rvu *rvu, int blkaddr, int slot) { - int i = 0, hard_lp_ctr = 100000; - u64 inprog, grp_ptr; - u16 nq_ptr, dq_ptr; + int timeout = 1000000; + u64 inprog, inst_ptr; + u64 qsize, pending; + int i = 0; /* Disable instructions enqueuing */ rvu_write64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_CTL), 0x0); - /* Disable executions in the LF's queue */ inprog = rvu_read64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG)); - inprog &= ~BIT_ULL(16); + inprog |= BIT_ULL(16); rvu_write64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG), inprog); + qsize = rvu_read64(rvu, blkaddr, + CPT_AF_BAR2_ALIASX(slot, CPT_LF_Q_SIZE)) & 0x7FFF; + do { + inst_ptr = rvu_read64(rvu, blkaddr, + CPT_AF_BAR2_ALIASX(slot, CPT_LF_Q_INST_PTR)); + pending = (FIELD_GET(XQ_XOR, inst_ptr) * qsize * 40) + + FIELD_GET(NQPTR, inst_ptr) - + FIELD_GET(DQPTR, inst_ptr); + udelay(1); + timeout--; + } while ((pending != 0) && (timeout != 0)); + + if (timeout == 0) + dev_warn(rvu->dev, "TIMEOUT: CPT poll on pending instructions\n"); + + timeout = 1000000; /* Wait for CPT queue to become execution-quiescent */ do { inprog = rvu_read64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG)); - if (INPROG_GRB_PARTIAL(inprog)) { - i = 0; - hard_lp_ctr--; - } else { - i++; - } - grp_ptr = rvu_read64(rvu, blkaddr, - CPT_AF_BAR2_ALIASX(slot, - CPT_LF_Q_GRP_PTR)); - nq_ptr = (grp_ptr >> 32) & 0x7FFF; - dq_ptr = grp_ptr & 0x7FFF; - - } while (hard_lp_ctr && (i < 10) && (nq_ptr != dq_ptr)); - - if (hard_lp_ctr == 0) - dev_warn(rvu->dev, "CPT FLR hits hard loop counter\n"); - - i = 0; - hard_lp_ctr = 100000; - do { - inprog = rvu_read64(rvu, blkaddr, - CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG)); - - if ((INPROG_INFLIGHT(inprog) == 0) && - (INPROG_GWB(inprog) < 40) && - ((INPROG_GRB(inprog) == 0) || - (INPROG_GRB((inprog)) == 40))) { + if ((FIELD_GET(INFLIGHT, inprog) == 0) && + (FIELD_GET(GRB_CNT, inprog) == 0)) { i++; } else { i = 0; - hard_lp_ctr--; + timeout--; } - } while (hard_lp_ctr && (i < 10)); + } while ((timeout != 0) && (i < 10)); - if (hard_lp_ctr == 0) - dev_warn(rvu->dev, "CPT FLR hits hard loop counter\n"); + if (timeout == 0) + dev_warn(rvu->dev, "TIMEOUT: CPT poll on inflight count\n"); + /* Wait for 2 us to flush all queue writes to memory */ + udelay(2); } int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, int slot) @@ -1001,18 +996,15 @@ int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, int s if (is_cpt_pf(rvu, pcifunc) || is_cpt_vf(rvu, pcifunc)) cpt_rxc_teardown(rvu, blkaddr); + mutex_lock(&rvu->alias_lock); /* Enable BAR2 ALIAS for this pcifunc. */ reg = BIT_ULL(16) | pcifunc; - rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg); + rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg); cpt_lf_disable_iqueue(rvu, blkaddr, slot); - /* Set group drop to help clear out hardware */ - reg = rvu_read64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG)); - reg |= BIT_ULL(17); - rvu_write64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG), reg); - - rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0); + rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0); + mutex_unlock(&rvu->alias_lock); return 0; } @@ -1147,7 +1139,7 @@ int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc) /* Enable BAR2 ALIAS for this pcifunc. */ reg = BIT_ULL(16) | pcifunc; - rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg); + rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg); for (i = 0; i < max_ctx_entries; i++) { cam_data = rvu_read64(rvu, blkaddr, CPT_AF_CTX_CAM_DATA(i)); @@ -1160,7 +1152,7 @@ int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc) reg); } } - rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0); + rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0); unlock: mutex_unlock(&rvu->rsrc_lock); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h index 0e0d536645ac..5437bd20c719 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h @@ -545,6 +545,8 @@ #define CPT_LF_CTL 0x10 #define CPT_LF_INPROG 0x40 +#define CPT_LF_Q_SIZE 0x100 +#define CPT_LF_Q_INST_PTR 0x110 #define CPT_LF_Q_GRP_PTR 0x120 #define CPT_LF_CTX_FLUSH 0x510 From 9adb04ff62f51265002c2c83e718bcf459e06e48 Mon Sep 17 00:00:00 2001 From: Srujana Challa Date: Wed, 18 Jan 2023 17:33:51 +0530 Subject: [PATCH 371/398] octeontx2-af: optimize cpt pf identification Optimize CPT PF identification in mbox handling for faster mbox response by doing it at AF driver probe instead of every mbox message. Signed-off-by: Srujana Challa Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/octeontx2/af/rvu.c | 8 ++++++++ drivers/net/ethernet/marvell/octeontx2/af/rvu.h | 2 ++ drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c | 13 ++++++++++--- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c index 3f5e09b77d4b..8683ce57ed3f 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -1164,8 +1164,16 @@ cpt: goto nix_err; } + err = rvu_cpt_init(rvu); + if (err) { + dev_err(rvu->dev, "%s: Failed to initialize cpt\n", __func__); + goto mcs_err; + } + return 0; +mcs_err: + rvu_mcs_exit(rvu); nix_err: rvu_nix_freemem(rvu); npa_err: diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h index 20c75d7c962e..2f480c73ef55 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -511,6 +511,7 @@ struct rvu { struct ptp *ptp; int mcs_blk_cnt; + int cpt_pf_num; #ifdef CONFIG_DEBUG_FS struct rvu_debugfs rvu_dbg; @@ -877,6 +878,7 @@ void rvu_cpt_unregister_interrupts(struct rvu *rvu); int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, int slot); int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc); +int rvu_cpt_init(struct rvu *rvu); /* CN10K RVU */ int rvu_set_channels_base(struct rvu *rvu); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index e8973294c4f8..f970cb9b0bff 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c @@ -340,7 +340,7 @@ static int get_cpt_pf_num(struct rvu *rvu) static bool is_cpt_pf(struct rvu *rvu, u16 pcifunc) { - int cpt_pf_num = get_cpt_pf_num(rvu); + int cpt_pf_num = rvu->cpt_pf_num; if (rvu_get_pf(pcifunc) != cpt_pf_num) return false; @@ -352,7 +352,7 @@ static bool is_cpt_pf(struct rvu *rvu, u16 pcifunc) static bool is_cpt_vf(struct rvu *rvu, u16 pcifunc) { - int cpt_pf_num = get_cpt_pf_num(rvu); + int cpt_pf_num = rvu->cpt_pf_num; if (rvu_get_pf(pcifunc) != cpt_pf_num) return false; @@ -1015,7 +1015,7 @@ int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, int s static int cpt_inline_inb_lf_cmd_send(struct rvu *rvu, int blkaddr, int nix_blkaddr) { - int cpt_pf_num = get_cpt_pf_num(rvu); + int cpt_pf_num = rvu->cpt_pf_num; struct cpt_inst_lmtst_req *req; dma_addr_t res_daddr; int timeout = 3000; @@ -1159,3 +1159,10 @@ unlock: return 0; } + +int rvu_cpt_init(struct rvu *rvu) +{ + /* Retrieve CPT PF number */ + rvu->cpt_pf_num = get_cpt_pf_num(rvu); + return 0; +} From d5b2e0a299f36c6ccdda4830525ca20550243536 Mon Sep 17 00:00:00 2001 From: Nithin Dabilpuram Date: Wed, 18 Jan 2023 17:33:52 +0530 Subject: [PATCH 372/398] octeontx2-af: restore rxc conf after teardown sequence CN10K CPT coprocessor includes a component named RXC which is responsible for reassembly of inner IP packets. RXC has the feature to evict oldest entries based on age/threshold. The age/threshold is being set to minimum values to evict all entries at the time of teardown. This patch adds code to restore timeout and threshold config after teardown sequence is complete as it is global config. Signed-off-by: Nithin Dabilpuram Signed-off-by: David S. Miller --- .../ethernet/marvell/octeontx2/af/rvu_cpt.c | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index f970cb9b0bff..302ff549284e 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c @@ -812,10 +812,21 @@ int rvu_mbox_handler_cpt_sts(struct rvu *rvu, struct cpt_sts_req *req, #define RXC_ZOMBIE_COUNT GENMASK_ULL(60, 48) static void cpt_rxc_time_cfg(struct rvu *rvu, struct cpt_rxc_time_cfg_req *req, - int blkaddr) + int blkaddr, struct cpt_rxc_time_cfg_req *save) { u64 dfrg_reg; + if (save) { + /* Save older config */ + dfrg_reg = rvu_read64(rvu, blkaddr, CPT_AF_RXC_DFRG); + save->zombie_thres = FIELD_GET(RXC_ZOMBIE_THRES, dfrg_reg); + save->zombie_limit = FIELD_GET(RXC_ZOMBIE_LIMIT, dfrg_reg); + save->active_thres = FIELD_GET(RXC_ACTIVE_THRES, dfrg_reg); + save->active_limit = FIELD_GET(RXC_ACTIVE_LIMIT, dfrg_reg); + + save->step = rvu_read64(rvu, blkaddr, CPT_AF_RXC_TIME_CFG); + } + dfrg_reg = FIELD_PREP(RXC_ZOMBIE_THRES, req->zombie_thres); dfrg_reg |= FIELD_PREP(RXC_ZOMBIE_LIMIT, req->zombie_limit); dfrg_reg |= FIELD_PREP(RXC_ACTIVE_THRES, req->active_thres); @@ -840,7 +851,7 @@ int rvu_mbox_handler_cpt_rxc_time_cfg(struct rvu *rvu, !is_cpt_vf(rvu, req->hdr.pcifunc)) return CPT_AF_ERR_ACCESS_DENIED; - cpt_rxc_time_cfg(rvu, req, blkaddr); + cpt_rxc_time_cfg(rvu, req, blkaddr, NULL); return 0; } @@ -886,7 +897,7 @@ int rvu_mbox_handler_cpt_lf_reset(struct rvu *rvu, struct cpt_lf_rst_req *req, static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr) { - struct cpt_rxc_time_cfg_req req; + struct cpt_rxc_time_cfg_req req, prev; int timeout = 2000; u64 reg; @@ -902,7 +913,7 @@ static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr) req.active_thres = 1; req.active_limit = 1; - cpt_rxc_time_cfg(rvu, &req, blkaddr); + cpt_rxc_time_cfg(rvu, &req, blkaddr, &prev); do { reg = rvu_read64(rvu, blkaddr, CPT_AF_RXC_ACTIVE_STS); @@ -928,6 +939,9 @@ static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr) if (timeout == 0) dev_warn(rvu->dev, "Poll for RXC zombie count hits hard loop counter\n"); + + /* Restore config */ + cpt_rxc_time_cfg(rvu, &prev, blkaddr, NULL); } #define INFLIGHT GENMASK_ULL(8, 0) From c0688ec002a451d04a51d43b849765c5ce6cb36f Mon Sep 17 00:00:00 2001 From: Srujana Challa Date: Wed, 18 Jan 2023 17:33:53 +0530 Subject: [PATCH 373/398] octeontx2-af: update cpt lf alloc mailbox The CN10K CPT coprocessor contains a context processor to accelerate updates to the IPsec security association contexts. The context processor contains a context cache. This patch updates CPT LF ALLOC mailbox to config ctx_ilen requested by VFs. CPT_LF_ALLOC:ctx_ilen is the size of initial context fetch. Signed-off-by: Srujana Challa Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/octeontx2/af/mbox.h | 2 ++ drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h index b121e3d9f561..e2ae9c317ce2 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -1610,6 +1610,8 @@ struct cpt_lf_alloc_req_msg { u16 sso_pf_func; u16 eng_grpmsk; int blkaddr; + u8 ctx_ilen_valid : 1; + u8 ctx_ilen : 7; }; #define CPT_INLINE_INBOUND 0 diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index 302ff549284e..d7ca7e953683 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c @@ -17,7 +17,7 @@ #define PCI_DEVID_OTX2_CPT10K_PF 0xA0F2 /* Length of initial context fetch in 128 byte words */ -#define CPT_CTX_ILEN 2ULL +#define CPT_CTX_ILEN 1ULL #define cpt_get_eng_sts(e_min, e_max, rsp, etype) \ ({ \ @@ -421,8 +421,12 @@ int rvu_mbox_handler_cpt_lf_alloc(struct rvu *rvu, /* Set CPT LF group and priority */ val = (u64)req->eng_grpmsk << 48 | 1; - if (!is_rvu_otx2(rvu)) - val |= (CPT_CTX_ILEN << 17); + if (!is_rvu_otx2(rvu)) { + if (req->ctx_ilen_valid) + val |= (req->ctx_ilen << 17); + else + val |= (CPT_CTX_ILEN << 17); + } rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL(cptlf), val); From 8299ffe3dc3dc9ac2bd60e3a8332008f03156aca Mon Sep 17 00:00:00 2001 From: Srujana Challa Date: Wed, 18 Jan 2023 17:33:54 +0530 Subject: [PATCH 374/398] octeontx2-af: add mbox to return CPT_AF_FLT_INT info CPT HW would trigger the CPT AF FLT interrupt when CPT engines hits some uncorrectable errors and AF is the one which receives the interrupt and recovers the engines. This patch adds a mailbox for CPT VFs to request for CPT faulted and recovered engines info. Signed-off-by: Srujana Challa Signed-off-by: David S. Miller --- .../net/ethernet/marvell/octeontx2/af/mbox.h | 17 +++++++++ .../net/ethernet/marvell/octeontx2/af/rvu.h | 4 +++ .../ethernet/marvell/octeontx2/af/rvu_cpt.c | 35 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h index e2ae9c317ce2..84761c7f6717 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -196,6 +196,8 @@ M(CPT_RXC_TIME_CFG, 0xA06, cpt_rxc_time_cfg, cpt_rxc_time_cfg_req, \ msg_rsp) \ M(CPT_CTX_CACHE_SYNC, 0xA07, cpt_ctx_cache_sync, msg_req, msg_rsp) \ M(CPT_LF_RESET, 0xA08, cpt_lf_reset, cpt_lf_rst_req, msg_rsp) \ +M(CPT_FLT_ENG_INFO, 0xA09, cpt_flt_eng_info, cpt_flt_eng_info_req, \ + cpt_flt_eng_info_rsp) \ /* SDP mbox IDs (range 0x1000 - 0x11FF) */ \ M(SET_SDP_CHAN_INFO, 0x1000, set_sdp_chan_info, sdp_chan_info_msg, msg_rsp) \ M(GET_SDP_CHAN_INFO, 0x1001, get_sdp_chan_info, msg_req, sdp_get_chan_info_msg) \ @@ -1702,6 +1704,21 @@ struct cpt_lf_rst_req { u32 rsvd; }; +/* Mailbox message format to request for CPT faulted engines */ +struct cpt_flt_eng_info_req { + struct mbox_msghdr hdr; + int blkaddr; + bool reset; + u32 rsvd; +}; + +struct cpt_flt_eng_info_rsp { + struct mbox_msghdr hdr; + u64 flt_eng_map[CPT_10K_AF_INT_VEC_RVU]; + u64 rcvrd_eng_map[CPT_10K_AF_INT_VEC_RVU]; + u64 rsvd; +}; + struct sdp_node_info { /* Node to which this PF belons to */ u8 node_id; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h index 2f480c73ef55..5eea2b6cf6bd 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -108,6 +108,8 @@ struct rvu_block { u64 lfreset_reg; unsigned char name[NAME_SIZE]; struct rvu *rvu; + u64 cpt_flt_eng_map[3]; + u64 cpt_rcvrd_eng_map[3]; }; struct nix_mcast { @@ -526,6 +528,8 @@ struct rvu { struct list_head mcs_intrq_head; /* mcs interrupt queue lock */ spinlock_t mcs_intrq_lock; + /* CPT interrupt lock */ + spinlock_t cpt_intr_lock; }; static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index d7ca7e953683..f047185f38e0 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c @@ -70,6 +70,14 @@ static irqreturn_t cpt_af_flt_intr_handler(int vec, void *ptr) rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng), grp); rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng), val | 1ULL); + + spin_lock(&rvu->cpt_intr_lock); + block->cpt_flt_eng_map[vec] |= BIT_ULL(i); + val = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_STS(eng)); + val = val & 0x3; + if (val == 0x1 || val == 0x2) + block->cpt_rcvrd_eng_map[vec] |= BIT_ULL(i); + spin_unlock(&rvu->cpt_intr_lock); } rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(vec), reg); @@ -899,6 +907,31 @@ int rvu_mbox_handler_cpt_lf_reset(struct rvu *rvu, struct cpt_lf_rst_req *req, return 0; } +int rvu_mbox_handler_cpt_flt_eng_info(struct rvu *rvu, struct cpt_flt_eng_info_req *req, + struct cpt_flt_eng_info_rsp *rsp) +{ + struct rvu_block *block; + unsigned long flags; + int blkaddr, vec; + + blkaddr = validate_and_get_cpt_blkaddr(req->blkaddr); + if (blkaddr < 0) + return blkaddr; + + block = &rvu->hw->block[blkaddr]; + for (vec = 0; vec < CPT_10K_AF_INT_VEC_RVU; vec++) { + spin_lock_irqsave(&rvu->cpt_intr_lock, flags); + rsp->flt_eng_map[vec] = block->cpt_flt_eng_map[vec]; + rsp->rcvrd_eng_map[vec] = block->cpt_rcvrd_eng_map[vec]; + if (req->reset) { + block->cpt_flt_eng_map[vec] = 0x0; + block->cpt_rcvrd_eng_map[vec] = 0x0; + } + spin_unlock_irqrestore(&rvu->cpt_intr_lock, flags); + } + return 0; +} + static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr) { struct cpt_rxc_time_cfg_req req, prev; @@ -1182,5 +1215,7 @@ int rvu_cpt_init(struct rvu *rvu) { /* Retrieve CPT PF number */ rvu->cpt_pf_num = get_cpt_pf_num(rvu); + spin_lock_init(&rvu->cpt_intr_lock); + return 0; } From fdfc76a116b5e9d3e98e6c96fe83b42d011d21d4 Mon Sep 17 00:00:00 2001 From: Andrew Halaney Date: Wed, 18 Jan 2023 10:56:38 -0600 Subject: [PATCH 375/398] net: stmmac: enable all safety features by default In the original implementation of dwmac5 commit 8bf993a5877e ("net: stmmac: Add support for DWMAC5 and implement Safety Features") all safety features were enabled by default. Later it seems some implementations didn't have support for all the features, so in commit 5ac712dcdfef ("net: stmmac: enable platform specific safety features") the safety_feat_cfg structure was added to the callback and defined for some platforms to selectively enable these safety features. The problem is that only certain platforms were given that software support. If the automotive safety package bit is set in the hardware features register the safety feature callback is called for the platform, and for platforms that didn't get a safety_feat_cfg defined this results in the following NULL pointer dereference: [ 7.933303] Call trace: [ 7.935812] dwmac5_safety_feat_config+0x20/0x170 [stmmac] [ 7.941455] __stmmac_open+0x16c/0x474 [stmmac] [ 7.946117] stmmac_open+0x38/0x70 [stmmac] [ 7.950414] __dev_open+0x100/0x1dc [ 7.954006] __dev_change_flags+0x18c/0x204 [ 7.958297] dev_change_flags+0x24/0x6c [ 7.962237] do_setlink+0x2b8/0xfa4 [ 7.965827] __rtnl_newlink+0x4ec/0x840 [ 7.969766] rtnl_newlink+0x50/0x80 [ 7.973353] rtnetlink_rcv_msg+0x12c/0x374 [ 7.977557] netlink_rcv_skb+0x5c/0x130 [ 7.981500] rtnetlink_rcv+0x18/0x2c [ 7.985172] netlink_unicast+0x2e8/0x340 [ 7.989197] netlink_sendmsg+0x1a8/0x420 [ 7.993222] ____sys_sendmsg+0x218/0x280 [ 7.997249] ___sys_sendmsg+0xac/0x100 [ 8.001103] __sys_sendmsg+0x84/0xe0 [ 8.004776] __arm64_sys_sendmsg+0x24/0x30 [ 8.008983] invoke_syscall+0x48/0x114 [ 8.012840] el0_svc_common.constprop.0+0xcc/0xec [ 8.017665] do_el0_svc+0x38/0xb0 [ 8.021071] el0_svc+0x2c/0x84 [ 8.024212] el0t_64_sync_handler+0xf4/0x120 [ 8.028598] el0t_64_sync+0x190/0x194 Go back to the original behavior, if the automotive safety package is found to be supported in hardware enable all the features unless safety_feat_cfg is passed in saying this particular platform only supports a subset of the features. Fixes: 5ac712dcdfef ("net: stmmac: enable platform specific safety features") Reported-by: Ning Cai Signed-off-by: Andrew Halaney Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c index 9c2d40f853ed..413f66017219 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c @@ -186,11 +186,25 @@ static void dwmac5_handle_dma_err(struct net_device *ndev, int dwmac5_safety_feat_config(void __iomem *ioaddr, unsigned int asp, struct stmmac_safety_feature_cfg *safety_feat_cfg) { + struct stmmac_safety_feature_cfg all_safety_feats = { + .tsoee = 1, + .mrxpee = 1, + .mestee = 1, + .mrxee = 1, + .mtxee = 1, + .epsi = 1, + .edpp = 1, + .prtyen = 1, + .tmouten = 1, + }; u32 value; if (!asp) return -EINVAL; + if (!safety_feat_cfg) + safety_feat_cfg = &all_safety_feats; + /* 1. Enable Safety Features */ value = readl(ioaddr + MTL_ECC_CONTROL); value |= MEEAO; /* MTL ECC Error Addr Status Override */ From d2c865553adb7ad9abf3894cbb209cf1bc95484a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 17 Jan 2023 17:41:14 +0100 Subject: [PATCH 376/398] firmware: zynqmp: fix declarations for gcc-13 gcc-13.0.1 reports a type mismatch for two functions: drivers/firmware/xilinx/zynqmp.c:1228:5: error: conflicting types for 'zynqmp_pm_set_rpu_mode' due to enum/integer mismatch; have 'int(u32, enum rpu_oper_mode)' {aka 'int(unsigned int, enum rpu_oper_mode)'} [-Werror=enum-int-mismatch] 1228 | int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode) | ^~~~~~~~~~~~~~~~~~~~~~ In file included from drivers/firmware/xilinx/zynqmp.c:25: include/linux/firmware/xlnx-zynqmp.h:552:5: note: previous declaration of 'zynqmp_pm_set_rpu_mode' with type 'int(u32, u32)' {aka 'int(unsigned int, unsigned int)'} 552 | int zynqmp_pm_set_rpu_mode(u32 node_id, u32 arg1); | ^~~~~~~~~~~~~~~~~~~~~~ drivers/firmware/xilinx/zynqmp.c:1246:5: error: conflicting types for 'zynqmp_pm_set_tcm_config' due to enum/integer mismatch; have 'int(u32, enum rpu_tcm_comb)' {aka 'int(unsigned int, enum rpu_tcm_comb)'} [-Werror=enum-int-mismatch] 1246 | int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/firmware/xlnx-zynqmp.h:553:5: note: previous declaration of 'zynqmp_pm_set_tcm_config' with type 'int(u32, u32)' {aka 'int(unsigned int, unsigned int)'} 553 | int zynqmp_pm_set_tcm_config(u32 node_id, u32 arg1); | ^~~~~~~~~~~~~~~~~~~~~~~~ Change the declaration in the header to match the function definition. Acked-by: Michal Simek Signed-off-by: Arnd Bergmann --- include/linux/firmware/xlnx-zynqmp.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index b986e267d149..b09f443d3ab9 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h @@ -545,8 +545,8 @@ int zynqmp_pm_request_wake(const u32 node, const u64 address, const enum zynqmp_pm_request_ack ack); int zynqmp_pm_get_rpu_mode(u32 node_id, enum rpu_oper_mode *rpu_mode); -int zynqmp_pm_set_rpu_mode(u32 node_id, u32 arg1); -int zynqmp_pm_set_tcm_config(u32 node_id, u32 arg1); +int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode); +int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode); int zynqmp_pm_set_sd_config(u32 node, enum pm_sd_config_type config, u32 value); int zynqmp_pm_set_gem_config(u32 node, enum pm_gem_config_type config, u32 value); @@ -845,12 +845,12 @@ static inline int zynqmp_pm_get_rpu_mode(u32 node_id, enum rpu_oper_mode *rpu_mo return -ENODEV; } -static inline int zynqmp_pm_set_rpu_mode(u32 node_id, u32 arg1) +static inline int zynqmp_pm_set_rpu_mode(u32 node_id, enum rpu_oper_mode rpu_mode) { return -ENODEV; } -static inline int zynqmp_pm_set_tcm_config(u32 node_id, u32 arg1) +static inline int zynqmp_pm_set_tcm_config(u32 node_id, enum rpu_tcm_comb tcm_mode) { return -ENODEV; } From 2cbafffbf69addd7509072f4be5917f81d238cf6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 20 Jan 2023 11:16:59 +0100 Subject: [PATCH 377/398] Revert "serial: stm32: Merge hard IRQ and threaded IRQ handling into single IRQ handler" This reverts commit f24771b62a83239f0dce816bddf0f6807f436235 as it is reported to break the build. Reported-by: kernel test robot Link: https://lore.kernel.org/r/202301200130.ttBiTzfO-lkp@intel.com Fixes: f24771b62a83 ("serial: stm32: Merge hard IRQ and threaded IRQ handling into single IRQ handler") Cc: Sebastian Andrzej Siewior Cc: Valentin Caron # V3 Cc: Marek Vasut Cc: Johan Hovold Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/stm32-usart.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index 1e24bee2b0ef..a1490033aa16 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -797,9 +797,23 @@ static irqreturn_t stm32_usart_interrupt(int irq, void *ptr) spin_unlock(&port->lock); } + if (stm32_usart_rx_dma_enabled(port)) + return IRQ_WAKE_THREAD; + else + return IRQ_HANDLED; +} + +static irqreturn_t stm32_usart_threaded_interrupt(int irq, void *ptr) +{ + struct uart_port *port = ptr; + struct tty_port *tport = &port->state->port; + struct stm32_port *stm32_port = to_stm32_port(port); + unsigned int size; + unsigned long flags; + /* Receiver timeout irq for DMA RX */ - if (stm32_usart_rx_dma_enabled(port) && !stm32_port->throttled) { - spin_lock(&port->lock); + if (!stm32_port->throttled) { + spin_lock_irqsave(&port->lock, flags); size = stm32_usart_receive_chars(port, false); uart_unlock_and_check_sysrq_irqrestore(port, flags); if (size) @@ -1001,8 +1015,10 @@ static int stm32_usart_startup(struct uart_port *port) u32 val; int ret; - ret = request_irq(port->irq, stm32_usart_interrupt, - IRQF_NO_SUSPEND, name, port); + ret = request_threaded_irq(port->irq, stm32_usart_interrupt, + stm32_usart_threaded_interrupt, + IRQF_ONESHOT | IRQF_NO_SUSPEND, + name, port); if (ret) return ret; @@ -1585,6 +1601,13 @@ static int stm32_usart_of_dma_rx_probe(struct stm32_port *stm32port, struct dma_slave_config config; int ret; + /* + * Using DMA and threaded handler for the console could lead to + * deadlocks. + */ + if (uart_console(port)) + return -ENODEV; + stm32port->rx_buf = dma_alloc_coherent(dev, RX_BUF_L, &stm32port->rx_dma_buf, GFP_KERNEL); From a43866856125c3c432e2fbb6cc63cee1539ec4a7 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Tue, 13 Dec 2022 00:02:46 +0200 Subject: [PATCH 378/398] mei: bus: fix unlink on bus in error path Unconditional call to mei_cl_unlink in mei_cl_bus_dev_release leads to call of the mei_cl_unlink without corresponding mei_cl_link. This leads to miscalculation of open_handle_count (decrease without increase). Call unlink in mei_cldev_enable fail path and remove blanket unlink from mei_cl_bus_dev_release. Fixes: 34f1166afd67 ("mei: bus: need to unlink client before freeing") Cc: Signed-off-by: Alexander Usyskin Reviewed-by: Tomas Winkler Signed-off-by: Tomas Winkler Link: https://lore.kernel.org/r/20221212220247.286019-1-tomas.winkler@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/bus.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 4a08b624910a..a81b890c7ee6 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -702,13 +702,15 @@ void *mei_cldev_dma_map(struct mei_cl_device *cldev, u8 buffer_id, size_t size) if (cl->state == MEI_FILE_UNINITIALIZED) { ret = mei_cl_link(cl); if (ret) - goto out; + goto notlinked; /* update pointers */ cl->cldev = cldev; } ret = mei_cl_dma_alloc_and_map(cl, NULL, buffer_id, size); -out: + if (ret) + mei_cl_unlink(cl); +notlinked: mutex_unlock(&bus->device_lock); if (ret) return ERR_PTR(ret); @@ -758,7 +760,7 @@ int mei_cldev_enable(struct mei_cl_device *cldev) if (cl->state == MEI_FILE_UNINITIALIZED) { ret = mei_cl_link(cl); if (ret) - goto out; + goto notlinked; /* update pointers */ cl->cldev = cldev; } @@ -785,6 +787,9 @@ int mei_cldev_enable(struct mei_cl_device *cldev) } out: + if (ret) + mei_cl_unlink(cl); +notlinked: mutex_unlock(&bus->device_lock); return ret; @@ -1277,7 +1282,6 @@ static void mei_cl_bus_dev_release(struct device *dev) mei_cl_flush_queues(cldev->cl, NULL); mei_me_cl_put(cldev->me_cl); mei_dev_bus_put(cldev->bus); - mei_cl_unlink(cldev->cl); kfree(cldev->cl); kfree(cldev); } From 0c4d68261717f89fa8c4f98a6967c3832fcb3ad0 Mon Sep 17 00:00:00 2001 From: Alexander Usyskin Date: Tue, 13 Dec 2022 00:02:47 +0200 Subject: [PATCH 379/398] mei: me: add meteor lake point M DID Add Meteor Lake Point M device id. Cc: Signed-off-by: Alexander Usyskin Signed-off-by: Tomas Winkler Link: https://lore.kernel.org/r/20221212220247.286019-2-tomas.winkler@intel.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me-regs.h | 2 ++ drivers/misc/mei/pci-me.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h index 99966cd3e7d8..bdc65d50b945 100644 --- a/drivers/misc/mei/hw-me-regs.h +++ b/drivers/misc/mei/hw-me-regs.h @@ -111,6 +111,8 @@ #define MEI_DEV_ID_RPL_S 0x7A68 /* Raptor Lake Point S */ +#define MEI_DEV_ID_MTL_M 0x7E70 /* Meteor Lake Point M */ + /* * MEI HW Section */ diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index 704cd0caa172..5bf0d50d55a0 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -118,6 +118,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = { {MEI_PCI_DEVICE(MEI_DEV_ID_RPL_S, MEI_ME_PCH15_CFG)}, + {MEI_PCI_DEVICE(MEI_DEV_ID_MTL_M, MEI_ME_PCH15_CFG)}, + /* required last entry */ {0, } }; From 5023adc364df004bd8e57afe89a4bd8019485c3d Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 29 Nov 2022 12:45:16 +0300 Subject: [PATCH 380/398] misc: fastrpc: fix error code in fastrpc_req_mmap() The "err" variable shadows an earlier global variable so this code returns success instead of a negative error code. Fixes: 532ad70c6d44 ("misc: fastrpc: Add mmap request assigning for static PD pool") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/Y4XUrMETCl1O6t0A@kili Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index c9902a1dcf5d..876f0f146b16 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -1894,7 +1894,6 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) /* Add memory to static PD pool, protection thru hypervisor */ if (req.flags != ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) { struct qcom_scm_vmperm perm; - int err = 0; perm.vmid = QCOM_SCM_VMID_HLOS; perm.perm = QCOM_SCM_PERM_RWX; From 9446fa1683a7e3937d9970248ced427c1983a1c5 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Thu, 24 Nov 2022 17:49:39 +0000 Subject: [PATCH 381/398] misc: fastrpc: Fix use-after-free and race in fastrpc_map_find Currently, there is a race window between the point when the mutex is unlocked in fastrpc_map_lookup and the reference count increasing (fastrpc_map_get) in fastrpc_map_find, which can also lead to use-after-free. So lets merge fastrpc_map_find into fastrpc_map_lookup which allows us to both protect the maps list by also taking the &fl->lock spinlock and the reference count, since the spinlock will be released only after. Add take_ref argument to make this suitable for all callers. Fixes: 8f6c1d8c4f0c ("misc: fastrpc: Add fdlist implementation") Cc: stable Co-developed-by: Ola Jeppsson Signed-off-by: Ola Jeppsson Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221124174941.418450-2-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 876f0f146b16..dedc067fbec8 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -351,30 +351,31 @@ static void fastrpc_map_get(struct fastrpc_map *map) static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd, - struct fastrpc_map **ppmap) + struct fastrpc_map **ppmap, bool take_ref) { + struct fastrpc_session_ctx *sess = fl->sctx; struct fastrpc_map *map = NULL; + int ret = -ENOENT; - mutex_lock(&fl->mutex); + spin_lock(&fl->lock); list_for_each_entry(map, &fl->maps, node) { - if (map->fd == fd) { - *ppmap = map; - mutex_unlock(&fl->mutex); - return 0; + if (map->fd != fd) + continue; + + if (take_ref) { + ret = fastrpc_map_get(map); + if (ret) { + dev_dbg(sess->dev, "%s: Failed to get map fd=%d ret=%d\n", + __func__, fd, ret); + break; + } } + + *ppmap = map; + ret = 0; + break; } - mutex_unlock(&fl->mutex); - - return -ENOENT; -} - -static int fastrpc_map_find(struct fastrpc_user *fl, int fd, - struct fastrpc_map **ppmap) -{ - int ret = fastrpc_map_lookup(fl, fd, ppmap); - - if (!ret) - fastrpc_map_get(*ppmap); + spin_unlock(&fl->lock); return ret; } @@ -746,7 +747,7 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, struct fastrpc_map *map = NULL; int err = 0; - if (!fastrpc_map_find(fl, fd, ppmap)) + if (!fastrpc_map_lookup(fl, fd, ppmap, true)) return 0; map = kzalloc(sizeof(*map), GFP_KERNEL); @@ -1070,7 +1071,7 @@ static int fastrpc_put_args(struct fastrpc_invoke_ctx *ctx, for (i = 0; i < FASTRPC_MAX_FDLIST; i++) { if (!fdlist[i]) break; - if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap)) + if (!fastrpc_map_lookup(fl, (int)fdlist[i], &mmap, false)) fastrpc_map_put(mmap); } From 5bb96c8f9268e2fdb0e5321cbc358ee5941efc15 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Thu, 24 Nov 2022 17:49:40 +0000 Subject: [PATCH 382/398] misc: fastrpc: Don't remove map on creater_process and device_release Do not remove the map from the list on error path in fastrpc_init_create_process, instead call fastrpc_map_put, to avoid use-after-free. Do not remove it on fastrpc_device_release either, call fastrpc_map_put instead. The fastrpc_free_map is the only proper place to remove the map. This is called only after the reference count is 0. Fixes: b49f6d83e290 ("misc: fastrpc: Fix a possible double free") Cc: stable Co-developed-by: Ola Jeppsson Signed-off-by: Ola Jeppsson Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221124174941.418450-3-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index dedc067fbec8..9f8d52b59ed2 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -334,6 +334,13 @@ static void fastrpc_free_map(struct kref *ref) dma_buf_put(map->buf); } + if (map->fl) { + spin_lock(&map->fl->lock); + list_del(&map->node); + spin_unlock(&map->fl->lock); + map->fl = NULL; + } + kfree(map); } @@ -1434,12 +1441,7 @@ err_invoke: fl->init_mem = NULL; fastrpc_buf_free(imem); err_alloc: - if (map) { - spin_lock(&fl->lock); - list_del(&map->node); - spin_unlock(&fl->lock); - fastrpc_map_put(map); - } + fastrpc_map_put(map); err: kfree(args); @@ -1515,10 +1517,8 @@ static int fastrpc_device_release(struct inode *inode, struct file *file) fastrpc_context_put(ctx); } - list_for_each_entry_safe(map, m, &fl->maps, node) { - list_del(&map->node); + list_for_each_entry_safe(map, m, &fl->maps, node) fastrpc_map_put(map); - } list_for_each_entry_safe(buf, b, &fl->mmaps, node) { list_del(&buf->node); From 96b328d119eca7563c1edcc4e1039a62e6370ecb Mon Sep 17 00:00:00 2001 From: Ola Jeppsson Date: Thu, 24 Nov 2022 17:49:41 +0000 Subject: [PATCH 383/398] misc: fastrpc: Fix use-after-free race condition for maps It is possible that in between calling fastrpc_map_get() until map->fl->lock is taken in fastrpc_free_map(), another thread can call fastrpc_map_lookup() and get a reference to a map that is about to be deleted. Rewrite fastrpc_map_get() to only increase the reference count of a map if it's non-zero. Propagate this to callers so they can know if a map is about to be deleted. Fixes this warning: refcount_t: addition on 0; use-after-free. WARNING: CPU: 5 PID: 10100 at lib/refcount.c:25 refcount_warn_saturate ... Call trace: refcount_warn_saturate [fastrpc_map_get inlined] [fastrpc_map_lookup inlined] fastrpc_map_create fastrpc_internal_invoke fastrpc_device_ioctl __arm64_sys_ioctl invoke_syscall Fixes: c68cfb718c8f ("misc: fastrpc: Add support for context Invoke method") Cc: stable Signed-off-by: Ola Jeppsson Signed-off-by: Abel Vesa Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20221124174941.418450-4-srinivas.kandagatla@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index 9f8d52b59ed2..a2a1258531d0 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -350,10 +350,12 @@ static void fastrpc_map_put(struct fastrpc_map *map) kref_put(&map->refcount, fastrpc_free_map); } -static void fastrpc_map_get(struct fastrpc_map *map) +static int fastrpc_map_get(struct fastrpc_map *map) { - if (map) - kref_get(&map->refcount); + if (!map) + return -ENOENT; + + return kref_get_unless_zero(&map->refcount) ? 0 : -ENOENT; } From a769b05eeed7accc4019a1ed9799dd72067f1ce8 Mon Sep 17 00:00:00 2001 From: Khazhismel Kumykov Date: Tue, 17 Jan 2023 17:02:12 -0800 Subject: [PATCH 384/398] gsmi: fix null-deref in gsmi_get_variable We can get EFI variables without fetching the attribute, so we must allow for that in gsmi. commit 859748255b43 ("efi: pstore: Omit efivars caching EFI varstore access layer") added a new get_variable call with attr=NULL, which triggers panic in gsmi. Fixes: 74c5b31c6618 ("driver: Google EFI SMI") Cc: stable Signed-off-by: Khazhismel Kumykov Link: https://lore.kernel.org/r/20230118010212.1268474-1-khazhy@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/firmware/google/gsmi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c index 4e2575dfeb90..871bedf533a8 100644 --- a/drivers/firmware/google/gsmi.c +++ b/drivers/firmware/google/gsmi.c @@ -361,9 +361,10 @@ static efi_status_t gsmi_get_variable(efi_char16_t *name, memcpy(data, gsmi_dev.data_buf->start, *data_size); /* All variables are have the following attributes */ - *attr = EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS | - EFI_VARIABLE_RUNTIME_ACCESS; + if (attr) + *attr = EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS; } spin_unlock_irqrestore(&gsmi_dev.lock, flags); From aaca766c77fcf5aabda846d3372a1d40b0d4735d Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Thu, 12 Jan 2023 10:23:12 -0800 Subject: [PATCH 385/398] misc: fastrpc: Pass bitfield into qcom_scm_assign_mem The srcvm parameter of qcom_scm_assign_mem is a pointer to a bitfield of VMIDs. The bitfield is updated with which VMIDs have permissions after the qcom_scm_assign_mem call. This makes it simpler for clients to make qcom_scm_assign_mem calls later, they always pass in same srcvm bitfield and do not need to closely track whether memory was originally shared. When restoring permissions to HLOS, fastrpc is incorrectly using the first VMID directly -- neither the BIT nor the other possible VMIDs the memory was already assigned to. We already have a field intended for this purpose: "perms" in the struct fastrpc_channel_ctx, but it was never used. Start using the perms field. Cc: Abel Vesa Cc: Vamsi Krishna Gattupalli Cc: Srinivas Kandagatla Fixes: e90d91190619 ("misc: fastrpc: Add support to secure memory map") Fixes: 0871561055e6 ("misc: fastrpc: Add support for audiopd") Fixes: 532ad70c6d44 ("misc: fastrpc: Add mmap request assigning for static PD pool") Tested-by: Srinivas Kandagatla Signed-off-by: Elliot Berman drivers/misc/fastrpc.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) Link: https://lore.kernel.org/r/20230112182313.521467-1-quic_eberman@quicinc.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/fastrpc.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index a2a1258531d0..5310606113fe 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -321,7 +321,7 @@ static void fastrpc_free_map(struct kref *ref) perm.vmid = QCOM_SCM_VMID_HLOS; perm.perm = QCOM_SCM_PERM_RWX; err = qcom_scm_assign_mem(map->phys, map->size, - &(map->fl->cctx->vmperms[0].vmid), &perm, 1); + &map->fl->cctx->perms, &perm, 1); if (err) { dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", map->phys, map->size, err); @@ -798,10 +798,8 @@ static int fastrpc_map_create(struct fastrpc_user *fl, int fd, * If subsystem VMIDs are defined in DTSI, then do * hyp_assign from HLOS to those VM(s) */ - unsigned int perms = BIT(QCOM_SCM_VMID_HLOS); - map->attr = attr; - err = qcom_scm_assign_mem(map->phys, (u64)map->size, &perms, + err = qcom_scm_assign_mem(map->phys, (u64)map->size, &fl->cctx->perms, fl->cctx->vmperms, fl->cctx->vmcount); if (err) { dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d", @@ -1268,10 +1266,9 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, /* Map if we have any heap VMIDs associated with this ADSP Static Process. */ if (fl->cctx->vmcount) { - unsigned int perms = BIT(QCOM_SCM_VMID_HLOS); - err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, - (u64)fl->cctx->remote_heap->size, &perms, + (u64)fl->cctx->remote_heap->size, + &fl->cctx->perms, fl->cctx->vmperms, fl->cctx->vmcount); if (err) { dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d", @@ -1319,7 +1316,7 @@ err_invoke: perm.perm = QCOM_SCM_PERM_RWX; err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, (u64)fl->cctx->remote_heap->size, - &(fl->cctx->vmperms[0].vmid), &perm, 1); + &fl->cctx->perms, &perm, 1); if (err) dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); @@ -1901,7 +1898,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) perm.vmid = QCOM_SCM_VMID_HLOS; perm.perm = QCOM_SCM_PERM_RWX; err = qcom_scm_assign_mem(buf->phys, buf->size, - &(fl->cctx->vmperms[0].vmid), &perm, 1); + &fl->cctx->perms, &perm, 1); if (err) { dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", buf->phys, buf->size, err); From 3daed6345d5880464f46adab871d208e1baa2f3a Mon Sep 17 00:00:00 2001 From: Vishnu Dasa Date: Tue, 29 Nov 2022 23:05:11 -0800 Subject: [PATCH 386/398] VMCI: Use threaded irqs instead of tasklets The vmci_dispatch_dgs() tasklet function calls vmci_read_data() which uses wait_event() resulting in invalid sleep in an atomic context (and therefore potentially in a deadlock). Use threaded irqs to fix this issue and completely remove usage of tasklets. [ 20.264639] BUG: sleeping function called from invalid context at drivers/misc/vmw_vmci/vmci_guest.c:145 [ 20.264643] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 762, name: vmtoolsd [ 20.264645] preempt_count: 101, expected: 0 [ 20.264646] RCU nest depth: 0, expected: 0 [ 20.264647] 1 lock held by vmtoolsd/762: [ 20.264648] #0: ffff0000874ae440 (sk_lock-AF_VSOCK){+.+.}-{0:0}, at: vsock_connect+0x60/0x330 [vsock] [ 20.264658] Preemption disabled at: [ 20.264659] [] vmci_send_datagram+0x44/0xa0 [vmw_vmci] [ 20.264665] CPU: 0 PID: 762 Comm: vmtoolsd Not tainted 5.19.0-0.rc8.20220727git39c3c396f813.60.fc37.aarch64 #1 [ 20.264667] Hardware name: VMware, Inc. VBSA/VBSA, BIOS VEFI 12/31/2020 [ 20.264668] Call trace: [ 20.264669] dump_backtrace+0xc4/0x130 [ 20.264672] show_stack+0x24/0x80 [ 20.264673] dump_stack_lvl+0x88/0xb4 [ 20.264676] dump_stack+0x18/0x34 [ 20.264677] __might_resched+0x1a0/0x280 [ 20.264679] __might_sleep+0x58/0x90 [ 20.264681] vmci_read_data+0x74/0x120 [vmw_vmci] [ 20.264683] vmci_dispatch_dgs+0x64/0x204 [vmw_vmci] [ 20.264686] tasklet_action_common.constprop.0+0x13c/0x150 [ 20.264688] tasklet_action+0x40/0x50 [ 20.264689] __do_softirq+0x23c/0x6b4 [ 20.264690] __irq_exit_rcu+0x104/0x214 [ 20.264691] irq_exit_rcu+0x1c/0x50 [ 20.264693] el1_interrupt+0x38/0x6c [ 20.264695] el1h_64_irq_handler+0x18/0x24 [ 20.264696] el1h_64_irq+0x68/0x6c [ 20.264697] preempt_count_sub+0xa4/0xe0 [ 20.264698] _raw_spin_unlock_irqrestore+0x64/0xb0 [ 20.264701] vmci_send_datagram+0x7c/0xa0 [vmw_vmci] [ 20.264703] vmci_datagram_dispatch+0x84/0x100 [vmw_vmci] [ 20.264706] vmci_datagram_send+0x2c/0x40 [vmw_vmci] [ 20.264709] vmci_transport_send_control_pkt+0xb8/0x120 [vmw_vsock_vmci_transport] [ 20.264711] vmci_transport_connect+0x40/0x7c [vmw_vsock_vmci_transport] [ 20.264713] vsock_connect+0x278/0x330 [vsock] [ 20.264715] __sys_connect_file+0x8c/0xc0 [ 20.264718] __sys_connect+0x84/0xb4 [ 20.264720] __arm64_sys_connect+0x2c/0x3c [ 20.264721] invoke_syscall+0x78/0x100 [ 20.264723] el0_svc_common.constprop.0+0x68/0x124 [ 20.264724] do_el0_svc+0x38/0x4c [ 20.264725] el0_svc+0x60/0x180 [ 20.264726] el0t_64_sync_handler+0x11c/0x150 [ 20.264728] el0t_64_sync+0x190/0x194 Signed-off-by: Vishnu Dasa Suggested-by: Zack Rusin Reported-by: Nadav Amit Reported-by: Nathan Chancellor Tested-by: Nathan Chancellor Fixes: 463713eb6164 ("VMCI: dma dg: add support for DMA datagrams receive") Cc: # v5.18+ Cc: VMware PV-Drivers Reviewers Cc: Greg Kroah-Hartman Cc: Bryan Tan Reviewed-by: Bryan Tan Reviewed-by: Zack Rusin Link: https://lore.kernel.org/r/20221130070511.46558-1-vdasa@vmware.com Signed-off-by: Greg Kroah-Hartman --- drivers/misc/vmw_vmci/vmci_guest.c | 49 ++++++++++++------------------ 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/drivers/misc/vmw_vmci/vmci_guest.c b/drivers/misc/vmw_vmci/vmci_guest.c index aa7b05de97dd..4f8d962bb5b2 100644 --- a/drivers/misc/vmw_vmci/vmci_guest.c +++ b/drivers/misc/vmw_vmci/vmci_guest.c @@ -56,8 +56,6 @@ struct vmci_guest_device { bool exclusive_vectors; - struct tasklet_struct datagram_tasklet; - struct tasklet_struct bm_tasklet; struct wait_queue_head inout_wq; void *data_buffer; @@ -304,9 +302,8 @@ static int vmci_check_host_caps(struct pci_dev *pdev) * This function assumes that it has exclusive access to the data * in register(s) for the duration of the call. */ -static void vmci_dispatch_dgs(unsigned long data) +static void vmci_dispatch_dgs(struct vmci_guest_device *vmci_dev) { - struct vmci_guest_device *vmci_dev = (struct vmci_guest_device *)data; u8 *dg_in_buffer = vmci_dev->data_buffer; struct vmci_datagram *dg; size_t dg_in_buffer_size = VMCI_MAX_DG_SIZE; @@ -465,10 +462,8 @@ static void vmci_dispatch_dgs(unsigned long data) * Scans the notification bitmap for raised flags, clears them * and handles the notifications. */ -static void vmci_process_bitmap(unsigned long data) +static void vmci_process_bitmap(struct vmci_guest_device *dev) { - struct vmci_guest_device *dev = (struct vmci_guest_device *)data; - if (!dev->notification_bitmap) { dev_dbg(dev->dev, "No bitmap present in %s\n", __func__); return; @@ -486,13 +481,13 @@ static irqreturn_t vmci_interrupt(int irq, void *_dev) struct vmci_guest_device *dev = _dev; /* - * If we are using MSI-X with exclusive vectors then we simply schedule - * the datagram tasklet, since we know the interrupt was meant for us. + * If we are using MSI-X with exclusive vectors then we simply call + * vmci_dispatch_dgs(), since we know the interrupt was meant for us. * Otherwise we must read the ICR to determine what to do. */ if (dev->exclusive_vectors) { - tasklet_schedule(&dev->datagram_tasklet); + vmci_dispatch_dgs(dev); } else { unsigned int icr; @@ -502,12 +497,12 @@ static irqreturn_t vmci_interrupt(int irq, void *_dev) return IRQ_NONE; if (icr & VMCI_ICR_DATAGRAM) { - tasklet_schedule(&dev->datagram_tasklet); + vmci_dispatch_dgs(dev); icr &= ~VMCI_ICR_DATAGRAM; } if (icr & VMCI_ICR_NOTIFICATION) { - tasklet_schedule(&dev->bm_tasklet); + vmci_process_bitmap(dev); icr &= ~VMCI_ICR_NOTIFICATION; } @@ -536,7 +531,7 @@ static irqreturn_t vmci_interrupt_bm(int irq, void *_dev) struct vmci_guest_device *dev = _dev; /* For MSI-X we can just assume it was meant for us. */ - tasklet_schedule(&dev->bm_tasklet); + vmci_process_bitmap(dev); return IRQ_HANDLED; } @@ -638,10 +633,6 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, vmci_dev->iobase = iobase; vmci_dev->mmio_base = mmio_base; - tasklet_init(&vmci_dev->datagram_tasklet, - vmci_dispatch_dgs, (unsigned long)vmci_dev); - tasklet_init(&vmci_dev->bm_tasklet, - vmci_process_bitmap, (unsigned long)vmci_dev); init_waitqueue_head(&vmci_dev->inout_wq); if (mmio_base != NULL) { @@ -808,8 +799,9 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, * Request IRQ for legacy or MSI interrupts, or for first * MSI-X vector. */ - error = request_irq(pci_irq_vector(pdev, 0), vmci_interrupt, - IRQF_SHARED, KBUILD_MODNAME, vmci_dev); + error = request_threaded_irq(pci_irq_vector(pdev, 0), NULL, + vmci_interrupt, IRQF_SHARED, + KBUILD_MODNAME, vmci_dev); if (error) { dev_err(&pdev->dev, "Irq %u in use: %d\n", pci_irq_vector(pdev, 0), error); @@ -823,9 +815,9 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, * between the vectors. */ if (vmci_dev->exclusive_vectors) { - error = request_irq(pci_irq_vector(pdev, 1), - vmci_interrupt_bm, 0, KBUILD_MODNAME, - vmci_dev); + error = request_threaded_irq(pci_irq_vector(pdev, 1), NULL, + vmci_interrupt_bm, 0, + KBUILD_MODNAME, vmci_dev); if (error) { dev_err(&pdev->dev, "Failed to allocate irq %u: %d\n", @@ -833,9 +825,11 @@ static int vmci_guest_probe_device(struct pci_dev *pdev, goto err_free_irq; } if (caps_in_use & VMCI_CAPS_DMA_DATAGRAM) { - error = request_irq(pci_irq_vector(pdev, 2), - vmci_interrupt_dma_datagram, - 0, KBUILD_MODNAME, vmci_dev); + error = request_threaded_irq(pci_irq_vector(pdev, 2), + NULL, + vmci_interrupt_dma_datagram, + 0, KBUILD_MODNAME, + vmci_dev); if (error) { dev_err(&pdev->dev, "Failed to allocate irq %u: %d\n", @@ -871,8 +865,6 @@ err_free_bm_irq: err_free_irq: free_irq(pci_irq_vector(pdev, 0), vmci_dev); - tasklet_kill(&vmci_dev->datagram_tasklet); - tasklet_kill(&vmci_dev->bm_tasklet); err_disable_msi: pci_free_irq_vectors(pdev); @@ -943,9 +935,6 @@ static void vmci_guest_remove_device(struct pci_dev *pdev) free_irq(pci_irq_vector(pdev, 0), vmci_dev); pci_free_irq_vectors(pdev); - tasklet_kill(&vmci_dev->datagram_tasklet); - tasklet_kill(&vmci_dev->bm_tasklet); - if (vmci_dev->notification_bitmap) { /* * The device reset above cleared the bitmap state of the From 14ee78d5932afeb710c8305196a676a715bfdea8 Mon Sep 17 00:00:00 2001 From: Matthew Howell Date: Thu, 19 Jan 2023 14:40:29 -0500 Subject: [PATCH 387/398] serial: exar: Add support for Sealevel 7xxxC serial cards Add support for Sealevel 7xxxC serial cards. This patch: * Adds IDs to recognize 7xxxC cards from Sealevel Systems. * Updates exar_pci_probe() to set nr_ports to last two bytes of primary dev ID for these cards. Signed-off-by: Matthew Howell Cc: stable Link: https://lore.kernel.org/r/alpine.DEB.2.21.2301191440010.22558@tstest-VirtualBox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_exar.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/drivers/tty/serial/8250/8250_exar.c b/drivers/tty/serial/8250/8250_exar.c index 314a05e009df..64770c62bbec 100644 --- a/drivers/tty/serial/8250/8250_exar.c +++ b/drivers/tty/serial/8250/8250_exar.c @@ -43,6 +43,12 @@ #define PCI_DEVICE_ID_EXAR_XR17V4358 0x4358 #define PCI_DEVICE_ID_EXAR_XR17V8358 0x8358 +#define PCI_DEVICE_ID_SEALEVEL_710xC 0x1001 +#define PCI_DEVICE_ID_SEALEVEL_720xC 0x1002 +#define PCI_DEVICE_ID_SEALEVEL_740xC 0x1004 +#define PCI_DEVICE_ID_SEALEVEL_780xC 0x1008 +#define PCI_DEVICE_ID_SEALEVEL_716xC 0x1010 + #define UART_EXAR_INT0 0x80 #define UART_EXAR_8XMODE 0x88 /* 8X sampling rate select */ #define UART_EXAR_SLEEP 0x8b /* Sleep mode */ @@ -638,6 +644,8 @@ exar_pci_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) nr_ports = BIT(((pcidev->device & 0x38) >> 3) - 1); else if (board->num_ports) nr_ports = board->num_ports; + else if (pcidev->vendor == PCI_VENDOR_ID_SEALEVEL) + nr_ports = pcidev->device & 0xff; else nr_ports = pcidev->device & 0x0f; @@ -864,6 +872,12 @@ static const struct pci_device_id exar_pci_tbl[] = { EXAR_DEVICE(COMMTECH, 4224PCI335, pbn_fastcom335_4), EXAR_DEVICE(COMMTECH, 2324PCI335, pbn_fastcom335_4), EXAR_DEVICE(COMMTECH, 2328PCI335, pbn_fastcom335_8), + + EXAR_DEVICE(SEALEVEL, 710xC, pbn_exar_XR17V35x), + EXAR_DEVICE(SEALEVEL, 720xC, pbn_exar_XR17V35x), + EXAR_DEVICE(SEALEVEL, 740xC, pbn_exar_XR17V35x), + EXAR_DEVICE(SEALEVEL, 780xC, pbn_exar_XR17V35x), + EXAR_DEVICE(SEALEVEL, 716xC, pbn_exar_XR17V35x), { 0, } }; MODULE_DEVICE_TABLE(pci, exar_pci_tbl); From d3e599c090fc6977331150c5f0a69ab8ce87da21 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Wed, 18 Jan 2023 12:35:01 -0800 Subject: [PATCH 388/398] bnxt: Do not read past the end of test names Test names were being concatenated based on a offset beyond the end of the first name, which tripped the buffer overflow detection logic: detected buffer overflow in strnlen [...] Call Trace: bnxt_ethtool_init.cold+0x18/0x18 Refactor struct hwrm_selftest_qlist_output to use an actual array, and adjust the concatenation to use snprintf() rather than a series of strncat() calls. Reported-by: Niklas Cassel Link: https://lore.kernel.org/lkml/Y8F%2F1w1AZTvLglFX@x1-carbon/ Tested-by: Niklas Cassel Fixes: eb51365846bc ("bnxt_en: Add basic ethtool -t selftest support.") Cc: Michael Chan Cc: "David S. Miller" Cc: Eric Dumazet Cc: Jakub Kicinski Cc: Paolo Abeni Cc: netdev@vger.kernel.org Signed-off-by: Kees Cook Reviewed-by: Michael Chan Reviewed-by: Niklas Cassel Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 13 ++++--------- drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h | 9 +-------- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index cbf17fcfb7ab..ec573127b707 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -3969,7 +3969,7 @@ void bnxt_ethtool_init(struct bnxt *bp) test_info->timeout = HWRM_CMD_TIMEOUT; for (i = 0; i < bp->num_tests; i++) { char *str = test_info->string[i]; - char *fw_str = resp->test0_name + i * 32; + char *fw_str = resp->test_name[i]; if (i == BNXT_MACLPBK_TEST_IDX) { strcpy(str, "Mac loopback test (offline)"); @@ -3980,14 +3980,9 @@ void bnxt_ethtool_init(struct bnxt *bp) } else if (i == BNXT_IRQ_TEST_IDX) { strcpy(str, "Interrupt_test (offline)"); } else { - strscpy(str, fw_str, ETH_GSTRING_LEN); - strncat(str, " test", ETH_GSTRING_LEN - strlen(str)); - if (test_info->offline_mask & (1 << i)) - strncat(str, " (offline)", - ETH_GSTRING_LEN - strlen(str)); - else - strncat(str, " (online)", - ETH_GSTRING_LEN - strlen(str)); + snprintf(str, ETH_GSTRING_LEN, "%s test (%s)", + fw_str, test_info->offline_mask & (1 << i) ? + "offline" : "online"); } } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h index 2686a714a59f..a5408879e077 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h @@ -10249,14 +10249,7 @@ struct hwrm_selftest_qlist_output { u8 unused_0; __le16 test_timeout; u8 unused_1[2]; - char test0_name[32]; - char test1_name[32]; - char test2_name[32]; - char test3_name[32]; - char test4_name[32]; - char test5_name[32]; - char test6_name[32]; - char test7_name[32]; + char test_name[8][32]; u8 eyescope_target_BER_support; #define SELFTEST_QLIST_RESP_EYESCOPE_TARGET_BER_SUPPORT_BER_1E8_SUPPORTED 0x0UL #define SELFTEST_QLIST_RESP_EYESCOPE_TARGET_BER_SUPPORT_BER_1E9_SUPPORTED 0x1UL From 300b655db1b5152d6101bcb6801d50899b20c2d6 Mon Sep 17 00:00:00 2001 From: David Morley Date: Thu, 19 Jan 2023 19:00:28 +0000 Subject: [PATCH 389/398] tcp: fix rate_app_limited to default to 1 The initial default value of 0 for tp->rate_app_limited was incorrect, since a flow is indeed application-limited until it first sends data. Fixing the default to be 1 is generally correct but also specifically will help user-space applications avoid using the initial tcpi_delivery_rate value of 0 that persists until the connection has some non-zero bandwidth sample. Fixes: eb8329e0a04d ("tcp: export data delivery rate") Suggested-by: Yuchung Cheng Signed-off-by: David Morley Signed-off-by: Neal Cardwell Tested-by: David Morley Reviewed-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index c567d5e8053e..33f559f491c8 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -435,6 +435,7 @@ void tcp_init_sock(struct sock *sk) /* There's a bubble in the pipe until at least the first ACK. */ tp->app_limited = ~0U; + tp->rate_app_limited = 1; /* See draft-stevens-tcpca-spec-01 for discussion of the * initialization of these values. @@ -3178,6 +3179,7 @@ int tcp_disconnect(struct sock *sk, int flags) tp->plb_rehash = 0; /* There's a bubble in the pipe until at least the first ACK. */ tp->app_limited = ~0U; + tp->rate_app_limited = 1; tp->rack.mstamp = 0; tp->rack.advanced = 0; tp->rack.reo_wnd_steps = 1; From 5d3d01ae15d2f37ed0325c99ab47ef0ae5d05f3c Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Fri, 20 Jan 2023 13:27:14 +0100 Subject: [PATCH 390/398] usb: host: ehci-fsl: Fix module alias Commit ca07e1c1e4a6 ("drivers:usb:fsl:Make fsl ehci drv an independent driver module") changed DRV_NAME which was used for MODULE_ALIAS as well. Starting from this the module alias didn't match the platform device name created in fsl-mph-dr-of.c Change DRV_NAME to match the driver name for host mode in fsl-mph-dr-of. This is needed for module autoloading on ls1021a. Fixes: ca07e1c1e4a6 ("drivers:usb:fsl:Make fsl ehci drv an independent driver module") Cc: stable Signed-off-by: Alexander Stein Link: https://lore.kernel.org/r/20230120122714.3848784-1-alexander.stein@ew.tq-group.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 9cea785934e5..38d06e5abfbb 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -29,7 +29,7 @@ #include "ehci-fsl.h" #define DRIVER_DESC "Freescale EHCI Host controller driver" -#define DRV_NAME "ehci-fsl" +#define DRV_NAME "fsl-ehci" static struct hc_driver __read_mostly fsl_ehci_hc_driver; From 14ff7460bb58662d86aa50298943cc7d25532e28 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 20 Jan 2023 14:53:30 +0100 Subject: [PATCH 391/398] USB: misc: iowarrior: fix up header size for USB_DEVICE_ID_CODEMERCS_IOW100 The USB_DEVICE_ID_CODEMERCS_IOW100 header size was incorrect, it should be 12, not 13. Cc: stable Fixes: 17a82716587e ("USB: iowarrior: fix up report size handling for some devices") Reported-by: Christoph Jung Link: https://lore.kernel.org/r/20230120135330.3842518-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/iowarrior.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index f9427a67789c..1e3df27bab58 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -814,7 +814,7 @@ static int iowarrior_probe(struct usb_interface *interface, break; case USB_DEVICE_ID_CODEMERCS_IOW100: - dev->report_size = 13; + dev->report_size = 12; break; } } From 45a919bbb21c642e0c34dac483d1e003560159dc Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 20 Jan 2023 08:38:16 -0800 Subject: [PATCH 392/398] Revert "Merge branch 'octeontx2-af-CPT'" This reverts commit b4fbf0b27fa9dd2594b3371532341bd4636a00f9, reversing changes made to 6c977c5c2e4c5d8ad1b604724cc344e38f96fe9b. This seems like net-next material. Signed-off-by: Jakub Kicinski --- .../net/ethernet/marvell/octeontx2/af/mbox.h | 27 -- .../net/ethernet/marvell/octeontx2/af/rvu.c | 8 - .../net/ethernet/marvell/octeontx2/af/rvu.h | 18 - .../ethernet/marvell/octeontx2/af/rvu_cpt.c | 311 +++++------------- .../ethernet/marvell/octeontx2/af/rvu_reg.h | 2 - 5 files changed, 88 insertions(+), 278 deletions(-) diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h index 84761c7f6717..d2584ebb7a70 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h @@ -195,9 +195,6 @@ M(CPT_STATS, 0xA05, cpt_sts, cpt_sts_req, cpt_sts_rsp) \ M(CPT_RXC_TIME_CFG, 0xA06, cpt_rxc_time_cfg, cpt_rxc_time_cfg_req, \ msg_rsp) \ M(CPT_CTX_CACHE_SYNC, 0xA07, cpt_ctx_cache_sync, msg_req, msg_rsp) \ -M(CPT_LF_RESET, 0xA08, cpt_lf_reset, cpt_lf_rst_req, msg_rsp) \ -M(CPT_FLT_ENG_INFO, 0xA09, cpt_flt_eng_info, cpt_flt_eng_info_req, \ - cpt_flt_eng_info_rsp) \ /* SDP mbox IDs (range 0x1000 - 0x11FF) */ \ M(SET_SDP_CHAN_INFO, 0x1000, set_sdp_chan_info, sdp_chan_info_msg, msg_rsp) \ M(GET_SDP_CHAN_INFO, 0x1001, get_sdp_chan_info, msg_req, sdp_get_chan_info_msg) \ @@ -1612,8 +1609,6 @@ struct cpt_lf_alloc_req_msg { u16 sso_pf_func; u16 eng_grpmsk; int blkaddr; - u8 ctx_ilen_valid : 1; - u8 ctx_ilen : 7; }; #define CPT_INLINE_INBOUND 0 @@ -1697,28 +1692,6 @@ struct cpt_inst_lmtst_req { u64 rsvd; }; -/* Mailbox message format to request for CPT LF reset */ -struct cpt_lf_rst_req { - struct mbox_msghdr hdr; - u32 slot; - u32 rsvd; -}; - -/* Mailbox message format to request for CPT faulted engines */ -struct cpt_flt_eng_info_req { - struct mbox_msghdr hdr; - int blkaddr; - bool reset; - u32 rsvd; -}; - -struct cpt_flt_eng_info_rsp { - struct mbox_msghdr hdr; - u64 flt_eng_map[CPT_10K_AF_INT_VEC_RVU]; - u64 rcvrd_eng_map[CPT_10K_AF_INT_VEC_RVU]; - u64 rsvd; -}; - struct sdp_node_info { /* Node to which this PF belons to */ u8 node_id; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c index 8683ce57ed3f..3f5e09b77d4b 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -1164,16 +1164,8 @@ cpt: goto nix_err; } - err = rvu_cpt_init(rvu); - if (err) { - dev_err(rvu->dev, "%s: Failed to initialize cpt\n", __func__); - goto mcs_err; - } - return 0; -mcs_err: - rvu_mcs_exit(rvu); nix_err: rvu_nix_freemem(rvu); npa_err: diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h index 5eea2b6cf6bd..7f0a64731c67 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h @@ -108,8 +108,6 @@ struct rvu_block { u64 lfreset_reg; unsigned char name[NAME_SIZE]; struct rvu *rvu; - u64 cpt_flt_eng_map[3]; - u64 cpt_rcvrd_eng_map[3]; }; struct nix_mcast { @@ -461,7 +459,6 @@ struct rvu { struct rvu_pfvf *pf; struct rvu_pfvf *hwvf; struct mutex rsrc_lock; /* Serialize resource alloc/free */ - struct mutex alias_lock; /* Serialize bar2 alias access */ int vfs; /* Number of VFs attached to RVU */ int nix_blkaddr[MAX_NIX_BLKS]; @@ -513,7 +510,6 @@ struct rvu { struct ptp *ptp; int mcs_blk_cnt; - int cpt_pf_num; #ifdef CONFIG_DEBUG_FS struct rvu_debugfs rvu_dbg; @@ -528,8 +524,6 @@ struct rvu { struct list_head mcs_intrq_head; /* mcs interrupt queue lock */ spinlock_t mcs_intrq_lock; - /* CPT interrupt lock */ - spinlock_t cpt_intr_lock; }; static inline void rvu_write64(struct rvu *rvu, u64 block, u64 offset, u64 val) @@ -552,17 +546,6 @@ static inline u64 rvupf_read64(struct rvu *rvu, u64 offset) return readq(rvu->pfreg_base + offset); } -static inline void rvu_bar2_sel_write64(struct rvu *rvu, u64 block, u64 offset, u64 val) -{ - /* HW requires read back of RVU_AF_BAR2_SEL register to make sure completion of - * write operation. - */ - rvu_write64(rvu, block, offset, val); - rvu_read64(rvu, block, offset); - /* Barrier to ensure read completes before accessing LF registers */ - mb(); -} - /* Silicon revisions */ static inline bool is_rvu_pre_96xx_C0(struct rvu *rvu) { @@ -882,7 +865,6 @@ void rvu_cpt_unregister_interrupts(struct rvu *rvu); int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, int slot); int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc); -int rvu_cpt_init(struct rvu *rvu); /* CN10K RVU */ int rvu_set_channels_base(struct rvu *rvu); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c index f047185f38e0..38bbae5d9ae0 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cpt.c @@ -17,7 +17,7 @@ #define PCI_DEVID_OTX2_CPT10K_PF 0xA0F2 /* Length of initial context fetch in 128 byte words */ -#define CPT_CTX_ILEN 1ULL +#define CPT_CTX_ILEN 2ULL #define cpt_get_eng_sts(e_min, e_max, rsp, etype) \ ({ \ @@ -37,68 +37,34 @@ (_rsp)->free_sts_##etype = free_sts; \ }) -static irqreturn_t cpt_af_flt_intr_handler(int vec, void *ptr) +static irqreturn_t rvu_cpt_af_flt_intr_handler(int irq, void *ptr) { struct rvu_block *block = ptr; struct rvu *rvu = block->rvu; int blkaddr = block->addr; - u64 reg, val; - int i, eng; - u8 grp; + u64 reg0, reg1, reg2; - reg = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(vec)); - dev_err_ratelimited(rvu->dev, "Received CPTAF FLT%d irq : 0x%llx", vec, reg); - - i = -1; - while ((i = find_next_bit((unsigned long *)®, 64, i + 1)) < 64) { - switch (vec) { - case 0: - eng = i; - break; - case 1: - eng = i + 64; - break; - case 2: - eng = i + 128; - break; - } - grp = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng)) & 0xFF; - /* Disable and enable the engine which triggers fault */ - rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng), 0x0); - val = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng)); - rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng), val & ~1ULL); - - rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL2(eng), grp); - rvu_write64(rvu, blkaddr, CPT_AF_EXEX_CTL(eng), val | 1ULL); - - spin_lock(&rvu->cpt_intr_lock); - block->cpt_flt_eng_map[vec] |= BIT_ULL(i); - val = rvu_read64(rvu, blkaddr, CPT_AF_EXEX_STS(eng)); - val = val & 0x3; - if (val == 0x1 || val == 0x2) - block->cpt_rcvrd_eng_map[vec] |= BIT_ULL(i); - spin_unlock(&rvu->cpt_intr_lock); + reg0 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(0)); + reg1 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(1)); + if (!is_rvu_otx2(rvu)) { + reg2 = rvu_read64(rvu, blkaddr, CPT_AF_FLTX_INT(2)); + dev_err_ratelimited(rvu->dev, + "Received CPTAF FLT irq : 0x%llx, 0x%llx, 0x%llx", + reg0, reg1, reg2); + } else { + dev_err_ratelimited(rvu->dev, + "Received CPTAF FLT irq : 0x%llx, 0x%llx", + reg0, reg1); } - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(vec), reg); + + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(0), reg0); + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(1), reg1); + if (!is_rvu_otx2(rvu)) + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT(2), reg2); return IRQ_HANDLED; } -static irqreturn_t rvu_cpt_af_flt0_intr_handler(int irq, void *ptr) -{ - return cpt_af_flt_intr_handler(CPT_AF_INT_VEC_FLT0, ptr); -} - -static irqreturn_t rvu_cpt_af_flt1_intr_handler(int irq, void *ptr) -{ - return cpt_af_flt_intr_handler(CPT_AF_INT_VEC_FLT1, ptr); -} - -static irqreturn_t rvu_cpt_af_flt2_intr_handler(int irq, void *ptr) -{ - return cpt_af_flt_intr_handler(CPT_10K_AF_INT_VEC_FLT2, ptr); -} - static irqreturn_t rvu_cpt_af_rvu_intr_handler(int irq, void *ptr) { struct rvu_block *block = ptr; @@ -153,10 +119,8 @@ static void cpt_10k_unregister_interrupts(struct rvu_block *block, int off) int i; /* Disable all CPT AF interrupts */ - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(0), ~0ULL); - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(1), ~0ULL); - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(2), 0xFFFF); - + for (i = 0; i < CPT_10K_AF_INT_VEC_RVU; i++) + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1); rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1); rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1); @@ -187,7 +151,7 @@ static void cpt_unregister_interrupts(struct rvu *rvu, int blkaddr) /* Disable all CPT AF interrupts */ for (i = 0; i < CPT_AF_INT_VEC_RVU; i++) - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), ~0ULL); + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1C(i), 0x1); rvu_write64(rvu, blkaddr, CPT_AF_RVU_INT_ENA_W1C, 0x1); rvu_write64(rvu, blkaddr, CPT_AF_RAS_INT_ENA_W1C, 0x1); @@ -208,31 +172,16 @@ static int cpt_10k_register_interrupts(struct rvu_block *block, int off) { struct rvu *rvu = block->rvu; int blkaddr = block->addr; - irq_handler_t flt_fn; int i, ret; for (i = CPT_10K_AF_INT_VEC_FLT0; i < CPT_10K_AF_INT_VEC_RVU; i++) { sprintf(&rvu->irq_name[(off + i) * NAME_SIZE], "CPTAF FLT%d", i); - - switch (i) { - case CPT_10K_AF_INT_VEC_FLT0: - flt_fn = rvu_cpt_af_flt0_intr_handler; - break; - case CPT_10K_AF_INT_VEC_FLT1: - flt_fn = rvu_cpt_af_flt1_intr_handler; - break; - case CPT_10K_AF_INT_VEC_FLT2: - flt_fn = rvu_cpt_af_flt2_intr_handler; - break; - } ret = rvu_cpt_do_register_interrupt(block, off + i, - flt_fn, &rvu->irq_name[(off + i) * NAME_SIZE]); + rvu_cpt_af_flt_intr_handler, + &rvu->irq_name[(off + i) * NAME_SIZE]); if (ret) goto err; - if (i == CPT_10K_AF_INT_VEC_FLT2) - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0xFFFF); - else - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), ~0ULL); + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1); } ret = rvu_cpt_do_register_interrupt(block, off + CPT_10K_AF_INT_VEC_RVU, @@ -259,8 +208,8 @@ static int cpt_register_interrupts(struct rvu *rvu, int blkaddr) { struct rvu_hwinfo *hw = rvu->hw; struct rvu_block *block; - irq_handler_t flt_fn; int i, offs, ret = 0; + char irq_name[16]; if (!is_block_implemented(rvu->hw, blkaddr)) return 0; @@ -277,20 +226,13 @@ static int cpt_register_interrupts(struct rvu *rvu, int blkaddr) return cpt_10k_register_interrupts(block, offs); for (i = CPT_AF_INT_VEC_FLT0; i < CPT_AF_INT_VEC_RVU; i++) { - sprintf(&rvu->irq_name[(offs + i) * NAME_SIZE], "CPTAF FLT%d", i); - switch (i) { - case CPT_AF_INT_VEC_FLT0: - flt_fn = rvu_cpt_af_flt0_intr_handler; - break; - case CPT_AF_INT_VEC_FLT1: - flt_fn = rvu_cpt_af_flt1_intr_handler; - break; - } + snprintf(irq_name, sizeof(irq_name), "CPTAF FLT%d", i); ret = rvu_cpt_do_register_interrupt(block, offs + i, - flt_fn, &rvu->irq_name[(offs + i) * NAME_SIZE]); + rvu_cpt_af_flt_intr_handler, + irq_name); if (ret) goto err; - rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), ~0ULL); + rvu_write64(rvu, blkaddr, CPT_AF_FLTX_INT_ENA_W1S(i), 0x1); } ret = rvu_cpt_do_register_interrupt(block, offs + CPT_AF_INT_VEC_RVU, @@ -348,7 +290,7 @@ static int get_cpt_pf_num(struct rvu *rvu) static bool is_cpt_pf(struct rvu *rvu, u16 pcifunc) { - int cpt_pf_num = rvu->cpt_pf_num; + int cpt_pf_num = get_cpt_pf_num(rvu); if (rvu_get_pf(pcifunc) != cpt_pf_num) return false; @@ -360,7 +302,7 @@ static bool is_cpt_pf(struct rvu *rvu, u16 pcifunc) static bool is_cpt_vf(struct rvu *rvu, u16 pcifunc) { - int cpt_pf_num = rvu->cpt_pf_num; + int cpt_pf_num = get_cpt_pf_num(rvu); if (rvu_get_pf(pcifunc) != cpt_pf_num) return false; @@ -429,12 +371,8 @@ int rvu_mbox_handler_cpt_lf_alloc(struct rvu *rvu, /* Set CPT LF group and priority */ val = (u64)req->eng_grpmsk << 48 | 1; - if (!is_rvu_otx2(rvu)) { - if (req->ctx_ilen_valid) - val |= (req->ctx_ilen << 17); - else - val |= (CPT_CTX_ILEN << 17); - } + if (!is_rvu_otx2(rvu)) + val |= (CPT_CTX_ILEN << 17); rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL(cptlf), val); @@ -824,21 +762,10 @@ int rvu_mbox_handler_cpt_sts(struct rvu *rvu, struct cpt_sts_req *req, #define RXC_ZOMBIE_COUNT GENMASK_ULL(60, 48) static void cpt_rxc_time_cfg(struct rvu *rvu, struct cpt_rxc_time_cfg_req *req, - int blkaddr, struct cpt_rxc_time_cfg_req *save) + int blkaddr) { u64 dfrg_reg; - if (save) { - /* Save older config */ - dfrg_reg = rvu_read64(rvu, blkaddr, CPT_AF_RXC_DFRG); - save->zombie_thres = FIELD_GET(RXC_ZOMBIE_THRES, dfrg_reg); - save->zombie_limit = FIELD_GET(RXC_ZOMBIE_LIMIT, dfrg_reg); - save->active_thres = FIELD_GET(RXC_ACTIVE_THRES, dfrg_reg); - save->active_limit = FIELD_GET(RXC_ACTIVE_LIMIT, dfrg_reg); - - save->step = rvu_read64(rvu, blkaddr, CPT_AF_RXC_TIME_CFG); - } - dfrg_reg = FIELD_PREP(RXC_ZOMBIE_THRES, req->zombie_thres); dfrg_reg |= FIELD_PREP(RXC_ZOMBIE_LIMIT, req->zombie_limit); dfrg_reg |= FIELD_PREP(RXC_ACTIVE_THRES, req->active_thres); @@ -863,7 +790,7 @@ int rvu_mbox_handler_cpt_rxc_time_cfg(struct rvu *rvu, !is_cpt_vf(rvu, req->hdr.pcifunc)) return CPT_AF_ERR_ACCESS_DENIED; - cpt_rxc_time_cfg(rvu, req, blkaddr, NULL); + cpt_rxc_time_cfg(rvu, req, blkaddr); return 0; } @@ -874,67 +801,9 @@ int rvu_mbox_handler_cpt_ctx_cache_sync(struct rvu *rvu, struct msg_req *req, return rvu_cpt_ctx_flush(rvu, req->hdr.pcifunc); } -int rvu_mbox_handler_cpt_lf_reset(struct rvu *rvu, struct cpt_lf_rst_req *req, - struct msg_rsp *rsp) -{ - u16 pcifunc = req->hdr.pcifunc; - struct rvu_block *block; - int cptlf, blkaddr, ret; - u16 actual_slot; - u64 ctl, ctl2; - - blkaddr = rvu_get_blkaddr_from_slot(rvu, BLKTYPE_CPT, pcifunc, - req->slot, &actual_slot); - if (blkaddr < 0) - return CPT_AF_ERR_LF_INVALID; - - block = &rvu->hw->block[blkaddr]; - - cptlf = rvu_get_lf(rvu, block, pcifunc, actual_slot); - if (cptlf < 0) - return CPT_AF_ERR_LF_INVALID; - ctl = rvu_read64(rvu, blkaddr, CPT_AF_LFX_CTL(cptlf)); - ctl2 = rvu_read64(rvu, blkaddr, CPT_AF_LFX_CTL2(cptlf)); - - ret = rvu_lf_reset(rvu, block, cptlf); - if (ret) - dev_err(rvu->dev, "Failed to reset blkaddr %d LF%d\n", - block->addr, cptlf); - - rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL(cptlf), ctl); - rvu_write64(rvu, blkaddr, CPT_AF_LFX_CTL2(cptlf), ctl2); - - return 0; -} - -int rvu_mbox_handler_cpt_flt_eng_info(struct rvu *rvu, struct cpt_flt_eng_info_req *req, - struct cpt_flt_eng_info_rsp *rsp) -{ - struct rvu_block *block; - unsigned long flags; - int blkaddr, vec; - - blkaddr = validate_and_get_cpt_blkaddr(req->blkaddr); - if (blkaddr < 0) - return blkaddr; - - block = &rvu->hw->block[blkaddr]; - for (vec = 0; vec < CPT_10K_AF_INT_VEC_RVU; vec++) { - spin_lock_irqsave(&rvu->cpt_intr_lock, flags); - rsp->flt_eng_map[vec] = block->cpt_flt_eng_map[vec]; - rsp->rcvrd_eng_map[vec] = block->cpt_rcvrd_eng_map[vec]; - if (req->reset) { - block->cpt_flt_eng_map[vec] = 0x0; - block->cpt_rcvrd_eng_map[vec] = 0x0; - } - spin_unlock_irqrestore(&rvu->cpt_intr_lock, flags); - } - return 0; -} - static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr) { - struct cpt_rxc_time_cfg_req req, prev; + struct cpt_rxc_time_cfg_req req; int timeout = 2000; u64 reg; @@ -950,7 +819,7 @@ static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr) req.active_thres = 1; req.active_limit = 1; - cpt_rxc_time_cfg(rvu, &req, blkaddr, &prev); + cpt_rxc_time_cfg(rvu, &req, blkaddr); do { reg = rvu_read64(rvu, blkaddr, CPT_AF_RXC_ACTIVE_STS); @@ -976,68 +845,70 @@ static void cpt_rxc_teardown(struct rvu *rvu, int blkaddr) if (timeout == 0) dev_warn(rvu->dev, "Poll for RXC zombie count hits hard loop counter\n"); - - /* Restore config */ - cpt_rxc_time_cfg(rvu, &prev, blkaddr, NULL); } -#define INFLIGHT GENMASK_ULL(8, 0) -#define GRB_CNT GENMASK_ULL(39, 32) -#define GWB_CNT GENMASK_ULL(47, 40) -#define XQ_XOR GENMASK_ULL(63, 63) -#define DQPTR GENMASK_ULL(19, 0) -#define NQPTR GENMASK_ULL(51, 32) +#define INPROG_INFLIGHT(reg) ((reg) & 0x1FF) +#define INPROG_GRB_PARTIAL(reg) ((reg) & BIT_ULL(31)) +#define INPROG_GRB(reg) (((reg) >> 32) & 0xFF) +#define INPROG_GWB(reg) (((reg) >> 40) & 0xFF) static void cpt_lf_disable_iqueue(struct rvu *rvu, int blkaddr, int slot) { - int timeout = 1000000; - u64 inprog, inst_ptr; - u64 qsize, pending; - int i = 0; + int i = 0, hard_lp_ctr = 100000; + u64 inprog, grp_ptr; + u16 nq_ptr, dq_ptr; /* Disable instructions enqueuing */ rvu_write64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_CTL), 0x0); + /* Disable executions in the LF's queue */ inprog = rvu_read64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG)); - inprog |= BIT_ULL(16); + inprog &= ~BIT_ULL(16); rvu_write64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG), inprog); - qsize = rvu_read64(rvu, blkaddr, - CPT_AF_BAR2_ALIASX(slot, CPT_LF_Q_SIZE)) & 0x7FFF; - do { - inst_ptr = rvu_read64(rvu, blkaddr, - CPT_AF_BAR2_ALIASX(slot, CPT_LF_Q_INST_PTR)); - pending = (FIELD_GET(XQ_XOR, inst_ptr) * qsize * 40) + - FIELD_GET(NQPTR, inst_ptr) - - FIELD_GET(DQPTR, inst_ptr); - udelay(1); - timeout--; - } while ((pending != 0) && (timeout != 0)); - - if (timeout == 0) - dev_warn(rvu->dev, "TIMEOUT: CPT poll on pending instructions\n"); - - timeout = 1000000; /* Wait for CPT queue to become execution-quiescent */ do { inprog = rvu_read64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG)); + if (INPROG_GRB_PARTIAL(inprog)) { + i = 0; + hard_lp_ctr--; + } else { + i++; + } - if ((FIELD_GET(INFLIGHT, inprog) == 0) && - (FIELD_GET(GRB_CNT, inprog) == 0)) { + grp_ptr = rvu_read64(rvu, blkaddr, + CPT_AF_BAR2_ALIASX(slot, + CPT_LF_Q_GRP_PTR)); + nq_ptr = (grp_ptr >> 32) & 0x7FFF; + dq_ptr = grp_ptr & 0x7FFF; + + } while (hard_lp_ctr && (i < 10) && (nq_ptr != dq_ptr)); + + if (hard_lp_ctr == 0) + dev_warn(rvu->dev, "CPT FLR hits hard loop counter\n"); + + i = 0; + hard_lp_ctr = 100000; + do { + inprog = rvu_read64(rvu, blkaddr, + CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG)); + + if ((INPROG_INFLIGHT(inprog) == 0) && + (INPROG_GWB(inprog) < 40) && + ((INPROG_GRB(inprog) == 0) || + (INPROG_GRB((inprog)) == 40))) { i++; } else { i = 0; - timeout--; + hard_lp_ctr--; } - } while ((timeout != 0) && (i < 10)); + } while (hard_lp_ctr && (i < 10)); - if (timeout == 0) - dev_warn(rvu->dev, "TIMEOUT: CPT poll on inflight count\n"); - /* Wait for 2 us to flush all queue writes to memory */ - udelay(2); + if (hard_lp_ctr == 0) + dev_warn(rvu->dev, "CPT FLR hits hard loop counter\n"); } int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, int slot) @@ -1047,15 +918,18 @@ int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, int s if (is_cpt_pf(rvu, pcifunc) || is_cpt_vf(rvu, pcifunc)) cpt_rxc_teardown(rvu, blkaddr); - mutex_lock(&rvu->alias_lock); /* Enable BAR2 ALIAS for this pcifunc. */ reg = BIT_ULL(16) | pcifunc; - rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg); + rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg); cpt_lf_disable_iqueue(rvu, blkaddr, slot); - rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0); - mutex_unlock(&rvu->alias_lock); + /* Set group drop to help clear out hardware */ + reg = rvu_read64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG)); + reg |= BIT_ULL(17); + rvu_write64(rvu, blkaddr, CPT_AF_BAR2_ALIASX(slot, CPT_LF_INPROG), reg); + + rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0); return 0; } @@ -1066,7 +940,7 @@ int rvu_cpt_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int lf, int s static int cpt_inline_inb_lf_cmd_send(struct rvu *rvu, int blkaddr, int nix_blkaddr) { - int cpt_pf_num = rvu->cpt_pf_num; + int cpt_pf_num = get_cpt_pf_num(rvu); struct cpt_inst_lmtst_req *req; dma_addr_t res_daddr; int timeout = 3000; @@ -1190,7 +1064,7 @@ int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc) /* Enable BAR2 ALIAS for this pcifunc. */ reg = BIT_ULL(16) | pcifunc; - rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg); + rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, reg); for (i = 0; i < max_ctx_entries; i++) { cam_data = rvu_read64(rvu, blkaddr, CPT_AF_CTX_CAM_DATA(i)); @@ -1203,19 +1077,10 @@ int rvu_cpt_ctx_flush(struct rvu *rvu, u16 pcifunc) reg); } } - rvu_bar2_sel_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0); + rvu_write64(rvu, blkaddr, CPT_AF_BAR2_SEL, 0); unlock: mutex_unlock(&rvu->rsrc_lock); return 0; } - -int rvu_cpt_init(struct rvu *rvu) -{ - /* Retrieve CPT PF number */ - rvu->cpt_pf_num = get_cpt_pf_num(rvu); - spin_lock_init(&rvu->cpt_intr_lock); - - return 0; -} diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h index 5437bd20c719..0e0d536645ac 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.h @@ -545,8 +545,6 @@ #define CPT_LF_CTL 0x10 #define CPT_LF_INPROG 0x40 -#define CPT_LF_Q_SIZE 0x100 -#define CPT_LF_Q_INST_PTR 0x110 #define CPT_LF_Q_GRP_PTR 0x120 #define CPT_LF_CTX_FLUSH 0x510 From 56d8e3180c065c9b78ed77afcd0cf99677a4e22f Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Fri, 20 Jan 2023 16:38:05 +0000 Subject: [PATCH 393/398] io_uring/msg_ring: fix flagging remote execution There is a couple of problems with queueing a tw in io_msg_ring_data() for remote execution. First, once we queue it the target ring can go away and so setting IORING_SQ_TASKRUN there is not safe. Secondly, the userspace might not expect IORING_SQ_TASKRUN. Extract a helper and uniformly use TWA_SIGNAL without TWA_SIGNAL_NO_IPI tricks for now, just as it was done in the original patch. Cc: stable@vger.kernel.org Fixes: 6d043ee1164ca ("io_uring: do msg_ring in target task via tw") Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- io_uring/msg_ring.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c index a333781565d3..bb868447dcdf 100644 --- a/io_uring/msg_ring.c +++ b/io_uring/msg_ring.c @@ -58,6 +58,25 @@ void io_msg_ring_cleanup(struct io_kiocb *req) msg->src_file = NULL; } +static inline bool io_msg_need_remote(struct io_ring_ctx *target_ctx) +{ + if (!target_ctx->task_complete) + return false; + return current != target_ctx->submitter_task; +} + +static int io_msg_exec_remote(struct io_kiocb *req, task_work_func_t func) +{ + struct io_ring_ctx *ctx = req->file->private_data; + struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); + + init_task_work(&msg->tw, func); + if (task_work_add(ctx->submitter_task, &msg->tw, TWA_SIGNAL)) + return -EOWNERDEAD; + + return IOU_ISSUE_SKIP_COMPLETE; +} + static void io_msg_tw_complete(struct callback_head *head) { struct io_msg *msg = container_of(head, struct io_msg, tw); @@ -96,15 +115,8 @@ static int io_msg_ring_data(struct io_kiocb *req, unsigned int issue_flags) if (msg->src_fd || msg->dst_fd || msg->flags) return -EINVAL; - if (target_ctx->task_complete && current != target_ctx->submitter_task) { - init_task_work(&msg->tw, io_msg_tw_complete); - if (task_work_add(target_ctx->submitter_task, &msg->tw, - TWA_SIGNAL_NO_IPI)) - return -EOWNERDEAD; - - atomic_or(IORING_SQ_TASKRUN, &target_ctx->rings->sq_flags); - return IOU_ISSUE_SKIP_COMPLETE; - } + if (io_msg_need_remote(target_ctx)) + return io_msg_exec_remote(req, io_msg_tw_complete); ret = -EOVERFLOW; if (target_ctx->flags & IORING_SETUP_IOPOLL) { @@ -202,14 +214,8 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags) req->flags |= REQ_F_NEED_CLEANUP; } - if (target_ctx->task_complete && current != target_ctx->submitter_task) { - init_task_work(&msg->tw, io_msg_tw_fd_complete); - if (task_work_add(target_ctx->submitter_task, &msg->tw, - TWA_SIGNAL)) - return -EOWNERDEAD; - - return IOU_ISSUE_SKIP_COMPLETE; - } + if (io_msg_need_remote(target_ctx)) + return io_msg_exec_remote(req, io_msg_tw_fd_complete); return io_msg_install_complete(req, issue_flags); } From 8579538c89e33ce78be2feb41e07489c8cbf8f31 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Fri, 20 Jan 2023 16:38:06 +0000 Subject: [PATCH 394/398] io_uring/msg_ring: fix remote queue to disabled ring IORING_SETUP_R_DISABLED rings don't have the submitter task set, so it's not always safe to use ->submitter_task. Disallow posting msg_ring messaged to disabled rings. Also add task NULL check for loosy sync around testing for IORING_SETUP_R_DISABLED. Cc: stable@vger.kernel.org Fixes: 6d043ee1164ca ("io_uring: do msg_ring in target task via tw") Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe --- io_uring/io_uring.c | 4 ++-- io_uring/msg_ring.c | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 2ac1cd8d23ea..0a4efada9b3c 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -3674,7 +3674,7 @@ static __cold int io_uring_create(unsigned entries, struct io_uring_params *p, if (ctx->flags & IORING_SETUP_SINGLE_ISSUER && !(ctx->flags & IORING_SETUP_R_DISABLED)) - ctx->submitter_task = get_task_struct(current); + WRITE_ONCE(ctx->submitter_task, get_task_struct(current)); file = io_uring_get_file(ctx); if (IS_ERR(file)) { @@ -3868,7 +3868,7 @@ static int io_register_enable_rings(struct io_ring_ctx *ctx) return -EBADFD; if (ctx->flags & IORING_SETUP_SINGLE_ISSUER && !ctx->submitter_task) - ctx->submitter_task = get_task_struct(current); + WRITE_ONCE(ctx->submitter_task, get_task_struct(current)); if (ctx->restrictions.registered) ctx->restricted = 1; diff --git a/io_uring/msg_ring.c b/io_uring/msg_ring.c index bb868447dcdf..15602a136821 100644 --- a/io_uring/msg_ring.c +++ b/io_uring/msg_ring.c @@ -69,6 +69,10 @@ static int io_msg_exec_remote(struct io_kiocb *req, task_work_func_t func) { struct io_ring_ctx *ctx = req->file->private_data; struct io_msg *msg = io_kiocb_to_cmd(req, struct io_msg); + struct task_struct *task = READ_ONCE(ctx->submitter_task); + + if (unlikely(!task)) + return -EOWNERDEAD; init_task_work(&msg->tw, func); if (task_work_add(ctx->submitter_task, &msg->tw, TWA_SIGNAL)) @@ -114,6 +118,8 @@ static int io_msg_ring_data(struct io_kiocb *req, unsigned int issue_flags) if (msg->src_fd || msg->dst_fd || msg->flags) return -EINVAL; + if (target_ctx->flags & IORING_SETUP_R_DISABLED) + return -EBADFD; if (io_msg_need_remote(target_ctx)) return io_msg_exec_remote(req, io_msg_tw_complete); @@ -206,6 +212,8 @@ static int io_msg_send_fd(struct io_kiocb *req, unsigned int issue_flags) if (target_ctx == ctx) return -EINVAL; + if (target_ctx->flags & IORING_SETUP_R_DISABLED) + return -EBADFD; if (!src_file) { src_file = io_msg_grab_file(req, issue_flags); if (!src_file) From 8caa03f10bf92cb8657408a6ece6a8a73f96ce13 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 20 Jan 2023 15:08:21 -0700 Subject: [PATCH 395/398] io_uring/poll: don't reissue in case of poll race on multishot request A previous commit fixed a poll race that can occur, but it's only applicable for multishot requests. For a multishot request, we can safely ignore a spurious wakeup, as we never leave the waitqueue to begin with. A blunt reissue of a multishot armed request can cause us to leak a buffer, if they are ring provided. While this seems like a bug in itself, it's not really defined behavior to reissue a multishot request directly. It's less efficient to do so as well, and not required to rearm anything like it is for singleshot poll requests. Cc: stable@vger.kernel.org Fixes: 6e5aedb9324a ("io_uring/poll: attempt request issue after racy poll wakeup") Reported-and-tested-by: Olivier Langlois Link: https://github.com/axboe/liburing/issues/778 Signed-off-by: Jens Axboe --- io_uring/poll.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/io_uring/poll.c b/io_uring/poll.c index 32e5fc8365e6..2ac1366adbd7 100644 --- a/io_uring/poll.c +++ b/io_uring/poll.c @@ -283,8 +283,12 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked) * to the waitqueue, so if we get nothing back, we * should be safe and attempt a reissue. */ - if (unlikely(!req->cqe.res)) + if (unlikely(!req->cqe.res)) { + /* Multishot armed need not reissue */ + if (!(req->apoll_events & EPOLLONESHOT)) + continue; return IOU_POLL_REISSUE; + } } if (req->apoll_events & EPOLLONESHOT) return IOU_POLL_DONE; From 739790605705ddcf18f21782b9c99ad7d53a8c11 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 20 Jan 2023 11:03:20 +0100 Subject: [PATCH 396/398] prlimit: do_prlimit needs to have a speculation check do_prlimit() adds the user-controlled resource value to a pointer that will subsequently be dereferenced. In order to help prevent this codepath from being used as a spectre "gadget" a barrier needs to be added after checking the range. Reported-by: Jordy Zomer Tested-by: Jordy Zomer Suggested-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman --- kernel/sys.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/sys.c b/kernel/sys.c index 5fd54bf0e886..88b31f096fb2 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -1442,6 +1442,8 @@ static int do_prlimit(struct task_struct *tsk, unsigned int resource, if (resource >= RLIM_NLIMITS) return -EINVAL; + resource = array_index_nospec(resource, RLIM_NLIMITS); + if (new_rlim) { if (new_rlim->rlim_cur > new_rlim->rlim_max) return -EINVAL; From f3bbac32475b27f49be201f896d98d4009de1562 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 17 Jan 2023 20:27:23 -0800 Subject: [PATCH 397/398] ext4: deal with legacy signed xattr name hash values We potentially have old hashes of the xattr names generated on systems with signed 'char' types. Now that everybody uses '-funsigned-char', those hashes will no longer match. This only happens if you use xattrs names that have the high bit set, which probably doesn't happen in practice, but the xfstest generic/454 shows it. Instead of adding a new "signed xattr hash filesystem" bit and having to deal with all the possible combinations, just calculate the hash both ways if the first one fails, and always generate new hashes with the proper unsigned char version. Reported-by: kernel test robot Link: https://lore.kernel.org/oe-lkp/202212291509.704a11c9-oliver.sang@intel.com Link: https://lore.kernel.org/all/CAHk-=whUNjwqZXa-MH9KMmc_CpQpoFKFjAB9ZKHuu=TbsouT4A@mail.gmail.com/ Exposed-by: 3bc753c06dd0 ("kbuild: treat char as always unsigned") Cc: Eric Biggers Cc: Andreas Dilger Cc: Theodore Ts'o , Cc: Jason Donenfeld Cc: Masahiro Yamada Signed-off-by: Linus Torvalds --- fs/ext4/xattr.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 7decaaf27e82..69a1b8c6a2ec 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -81,6 +81,8 @@ ext4_xattr_block_cache_find(struct inode *, struct ext4_xattr_header *, struct mb_cache_entry **); static __le32 ext4_xattr_hash_entry(char *name, size_t name_len, __le32 *value, size_t value_count); +static __le32 ext4_xattr_hash_entry_signed(char *name, size_t name_len, __le32 *value, + size_t value_count); static void ext4_xattr_rehash(struct ext4_xattr_header *); static const struct xattr_handler * const ext4_xattr_handler_map[] = { @@ -470,8 +472,21 @@ ext4_xattr_inode_verify_hashes(struct inode *ea_inode, tmp_data = cpu_to_le32(hash); e_hash = ext4_xattr_hash_entry(entry->e_name, entry->e_name_len, &tmp_data, 1); - if (e_hash != entry->e_hash) - return -EFSCORRUPTED; + /* All good? */ + if (e_hash == entry->e_hash) + return 0; + + /* + * Not good. Maybe the entry hash was calculated + * using the buggy signed char version? + */ + e_hash = ext4_xattr_hash_entry_signed(entry->e_name, entry->e_name_len, + &tmp_data, 1); + if (e_hash == entry->e_hash) + return 0; + + /* Still no match - bad */ + return -EFSCORRUPTED; } return 0; } @@ -3091,6 +3106,28 @@ static __le32 ext4_xattr_hash_entry(char *name, size_t name_len, __le32 *value, return cpu_to_le32(hash); } +/* + * ext4_xattr_hash_entry_signed() + * + * Compute the hash of an extended attribute incorrectly. + */ +static __le32 ext4_xattr_hash_entry_signed(char *name, size_t name_len, __le32 *value, size_t value_count) +{ + __u32 hash = 0; + + while (name_len--) { + hash = (hash << NAME_HASH_SHIFT) ^ + (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ + (signed char)*name++; + } + while (value_count--) { + hash = (hash << VALUE_HASH_SHIFT) ^ + (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ + le32_to_cpu(*value++); + } + return cpu_to_le32(hash); +} + #undef NAME_HASH_SHIFT #undef VALUE_HASH_SHIFT From 2241ab53cbb5cdb08a6b2d4688feb13971058f65 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 21 Jan 2023 16:27:01 -0800 Subject: [PATCH 398/398] Linux 6.2-rc5 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 33a4e312b66d..c1ead4cd2342 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 6 PATCHLEVEL = 2 SUBLEVEL = 0 -EXTRAVERSION = -rc4 +EXTRAVERSION = -rc5 NAME = Hurr durr I'ma ninja sloth # *DOCUMENTATION*