From ba79c5e45eecb9e009eca7f5da224f6e42bd4fcb Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Mon, 30 May 2022 14:57:50 +0300 Subject: [PATCH 001/246] MAINTAINERS: Update Intel pin control to Supported The actual status of the code is Supported. Reported-by: dave.hansen@linux.intel.com Signed-off-by: Andy Shevchenko Acked-by: Mika Westerberg --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index a6d3bd9d2a8d..bb033cf3dd32 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15730,7 +15730,7 @@ F: drivers/pinctrl/freescale/ PIN CONTROLLER - INTEL M: Mika Westerberg M: Andy Shevchenko -S: Maintained +S: Supported T: git git://git.kernel.org/pub/scm/linux/kernel/git/pinctrl/intel.git F: drivers/pinctrl/intel/ From 5871321fb4558c55bf9567052b618ff0be6b975e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 4 Jun 2022 11:52:46 +0100 Subject: [PATCH 002/246] ASoC: ops: Fix off by one in range control validation We currently report that range controls accept a range of 0..(max-min) but accept writes in the range 0..(max-min+1). Remove that extra +1. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220604105246.4055214-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index e693070f51fe..d867f449d82d 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -526,7 +526,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, return -EINVAL; if (mc->platform_max && tmp > mc->platform_max) return -EINVAL; - if (tmp > mc->max - mc->min + 1) + if (tmp > mc->max - mc->min) return -EINVAL; if (invert) @@ -547,7 +547,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, return -EINVAL; if (mc->platform_max && tmp > mc->platform_max) return -EINVAL; - if (tmp > mc->max - mc->min + 1) + if (tmp > mc->max - mc->min) return -EINVAL; if (invert) From a1ea0857b59757733d58908dd55bf4b722ee574f Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 8 Jun 2022 02:11:54 +0000 Subject: [PATCH 003/246] clk: stm32: rcc_reset: Fix missing spin_lock_init() The driver allocates the spinlock but not initialize it. Use spin_lock_init() on it to initialize it correctly. Fixes: 637cee5ffc71 ("clk: stm32: Introduce STM32MP13 RCC drivers (Reset Clock Controller)") Reported-by: Hulk Robot Signed-off-by: Wei Yongjun Link: https://lore.kernel.org/r/20220608021154.990347-1-weiyongjun1@huawei.com Tested-by: Gabriel Fernandez Reviewed-by: Gabriel Fernandez Signed-off-by: Stephen Boyd --- drivers/clk/stm32/reset-stm32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/clk/stm32/reset-stm32.c b/drivers/clk/stm32/reset-stm32.c index 040870130e4b..e89381528af9 100644 --- a/drivers/clk/stm32/reset-stm32.c +++ b/drivers/clk/stm32/reset-stm32.c @@ -111,6 +111,7 @@ int stm32_rcc_reset_init(struct device *dev, const struct of_device_id *match, if (!reset_data) return -ENOMEM; + spin_lock_init(&reset_data->lock); reset_data->membase = base; reset_data->rcdev.owner = THIS_MODULE; reset_data->rcdev.ops = &stm32_reset_ops; From 34d2cd3fccced12b958b8848e3eff0ee4296764c Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Thu, 12 May 2022 06:16:10 +0400 Subject: [PATCH 004/246] ARM: meson: Fix refcount leak in meson_smp_prepare_cpus of_find_compatible_node() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. Add missing of_node_put() to avoid refcount leak. Fixes: d850f3e5d296 ("ARM: meson: Add SMP bringup code for Meson8 and Meson8b") Signed-off-by: Miaoqian Lin Reviewed-by: Martin Blumenstingl Signed-off-by: Neil Armstrong Link: https://lore.kernel.org/r/20220512021611.47921-1-linmq006@gmail.com --- arch/arm/mach-meson/platsmp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-meson/platsmp.c b/arch/arm/mach-meson/platsmp.c index 4b8ad728bb42..32ac60b89fdc 100644 --- a/arch/arm/mach-meson/platsmp.c +++ b/arch/arm/mach-meson/platsmp.c @@ -71,6 +71,7 @@ static void __init meson_smp_prepare_cpus(const char *scu_compatible, } sram_base = of_iomap(node, 0); + of_node_put(node); if (!sram_base) { pr_err("Couldn't map SRAM registers\n"); return; @@ -91,6 +92,7 @@ static void __init meson_smp_prepare_cpus(const char *scu_compatible, } scu_base = of_iomap(node, 0); + of_node_put(node); if (!scu_base) { pr_err("Couldn't map SCU registers\n"); return; From 84a85d3fef2e75b1fe9fc2af6f5267122555a1ed Mon Sep 17 00:00:00 2001 From: Haowen Bai Date: Thu, 21 Apr 2022 10:26:59 +0800 Subject: [PATCH 005/246] pinctrl: aspeed: Fix potential NULL dereference in aspeed_pinmux_set_mux() pdesc could be null but still dereference pdesc->name and it will lead to a null pointer access. So we move a null check before dereference. Signed-off-by: Haowen Bai Link: https://lore.kernel.org/r/1650508019-22554-1-git-send-email-baihaowen@meizu.com Signed-off-by: Linus Walleij --- drivers/pinctrl/aspeed/pinctrl-aspeed.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pinctrl-aspeed.c index c94e24aadf92..83d47ff1cea8 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c @@ -236,11 +236,11 @@ int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, const struct aspeed_sig_expr **funcs; const struct aspeed_sig_expr ***prios; - pr_debug("Muxing pin %s for %s\n", pdesc->name, pfunc->name); - if (!pdesc) return -EINVAL; + pr_debug("Muxing pin %s for %s\n", pdesc->name, pfunc->name); + prios = pdesc->prios; if (!prios) From aaefa29270d9551b604165a08406543efa9d16f5 Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Wed, 25 May 2022 21:49:56 -0500 Subject: [PATCH 006/246] pinctrl: sunxi: a83t: Fix NAND function name for some pins The other NAND pins on Port C use the "nand0" function name. "nand0" also matches all of the other Allwinner SoCs. Fixes: 4730f33f0d82 ("pinctrl: sunxi: add allwinner A83T PIO controller support") Signed-off-by: Samuel Holland Acked-by: Jernej Skrabec Link: https://lore.kernel.org/r/20220526024956.49500-1-samuel@sholland.org Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c index 4ada80317a3b..b5c1a8f363f3 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c +++ b/drivers/pinctrl/sunxi/pinctrl-sun8i-a83t.c @@ -158,26 +158,26 @@ static const struct sunxi_desc_pin sun8i_a83t_pins[] = { SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 14), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQ6 */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQ6 */ SUNXI_FUNCTION(0x3, "mmc2")), /* D6 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 15), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQ7 */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQ7 */ SUNXI_FUNCTION(0x3, "mmc2")), /* D7 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 16), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand"), /* DQS */ + SUNXI_FUNCTION(0x2, "nand0"), /* DQS */ SUNXI_FUNCTION(0x3, "mmc2")), /* RST */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 17), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand")), /* CE2 */ + SUNXI_FUNCTION(0x2, "nand0")), /* CE2 */ SUNXI_PIN(SUNXI_PINCTRL_PIN(C, 18), SUNXI_FUNCTION(0x0, "gpio_in"), SUNXI_FUNCTION(0x1, "gpio_out"), - SUNXI_FUNCTION(0x2, "nand")), /* CE3 */ + SUNXI_FUNCTION(0x2, "nand0")), /* CE3 */ /* Hole */ SUNXI_PIN(SUNXI_PINCTRL_PIN(D, 2), SUNXI_FUNCTION(0x0, "gpio_in"), From a79e69c8714f416bd324952d06d1dd7bce3f35bf Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Mon, 13 Jun 2022 10:51:00 +0200 Subject: [PATCH 007/246] MAINTAINERS: add include/dt-bindings/clock to COMMON CLK FRAMEWORK Maintainers of the directory Documentation/devicetree/bindings/clock are also the maintainers of the corresponding directory in include/dt-bindings/clock. Add the file entry for include/dt-bindings/clock to the appropriate section in MAINTAINERS. Signed-off-by: Lukas Bulwahn Link: https://lore.kernel.org/r/20220613085100.402-1-lukas.bulwahn@gmail.com Signed-off-by: Stephen Boyd --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index a6d3bd9d2a8d..c1abc53f9e91 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -4952,6 +4952,7 @@ Q: http://patchwork.kernel.org/project/linux-clk/list/ T: git git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux.git F: Documentation/devicetree/bindings/clock/ F: drivers/clk/ +F: include/dt-bindings/clock/ F: include/linux/clk-pr* F: include/linux/clk/ F: include/linux/of_clk.h From a1016ba9f908d3d00b9483e2d9d5840ba744f122 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 7 Jun 2022 13:46:40 -0300 Subject: [PATCH 008/246] ARM: dts: imx7d-smegw01: Fix the SDIO description usdhc2 is connected to a Wifi chip that is powered by a 3.3V supply. Pass the "no-1-8-v" property to guarantee that no communication is made at 1.8V. While at it, also remove the unnecessary properties: "cap-sd-highspeed", "sd-uhs-ddr50", and "mmc-ddr-1_8v". Fixes: 9ac0ae97e349 ("ARM: dts: imx7d-smegw01: Add support for i.MX7D SMEGW01 board") Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/boot/dts/imx7d-smegw01.dts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/imx7d-smegw01.dts b/arch/arm/boot/dts/imx7d-smegw01.dts index c6b32064a009..21b509c43393 100644 --- a/arch/arm/boot/dts/imx7d-smegw01.dts +++ b/arch/arm/boot/dts/imx7d-smegw01.dts @@ -216,10 +216,8 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc2>; bus-width = <4>; + no-1-8-v; non-removable; - cap-sd-highspeed; - sd-uhs-ddr50; - mmc-ddr-1_8v; vmmc-supply = <®_wifi>; enable-sdio-wakeup; status = "okay"; From 754f04cac362417b157e30d5dc4046b5ec92060c Mon Sep 17 00:00:00 2001 From: Cristian Marussi Date: Thu, 16 Jun 2022 18:03:47 +0100 Subject: [PATCH 009/246] firmware: arm_scmi: Relax CLOCK_DESCRIBE_RATES out-of-spec checks A reply to CLOCK_DESCRIBE_RATES issued against a non rate-discrete clock should be composed of a triplet of rates descriptors (min/max/step) returned all in one reply message. This is not always the case when dealing with some SCMI server deployed in the wild: relax such constraint while maintaining memory safety by checking carefully the returned payload size. While at that cleanup a stale debug printout. Link: https://lore.kernel.org/r/20220616170347.2800771-1-cristian.marussi@arm.com Fixes: 7bc7caafe6b1 ("firmware: arm_scmi: Use common iterators in the clock protocol") Tested-by: Robin Murphy Signed-off-by: Cristian Marussi Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/clock.c | 26 +++++++++++++++++++++++++- drivers/firmware/arm_scmi/driver.c | 1 + drivers/firmware/arm_scmi/protocols.h | 3 +++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c index c7a83f6e38e5..3ed7ae0d6781 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -194,6 +194,7 @@ static int rate_cmp_func(const void *_r1, const void *_r2) } struct scmi_clk_ipriv { + struct device *dev; u32 clk_id; struct scmi_clock_info *clk; }; @@ -223,6 +224,29 @@ iter_clk_describe_update_state(struct scmi_iterator_state *st, st->num_returned = NUM_RETURNED(flags); p->clk->rate_discrete = RATE_DISCRETE(flags); + /* Warn about out of spec replies ... */ + if (!p->clk->rate_discrete && + (st->num_returned != 3 || st->num_remaining != 0)) { + dev_warn(p->dev, + "Out-of-spec CLOCK_DESCRIBE_RATES reply for %s - returned:%d remaining:%d rx_len:%zd\n", + p->clk->name, st->num_returned, st->num_remaining, + st->rx_len); + + /* + * A known quirk: a triplet is returned but num_returned != 3 + * Check for a safe payload size and fix. + */ + if (st->num_returned != 3 && st->num_remaining == 0 && + st->rx_len == sizeof(*r) + sizeof(__le32) * 2 * 3) { + st->num_returned = 3; + st->num_remaining = 0; + } else { + dev_err(p->dev, + "Cannot fix out-of-spec reply !\n"); + return -EPROTO; + } + } + return 0; } @@ -255,7 +279,6 @@ iter_clk_describe_process_response(const struct scmi_protocol_handle *ph, *rate = RATE_TO_U64(r->rate[st->loop_idx]); p->clk->list.num_rates++; - //XXX dev_dbg(ph->dev, "Rate %llu Hz\n", *rate); } return ret; @@ -275,6 +298,7 @@ scmi_clock_describe_rates_get(const struct scmi_protocol_handle *ph, u32 clk_id, struct scmi_clk_ipriv cpriv = { .clk_id = clk_id, .clk = clk, + .dev = ph->dev, }; iter = ph->hops->iter_response_init(ph, &ops, SCMI_MAX_NUM_RATES, diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index c1922bd650ae..8b7ac6663d57 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1223,6 +1223,7 @@ static int scmi_iterator_run(void *iter) if (ret) break; + st->rx_len = i->t->rx.len; ret = iops->update_state(st, i->resp, i->priv); if (ret) break; diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h index c679f3fb8718..51c31379f9b3 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h @@ -179,6 +179,8 @@ struct scmi_protocol_handle { * @max_resources: Maximum acceptable number of items, configured by the caller * depending on the underlying resources that it is querying. * @loop_idx: The iterator loop index in the current multi-part reply. + * @rx_len: Size in bytes of the currenly processed message; it can be used by + * the user of the iterator to verify a reply size. * @priv: Optional pointer to some additional state-related private data setup * by the caller during the iterations. */ @@ -188,6 +190,7 @@ struct scmi_iterator_state { unsigned int num_remaining; unsigned int max_resources; unsigned int loop_idx; + size_t rx_len; void *priv; }; From 372b2aee97028c75a6e12d205a2e5f0c8626efc6 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 2 Jun 2022 12:06:21 -0700 Subject: [PATCH 010/246] arm64: dts: qcom: Remove duplicate sc7180-trogdor include on lazor/homestar The sc7180-trogdor-{lazor,homestar}-*.dtsi files all include sc7180-trogdor.dtsi and sc7180-trogdor-lazor.dtsi or sc7180-trogdor-homestar.dtsi, so including it here in the sc7180-trogdor-{lazor,homestar}.dtsi file means we have a duplicate include after commit 19794489fa24 ("arm64: dts: qcom: Only include sc7180.dtsi in sc7180-trogdor.dtsi"). We include the sc7180-trogdor.dtsi file in a board like sc7180-trogdor-lazor-r1.dts so that we can include the display bridge snippet (e.g. sc7180-trogdor-ti-sn65dsi86.dtsi) instead of making ever increasing variants like sc7180-trogdor-lazor-ti-sn65dsi86.dtsi. Unfortunately, having the double include like this means the display bridge's i2c bus is left disabled instead of enabled by the bridge snippet. Any boards that use the i2c bus for the display bridge will have the bus disabled when we include sc7180-trogdor.dtsi the second time, which picks up the i2c status="disabled" line from sc7180.dtsi. This leads to the display not turning on and black screens at boot on lazor and homestar devices. Fix this by dropping the include and making a note that the sc7180-trogdor-{lazor,homestar}.dtsi file must be included after sc7180-trogdor.dtsi Reported-by: Douglas Anderson Cc: "Joseph S. Barrera III" Cc: Matthias Kaehlcke Fixes: 19794489fa24 ("arm64: dts: qcom: Only include sc7180.dtsi in sc7180-trogdor.dtsi") Signed-off-by: Stephen Boyd Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220602190621.1646679-1-swboyd@chromium.org --- arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi | 2 +- arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi index 9b3e3d13c165..d1e2df5164ea 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi @@ -5,7 +5,7 @@ * Copyright 2021 Google LLC. */ -#include "sc7180-trogdor.dtsi" +/* This file must be included after sc7180-trogdor.dtsi */ / { /* BOARD-SPECIFIC TOP LEVEL NODES */ diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi index fe2369c29aad..88f6a7d4d020 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor.dtsi @@ -5,7 +5,7 @@ * Copyright 2020 Google LLC. */ -#include "sc7180-trogdor.dtsi" +/* This file must be included after sc7180-trogdor.dtsi */ &ap_sar_sensor { semtech,cs0-ground; From c28d76d360f9f7af1f910342bde27939873bc45e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 21 Jun 2022 19:38:55 -0700 Subject: [PATCH 011/246] drm/msm/dpu: Increment vsync_cnt before waking up userspace The 'vsync_cnt' is used to count the number of frames for a crtc. Unfortunately, we increment the count after waking up userspace via dpu_crtc_vblank_callback() calling drm_crtc_handle_vblank(). drm_crtc_handle_vblank() wakes up userspace processes that have called drm_wait_vblank_ioctl(), and if that ioctl is expecting the count to increase it won't. Increment the count before calling into the drm APIs so that we don't have to worry about ordering the increment with anything else in drm. This fixes a software video decode test that fails to see frame counts increase on Trogdor boards. Cc: Mark Yacoub Cc: Jessica Zhang Fixes: 885455d6bf82 ("drm/msm: Change dpu_crtc_get_vblank_counter to use vsync count.") Signed-off-by: Stephen Boyd Reviewed-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov Tested-by: Jessica Zhang # Trogdor (sc7180) Patchwork: https://patchwork.freedesktop.org/patch/490531/ Link: https://lore.kernel.org/r/20220622023855.2970913-1-swboyd@chromium.org Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 3a462e327e0e..a1b8c4592943 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1251,12 +1251,13 @@ static void dpu_encoder_vblank_callback(struct drm_encoder *drm_enc, DPU_ATRACE_BEGIN("encoder_vblank_callback"); dpu_enc = to_dpu_encoder_virt(drm_enc); + atomic_inc(&phy_enc->vsync_cnt); + spin_lock_irqsave(&dpu_enc->enc_spinlock, lock_flags); if (dpu_enc->crtc) dpu_crtc_vblank_callback(dpu_enc->crtc); spin_unlock_irqrestore(&dpu_enc->enc_spinlock, lock_flags); - atomic_inc(&phy_enc->vsync_cnt); DPU_ATRACE_END("encoder_vblank_callback"); } From 0769d0a7ae3c26c0f2210578f83b3d1b30391601 Mon Sep 17 00:00:00 2001 From: Kuogee Hsieh Date: Wed, 22 Jun 2022 12:55:31 -0700 Subject: [PATCH 012/246] drm/msm/dp: reset drm_dev to NULL at dp_display_unbind() During msm initialize phase, dp_display_unbind() will be called to undo initializations had been done by dp_display_bind() previously if there is error happen at msm_drm_bind. Under this kind of circumstance, drm_device may not be populated completed which causes system crash at drm_dev_dbg(). This patch reset drm_dev to NULL so that following drm_dev_dbg() will not refer to any internal fields of drm_device to prevent system from crashing. Below are panic stack trace, [ 53.584904] Unable to handle kernel paging request at virtual address 0000000070018001 . [ 53.702212] Hardware name: Qualcomm Technologies, Inc. sc7280 CRD platform (rev5+) (DT) [ 53.710445] pstate: 20400009 (nzCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 53.717596] pc : string_nocheck+0x1c/0x64 [ 53.721738] lr : string+0x54/0x60 [ 53.725162] sp : ffffffc013d6b650 [ 53.728590] pmr_save: 000000e0 [ 53.731743] x29: ffffffc013d6b650 x28: 0000000000000002 x27: 0000000000ffffff [ 53.739083] x26: ffffffc013d6b710 x25: ffffffd07a066ae0 x24: ffffffd07a419f97 [ 53.746420] x23: ffffffd07a419f99 x22: ffffff81fef360d4 x21: ffffff81fef364d4 [ 53.753760] x20: ffffffc013d6b6f8 x19: ffffffd07a06683c x18: 0000000000000000 [ 53.761093] x17: 4020386678302f30 x16: 00000000000000b0 x15: ffffffd0797523c8 [ 53.768429] x14: 0000000000000004 x13: ffff0000ffffff00 x12: ffffffd07a066b2c [ 53.775780] x11: 0000000000000000 x10: 000000000000013c x9 : 0000000000000000 [ 53.783117] x8 : ffffff81fef364d4 x7 : 0000000000000000 x6 : 0000000000000000 [ 53.790445] x5 : 0000000000000000 x4 : ffff0a00ffffff04 x3 : ffff0a00ffffff04 [ 53.797783] x2 : 0000000070018001 x1 : ffffffffffffffff x0 : ffffff81fef360d4 [ 53.805136] Call trace: [ 53.807667] string_nocheck+0x1c/0x64 [ 53.811439] string+0x54/0x60 [ 53.814498] vsnprintf+0x374/0x53c [ 53.818009] pointer+0x3dc/0x40c [ 53.821340] vsnprintf+0x398/0x53c [ 53.824854] vscnprintf+0x3c/0x88 [ 53.828274] __trace_array_vprintk+0xcc/0x2d4 [ 53.832768] trace_array_printk+0x8c/0xb4 [ 53.836900] drm_trace_printf+0x74/0x9c [ 53.840875] drm_dev_dbg+0xfc/0x1b8 [ 53.844480] dp_pm_suspend+0x70/0xf8 [ 53.848164] dpm_run_callback+0x60/0x1a0 [ 53.852222] __device_suspend+0x304/0x3f4 [ 53.856363] dpm_suspend+0xf8/0x3a8 [ 53.859959] dpm_suspend_start+0x8c/0xc0 Fixes: 570d3e5d28db ("drm/msm/dp: stop event kernel thread when DP unbind") Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Stephen Boyd Patchwork: https://patchwork.freedesktop.org/patch/490756/ Link: https://lore.kernel.org/r/1655927731-22396-1-git-send-email-quic_khsieh@quicinc.com Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/dp/dp_display.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index a6117926a274..dcd80c8a794c 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -316,6 +316,8 @@ static void dp_display_unbind(struct device *dev, struct device *master, dp_power_client_deinit(dp->power); dp_aux_unregister(dp->aux); + dp->drm_dev = NULL; + dp->aux->drm_dev = NULL; priv->dp[dp->id] = NULL; } From eb174bd875ae504cdc1b5b209da288fffb1e5128 Mon Sep 17 00:00:00 2001 From: sunliming Date: Thu, 23 Jun 2022 09:27:07 +0800 Subject: [PATCH 013/246] drm/msm/dpu: Fix variable dereferenced before check Fixes the following smatch warning: drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c:261 dpu_encoder_phys_wb_atomic_check() warn: variable dereferenced before check 'conn_state' Fixes: d7d0e73f7de3 ("drm/msm/dpu: introduce the dpu_encoder_phys_* for writeback") Signed-off-by: sunliming Reported-by: kernel test robot Reported-by: Dan Carpenter Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/490850/ Link: https://lore.kernel.org/r/20220623012707.453972-1-sunliming@kylinos.cn Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c index 59da348ff339..0ec809ab06e7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c @@ -252,11 +252,6 @@ static int dpu_encoder_phys_wb_atomic_check( DPU_DEBUG("[atomic_check:%d, \"%s\",%d,%d]\n", phys_enc->wb_idx, mode->name, mode->hdisplay, mode->vdisplay); - if (!conn_state->writeback_job || !conn_state->writeback_job->fb) - return 0; - - fb = conn_state->writeback_job->fb; - if (!conn_state || !conn_state->connector) { DPU_ERROR("invalid connector state\n"); return -EINVAL; @@ -267,6 +262,11 @@ static int dpu_encoder_phys_wb_atomic_check( return -EINVAL; } + if (!conn_state->writeback_job || !conn_state->writeback_job->fb) + return 0; + + fb = conn_state->writeback_job->fb; + DPU_DEBUG("[fb_id:%u][fb:%u,%u]\n", fb->base.id, fb->width, fb->height); From b376471fb47d4905e72fe73e9eeed228f8f2f230 Mon Sep 17 00:00:00 2001 From: Jinzhou Su Date: Thu, 23 Jun 2022 11:15:09 +0800 Subject: [PATCH 014/246] cpufreq: amd-pstate: Add resume and suspend callbacks When system resumes from S3, the CPPC enable register will be cleared and reset to 0. So enable the CPPC interface by writing 1 to this register on system resume and disable it during system suspend. Signed-off-by: Jinzhou Su Signed-off-by: Jinzhou Su Acked-by: Huang Rui [ rjw: Subject and changelog edits ] Cc: All applicable Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/amd-pstate.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index 7be38bc6a673..9ac75c1cde9c 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -566,6 +566,28 @@ static int amd_pstate_cpu_exit(struct cpufreq_policy *policy) return 0; } +static int amd_pstate_cpu_resume(struct cpufreq_policy *policy) +{ + int ret; + + ret = amd_pstate_enable(true); + if (ret) + pr_err("failed to enable amd-pstate during resume, return %d\n", ret); + + return ret; +} + +static int amd_pstate_cpu_suspend(struct cpufreq_policy *policy) +{ + int ret; + + ret = amd_pstate_enable(false); + if (ret) + pr_err("failed to disable amd-pstate during suspend, return %d\n", ret); + + return ret; +} + /* Sysfs attributes */ /* @@ -636,6 +658,8 @@ static struct cpufreq_driver amd_pstate_driver = { .target = amd_pstate_target, .init = amd_pstate_cpu_init, .exit = amd_pstate_cpu_exit, + .suspend = amd_pstate_cpu_suspend, + .resume = amd_pstate_cpu_resume, .set_boost = amd_pstate_set_boost, .name = "amd-pstate", .attr = amd_pstate_attr, From 7cf2b0f9611b9971d663e1fc3206eeda3b902922 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 16 Jun 2022 07:44:31 -0700 Subject: [PATCH 015/246] xfs: bound maximum wait time for inodegc work Currently inodegc work can sit queued on the per-cpu queue until the workqueue is either flushed of the queue reaches a depth that triggers work queuing (and later throttling). This means that we could queue work that waits for a long time for some other event to trigger flushing. Hence instead of just queueing work at a specific depth, use a delayed work that queues the work at a bound time. We can still schedule the work immediately at a given depth, but we no long need to worry about leaving a number of items on the list that won't get processed until external events prevail. Signed-off-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_icache.c | 36 ++++++++++++++++++++++-------------- fs/xfs/xfs_mount.h | 2 +- fs/xfs/xfs_super.c | 2 +- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 5269354b1b69..786702273621 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -440,7 +440,7 @@ xfs_inodegc_queue_all( for_each_online_cpu(cpu) { gc = per_cpu_ptr(mp->m_inodegc, cpu); if (!llist_empty(&gc->list)) - queue_work_on(cpu, mp->m_inodegc_wq, &gc->work); + mod_delayed_work_on(cpu, mp->m_inodegc_wq, &gc->work, 0); } } @@ -1841,8 +1841,8 @@ void xfs_inodegc_worker( struct work_struct *work) { - struct xfs_inodegc *gc = container_of(work, struct xfs_inodegc, - work); + struct xfs_inodegc *gc = container_of(to_delayed_work(work), + struct xfs_inodegc, work); struct llist_node *node = llist_del_all(&gc->list); struct xfs_inode *ip, *n; @@ -2014,6 +2014,7 @@ xfs_inodegc_queue( struct xfs_inodegc *gc; int items; unsigned int shrinker_hits; + unsigned long queue_delay = 1; trace_xfs_inode_set_need_inactive(ip); spin_lock(&ip->i_flags_lock); @@ -2025,19 +2026,26 @@ xfs_inodegc_queue( items = READ_ONCE(gc->items); WRITE_ONCE(gc->items, items + 1); shrinker_hits = READ_ONCE(gc->shrinker_hits); - put_cpu_ptr(gc); - if (!xfs_is_inodegc_enabled(mp)) + /* + * We queue the work while holding the current CPU so that the work + * is scheduled to run on this CPU. + */ + if (!xfs_is_inodegc_enabled(mp)) { + put_cpu_ptr(gc); return; - - if (xfs_inodegc_want_queue_work(ip, items)) { - trace_xfs_inodegc_queue(mp, __return_address); - queue_work(mp->m_inodegc_wq, &gc->work); } + if (xfs_inodegc_want_queue_work(ip, items)) + queue_delay = 0; + + trace_xfs_inodegc_queue(mp, __return_address); + mod_delayed_work(mp->m_inodegc_wq, &gc->work, queue_delay); + put_cpu_ptr(gc); + if (xfs_inodegc_want_flush_work(ip, items, shrinker_hits)) { trace_xfs_inodegc_throttle(mp, __return_address); - flush_work(&gc->work); + flush_delayed_work(&gc->work); } } @@ -2054,7 +2062,7 @@ xfs_inodegc_cpu_dead( unsigned int count = 0; dead_gc = per_cpu_ptr(mp->m_inodegc, dead_cpu); - cancel_work_sync(&dead_gc->work); + cancel_delayed_work_sync(&dead_gc->work); if (llist_empty(&dead_gc->list)) return; @@ -2073,12 +2081,12 @@ xfs_inodegc_cpu_dead( llist_add_batch(first, last, &gc->list); count += READ_ONCE(gc->items); WRITE_ONCE(gc->items, count); - put_cpu_ptr(gc); if (xfs_is_inodegc_enabled(mp)) { trace_xfs_inodegc_queue(mp, __return_address); - queue_work(mp->m_inodegc_wq, &gc->work); + mod_delayed_work(mp->m_inodegc_wq, &gc->work, 0); } + put_cpu_ptr(gc); } /* @@ -2173,7 +2181,7 @@ xfs_inodegc_shrinker_scan( unsigned int h = READ_ONCE(gc->shrinker_hits); WRITE_ONCE(gc->shrinker_hits, h + 1); - queue_work_on(cpu, mp->m_inodegc_wq, &gc->work); + mod_delayed_work_on(cpu, mp->m_inodegc_wq, &gc->work, 0); no_items = false; } } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index ba5d42abf66e..d2eaebd85abf 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -61,7 +61,7 @@ struct xfs_error_cfg { */ struct xfs_inodegc { struct llist_head list; - struct work_struct work; + struct delayed_work work; /* approximate count of inodes in the list */ unsigned int items; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index ed18160e6181..90d9c419ecc5 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1074,7 +1074,7 @@ xfs_inodegc_init_percpu( gc = per_cpu_ptr(mp->m_inodegc, cpu); init_llist_head(&gc->list); gc->items = 0; - INIT_WORK(&gc->work, xfs_inodegc_worker); + INIT_DELAYED_WORK(&gc->work, xfs_inodegc_worker); } return 0; } From 5e672cd69f0a534a445df4372141fd0d1d00901d Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 16 Jun 2022 07:44:32 -0700 Subject: [PATCH 016/246] xfs: introduce xfs_inodegc_push() The current blocking mechanism for pushing the inodegc queue out to disk can result in systems becoming unusable when there is a long running inodegc operation. This is because the statfs() implementation currently issues a blocking flush of the inodegc queue and a significant number of common system utilities will call statfs() to discover something about the underlying filesystem. This can result in userspace operations getting stuck on inodegc progress, and when trying to remove a heavily reflinked file on slow storage with a full journal, this can result in delays measuring in hours. Avoid this problem by adding "push" function that expedites the flushing of the inodegc queue, but doesn't wait for it to complete. Convert xfs_fs_statfs() and xfs_qm_scall_getquota() to use this mechanism so they don't block but still ensure that queued operations are expedited. Fixes: ab23a7768739 ("xfs: per-cpu deferred inode inactivation queues") Reported-by: Chris Dunlop Signed-off-by: Dave Chinner [djwong: fix _getquota_next to use _inodegc_push too] Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_icache.c | 20 +++++++++++++++----- fs/xfs/xfs_icache.h | 1 + fs/xfs/xfs_qm_syscalls.c | 9 ++++++--- fs/xfs/xfs_super.c | 7 +++++-- fs/xfs/xfs_trace.h | 1 + 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 786702273621..2609825d53ee 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -1861,6 +1861,20 @@ xfs_inodegc_worker( } } +/* + * Expedite all pending inodegc work to run immediately. This does not wait for + * completion of the work. + */ +void +xfs_inodegc_push( + struct xfs_mount *mp) +{ + if (!xfs_is_inodegc_enabled(mp)) + return; + trace_xfs_inodegc_push(mp, __return_address); + xfs_inodegc_queue_all(mp); +} + /* * Force all currently queued inode inactivation work to run immediately and * wait for the work to finish. @@ -1869,12 +1883,8 @@ void xfs_inodegc_flush( struct xfs_mount *mp) { - if (!xfs_is_inodegc_enabled(mp)) - return; - + xfs_inodegc_push(mp); trace_xfs_inodegc_flush(mp, __return_address); - - xfs_inodegc_queue_all(mp); flush_workqueue(mp->m_inodegc_wq); } diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index 2e4cfddf8b8e..6cd180721659 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h @@ -76,6 +76,7 @@ void xfs_blockgc_stop(struct xfs_mount *mp); void xfs_blockgc_start(struct xfs_mount *mp); void xfs_inodegc_worker(struct work_struct *work); +void xfs_inodegc_push(struct xfs_mount *mp); void xfs_inodegc_flush(struct xfs_mount *mp); void xfs_inodegc_stop(struct xfs_mount *mp); void xfs_inodegc_start(struct xfs_mount *mp); diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 74ac9ca9e119..392cb39cc10c 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c @@ -454,9 +454,12 @@ xfs_qm_scall_getquota( struct xfs_dquot *dqp; int error; - /* Flush inodegc work at the start of a quota reporting scan. */ + /* + * Expedite pending inodegc work at the start of a quota reporting + * scan but don't block waiting for it to complete. + */ if (id == 0) - xfs_inodegc_flush(mp); + xfs_inodegc_push(mp); /* * Try to get the dquot. We don't want it allocated on disk, so don't @@ -498,7 +501,7 @@ xfs_qm_scall_getquota_next( /* Flush inodegc work at the start of a quota reporting scan. */ if (*id == 0) - xfs_inodegc_flush(mp); + xfs_inodegc_push(mp); error = xfs_qm_dqget_next(mp, *id, type, &dqp); if (error) diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 90d9c419ecc5..aa977c7ea370 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -797,8 +797,11 @@ xfs_fs_statfs( xfs_extlen_t lsize; int64_t ffree; - /* Wait for whatever inactivations are in progress. */ - xfs_inodegc_flush(mp); + /* + * Expedite background inodegc but don't wait. We do not want to block + * here waiting hours for a billion extent file to be truncated. + */ + xfs_inodegc_push(mp); statp->f_type = XFS_SUPER_MAGIC; statp->f_namelen = MAXNAMELEN - 1; diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index d32026585c1b..0fa1b7a2918c 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -240,6 +240,7 @@ DEFINE_EVENT(xfs_fs_class, name, \ TP_PROTO(struct xfs_mount *mp, void *caller_ip), \ TP_ARGS(mp, caller_ip)) DEFINE_FS_EVENT(xfs_inodegc_flush); +DEFINE_FS_EVENT(xfs_inodegc_push); DEFINE_FS_EVENT(xfs_inodegc_start); DEFINE_FS_EVENT(xfs_inodegc_stop); DEFINE_FS_EVENT(xfs_inodegc_queue); From 19fc5bb93c6bbdce8292b4d7eed04e2fa118d2fe Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Thu, 23 Jun 2022 13:25:09 -0500 Subject: [PATCH 017/246] powerpc/xive/spapr: correct bitmap allocation size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kasan detects access beyond the end of the xibm->bitmap allocation: BUG: KASAN: slab-out-of-bounds in _find_first_zero_bit+0x40/0x140 Read of size 8 at addr c00000001d1d0118 by task swapper/0/1 CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.19.0-rc2-00001-g90df023b36dd #28 Call Trace: [c00000001d98f770] [c0000000012baab8] dump_stack_lvl+0xac/0x108 (unreliable) [c00000001d98f7b0] [c00000000068faac] print_report+0x37c/0x710 [c00000001d98f880] [c0000000006902c0] kasan_report+0x110/0x354 [c00000001d98f950] [c000000000692324] __asan_load8+0xa4/0xe0 [c00000001d98f970] [c0000000011c6ed0] _find_first_zero_bit+0x40/0x140 [c00000001d98f9b0] [c0000000000dbfbc] xive_spapr_get_ipi+0xcc/0x260 [c00000001d98fa70] [c0000000000d6d28] xive_setup_cpu_ipi+0x1e8/0x450 [c00000001d98fb30] [c000000004032a20] pSeries_smp_probe+0x5c/0x118 [c00000001d98fb60] [c000000004018b44] smp_prepare_cpus+0x944/0x9ac [c00000001d98fc90] [c000000004009f9c] kernel_init_freeable+0x2d4/0x640 [c00000001d98fd90] [c0000000000131e8] kernel_init+0x28/0x1d0 [c00000001d98fe10] [c00000000000cd54] ret_from_kernel_thread+0x5c/0x64 Allocated by task 0: kasan_save_stack+0x34/0x70 __kasan_kmalloc+0xb4/0xf0 __kmalloc+0x268/0x540 xive_spapr_init+0x4d0/0x77c pseries_init_irq+0x40/0x27c init_IRQ+0x44/0x84 start_kernel+0x2a4/0x538 start_here_common+0x1c/0x20 The buggy address belongs to the object at c00000001d1d0118 which belongs to the cache kmalloc-8 of size 8 The buggy address is located 0 bytes inside of 8-byte region [c00000001d1d0118, c00000001d1d0120) The buggy address belongs to the physical page: page:c00c000000074740 refcount:1 mapcount:0 mapping:0000000000000000 index:0xc00000001d1d0558 pfn:0x1d1d flags: 0x7ffff000000200(slab|node=0|zone=0|lastcpupid=0x7ffff) raw: 007ffff000000200 c00000001d0003c8 c00000001d0003c8 c00000001d010480 raw: c00000001d1d0558 0000000001e1000a 00000001ffffffff 0000000000000000 page dumped because: kasan: bad access detected Memory state around the buggy address: c00000001d1d0000: fc 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc c00000001d1d0080: fc fc 00 fc fc fc fc fc fc fc fc fc fc fc fc fc >c00000001d1d0100: fc fc fc 02 fc fc fc fc fc fc fc fc fc fc fc fc ^ c00000001d1d0180: fc fc fc fc 04 fc fc fc fc fc fc fc fc fc fc fc c00000001d1d0200: fc fc fc fc fc 04 fc fc fc fc fc fc fc fc fc fc This happens because the allocation uses the wrong unit (bits) when it should pass (BITS_TO_LONGS(count) * sizeof(long)) or equivalent. With small numbers of bits, the allocated object can be smaller than sizeof(long), which results in invalid accesses. Use bitmap_zalloc() to allocate and initialize the irq bitmap, paired with bitmap_free() for consistency. Signed-off-by: Nathan Lynch Reviewed-by: Cédric Le Goater Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220623182509.3985625-1-nathanl@linux.ibm.com --- arch/powerpc/sysdev/xive/spapr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c index 7d5128676e83..d02911e78cfc 100644 --- a/arch/powerpc/sysdev/xive/spapr.c +++ b/arch/powerpc/sysdev/xive/spapr.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -57,7 +58,7 @@ static int __init xive_irq_bitmap_add(int base, int count) spin_lock_init(&xibm->lock); xibm->base = base; xibm->count = count; - xibm->bitmap = kzalloc(xibm->count, GFP_KERNEL); + xibm->bitmap = bitmap_zalloc(xibm->count, GFP_KERNEL); if (!xibm->bitmap) { kfree(xibm); return -ENOMEM; @@ -75,7 +76,7 @@ static void xive_irq_bitmap_remove_all(void) list_for_each_entry_safe(xibm, tmp, &xive_irq_bitmaps, list) { list_del(&xibm->list); - kfree(xibm->bitmap); + bitmap_free(xibm->bitmap); kfree(xibm); } } From 986481618023e18e187646b0fff05a3c337531cb Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Thu, 23 Jun 2022 10:56:17 +0200 Subject: [PATCH 018/246] powerpc/book3e: Fix PUD allocation size in map_kernel_page() Commit 2fb4706057bc ("powerpc: add support for folded p4d page tables") erroneously changed PUD setup to a mix of PMD and PUD. Fix it. While at it, use PTE_TABLE_SIZE instead of PAGE_SIZE for PTE tables in order to avoid any confusion. Fixes: 2fb4706057bc ("powerpc: add support for folded p4d page tables") Cc: stable@vger.kernel.org # v5.8+ Signed-off-by: Christophe Leroy Acked-by: Mike Rapoport Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/95ddfd6176d53e6c85e13bd1c358359daa56775f.1655974558.git.christophe.leroy@csgroup.eu --- arch/powerpc/mm/nohash/book3e_pgtable.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/mm/nohash/book3e_pgtable.c b/arch/powerpc/mm/nohash/book3e_pgtable.c index 7d4368d055a6..b80fc4a91a53 100644 --- a/arch/powerpc/mm/nohash/book3e_pgtable.c +++ b/arch/powerpc/mm/nohash/book3e_pgtable.c @@ -96,8 +96,8 @@ int __ref map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t prot) pgdp = pgd_offset_k(ea); p4dp = p4d_offset(pgdp, ea); if (p4d_none(*p4dp)) { - pmdp = early_alloc_pgtable(PMD_TABLE_SIZE); - p4d_populate(&init_mm, p4dp, pmdp); + pudp = early_alloc_pgtable(PUD_TABLE_SIZE); + p4d_populate(&init_mm, p4dp, pudp); } pudp = pud_offset(p4dp, ea); if (pud_none(*pudp)) { @@ -106,7 +106,7 @@ int __ref map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t prot) } pmdp = pmd_offset(pudp, ea); if (!pmd_present(*pmdp)) { - ptep = early_alloc_pgtable(PAGE_SIZE); + ptep = early_alloc_pgtable(PTE_TABLE_SIZE); pmd_populate_kernel(&init_mm, pmdp, ptep); } ptep = pte_offset_kernel(pmdp, ea); From 6886da5f49e6d86aad76807a93f3eef5e4f01b10 Mon Sep 17 00:00:00 2001 From: Liam Howlett Date: Fri, 24 Jun 2022 01:17:58 +0000 Subject: [PATCH 019/246] powerpc/prom_init: Fix kernel config grep When searching for config options, use the KCONFIG_CONFIG shell variable so that builds using non-standard config locations work. Fixes: 26deb04342e3 ("powerpc: prepare string/mem functions for KASAN") Cc: stable@vger.kernel.org # v5.2+ Signed-off-by: Liam R. Howlett Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220624011745.4060795-1-Liam.Howlett@oracle.com --- arch/powerpc/kernel/prom_init_check.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index b183ab9c5107..dfa5f729f774 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh @@ -13,7 +13,7 @@ # If you really need to reference something from prom_init.o add # it to the list below: -grep "^CONFIG_KASAN=y$" .config >/dev/null +grep "^CONFIG_KASAN=y$" ${KCONFIG_CONFIG} >/dev/null if [ $? -eq 0 ] then MEM_FUNCS="__memcpy __memset" From ae8b1631561a3634cc09d0c62bbdd938eade05ec Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 24 Jun 2022 12:11:32 +0200 Subject: [PATCH 020/246] ALSA: usb-audio: Workarounds for Behringer UMC 204/404 HD Both Behringer UMC 202 HD and 404 HD need explicit quirks to enable the implicit feedback mode and start the playback stream primarily. The former seems fixing the stuttering and the latter is required for a playback-only case. Note that the "clock source 41 is not valid" error message still appears even after this fix, but it should be only once at probe. The reason of the error is still unknown, but this seems to be mostly harmless as it's a one-off error and the driver retires the clock setup and it succeeds afterwards. BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=215934 Cc: Link: https://lore.kernel.org/r/20220624101132.14528-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index e8468f9b007d..12ce69b04f63 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1842,6 +1842,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x1397, 0x0508, /* Behringer UMC204HD */ + QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB), + DEVICE_FLG(0x1397, 0x0509, /* Behringer UMC404HD */ + QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB), DEVICE_FLG(0x13e5, 0x0001, /* Serato Phono */ QUIRK_FLAG_IGNORE_CTL_ERROR), DEVICE_FLG(0x154e, 0x1002, /* Denon DCD-1500RE */ From ac63716da3070f8cb6baaba3a058a0c7f22aeb5b Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:46 -0500 Subject: [PATCH 021/246] ASoC: Realtek/Maxim SoundWire codecs: disable pm_runtime on remove When binding/unbinding codec drivers, the following warnings are thrown: [ 107.266879] rt715-sdca sdw:3:025d:0714:01: Unbalanced pm_runtime_enable! [ 306.879700] rt711-sdca sdw:0:025d:0711:01: Unbalanced pm_runtime_enable! Add a remove callback for all Realtek/Maxim SoundWire codecs and remove this warning. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/max98373-sdw.c | 12 +++++++++++- sound/soc/codecs/rt1308-sdw.c | 11 +++++++++++ sound/soc/codecs/rt1316-sdw.c | 11 +++++++++++ sound/soc/codecs/rt5682-sdw.c | 5 ++++- sound/soc/codecs/rt700-sdw.c | 6 +++++- sound/soc/codecs/rt711-sdca-sdw.c | 6 +++++- sound/soc/codecs/rt711-sdw.c | 6 +++++- sound/soc/codecs/rt715-sdca-sdw.c | 12 ++++++++++++ sound/soc/codecs/rt715-sdw.c | 12 ++++++++++++ 9 files changed, 76 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c index f47e956d4f55..97b64477dde6 100644 --- a/sound/soc/codecs/max98373-sdw.c +++ b/sound/soc/codecs/max98373-sdw.c @@ -862,6 +862,16 @@ static int max98373_sdw_probe(struct sdw_slave *slave, return max98373_init(slave, regmap); } +static int max98373_sdw_remove(struct sdw_slave *slave) +{ + struct max98373_priv *max98373 = dev_get_drvdata(&slave->dev); + + if (max98373->first_hw_init) + pm_runtime_disable(&slave->dev); + + return 0; +} + #if defined(CONFIG_OF) static const struct of_device_id max98373_of_match[] = { { .compatible = "maxim,max98373", }, @@ -893,7 +903,7 @@ static struct sdw_driver max98373_sdw_driver = { .pm = &max98373_pm, }, .probe = max98373_sdw_probe, - .remove = NULL, + .remove = max98373_sdw_remove, .ops = &max98373_slave_ops, .id_table = max98373_id, }; diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index 1c11b42dd76e..72f673f278ee 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -691,6 +691,16 @@ static int rt1308_sdw_probe(struct sdw_slave *slave, return 0; } +static int rt1308_sdw_remove(struct sdw_slave *slave) +{ + struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(&slave->dev); + + if (rt1308->first_hw_init) + pm_runtime_disable(&slave->dev); + + return 0; +} + static const struct sdw_device_id rt1308_id[] = { SDW_SLAVE_ENTRY_EXT(0x025d, 0x1308, 0x2, 0, 0), {}, @@ -750,6 +760,7 @@ static struct sdw_driver rt1308_sdw_driver = { .pm = &rt1308_pm, }, .probe = rt1308_sdw_probe, + .remove = rt1308_sdw_remove, .ops = &rt1308_slave_ops, .id_table = rt1308_id, }; diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c index 60baa9ff1907..2d6b5f9d4d77 100644 --- a/sound/soc/codecs/rt1316-sdw.c +++ b/sound/soc/codecs/rt1316-sdw.c @@ -676,6 +676,16 @@ static int rt1316_sdw_probe(struct sdw_slave *slave, return rt1316_sdw_init(&slave->dev, regmap, slave); } +static int rt1316_sdw_remove(struct sdw_slave *slave) +{ + struct rt1316_sdw_priv *rt1316 = dev_get_drvdata(&slave->dev); + + if (rt1316->first_hw_init) + pm_runtime_disable(&slave->dev); + + return 0; +} + static const struct sdw_device_id rt1316_id[] = { SDW_SLAVE_ENTRY_EXT(0x025d, 0x1316, 0x3, 0x1, 0), {}, @@ -735,6 +745,7 @@ static struct sdw_driver rt1316_sdw_driver = { .pm = &rt1316_pm, }, .probe = rt1316_sdw_probe, + .remove = rt1316_sdw_remove, .ops = &rt1316_slave_ops, .id_table = rt1316_id, }; diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c index 248257a2e4e0..f04e18c32489 100644 --- a/sound/soc/codecs/rt5682-sdw.c +++ b/sound/soc/codecs/rt5682-sdw.c @@ -719,9 +719,12 @@ static int rt5682_sdw_remove(struct sdw_slave *slave) { struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev); - if (rt5682 && rt5682->hw_init) + if (rt5682->hw_init) cancel_delayed_work_sync(&rt5682->jack_detect_work); + if (rt5682->first_hw_init) + pm_runtime_disable(&slave->dev); + return 0; } diff --git a/sound/soc/codecs/rt700-sdw.c b/sound/soc/codecs/rt700-sdw.c index bda594899664..f7439e40ca8b 100644 --- a/sound/soc/codecs/rt700-sdw.c +++ b/sound/soc/codecs/rt700-sdw.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "rt700.h" @@ -463,11 +464,14 @@ static int rt700_sdw_remove(struct sdw_slave *slave) { struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev); - if (rt700 && rt700->hw_init) { + if (rt700->hw_init) { cancel_delayed_work_sync(&rt700->jack_detect_work); cancel_delayed_work_sync(&rt700->jack_btn_check_work); } + if (rt700->first_hw_init) + pm_runtime_disable(&slave->dev); + return 0; } diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c index aaf5af153d3f..c722a2b0041f 100644 --- a/sound/soc/codecs/rt711-sdca-sdw.c +++ b/sound/soc/codecs/rt711-sdca-sdw.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "rt711-sdca.h" #include "rt711-sdca-sdw.h" @@ -364,11 +365,14 @@ static int rt711_sdca_sdw_remove(struct sdw_slave *slave) { struct rt711_sdca_priv *rt711 = dev_get_drvdata(&slave->dev); - if (rt711 && rt711->hw_init) { + if (rt711->hw_init) { cancel_delayed_work_sync(&rt711->jack_detect_work); cancel_delayed_work_sync(&rt711->jack_btn_check_work); } + if (rt711->first_hw_init) + pm_runtime_disable(&slave->dev); + return 0; } diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c index bda2cc9439c9..f49c94baa37c 100644 --- a/sound/soc/codecs/rt711-sdw.c +++ b/sound/soc/codecs/rt711-sdw.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "rt711.h" @@ -464,12 +465,15 @@ static int rt711_sdw_remove(struct sdw_slave *slave) { struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev); - if (rt711 && rt711->hw_init) { + if (rt711->hw_init) { cancel_delayed_work_sync(&rt711->jack_detect_work); cancel_delayed_work_sync(&rt711->jack_btn_check_work); cancel_work_sync(&rt711->calibration_work); } + if (rt711->first_hw_init) + pm_runtime_disable(&slave->dev); + return 0; } diff --git a/sound/soc/codecs/rt715-sdca-sdw.c b/sound/soc/codecs/rt715-sdca-sdw.c index 0ecd2948f7aa..13e731d16675 100644 --- a/sound/soc/codecs/rt715-sdca-sdw.c +++ b/sound/soc/codecs/rt715-sdca-sdw.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "rt715-sdca.h" @@ -193,6 +194,16 @@ static int rt715_sdca_sdw_probe(struct sdw_slave *slave, return rt715_sdca_init(&slave->dev, mbq_regmap, regmap, slave); } +static int rt715_sdca_sdw_remove(struct sdw_slave *slave) +{ + struct rt715_sdca_priv *rt715 = dev_get_drvdata(&slave->dev); + + if (rt715->first_hw_init) + pm_runtime_disable(&slave->dev); + + return 0; +} + static const struct sdw_device_id rt715_sdca_id[] = { SDW_SLAVE_ENTRY_EXT(0x025d, 0x715, 0x3, 0x1, 0), SDW_SLAVE_ENTRY_EXT(0x025d, 0x714, 0x3, 0x1, 0), @@ -267,6 +278,7 @@ static struct sdw_driver rt715_sdw_driver = { .pm = &rt715_pm, }, .probe = rt715_sdca_sdw_probe, + .remove = rt715_sdca_sdw_remove, .ops = &rt715_sdca_slave_ops, .id_table = rt715_sdca_id, }; diff --git a/sound/soc/codecs/rt715-sdw.c b/sound/soc/codecs/rt715-sdw.c index a7b21b03c08b..b047bf87a100 100644 --- a/sound/soc/codecs/rt715-sdw.c +++ b/sound/soc/codecs/rt715-sdw.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -514,6 +515,16 @@ static int rt715_sdw_probe(struct sdw_slave *slave, return 0; } +static int rt715_sdw_remove(struct sdw_slave *slave) +{ + struct rt715_priv *rt715 = dev_get_drvdata(&slave->dev); + + if (rt715->first_hw_init) + pm_runtime_disable(&slave->dev); + + return 0; +} + static const struct sdw_device_id rt715_id[] = { SDW_SLAVE_ENTRY_EXT(0x025d, 0x714, 0x2, 0, 0), SDW_SLAVE_ENTRY_EXT(0x025d, 0x715, 0x2, 0, 0), @@ -575,6 +586,7 @@ static struct sdw_driver rt715_sdw_driver = { .pm = &rt715_pm, }, .probe = rt715_sdw_probe, + .remove = rt715_sdw_remove, .ops = &rt715_slave_ops, .id_table = rt715_id, }; From ed0a7fb29c9fd4f53eeb37d1fe2354df7a038047 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:47 -0500 Subject: [PATCH 022/246] ASoC: rt711-sdca-sdw: fix calibrate mutex initialization In codec driver bind/unbind test, the following warning is thrown: DEBUG_LOCKS_WARN_ON(lock->magic != lock) ... [ 699.182495] rt711_sdca_jack_init+0x1b/0x1d0 [snd_soc_rt711_sdca] [ 699.182498] rt711_sdca_set_jack_detect+0x3b/0x90 [snd_soc_rt711_sdca] [ 699.182500] snd_soc_component_set_jack+0x24/0x50 [snd_soc_core] A quick check in the code shows that the 'calibrate_mutex' used by this driver are not initialized at probe time. Moving the initialization to the probe removes the issue. BugLink: https://github.com/thesofproject/linux/issues/3644 Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt711-sdca-sdw.c | 3 +++ sound/soc/codecs/rt711-sdca.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c index c722a2b0041f..a085b2f530aa 100644 --- a/sound/soc/codecs/rt711-sdca-sdw.c +++ b/sound/soc/codecs/rt711-sdca-sdw.c @@ -373,6 +373,9 @@ static int rt711_sdca_sdw_remove(struct sdw_slave *slave) if (rt711->first_hw_init) pm_runtime_disable(&slave->dev); + mutex_destroy(&rt711->calibrate_mutex); + mutex_destroy(&rt711->disable_irq_lock); + return 0; } diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index 57629c18db38..af73bcb4560a 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -1412,6 +1412,7 @@ int rt711_sdca_init(struct device *dev, struct regmap *regmap, rt711->regmap = regmap; rt711->mbq_regmap = mbq_regmap; + mutex_init(&rt711->calibrate_mutex); mutex_init(&rt711->disable_irq_lock); /* @@ -1550,7 +1551,6 @@ int rt711_sdca_io_init(struct device *dev, struct sdw_slave *slave) rt711_sdca_jack_detect_handler); INIT_DELAYED_WORK(&rt711->jack_btn_check_work, rt711_sdca_btn_check_handler); - mutex_init(&rt711->calibrate_mutex); } /* calibration */ From fe154c4ff376bc31041c6441958a08243df09c99 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:48 -0500 Subject: [PATCH 023/246] ASoC: Intel: sof_sdw: handle errors on card registration If the card registration fails, typically because of deferred probes, the device properties added for headset codecs are not removed, which leads to kernel oopses in driver bind/unbind tests. We already clean-up the device properties when the card is removed, this code can be moved as a helper and called upon card registration errors. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/sof_sdw.c | 51 ++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 1f00679b4240..ad826ad82d51 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -1398,6 +1398,33 @@ static struct snd_soc_card card_sof_sdw = { .late_probe = sof_sdw_card_late_probe, }; +static void mc_dailink_exit_loop(struct snd_soc_card *card) +{ + struct snd_soc_dai_link *link; + int ret; + int i, j; + + for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { + if (!codec_info_list[i].exit) + continue; + /* + * We don't need to call .exit function if there is no matched + * dai link found. + */ + for_each_card_prelinks(card, j, link) { + if (!strcmp(link->codecs[0].dai_name, + codec_info_list[i].dai_name)) { + ret = codec_info_list[i].exit(card, link); + if (ret) + dev_warn(card->dev, + "codec exit failed %d\n", + ret); + break; + } + } + } +} + static int mc_probe(struct platform_device *pdev) { struct snd_soc_card *card = &card_sof_sdw; @@ -1462,6 +1489,7 @@ static int mc_probe(struct platform_device *pdev) ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) { dev_err(card->dev, "snd_soc_register_card failed %d\n", ret); + mc_dailink_exit_loop(card); return ret; } @@ -1473,29 +1501,8 @@ static int mc_probe(struct platform_device *pdev) static int mc_remove(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); - struct snd_soc_dai_link *link; - int ret; - int i, j; - for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { - if (!codec_info_list[i].exit) - continue; - /* - * We don't need to call .exit function if there is no matched - * dai link found. - */ - for_each_card_prelinks(card, j, link) { - if (!strcmp(link->codecs[0].dai_name, - codec_info_list[i].dai_name)) { - ret = codec_info_list[i].exit(card, link); - if (ret) - dev_warn(&pdev->dev, - "codec exit failed %d\n", - ret); - break; - } - } - } + mc_dailink_exit_loop(card); return 0; } From 08bb5dc6ce02374169213cea772b1c297eaf32d5 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:49 -0500 Subject: [PATCH 024/246] ASoC: rt711: fix calibrate mutex initialization Follow the same flow as rt711-sdca and initialize all mutexes at probe time. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt711-sdw.c | 3 +++ sound/soc/codecs/rt711.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c index f49c94baa37c..4fe68bcf2a7c 100644 --- a/sound/soc/codecs/rt711-sdw.c +++ b/sound/soc/codecs/rt711-sdw.c @@ -474,6 +474,9 @@ static int rt711_sdw_remove(struct sdw_slave *slave) if (rt711->first_hw_init) pm_runtime_disable(&slave->dev); + mutex_destroy(&rt711->calibrate_mutex); + mutex_destroy(&rt711->disable_irq_lock); + return 0; } diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index 9838fb4d5b9c..1e35ba433a7e 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -1204,6 +1204,7 @@ int rt711_init(struct device *dev, struct regmap *sdw_regmap, rt711->sdw_regmap = sdw_regmap; rt711->regmap = regmap; + mutex_init(&rt711->calibrate_mutex); mutex_init(&rt711->disable_irq_lock); /* @@ -1318,7 +1319,6 @@ int rt711_io_init(struct device *dev, struct sdw_slave *slave) rt711_jack_detect_handler); INIT_DELAYED_WORK(&rt711->jack_btn_check_work, rt711_btn_check_handler); - mutex_init(&rt711->calibrate_mutex); INIT_WORK(&rt711->calibration_work, rt711_calibration_work); schedule_work(&rt711->calibration_work); } From 0484271ab0ce50649329fa9dc23c50853c5b26a4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:50 -0500 Subject: [PATCH 025/246] ASoC: rt7*-sdw: harden jack_detect_handler Realtek headset codec drivers typically check if the card is instantiated before proceeding with the jack detection. The rt700, rt711 and rt711-sdca are however missing a check on the card pointer, which can lead to NULL dereferences encountered in driver bind/unbind tests. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-6-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt700.c | 2 +- sound/soc/codecs/rt711-sdca.c | 2 +- sound/soc/codecs/rt711.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index af32295fa9b9..4a99d5f4706f 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -162,7 +162,7 @@ static void rt700_jack_detect_handler(struct work_struct *work) if (!rt700->hs_jack) return; - if (!rt700->component->card->instantiated) + if (!rt700->component->card || !rt700->component->card->instantiated) return; reg = RT700_VERB_GET_PIN_SENSE | RT700_HP_OUT; diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index af73bcb4560a..93b36f05cb56 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -294,7 +294,7 @@ static void rt711_sdca_jack_detect_handler(struct work_struct *work) if (!rt711->hs_jack) return; - if (!rt711->component->card->instantiated) + if (!rt711->component->card || !rt711->component->card->instantiated) return; /* SDW_SCP_SDCA_INT_SDCA_0 is used for jack detection */ diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index 1e35ba433a7e..2f445b27305a 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -242,7 +242,7 @@ static void rt711_jack_detect_handler(struct work_struct *work) if (!rt711->hs_jack) return; - if (!rt711->component->card->instantiated) + if (!rt711->component->card || !rt711->component->card->instantiated) return; if (pm_runtime_status_suspended(rt711->slave->dev.parent)) { From ba98d7d8b60ba410aa03834f6aa48fd3b2e68478 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:51 -0500 Subject: [PATCH 026/246] ASoC: codecs: rt700/rt711/rt711-sdca: initialize workqueues in probe The workqueues are initialized in the io_init functions, which isn't quite right. In some tests, this leads to warnings throw from __queue_delayed_work() WARN_ON_FUNCTION_MISMATCH(timer->function, delayed_work_timer_fn); Move all the initializations to the probe functions. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt700.c | 12 +++++------- sound/soc/codecs/rt711-sdca.c | 10 +++------- sound/soc/codecs/rt711.c | 12 +++++------- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index 4a99d5f4706f..7a6cf3434591 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -1115,6 +1115,11 @@ int rt700_init(struct device *dev, struct regmap *sdw_regmap, mutex_init(&rt700->disable_irq_lock); + INIT_DELAYED_WORK(&rt700->jack_detect_work, + rt700_jack_detect_handler); + INIT_DELAYED_WORK(&rt700->jack_btn_check_work, + rt700_btn_check_handler); + /* * Mark hw_init to false * HW init will be performed when device reports present @@ -1209,13 +1214,6 @@ int rt700_io_init(struct device *dev, struct sdw_slave *slave) /* Finish Initial Settings, set power to D3 */ regmap_write(rt700->regmap, RT700_SET_AUDIO_POWER_STATE, AC_PWRST_D3); - if (!rt700->first_hw_init) { - INIT_DELAYED_WORK(&rt700->jack_detect_work, - rt700_jack_detect_handler); - INIT_DELAYED_WORK(&rt700->jack_btn_check_work, - rt700_btn_check_handler); - } - /* * if set_jack callback occurred early than io_init, * we set up the jack detection function now diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index 93b36f05cb56..2b3b77577d1f 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -1415,6 +1415,9 @@ int rt711_sdca_init(struct device *dev, struct regmap *regmap, mutex_init(&rt711->calibrate_mutex); mutex_init(&rt711->disable_irq_lock); + INIT_DELAYED_WORK(&rt711->jack_detect_work, rt711_sdca_jack_detect_handler); + INIT_DELAYED_WORK(&rt711->jack_btn_check_work, rt711_sdca_btn_check_handler); + /* * Mark hw_init to false * HW init will be performed when device reports present @@ -1546,13 +1549,6 @@ int rt711_sdca_io_init(struct device *dev, struct sdw_slave *slave) rt711_sdca_index_update_bits(rt711, RT711_VENDOR_HDA_CTL, RT711_PUSH_BTN_INT_CTL0, 0x20, 0x00); - if (!rt711->first_hw_init) { - INIT_DELAYED_WORK(&rt711->jack_detect_work, - rt711_sdca_jack_detect_handler); - INIT_DELAYED_WORK(&rt711->jack_btn_check_work, - rt711_sdca_btn_check_handler); - } - /* calibration */ ret = rt711_sdca_calibration(rt711); if (ret < 0) diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index 2f445b27305a..5709a6bbe8fc 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -1207,6 +1207,10 @@ int rt711_init(struct device *dev, struct regmap *sdw_regmap, mutex_init(&rt711->calibrate_mutex); mutex_init(&rt711->disable_irq_lock); + INIT_DELAYED_WORK(&rt711->jack_detect_work, rt711_jack_detect_handler); + INIT_DELAYED_WORK(&rt711->jack_btn_check_work, rt711_btn_check_handler); + INIT_WORK(&rt711->calibration_work, rt711_calibration_work); + /* * Mark hw_init to false * HW init will be performed when device reports present @@ -1314,14 +1318,8 @@ int rt711_io_init(struct device *dev, struct sdw_slave *slave) if (rt711->first_hw_init) rt711_calibration(rt711); - else { - INIT_DELAYED_WORK(&rt711->jack_detect_work, - rt711_jack_detect_handler); - INIT_DELAYED_WORK(&rt711->jack_btn_check_work, - rt711_btn_check_handler); - INIT_WORK(&rt711->calibration_work, rt711_calibration_work); + else schedule_work(&rt711->calibration_work); - } /* * if set_jack callback occurred early than io_init, From 40737057b48f1b4db67b0d766b95c87ba8fc5e03 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 6 Jun 2022 15:37:52 -0500 Subject: [PATCH 027/246] ASoC: codecs: rt700/rt711/rt711-sdca: resume bus/codec in .set_jack_detect The .set_jack_detect() codec component callback is invoked during card registration, which happens when the machine driver is probed. The issue is that this callback can race with the bus suspend/resume, and IO timeouts can happen. This can be reproduced very easily if the machine driver is 'blacklisted' and manually probed after the bus suspends. The bus and codec need to be re-initialized using pm_runtime helpers. Previous contributions tried to make sure accesses to the bus during the .set_jack_detect() component callback only happen when the bus is active. This was done by changing the regcache status on a component remove. This is however a layering violation, the regcache status should only be modified on device probe, suspend and resume. The component probe/remove should not modify how the device regcache is handled. This solution also didn't handle all the possible race conditions, and the RT700 headset codec was not handled. This patch tries to resume the codec device before handling the jack initializations. In case the codec has not yet been initialized, pm_runtime may not be enabled yet, so we don't squelch the -EACCES error code and only stop the jack information. When the codec reports as attached, the jack initialization will proceed as usual. BugLink: https://github.com/thesofproject/linux/issues/3643 Fixes: 7ad4d237e7c4a ('ASoC: rt711-sdca: Add RT711 SDCA vendor-specific driver') Fixes: 899b12542b089 ('ASoC: rt711: add snd_soc_component remove callback') Signed-off-by: Pierre-Louis Bossart Reviewed-by: Rander Wang Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220606203752.144159-8-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt700.c | 16 +++++++++++++--- sound/soc/codecs/rt711-sdca.c | 26 ++++++++++++++------------ sound/soc/codecs/rt711.c | 24 +++++++++++++----------- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index 7a6cf3434591..9bceeeb830b1 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -315,17 +315,27 @@ static int rt700_set_jack_detect(struct snd_soc_component *component, struct snd_soc_jack *hs_jack, void *data) { struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component); + int ret; rt700->hs_jack = hs_jack; - if (!rt700->hw_init) { - dev_dbg(&rt700->slave->dev, - "%s hw_init not ready yet\n", __func__); + ret = pm_runtime_resume_and_get(component->dev); + if (ret < 0) { + if (ret != -EACCES) { + dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret); + return ret; + } + + /* pm_runtime not enabled yet */ + dev_dbg(component->dev, "%s: skipping jack init for now\n", __func__); return 0; } rt700_jack_init(rt700); + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); + return 0; } diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index 2b3b77577d1f..dfe3c9299ebd 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -487,16 +487,27 @@ static int rt711_sdca_set_jack_detect(struct snd_soc_component *component, struct snd_soc_jack *hs_jack, void *data) { struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); + int ret; rt711->hs_jack = hs_jack; - if (!rt711->hw_init) { - dev_dbg(&rt711->slave->dev, - "%s hw_init not ready yet\n", __func__); + ret = pm_runtime_resume_and_get(component->dev); + if (ret < 0) { + if (ret != -EACCES) { + dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret); + return ret; + } + + /* pm_runtime not enabled yet */ + dev_dbg(component->dev, "%s: skipping jack init for now\n", __func__); return 0; } rt711_sdca_jack_init(rt711); + + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); + return 0; } @@ -1190,14 +1201,6 @@ static int rt711_sdca_probe(struct snd_soc_component *component) return 0; } -static void rt711_sdca_remove(struct snd_soc_component *component) -{ - struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component); - - regcache_cache_only(rt711->regmap, true); - regcache_cache_only(rt711->mbq_regmap, true); -} - static const struct snd_soc_component_driver soc_sdca_dev_rt711 = { .probe = rt711_sdca_probe, .controls = rt711_sdca_snd_controls, @@ -1207,7 +1210,6 @@ static const struct snd_soc_component_driver soc_sdca_dev_rt711 = { .dapm_routes = rt711_sdca_audio_map, .num_dapm_routes = ARRAY_SIZE(rt711_sdca_audio_map), .set_jack = rt711_sdca_set_jack_detect, - .remove = rt711_sdca_remove, .endianness = 1, }; diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index 5709a6bbe8fc..9df800abfc2d 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -457,17 +457,27 @@ static int rt711_set_jack_detect(struct snd_soc_component *component, struct snd_soc_jack *hs_jack, void *data) { struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component); + int ret; rt711->hs_jack = hs_jack; - if (!rt711->hw_init) { - dev_dbg(&rt711->slave->dev, - "%s hw_init not ready yet\n", __func__); + ret = pm_runtime_resume_and_get(component->dev); + if (ret < 0) { + if (ret != -EACCES) { + dev_err(component->dev, "%s: failed to resume %d\n", __func__, ret); + return ret; + } + + /* pm_runtime not enabled yet */ + dev_dbg(component->dev, "%s: skipping jack init for now\n", __func__); return 0; } rt711_jack_init(rt711); + pm_runtime_mark_last_busy(component->dev); + pm_runtime_put_autosuspend(component->dev); + return 0; } @@ -932,13 +942,6 @@ static int rt711_probe(struct snd_soc_component *component) return 0; } -static void rt711_remove(struct snd_soc_component *component) -{ - struct rt711_priv *rt711 = snd_soc_component_get_drvdata(component); - - regcache_cache_only(rt711->regmap, true); -} - static const struct snd_soc_component_driver soc_codec_dev_rt711 = { .probe = rt711_probe, .set_bias_level = rt711_set_bias_level, @@ -949,7 +952,6 @@ static const struct snd_soc_component_driver soc_codec_dev_rt711 = { .dapm_routes = rt711_audio_map, .num_dapm_routes = ARRAY_SIZE(rt711_audio_map), .set_jack = rt711_set_jack_detect, - .remove = rt711_remove, .endianness = 1, }; From ed0073bd0fccec459b526918be70bf9dc551581a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 8 Jun 2022 02:09:16 +0000 Subject: [PATCH 028/246] ASoC: ak4613: cares Simple-Audio-Card case for TDM Renesas is the only user of ak4613 on upstream for now, and commit f28dbaa958fbd8 ("ASoC: ak4613: add TDM256 support") added TDM256 support. Renesas tested part of it, because of board connection. It was assuming ak4613 is probed via Audio-Graph-Card, but it might be probed via Simple-Audio-Card either. It will indicates WARNING in such case. This patch fixup it. Reported-by: Geert Uytterhoeven Signed-off-by: Kuninori Morimoto Tested-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/87h74v29f7.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown --- sound/soc/codecs/ak4613.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c index 55e773f92122..93606e5afd8f 100644 --- a/sound/soc/codecs/ak4613.c +++ b/sound/soc/codecs/ak4613.c @@ -868,10 +868,12 @@ static void ak4613_parse_of(struct ak4613_priv *priv, /* * connected STDI + * TDM support is assuming it is probed via Audio-Graph-Card style here. + * Default is SDTIx1 if it was probed via Simple-Audio-Card for now. */ sdti_num = of_graph_get_endpoint_count(np); - if (WARN_ON((sdti_num > 3) || (sdti_num < 1))) - return; + if ((sdti_num >= SDTx_MAX) || (sdti_num < 1)) + sdti_num = 1; AK4613_CONFIG_SDTI_set(priv, sdti_num); } From 08f8a93198e300dff9649bbae424cd805d313326 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 9 Jun 2022 11:59:47 +0300 Subject: [PATCH 029/246] ASoC: SOF: Intel: hda-dsp: Expose hda_dsp_core_power_up() The hda_dsp_core_power_up() needs to be exposed so that it can be used in hda-loader.c to correct the boot flow. The first step must not unstall the core, it should only power up the core(s). Add sanity check for the core_mask while exposing it to be safe. Complements: 2a68ff846164 ("ASoC: SOF: Intel: hda: Revisit IMR boot sequence") Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609085949.29062-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-dsp.c | 10 +++++++++- sound/soc/sof/intel/hda.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 000ea906670c..e24eea725acb 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -181,12 +181,20 @@ int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask) * Power Management. */ -static int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask) +int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask) { + struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + const struct sof_intel_dsp_desc *chip = hda->desc; unsigned int cpa; u32 adspcs; int ret; + /* restrict core_mask to host managed cores mask */ + core_mask &= chip->host_managed_cores_mask; + /* return if core_mask is not valid */ + if (!core_mask) + return 0; + /* update bits */ snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS, HDA_DSP_ADSPCS_SPA_MASK(core_mask), diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 3e0f7b0c586a..0f57ef5d9b8e 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -497,6 +497,7 @@ struct sof_intel_hda_stream { */ int hda_dsp_probe(struct snd_sof_dev *sdev); int hda_dsp_remove(struct snd_sof_dev *sdev); +int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask); int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask); int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask); int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev, From c31691e0d126ec5d60d2b6b03f699c11b613b219 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 9 Jun 2022 11:59:48 +0300 Subject: [PATCH 030/246] ASoC: SOF: Intel: hda-loader: Make sure that the fw load sequence is followed The hda_dsp_enable_core() is powering up _and_ unstall the core in one call while the first step of the firmware loading must not unstall the core. The core can be unstalled only after the set cpb_cfp and the configuration of the IPC register for the ROM_CONTROL message. Complements: 2a68ff846164 ("ASoC: SOF: Intel: hda: Revisit IMR boot sequence") Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609085949.29062-3-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 64290125d7cd..103e62bcfa82 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -110,7 +110,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot) int ret; /* step 1: power up corex */ - ret = hda_dsp_enable_core(sdev, chip->host_managed_cores_mask); + ret = hda_dsp_core_power_up(sdev, chip->host_managed_cores_mask); if (ret < 0) { if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n"); From bbfef046c6613404c01aeb9e9928bebb78dd327a Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 9 Jun 2022 11:59:49 +0300 Subject: [PATCH 031/246] ASoC: SOF: Intel: hda-loader: Clarify the cl_dsp_init() flow Update the comment for the cl_dsp_init() to clarify what is done by the function and use the chip->init_core_mask instead of BIT(0) when unstalling/running the init core. Complements: 2a68ff846164 ("ASoC: SOF: Intel: hda: Revisit IMR boot sequence") Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Link: https://lore.kernel.org/r/20220609085949.29062-4-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index 103e62bcfa82..d3ec5996a9a3 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -95,9 +95,9 @@ out_put: } /* - * first boot sequence has some extra steps. core 0 waits for power - * status on core 1, so power up core 1 also momentarily, keep it in - * reset/stall and then turn it off + * first boot sequence has some extra steps. + * power on all host managed cores and only unstall/run the boot core to boot the + * DSP then turn off all non boot cores (if any) is powered on. */ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot) { @@ -127,7 +127,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, bool imr_boot) snd_sof_dsp_write(sdev, HDA_DSP_BAR, chip->ipc_req, ipc_hdr); /* step 3: unset core 0 reset state & unstall/run core 0 */ - ret = hda_dsp_core_run(sdev, BIT(0)); + ret = hda_dsp_core_run(sdev, chip->init_core_mask); if (ret < 0) { if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS) dev_err(sdev->dev, From c2d1aec3f5da2475aa13a487d329823b7d27d499 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Jun 2022 11:47:35 +0300 Subject: [PATCH 032/246] ASoC: SOF: ipc3-topology: Move and correct size checks in sof_ipc3_control_load_bytes() Move the size checks prior to allocating memory as these checks do not need the data to be allocated and in case of an error we would not need to free the allocation. The max size must not be less than the size of struct sof_ipc_ctrl_data + struct sof_abi_hdr as the ABI header needs to be present under all circumstances. The check was incorrectly used or between the two size checks. Fixes: b5cee8feb1d4 ("ASoC: SOF: topology: Make control parsing IPC agnostic") Signed-off-by: Peter Ujfalusi Reviewed-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20220610084735.19397-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/ipc3-topology.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 043554d7cb4a..10740c55294d 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -1577,24 +1577,23 @@ static int sof_ipc3_control_load_bytes(struct snd_sof_dev *sdev, struct snd_sof_ struct sof_ipc_ctrl_data *cdata; int ret; + if (scontrol->max_size < (sizeof(*cdata) + sizeof(struct sof_abi_hdr))) { + dev_err(sdev->dev, "%s: insufficient size for a bytes control: %zu.\n", + __func__, scontrol->max_size); + return -EINVAL; + } + + if (scontrol->priv_size > scontrol->max_size - sizeof(*cdata)) { + dev_err(sdev->dev, + "%s: bytes data size %zu exceeds max %zu.\n", __func__, + scontrol->priv_size, scontrol->max_size - sizeof(*cdata)); + return -EINVAL; + } + scontrol->ipc_control_data = kzalloc(scontrol->max_size, GFP_KERNEL); if (!scontrol->ipc_control_data) return -ENOMEM; - if (scontrol->max_size < sizeof(*cdata) || - scontrol->max_size < sizeof(struct sof_abi_hdr)) { - ret = -EINVAL; - goto err; - } - - /* init the get/put bytes data */ - if (scontrol->priv_size > scontrol->max_size - sizeof(*cdata)) { - dev_err(sdev->dev, "err: bytes data size %zu exceeds max %zu.\n", - scontrol->priv_size, scontrol->max_size - sizeof(*cdata)); - ret = -EINVAL; - goto err; - } - scontrol->size = sizeof(struct sof_ipc_ctrl_data) + scontrol->priv_size; cdata = scontrol->ipc_control_data; From af2d146a8041c67efdd620c9463973ce0650b7b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Fri, 10 Jun 2022 14:42:57 +0200 Subject: [PATCH 033/246] ASoC: Intel: avs: Fix parsing UUIDs in topology MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use correct type for parsing UUIDs, this eliminates warning present, when compiling with W=1. Fixes: 34ae2cd53673 ("ASoC: Intel: avs: Add topology parsing infrastructure") Reported-by: Pierre-Louis Bossart Signed-off-by: Amadeusz Sławiński Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220610124257.4160658-1-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/avs/topology.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c index 0d11cc8aab0b..6a06fe387d13 100644 --- a/sound/soc/intel/avs/topology.c +++ b/sound/soc/intel/avs/topology.c @@ -128,10 +128,10 @@ struct avs_tplg_token_parser { static int avs_parse_uuid_token(struct snd_soc_component *comp, void *elem, void *object, u32 offset) { - struct snd_soc_tplg_vendor_value_elem *tuple = elem; + struct snd_soc_tplg_vendor_uuid_elem *tuple = elem; guid_t *val = (guid_t *)((u8 *)object + offset); - guid_copy((guid_t *)val, (const guid_t *)&tuple->value); + guid_copy((guid_t *)val, (const guid_t *)&tuple->uuid); return 0; } From 12abc4d10d5502e4f3d8f1c6f9e8245747a44708 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Fri, 10 Jun 2022 14:44:20 +0200 Subject: [PATCH 034/246] ASoC: Remove unused hw_write_t type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 81da8a0b7975 ("ASoC: remove codec hw_write/control_data") removed use of hw_write_t in struct snd_soc_codec, but it left type definition. Fully clean it up. Fixes: 81da8a0b7975 ("ASoC: remove codec hw_write/control_data") Signed-off-by: Amadeusz Sławiński Reviewed-by: Cezary Rojewski Link: https://lore.kernel.org/r/20220610124420.4160986-1-amadeuszx.slawinski@linux.intel.com Signed-off-by: Mark Brown --- include/sound/soc.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index f20f5f890794..b276dcb5d4e8 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -408,8 +408,6 @@ struct snd_soc_jack_pin; struct snd_soc_jack_gpio; -typedef int (*hw_write_t)(void *,const char* ,int); - enum snd_soc_pcm_subclass { SND_SOC_PCM_CLASS_PCM = 0, SND_SOC_PCM_CLASS_BE = 1, From 58136d93d4e2c1207a5e4f3044815cd40b1d95fd Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 10 Jun 2022 15:48:18 +0100 Subject: [PATCH 035/246] ASoC: qdsp6: q6apm-dai: unprepare stream if its already prepared prepare callback can be called multiple times, so unprepare the stream if its already prepared. Without this DSP is not happy to setting the params on a already prepared graph. Fixes: 9b4fe0f1cd79 ("ASoC: qdsp6: audioreach: add q6apm-dai support") Reported-by: Srinivasa Rao Mandadapu Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220610144818.511797-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- sound/soc/qcom/qdsp6/q6apm-dai.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c index 19c4a90ec1ea..ee59ef36b85a 100644 --- a/sound/soc/qcom/qdsp6/q6apm-dai.c +++ b/sound/soc/qcom/qdsp6/q6apm-dai.c @@ -147,6 +147,12 @@ static int q6apm_dai_prepare(struct snd_soc_component *component, cfg.num_channels = runtime->channels; cfg.bit_width = prtd->bits_per_sample; + if (prtd->state) { + /* clear the previous setup if any */ + q6apm_graph_stop(prtd->graph); + q6apm_unmap_memory_regions(prtd->graph, substream->stream); + } + prtd->pcm_count = snd_pcm_lib_period_bytes(substream); prtd->pos = 0; /* rate and channels are sent to audio driver */ From be6dd72edb216f20fc80e426ece9fe9b8aabf033 Mon Sep 17 00:00:00 2001 From: Yassine Oudjana Date: Mon, 6 Jun 2022 19:22:26 +0400 Subject: [PATCH 036/246] ASoC: wcd9335: Remove RX channel from old list before adding it to a new one Currently in slim_rx_mux_put, an RX channel gets added to a new list even if it is already in one. This can mess up links and make either it, the new list head, or both, get linked to the wrong entries. This can cause an entry to link to itself which in turn ends up making list_for_each_entry in other functions loop infinitely. To avoid issues, always remove the RX channel from any list it's in before adding it to a new list. Signed-off-by: Yassine Oudjana Link: https://lore.kernel.org/r/20220606152226.149164-1-y.oudjana@protonmail.com Signed-off-by: Mark Brown --- sound/soc/codecs/wcd9335.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 617a36a89dfe..597420679505 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -1289,9 +1289,12 @@ static int slim_rx_mux_put(struct snd_kcontrol *kc, wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; + /* Remove channel from any list it's in before adding it to a new one */ + list_del_init(&wcd->rx_chs[port_id].list); + switch (wcd->rx_port_value[port_id]) { case 0: - list_del_init(&wcd->rx_chs[port_id].list); + /* Channel already removed from lists. Nothing to do here */ break; case 1: list_add_tail(&wcd->rx_chs[port_id].list, From a7786cbae4b2732815da98efa39df96746b5bd0d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Jun 2022 14:46:09 +0200 Subject: [PATCH 037/246] ASoC: wcd9335: Fix spurious event generation The slimbus mux put operation unconditionally reports a change in value which means that spurious events are generated. Fix this by exiting early in that case. Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220603124609.4024666-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd9335.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 597420679505..d9f135200688 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -1287,6 +1287,9 @@ static int slim_rx_mux_put(struct snd_kcontrol *kc, struct snd_soc_dapm_update *update = NULL; u32 port_id = w->shift; + if (wcd->rx_port_value[port_id] == ucontrol->value.enumerated.item[0]) + return 0; + wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; /* Remove channel from any list it's in before adding it to a new one */ From 10e7ff0047921e32b919ecee7be706dd33c107f8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Jun 2022 14:25:26 +0200 Subject: [PATCH 038/246] ASoC: wcd938x: Fix event generation for some controls Currently wcd938x_*_put() unconditionally report that the value of the control changed, resulting in spurious events being generated. Return 0 in that case instead as we should. There is still an issue in the compander control which is a bit more complex. Signed-off-by: Mark Brown Reported-by: kernel test robot Link: https://lore.kernel.org/r/20220603122526.3914942-1-broonie@kernel.org Signed-off-by: Mark Brown --- sound/soc/codecs/wcd938x.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index c1b61b997f69..781ae569be29 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -2519,6 +2519,9 @@ static int wcd938x_tx_mode_put(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; int path = e->shift_l; + if (wcd938x->tx_mode[path] == ucontrol->value.enumerated.item[0]) + return 0; + wcd938x->tx_mode[path] = ucontrol->value.enumerated.item[0]; return 1; @@ -2541,6 +2544,9 @@ static int wcd938x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + if (wcd938x->hph_mode == ucontrol->value.enumerated.item[0]) + return 0; + wcd938x->hph_mode = ucontrol->value.enumerated.item[0]; return 1; @@ -2632,6 +2638,9 @@ static int wcd938x_ldoh_put(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + if (wcd938x->ldoh == ucontrol->value.integer.value[0]) + return 0; + wcd938x->ldoh = ucontrol->value.integer.value[0]; return 1; @@ -2654,6 +2663,9 @@ static int wcd938x_bcs_put(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component); + if (wcd938x->bcs_dis == ucontrol->value.integer.value[0]) + return 0; + wcd938x->bcs_dis = ucontrol->value.integer.value[0]; return 1; From a7d9391dc3d570aed87ed764db95b16760c898e4 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Fri, 10 Jun 2022 16:43:13 -0500 Subject: [PATCH 039/246] MAINTAINERS: update ASoC/Intel/SOF maintainers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keyon Jie was a key contributor to the Intel ASoC and SOF Intel drivers, but he's moved on to a different role within Intel. We wish him all the best in his new endeavors. Bard Liao, Kai Vehmanen, Ranjani Sridharan and Peter Ujfalusi have been involved in the Intel multi-maintainer team, it's time to update the MAINTAINERS entry to reflect their contributions and clarify their role. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Kai Vehmanen Reviewed-by: Bard Liao Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220610214313.42903-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- MAINTAINERS | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index a6d3bd9d2a8d..440f3d7c93b9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9803,7 +9803,10 @@ INTEL ASoC DRIVERS M: Cezary Rojewski M: Pierre-Louis Bossart M: Liam Girdwood -M: Jie Yang +M: Peter Ujfalusi +M: Bard Liao +M: Ranjani Sridharan +M: Kai Vehmanen L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Supported F: sound/soc/intel/ @@ -18670,8 +18673,10 @@ F: sound/soc/ SOUND - SOUND OPEN FIRMWARE (SOF) DRIVERS M: Pierre-Louis Bossart M: Liam Girdwood +M: Peter Ujfalusi +M: Bard Liao M: Ranjani Sridharan -M: Kai Vehmanen +R: Kai Vehmanen M: Daniel Baluta L: sound-open-firmware@alsa-project.org (moderated for non-subscribers) S: Supported From 4e07479eab8a044cc9542414ccb4aeb8eb033bde Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 12 Jun 2022 17:56:52 +0200 Subject: [PATCH 040/246] ASoC: Intel: bytcr_wm5102: Fix GPIO related probe-ordering problem The "wlf,spkvdd-ena" GPIO needed by the bytcr_wm5102 driver is made available through a gpio-lookup table. This gpio-lookup table is registered by drivers/mfd/arizona-spi.c, which may get probed after the bytcr_wm5102 driver. If the gpio-lookup table has not registered yet then the gpiod_get() will return -ENOENT. Treat -ENOENT as -EPROBE_DEFER to still keep things working in this case. Signed-off-by: Hans de Goede Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220612155652.107310-1-hdegoede@redhat.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/bytcr_wm5102.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 00384c6fbcaa..330c0ace1638 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -421,8 +421,17 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) priv->spkvdd_en_gpio = gpiod_get(codec_dev, "wlf,spkvdd-ena", GPIOD_OUT_LOW); put_device(codec_dev); - if (IS_ERR(priv->spkvdd_en_gpio)) - return dev_err_probe(dev, PTR_ERR(priv->spkvdd_en_gpio), "getting spkvdd-GPIO\n"); + if (IS_ERR(priv->spkvdd_en_gpio)) { + ret = PTR_ERR(priv->spkvdd_en_gpio); + /* + * The spkvdd gpio-lookup is registered by: drivers/mfd/arizona-spi.c, + * so -ENOENT means that arizona-spi hasn't probed yet. + */ + if (ret == -ENOENT) + ret = -EPROBE_DEFER; + + return dev_err_probe(dev, ret, "getting spkvdd-GPIO\n"); + } /* override platform name, if required */ byt_wm5102_card.dev = dev; From 427eb3e1ed530792231bc5bbee6dec99fc57aeb7 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 15 Jun 2022 11:19:44 +0300 Subject: [PATCH 041/246] ASoC: SOF: mediatek: Fix error code in probe This should return PTR_ERR() instead of IS_ERR(). Fixes: e0100bfd383c ("ASoC: SOF: mediatek: Add mt8186 ipc support") Signed-off-by: Dan Carpenter Acked-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/YqmWIK8sTj578OJP@kili Signed-off-by: Mark Brown --- sound/soc/sof/mediatek/mt8186/mt8186.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c index 3333a0634e29..e006532caf2f 100644 --- a/sound/soc/sof/mediatek/mt8186/mt8186.c +++ b/sound/soc/sof/mediatek/mt8186/mt8186.c @@ -392,7 +392,7 @@ static int mt8186_dsp_probe(struct snd_sof_dev *sdev) PLATFORM_DEVID_NONE, pdev, sizeof(*pdev)); if (IS_ERR(priv->ipc_dev)) { - ret = IS_ERR(priv->ipc_dev); + ret = PTR_ERR(priv->ipc_dev); dev_err(sdev->dev, "failed to create mtk-adsp-ipc device\n"); goto err_adsp_off; } From ca7ab1dcf58dfce5bc851bf7e50fd94822c24665 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 16 Jun 2022 15:19:53 -0500 Subject: [PATCH 042/246] ASoC: SOF: Intel: hda: Fix compressed stream position tracking Commit 288fad2f71fa ("ASoC: SOF: Intel: hda: add quirks for HDAudio DMA position information") modified the PCM path only, but left the compressed data patch using an obsolete option. Move the functionality in a helper that can be called for both PCM and compressed data. Reviewed-by: Ranjani Sridharan Fixes: 288fad2f71fa ("ASoC: SOF: Intel: hda: add quirks for HDAudio DMA position information") Signed-off-by: Peter Ujfalusi Signed-off-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20220616201953.130876-1-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-pcm.c | 74 +------------------------ sound/soc/sof/intel/hda-stream.c | 94 ++++++++++++++++++++++++++++++-- sound/soc/sof/intel/hda.h | 3 + 3 files changed, 94 insertions(+), 77 deletions(-) diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index dc1f743730c0..6888e0a4665d 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -192,79 +192,7 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev, goto found; } - switch (sof_hda_position_quirk) { - case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY: - /* - * This legacy code, inherited from the Skylake driver, - * mixes DPIB registers and DPIB DDR updates and - * does not seem to follow any known hardware recommendations. - * It's not clear e.g. why there is a different flow - * for capture and playback, the only information that matters is - * what traffic class is used, and on all SOF-enabled platforms - * only VC0 is supported so the work-around was likely not necessary - * and quite possibly wrong. - */ - - /* DPIB/posbuf position mode: - * For Playback, Use DPIB register from HDA space which - * reflects the actual data transferred. - * For Capture, Use the position buffer for pointer, as DPIB - * is not accurate enough, its update may be completed - * earlier than the data written to DDR. - */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, - AZX_REG_VS_SDXDPIB_XBASE + - (AZX_REG_VS_SDXDPIB_XINTERVAL * - hstream->index)); - } else { - /* - * For capture stream, we need more workaround to fix the - * position incorrect issue: - * - * 1. Wait at least 20us before reading position buffer after - * the interrupt generated(IOC), to make sure position update - * happens on frame boundary i.e. 20.833uSec for 48KHz. - * 2. Perform a dummy Read to DPIB register to flush DMA - * position value. - * 3. Read the DMA Position from posbuf. Now the readback - * value should be >= period boundary. - */ - usleep_range(20, 21); - snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, - AZX_REG_VS_SDXDPIB_XBASE + - (AZX_REG_VS_SDXDPIB_XINTERVAL * - hstream->index)); - pos = snd_hdac_stream_get_pos_posbuf(hstream); - } - break; - case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS: - /* - * In case VC1 traffic is disabled this is the recommended option - */ - pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, - AZX_REG_VS_SDXDPIB_XBASE + - (AZX_REG_VS_SDXDPIB_XINTERVAL * - hstream->index)); - break; - case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE: - /* - * This is the recommended option when VC1 is enabled. - * While this isn't needed for SOF platforms it's added for - * consistency and debug. - */ - pos = snd_hdac_stream_get_pos_posbuf(hstream); - break; - default: - dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n", - sof_hda_position_quirk); - pos = 0; - break; - } - - if (pos >= hstream->bufsize) - pos = 0; - + pos = hda_dsp_stream_get_position(hstream, substream->stream, true); found: pos = bytes_to_frames(substream->runtime, pos); diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index daeb64c495e4..d95ae17e81cc 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -707,12 +707,13 @@ bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev) } static void -hda_dsp_set_bytes_transferred(struct hdac_stream *hstream, u64 buffer_size) +hda_dsp_compr_bytes_transferred(struct hdac_stream *hstream, int direction) { + u64 buffer_size = hstream->bufsize; u64 prev_pos, pos, num_bytes; div64_u64_rem(hstream->curr_pos, buffer_size, &prev_pos); - pos = snd_hdac_stream_get_pos_posbuf(hstream); + pos = hda_dsp_stream_get_position(hstream, direction, false); if (pos < prev_pos) num_bytes = (buffer_size - prev_pos) + pos; @@ -748,8 +749,7 @@ static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status) if (s->substream && sof_hda->no_ipc_position) { snd_sof_pcm_period_elapsed(s->substream); } else if (s->cstream) { - hda_dsp_set_bytes_transferred(s, - s->cstream->runtime->buffer_size); + hda_dsp_compr_bytes_transferred(s, s->cstream->direction); snd_compr_fragment_elapsed(s->cstream); } } @@ -1009,3 +1009,89 @@ void hda_dsp_stream_free(struct snd_sof_dev *sdev) devm_kfree(sdev->dev, hda_stream); } } + +snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream, + int direction, bool can_sleep) +{ + struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream); + struct sof_intel_hda_stream *hda_stream = hstream_to_sof_hda_stream(hext_stream); + struct snd_sof_dev *sdev = hda_stream->sdev; + snd_pcm_uframes_t pos; + + switch (sof_hda_position_quirk) { + case SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY: + /* + * This legacy code, inherited from the Skylake driver, + * mixes DPIB registers and DPIB DDR updates and + * does not seem to follow any known hardware recommendations. + * It's not clear e.g. why there is a different flow + * for capture and playback, the only information that matters is + * what traffic class is used, and on all SOF-enabled platforms + * only VC0 is supported so the work-around was likely not necessary + * and quite possibly wrong. + */ + + /* DPIB/posbuf position mode: + * For Playback, Use DPIB register from HDA space which + * reflects the actual data transferred. + * For Capture, Use the position buffer for pointer, as DPIB + * is not accurate enough, its update may be completed + * earlier than the data written to DDR. + */ + if (direction == SNDRV_PCM_STREAM_PLAYBACK) { + pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, + AZX_REG_VS_SDXDPIB_XBASE + + (AZX_REG_VS_SDXDPIB_XINTERVAL * + hstream->index)); + } else { + /* + * For capture stream, we need more workaround to fix the + * position incorrect issue: + * + * 1. Wait at least 20us before reading position buffer after + * the interrupt generated(IOC), to make sure position update + * happens on frame boundary i.e. 20.833uSec for 48KHz. + * 2. Perform a dummy Read to DPIB register to flush DMA + * position value. + * 3. Read the DMA Position from posbuf. Now the readback + * value should be >= period boundary. + */ + if (can_sleep) + usleep_range(20, 21); + + snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, + AZX_REG_VS_SDXDPIB_XBASE + + (AZX_REG_VS_SDXDPIB_XINTERVAL * + hstream->index)); + pos = snd_hdac_stream_get_pos_posbuf(hstream); + } + break; + case SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS: + /* + * In case VC1 traffic is disabled this is the recommended option + */ + pos = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, + AZX_REG_VS_SDXDPIB_XBASE + + (AZX_REG_VS_SDXDPIB_XINTERVAL * + hstream->index)); + break; + case SOF_HDA_POSITION_QUIRK_USE_DPIB_DDR_UPDATE: + /* + * This is the recommended option when VC1 is enabled. + * While this isn't needed for SOF platforms it's added for + * consistency and debug. + */ + pos = snd_hdac_stream_get_pos_posbuf(hstream); + break; + default: + dev_err_once(sdev->dev, "hda_position_quirk value %d not supported\n", + sof_hda_position_quirk); + pos = 0; + break; + } + + if (pos >= hstream->bufsize) + pos = 0; + + return pos; +} diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 0f57ef5d9b8e..06476ffe96d7 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -565,6 +565,9 @@ int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev, bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev); bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev); +snd_pcm_uframes_t hda_dsp_stream_get_position(struct hdac_stream *hstream, + int direction, bool can_sleep); + struct hdac_ext_stream * hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags); int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag); From a933084558c61cac8c902d2474b39444d87fba46 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 15:18:16 -0500 Subject: [PATCH 043/246] ASoC: SOF: pm: add explicit behavior for ACPI S1 and S2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The existing code only deals with S0 and S3, let's start adding S1 and S2. No functional change. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220616201818.130802-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/pm.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 18eb327a57f0..239f39a5166a 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -335,8 +335,18 @@ int snd_sof_prepare(struct device *dev) return 0; #if defined(CONFIG_ACPI) - if (acpi_target_system_state() == ACPI_STATE_S0) + switch (acpi_target_system_state()) { + case ACPI_STATE_S0: sdev->system_suspend_target = SOF_SUSPEND_S0IX; + break; + case ACPI_STATE_S1: + case ACPI_STATE_S2: + case ACPI_STATE_S3: + sdev->system_suspend_target = SOF_SUSPEND_S3; + break; + default: + break; + } #endif return 0; From 9d2d462713384538477703e68577b05131c7d97d Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 15:18:17 -0500 Subject: [PATCH 044/246] ASoC: SOF: pm: add definitions for S4 and S5 states MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We currently don't have a means to differentiate between S3, S4 and S5. Add definitions so that we have select different code paths depending on the target state in follow-up patches. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220616201818.130802-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/pm.c | 9 +++++++++ sound/soc/sof/sof-priv.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 239f39a5166a..df740be645e8 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -23,6 +23,9 @@ static u32 snd_sof_dsp_power_target(struct snd_sof_dev *sdev) u32 target_dsp_state; switch (sdev->system_suspend_target) { + case SOF_SUSPEND_S5: + case SOF_SUSPEND_S4: + /* DSP should be in D3 if the system is suspending to S3+ */ case SOF_SUSPEND_S3: /* DSP should be in D3 if the system is suspending to S3 */ target_dsp_state = SOF_DSP_PM_D3; @@ -344,6 +347,12 @@ int snd_sof_prepare(struct device *dev) case ACPI_STATE_S3: sdev->system_suspend_target = SOF_SUSPEND_S3; break; + case ACPI_STATE_S4: + sdev->system_suspend_target = SOF_SUSPEND_S4; + break; + case ACPI_STATE_S5: + sdev->system_suspend_target = SOF_SUSPEND_S5; + break; default: break; } diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 9d7f53ff9c70..f0f3d72c0da7 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -85,6 +85,8 @@ enum sof_system_suspend_state { SOF_SUSPEND_NONE = 0, SOF_SUSPEND_S0IX, SOF_SUSPEND_S3, + SOF_SUSPEND_S4, + SOF_SUSPEND_S5, }; enum sof_dfsentry_type { From 391153522d186f19a008d824bb3a05950351ce6c Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Thu, 16 Jun 2022 15:18:18 -0500 Subject: [PATCH 045/246] ASoC: SOF: Intel: disable IMR boot when resuming from ACPI S4 and S5 states MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IMR was assumed to be preserved when suspending to S4 and S5 states, but community reports invalidate that assumption, the hardware seems to be powered off and the IMR memory content cleared. Make sure regular boot with firmware download is used for S4 and S5. BugLink: https://github.com/thesofproject/sof/issues/5892 Fixes: 5fb5f51185126 ("ASoC: SOF: Intel: hda-loader: add IMR restore support") Signed-off-by: Pierre-Louis Bossart Reviewed-by: Ranjani Sridharan Reviewed-by: Péter Ujfalusi Link: https://lore.kernel.org/r/20220616201818.130802-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/intel/hda-loader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c index d3ec5996a9a3..145d483bd129 100644 --- a/sound/soc/sof/intel/hda-loader.c +++ b/sound/soc/sof/intel/hda-loader.c @@ -389,7 +389,8 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) struct snd_dma_buffer dmab; int ret, ret1, i; - if (hda->imrboot_supported && !sdev->first_boot) { + if (sdev->system_suspend_target < SOF_SUSPEND_S4 && + hda->imrboot_supported && !sdev->first_boot) { dev_dbg(sdev->dev, "IMR restore supported, booting from IMR directly\n"); hda->boot_iteration = 0; ret = hda_dsp_boot_imr(sdev); From a5450aba737dae3ee1a64b282e609d8375d6700c Mon Sep 17 00:00:00 2001 From: Judy Hsiao Date: Wed, 15 Jun 2022 04:56:43 +0000 Subject: [PATCH 046/246] ASoC: rockchip: i2s: switch BCLK to GPIO We discoverd that the state of BCLK on, LRCLK off and SD_MODE on may cause the speaker melting issue. Removing LRCLK while BCLK is present can cause unexpected output behavior including a large DC output voltage as described in the Max98357a datasheet. In order to: 1. prevent BCLK from turning on by other component. 2. keep BCLK and LRCLK being present at the same time This patch switches BCLK to GPIO func before LRCLK output, and configures BCLK func back during LRCLK is output. Without this fix, BCLK is turned on 11 ms earlier than LRCK by the da7219. With this fix, BCLK is turned on only 0.4 ms earlier than LRCK by the rockchip codec. Signed-off-by: Judy Hsiao Link: https://lore.kernel.org/r/20220615045643.3137287-1-judyhsiao@chromium.org Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 160 ++++++++++++++++++++++++------ 1 file changed, 129 insertions(+), 31 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 4ce5d2579387..99a128a666fb 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -54,8 +55,40 @@ struct rk_i2s_dev { const struct rk_i2s_pins *pins; unsigned int bclk_ratio; spinlock_t lock; /* tx/rx lock */ + struct pinctrl *pinctrl; + struct pinctrl_state *bclk_on; + struct pinctrl_state *bclk_off; }; +static int i2s_pinctrl_select_bclk_on(struct rk_i2s_dev *i2s) +{ + int ret = 0; + + if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_on)) + ret = pinctrl_select_state(i2s->pinctrl, + i2s->bclk_on); + + if (ret) + dev_err(i2s->dev, "bclk enable failed %d\n", ret); + + return ret; +} + +static int i2s_pinctrl_select_bclk_off(struct rk_i2s_dev *i2s) +{ + + int ret = 0; + + if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_off)) + ret = pinctrl_select_state(i2s->pinctrl, + i2s->bclk_off); + + if (ret) + dev_err(i2s->dev, "bclk disable failed %d\n", ret); + + return ret; +} + static int i2s_runtime_suspend(struct device *dev) { struct rk_i2s_dev *i2s = dev_get_drvdata(dev); @@ -92,38 +125,49 @@ static inline struct rk_i2s_dev *to_info(struct snd_soc_dai *dai) return snd_soc_dai_get_drvdata(dai); } -static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) +static int rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) { unsigned int val = 0; int retry = 10; + int ret = 0; spin_lock(&i2s->lock); if (on) { - regmap_update_bits(i2s->regmap, I2S_DMACR, - I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, + I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE); + if (ret < 0) + goto end; - regmap_update_bits(i2s->regmap, I2S_XFER, - I2S_XFER_TXS_START | I2S_XFER_RXS_START, - I2S_XFER_TXS_START | I2S_XFER_RXS_START); + ret = regmap_update_bits(i2s->regmap, I2S_XFER, + I2S_XFER_TXS_START | I2S_XFER_RXS_START, + I2S_XFER_TXS_START | I2S_XFER_RXS_START); + if (ret < 0) + goto end; i2s->tx_start = true; } else { i2s->tx_start = false; - regmap_update_bits(i2s->regmap, I2S_DMACR, - I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, + I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE); + if (ret < 0) + goto end; if (!i2s->rx_start) { - regmap_update_bits(i2s->regmap, I2S_XFER, - I2S_XFER_TXS_START | - I2S_XFER_RXS_START, - I2S_XFER_TXS_STOP | - I2S_XFER_RXS_STOP); + ret = regmap_update_bits(i2s->regmap, I2S_XFER, + I2S_XFER_TXS_START | + I2S_XFER_RXS_START, + I2S_XFER_TXS_STOP | + I2S_XFER_RXS_STOP); + if (ret < 0) + goto end; udelay(150); - regmap_update_bits(i2s->regmap, I2S_CLR, - I2S_CLR_TXC | I2S_CLR_RXC, - I2S_CLR_TXC | I2S_CLR_RXC); + ret = regmap_update_bits(i2s->regmap, I2S_CLR, + I2S_CLR_TXC | I2S_CLR_RXC, + I2S_CLR_TXC | I2S_CLR_RXC); + if (ret < 0) + goto end; regmap_read(i2s->regmap, I2S_CLR, &val); @@ -138,44 +182,57 @@ static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on) } } } +end: spin_unlock(&i2s->lock); + if (ret < 0) + dev_err(i2s->dev, "lrclk update failed\n"); + + return ret; } -static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) +static int rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) { unsigned int val = 0; int retry = 10; + int ret = 0; spin_lock(&i2s->lock); if (on) { - regmap_update_bits(i2s->regmap, I2S_DMACR, + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE); + if (ret < 0) + goto end; - regmap_update_bits(i2s->regmap, I2S_XFER, + ret = regmap_update_bits(i2s->regmap, I2S_XFER, I2S_XFER_TXS_START | I2S_XFER_RXS_START, I2S_XFER_TXS_START | I2S_XFER_RXS_START); + if (ret < 0) + goto end; i2s->rx_start = true; } else { i2s->rx_start = false; - regmap_update_bits(i2s->regmap, I2S_DMACR, + ret = regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE); + if (ret < 0) + goto end; if (!i2s->tx_start) { - regmap_update_bits(i2s->regmap, I2S_XFER, + ret = regmap_update_bits(i2s->regmap, I2S_XFER, I2S_XFER_TXS_START | I2S_XFER_RXS_START, I2S_XFER_TXS_STOP | I2S_XFER_RXS_STOP); - + if (ret < 0) + goto end; udelay(150); - regmap_update_bits(i2s->regmap, I2S_CLR, + ret = regmap_update_bits(i2s->regmap, I2S_CLR, I2S_CLR_TXC | I2S_CLR_RXC, I2S_CLR_TXC | I2S_CLR_RXC); - + if (ret < 0) + goto end; regmap_read(i2s->regmap, I2S_CLR, &val); - /* Should wait for clear operation to finish */ while (val) { regmap_read(i2s->regmap, I2S_CLR, &val); @@ -187,7 +244,12 @@ static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on) } } } +end: spin_unlock(&i2s->lock); + if (ret < 0) + dev_err(i2s->dev, "lrclk update failed\n"); + + return ret; } static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, @@ -425,17 +487,26 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - rockchip_snd_rxctrl(i2s, 1); + ret = rockchip_snd_rxctrl(i2s, 1); else - rockchip_snd_txctrl(i2s, 1); + ret = rockchip_snd_txctrl(i2s, 1); + /* Do not turn on bclk if lrclk open fails. */ + if (ret < 0) + return ret; + i2s_pinctrl_select_bclk_on(i2s); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - rockchip_snd_rxctrl(i2s, 0); - else - rockchip_snd_txctrl(i2s, 0); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (!i2s->tx_start) + i2s_pinctrl_select_bclk_off(i2s); + ret = rockchip_snd_rxctrl(i2s, 0); + } else { + if (!i2s->rx_start) + i2s_pinctrl_select_bclk_off(i2s); + ret = rockchip_snd_txctrl(i2s, 0); + } break; default: ret = -EINVAL; @@ -736,6 +807,33 @@ static int rockchip_i2s_probe(struct platform_device *pdev) } i2s->bclk_ratio = 64; + i2s->pinctrl = devm_pinctrl_get(&pdev->dev); + if (IS_ERR(i2s->pinctrl)) + dev_err(&pdev->dev, "failed to find i2s pinctrl\n"); + + i2s->bclk_on = pinctrl_lookup_state(i2s->pinctrl, + "bclk_on"); + if (IS_ERR_OR_NULL(i2s->bclk_on)) + dev_err(&pdev->dev, "failed to find i2s default state\n"); + else + dev_dbg(&pdev->dev, "find i2s bclk state\n"); + + i2s->bclk_off = pinctrl_lookup_state(i2s->pinctrl, + "bclk_off"); + if (IS_ERR_OR_NULL(i2s->bclk_off)) + dev_err(&pdev->dev, "failed to find i2s gpio state\n"); + else + dev_dbg(&pdev->dev, "find i2s bclk_off state\n"); + + i2s_pinctrl_select_bclk_off(i2s); + + i2s->playback_dma_data.addr = res->start + I2S_TXDR; + i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + i2s->playback_dma_data.maxburst = 4; + + i2s->capture_dma_data.addr = res->start + I2S_RXDR; + i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + i2s->capture_dma_data.maxburst = 4; dev_set_drvdata(&pdev->dev, i2s); From f2c2f31f00ce48d96dec28b9f8d70f73213ed4af Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Fri, 17 Jun 2022 14:02:30 -0700 Subject: [PATCH 047/246] MAINTAINERS: update ASoC Qualcomm maintainer email-id Update Banajit's email address from codeaurora.org to quicinc.com, as codeaurora.org is not in use anymore. Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20220617210230.7685-1-srinivas.kandagatla@linaro.org Signed-off-by: Mark Brown --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 440f3d7c93b9..171fa3160696 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16247,7 +16247,7 @@ F: drivers/crypto/qat/ QCOM AUDIO (ASoC) DRIVERS M: Srinivas Kandagatla -M: Banajit Goswami +M: Banajit Goswami L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Supported F: sound/soc/codecs/lpass-va-macro.c From 9896c029f0df628c6cb108253d09b1d61f1d4a88 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 21 Jun 2022 11:20:38 +0100 Subject: [PATCH 048/246] ASoC: wm_adsp: Fix event for preloader The preloader controls on ADSP should return a value of 1 if the preloader value was changed, update to correct this. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220621102041.1713504-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm_adsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 6d7fd88243aa..a7784ac15dde 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -997,7 +997,7 @@ int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, snd_soc_dapm_sync(dapm); } - return 0; + return 1; } EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); From 0bc0ae9a5938d512fd5d44f11c9c04892dcf4961 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 21 Jun 2022 11:20:39 +0100 Subject: [PATCH 049/246] ASoC: wm5110: Fix DRE control The DRE controls on wm5110 should return a value of 1 if the DRE state is actually changed, update to fix this. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220621102041.1713504-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 4973ba1ed779..4ab7a672f8de 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -413,6 +413,7 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol, unsigned int rnew = (!!ucontrol->value.integer.value[1]) << mc->rshift; unsigned int lold, rold; unsigned int lena, rena; + bool change = false; int ret; snd_soc_dapm_mutex_lock(dapm); @@ -440,8 +441,8 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol, goto err; } - ret = regmap_update_bits(arizona->regmap, ARIZONA_DRE_ENABLE, - mask, lnew | rnew); + ret = regmap_update_bits_check(arizona->regmap, ARIZONA_DRE_ENABLE, + mask, lnew | rnew, &change); if (ret) { dev_err(arizona->dev, "Failed to set DRE: %d\n", ret); goto err; @@ -454,6 +455,9 @@ static int wm5110_put_dre(struct snd_kcontrol *kcontrol, if (!rnew && rold) wm5110_clear_pga_volume(arizona, mc->rshift); + if (change) + ret = 1; + err: snd_soc_dapm_mutex_unlock(dapm); From c6a5f22f9b4fd5f21414be690ce34046d9712f05 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Tue, 21 Jun 2022 11:20:40 +0100 Subject: [PATCH 050/246] ASoC: cs35l41: Correct some control names Various boolean controls on cs35l41 are missing the required "Switch" in the name, add these. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220621102041.1713504-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l41.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 3e68a07a3c8e..71ab2a5d1c55 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -333,7 +333,7 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = { SOC_SINGLE("HW Noise Gate Enable", CS35L41_NG_CFG, 8, 63, 0), SOC_SINGLE("HW Noise Gate Delay", CS35L41_NG_CFG, 4, 7, 0), SOC_SINGLE("HW Noise Gate Threshold", CS35L41_NG_CFG, 0, 7, 0), - SOC_SINGLE("Aux Noise Gate CH1 Enable", + SOC_SINGLE("Aux Noise Gate CH1 Switch", CS35L41_MIXER_NGATE_CH1_CFG, 16, 1, 0), SOC_SINGLE("Aux Noise Gate CH1 Entry Delay", CS35L41_MIXER_NGATE_CH1_CFG, 8, 15, 0), @@ -341,15 +341,15 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = { CS35L41_MIXER_NGATE_CH1_CFG, 0, 7, 0), SOC_SINGLE("Aux Noise Gate CH2 Entry Delay", CS35L41_MIXER_NGATE_CH2_CFG, 8, 15, 0), - SOC_SINGLE("Aux Noise Gate CH2 Enable", + SOC_SINGLE("Aux Noise Gate CH2 Switch", CS35L41_MIXER_NGATE_CH2_CFG, 16, 1, 0), SOC_SINGLE("Aux Noise Gate CH2 Threshold", CS35L41_MIXER_NGATE_CH2_CFG, 0, 7, 0), - SOC_SINGLE("SCLK Force", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0), - SOC_SINGLE("LRCLK Force", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0), - SOC_SINGLE("Invert Class D", CS35L41_AMP_DIG_VOL_CTRL, + SOC_SINGLE("SCLK Force Switch", CS35L41_SP_FORMAT, CS35L41_SCLK_FRC_SHIFT, 1, 0), + SOC_SINGLE("LRCLK Force Switch", CS35L41_SP_FORMAT, CS35L41_LRCLK_FRC_SHIFT, 1, 0), + SOC_SINGLE("Invert Class D Switch", CS35L41_AMP_DIG_VOL_CTRL, CS35L41_AMP_INV_PCM_SHIFT, 1, 0), - SOC_SINGLE("Amp Gain ZC", CS35L41_AMP_GAIN_CTRL, + SOC_SINGLE("Amp Gain ZC Switch", CS35L41_AMP_GAIN_CTRL, CS35L41_AMP_GAIN_ZC_SHIFT, 1, 0), WM_ADSP2_PRELOAD_SWITCH("DSP1", 1), WM_ADSP_FW_CONTROL("DSP1", 0), From 1df793d479bef546569fc2e409ff8bb3f0fb8e99 Mon Sep 17 00:00:00 2001 From: Shuming Fan Date: Tue, 21 Jun 2022 17:07:19 +0800 Subject: [PATCH 051/246] ASoC: rt711-sdca: fix kernel NULL pointer dereference when IO error The initial settings will be written before the codec probe function. But, the rt711->component doesn't be assigned yet. If IO error happened during initial settings operations, it will cause the kernel panic. This patch changed component->dev to slave->dev to fix this issue. Signed-off-by: Shuming Fan Link: https://lore.kernel.org/r/20220621090719.30558-1-shumingf@realtek.com Signed-off-by: Mark Brown --- sound/soc/codecs/rt711-sdca.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index dfe3c9299ebd..5ad53bbc8528 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -34,7 +34,7 @@ static int rt711_sdca_index_write(struct rt711_sdca_priv *rt711, ret = regmap_write(regmap, addr, value); if (ret < 0) - dev_err(rt711->component->dev, + dev_err(&rt711->slave->dev, "Failed to set private value: %06x <= %04x ret=%d\n", addr, value, ret); @@ -50,7 +50,7 @@ static int rt711_sdca_index_read(struct rt711_sdca_priv *rt711, ret = regmap_read(regmap, addr, value); if (ret < 0) - dev_err(rt711->component->dev, + dev_err(&rt711->slave->dev, "Failed to get private value: %06x => %04x ret=%d\n", addr, *value, ret); From 11d7a12f7f50baa5af9090b131c9b03af59503e7 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 11:51:15 +0100 Subject: [PATCH 052/246] ASoC: dapm: Initialise kcontrol data for mux/demux controls DAPM keeps a copy of the current value of mux/demux controls, however this value is only initialised in the case of autodisable controls. This leads to false notification events when first modifying a DAPM kcontrol that has a non-zero default. Autodisable controls are left as they are, since they already initialise the value, and there would be more work required to support autodisable muxes where the first option isn't disabled and/or that isn't the default. Technically this issue could affect mixer/switch elements as well, although not on any of the devices I am currently running. There is also a little more work to do to address the issue there due to that side supporting stereo controls, so that has not been tackled in this patch. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623105120.1981154-1-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 869c76506b66..a8e842e02cdc 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -62,6 +62,8 @@ struct snd_soc_dapm_widget * snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget); +static unsigned int soc_dapm_read(struct snd_soc_dapm_context *dapm, int reg); + /* dapm power sequences - make this per codec in the future */ static int dapm_up_seq[] = { [snd_soc_dapm_pre] = 1, @@ -442,6 +444,9 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, snd_soc_dapm_add_path(widget->dapm, data->widget, widget, NULL, NULL); + } else if (e->reg != SND_SOC_NOPM) { + data->value = soc_dapm_read(widget->dapm, e->reg) & + (e->mask << e->shift_l); } break; default: From 46b0d050c8c7df6dfb2c376aaa149bf2cfc5ca3e Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 11:51:16 +0100 Subject: [PATCH 053/246] ASoC: cs35l41: Add ASP TX3/4 source to register patch The mixer controls for ASP TX3/4 are set to values that are not included in their enumeration control. This will cause spurious event notifications when the controls are first changed, as the register value changes whilst the actual visible enumeration value does not. Use the register patch to set them to a known value, zero, which equates to zero fill, thereby avoiding the spurious notifications. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623105120.1981154-2-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs35l41-lib.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index 6d3070ea9e06..198cfe54a46f 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -37,8 +37,8 @@ static const struct reg_default cs35l41_reg[] = { { CS35L41_DAC_PCM1_SRC, 0x00000008 }, { CS35L41_ASP_TX1_SRC, 0x00000018 }, { CS35L41_ASP_TX2_SRC, 0x00000019 }, - { CS35L41_ASP_TX3_SRC, 0x00000020 }, - { CS35L41_ASP_TX4_SRC, 0x00000021 }, + { CS35L41_ASP_TX3_SRC, 0x00000000 }, + { CS35L41_ASP_TX4_SRC, 0x00000000 }, { CS35L41_DSP1_RX1_SRC, 0x00000008 }, { CS35L41_DSP1_RX2_SRC, 0x00000009 }, { CS35L41_DSP1_RX3_SRC, 0x00000018 }, @@ -644,6 +644,8 @@ static const struct reg_sequence cs35l41_reva0_errata_patch[] = { { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, { CS35L41_PWR_CTRL2, 0x00000000 }, { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, + { CS35L41_ASP_TX3_SRC, 0x00000000 }, + { CS35L41_ASP_TX4_SRC, 0x00000000 }, }; static const struct reg_sequence cs35l41_revb0_errata_patch[] = { @@ -655,6 +657,8 @@ static const struct reg_sequence cs35l41_revb0_errata_patch[] = { { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, { CS35L41_PWR_CTRL2, 0x00000000 }, { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, + { CS35L41_ASP_TX3_SRC, 0x00000000 }, + { CS35L41_ASP_TX4_SRC, 0x00000000 }, }; static const struct reg_sequence cs35l41_revb2_errata_patch[] = { @@ -666,6 +670,8 @@ static const struct reg_sequence cs35l41_revb2_errata_patch[] = { { CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000 }, { CS35L41_PWR_CTRL2, 0x00000000 }, { CS35L41_AMP_GAIN_CTRL, 0x00000000 }, + { CS35L41_ASP_TX3_SRC, 0x00000000 }, + { CS35L41_ASP_TX4_SRC, 0x00000000 }, }; static const struct reg_sequence cs35l41_fs_errata_patch[] = { From 7f103af4a10f375b9b346b4d0b730f6a66b8c451 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 11:51:17 +0100 Subject: [PATCH 054/246] ASoC: cs47l15: Fix event generation for low power mux control cs47l15_in1_adc_put always returns zero regardless of if the control value was updated. This results in missing notifications to user-space of the control change. Update the handling to return 1 when the value is changed. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623105120.1981154-3-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/cs47l15.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs47l15.c b/sound/soc/codecs/cs47l15.c index 391fd7da331f..1c7d52bef893 100644 --- a/sound/soc/codecs/cs47l15.c +++ b/sound/soc/codecs/cs47l15.c @@ -122,6 +122,9 @@ static int cs47l15_in1_adc_put(struct snd_kcontrol *kcontrol, snd_soc_kcontrol_component(kcontrol); struct cs47l15 *cs47l15 = snd_soc_component_get_drvdata(component); + if (!!ucontrol->value.integer.value[0] == cs47l15->in1_lp_mode) + return 0; + switch (ucontrol->value.integer.value[0]) { case 0: /* Set IN1 to normal mode */ @@ -150,7 +153,7 @@ static int cs47l15_in1_adc_put(struct snd_kcontrol *kcontrol, break; } - return 0; + return 1; } static const struct snd_kcontrol_new cs47l15_snd_controls[] = { From e3cabbef3db8269207a6b8808f510137669f8deb Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 11:51:18 +0100 Subject: [PATCH 055/246] ASoC: madera: Fix event generation for OUT1 demux madera_out1_demux_put returns the value of snd_soc_dapm_mux_update_power, which returns a 1 if a path was found for the kcontrol. This is obviously different to the expected return a 1 if the control was updated value. This results in spurious notifications to user-space. Update the handling to only return a 1 when the value is changed. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623105120.1981154-4-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/madera.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/madera.c b/sound/soc/codecs/madera.c index 272041c6236a..8095a87117cf 100644 --- a/sound/soc/codecs/madera.c +++ b/sound/soc/codecs/madera.c @@ -618,7 +618,13 @@ int madera_out1_demux_put(struct snd_kcontrol *kcontrol, end: snd_soc_dapm_mutex_unlock(dapm); - return snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); + ret = snd_soc_dapm_mux_update_power(dapm, kcontrol, mux, e, NULL); + if (ret < 0) { + dev_err(madera->dev, "Failed to update demux power state: %d\n", ret); + return ret; + } + + return change; } EXPORT_SYMBOL_GPL(madera_out1_demux_put); From 980555e95f7cabdc9c80a07107622b097ba23703 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Thu, 23 Jun 2022 11:51:19 +0100 Subject: [PATCH 056/246] ASoC: madera: Fix event generation for rate controls madera_adsp_rate_put always returns zero regardless of if the control value was updated. This results in missing notifications to user-space of the control change. Update the handling to return 1 when the value is changed. Signed-off-by: Charles Keepax Link: https://lore.kernel.org/r/20220623105120.1981154-5-ckeepax@opensource.cirrus.com Signed-off-by: Mark Brown --- sound/soc/codecs/madera.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/madera.c b/sound/soc/codecs/madera.c index 8095a87117cf..b9f19fbd2911 100644 --- a/sound/soc/codecs/madera.c +++ b/sound/soc/codecs/madera.c @@ -899,7 +899,7 @@ static int madera_adsp_rate_put(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; const int adsp_num = e->shift_l; const unsigned int item = ucontrol->value.enumerated.item[0]; - int ret; + int ret = 0; if (item >= e->items) return -EINVAL; @@ -916,10 +916,10 @@ static int madera_adsp_rate_put(struct snd_kcontrol *kcontrol, "Cannot change '%s' while in use by active audio paths\n", kcontrol->id.name); ret = -EBUSY; - } else { + } else if (priv->adsp_rate_cache[adsp_num] != e->values[item]) { /* Volatile register so defer until the codec is powered up */ priv->adsp_rate_cache[adsp_num] = e->values[item]; - ret = 0; + ret = 1; } mutex_unlock(&priv->rate_lock); From de9b3d9616078f1d1d0d51b01cdafa101733f935 Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Fri, 11 Mar 2022 00:19:34 +0200 Subject: [PATCH 057/246] arm64: dts: qcom: sm8450: fix interconnects property of UFS node All interconnect device tree nodes on sm8450 are 2-cells, however in UFS node they are handled as 1-cells, fix it. Fixes: aa2d0bf04a3c ("arm64: dts: qcom: sm8450: add interconnect nodes") Signed-off-by: Vladimir Zapolskiy Reviewed-by: Dmitry Baryshkov Reviewed-by: Vinod Koul Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220310221934.1560729-1-vladimir.zapolskiy@linaro.org --- arch/arm64/boot/dts/qcom/sm8450.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi index 7d08fad76371..b2accf996094 100644 --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -3037,8 +3037,8 @@ iommus = <&apps_smmu 0xe0 0x0>; - interconnects = <&aggre1_noc MASTER_UFS_MEM &mc_virt SLAVE_EBI1>, - <&gem_noc MASTER_APPSS_PROC &config_noc SLAVE_UFS_MEM_CFG>; + interconnects = <&aggre1_noc MASTER_UFS_MEM 0 &mc_virt SLAVE_EBI1 0>, + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_UFS_MEM_CFG 0>; interconnect-names = "ufs-ddr", "cpu-ufs"; clock-names = "core_clk", From ef9102004a87cb3f8b26e000a095a261fc0467d3 Mon Sep 17 00:00:00 2001 From: Chris Ye Date: Tue, 31 May 2022 17:09:54 -0700 Subject: [PATCH 058/246] nvdimm: Fix badblocks clear off-by-one error nvdimm_clear_badblocks_region() validates badblock clearing requests against the span of the region, however it compares the inclusive badblock request range to the exclusive region range. Fix up the off-by-one error. Fixes: 23f498448362 ("libnvdimm: rework region badblocks clearing") Cc: Signed-off-by: Chris Ye Reviewed-by: Vishal Verma Link: https://lore.kernel.org/r/165404219489.2445897.9792886413715690399.stgit@dwillia2-xfh Signed-off-by: Dan Williams --- drivers/nvdimm/bus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index a4fc17db707c..b38d0355b0ac 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -176,8 +176,8 @@ static int nvdimm_clear_badblocks_region(struct device *dev, void *data) ndr_end = nd_region->ndr_start + nd_region->ndr_size - 1; /* make sure we are in the region */ - if (ctx->phys < nd_region->ndr_start - || (ctx->phys + ctx->cleared) > ndr_end) + if (ctx->phys < nd_region->ndr_start || + (ctx->phys + ctx->cleared - 1) > ndr_end) return 0; sector = (ctx->phys - nd_region->ndr_start) / 512; From 179a93f74b29d0f37871d7afe826292cda90f113 Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Fri, 24 Jun 2022 07:31:35 +0900 Subject: [PATCH 059/246] fprobe, samples: Add module parameter descriptions Add module parameter descriptions for the fprobe_example module. Signed-off-by: Masami Hiramatsu (Google) Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/165602349520.56016.1314423560740428008.stgit@devnote2 --- samples/fprobe/fprobe_example.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/samples/fprobe/fprobe_example.c b/samples/fprobe/fprobe_example.c index 01ee6c8c8382..18b1e5c4b431 100644 --- a/samples/fprobe/fprobe_example.c +++ b/samples/fprobe/fprobe_example.c @@ -25,12 +25,19 @@ static unsigned long nhit; static char symbol[MAX_SYMBOL_LEN] = "kernel_clone"; module_param_string(symbol, symbol, sizeof(symbol), 0644); +MODULE_PARM_DESC(symbol, "Probed symbol(s), given by comma separated symbols or a wildcard pattern."); + static char nosymbol[MAX_SYMBOL_LEN] = ""; module_param_string(nosymbol, nosymbol, sizeof(nosymbol), 0644); +MODULE_PARM_DESC(nosymbol, "Not-probed symbols, given by a wildcard pattern."); + static bool stackdump = true; module_param(stackdump, bool, 0644); +MODULE_PARM_DESC(stackdump, "Enable stackdump."); + static bool use_trace = false; module_param(use_trace, bool, 0644); +MODULE_PARM_DESC(use_trace, "Use trace_printk instead of printk. This is only for debugging."); static void show_backtrace(void) { From fbb564a557809466c171b95f8d593a0972450ff2 Mon Sep 17 00:00:00 2001 From: wuchi Date: Sun, 5 Jun 2022 22:58:35 +0800 Subject: [PATCH 060/246] lib/sbitmap: Fix invalid loop in __sbitmap_queue_get_batch() 1. Getting next index before continue branch. 2. Checking free bits when setting the target bits. Otherwise, it may reuse the busying bits. Signed-off-by: wuchi Reviewed-by: Martin Wilck Link: https://lore.kernel.org/r/20220605145835.26916-1-wuchi.zero@gmail.com Fixes: 9672b0d43782 ("sbitmap: add __sbitmap_queue_get_batch()") Signed-off-by: Jens Axboe --- lib/sbitmap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/sbitmap.c b/lib/sbitmap.c index ae4fd4de9ebe..29eb0484215a 100644 --- a/lib/sbitmap.c +++ b/lib/sbitmap.c @@ -528,7 +528,7 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags, sbitmap_deferred_clear(map); if (map->word == (1UL << (map_depth - 1)) - 1) - continue; + goto next; nr = find_first_zero_bit(&map->word, map_depth); if (nr + nr_tags <= map_depth) { @@ -539,6 +539,8 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags, get_mask = ((1UL << map_tags) - 1) << nr; do { val = READ_ONCE(map->word); + if ((val & ~get_mask) != val) + goto next; ret = atomic_long_cmpxchg(ptr, val, get_mask | val); } while (ret != val); get_mask = (get_mask & ~ret) >> nr; @@ -549,6 +551,7 @@ unsigned long __sbitmap_queue_get_batch(struct sbitmap_queue *sbq, int nr_tags, return get_mask; } } +next: /* Jump to next index. */ if (++index >= sb->map_nr) index = 0; From 47bf59c4755930f616dd90c8c6a85f40a6d347ea Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Sun, 1 May 2022 20:40:16 +0200 Subject: [PATCH 061/246] arm64: dts: qcom: msm8994: Fix CPU6/7 reg values CPU6 and CPU7 were mistakengly pointing to CPU5 reg. Fix it. Fixes: 02d8091bbca0 ("arm64: dts: qcom: msm8994: Add a proper CPU map") Signed-off-by: Konrad Dybcio Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220501184016.64138-1-konrad.dybcio@somainline.org --- arch/arm64/boot/dts/qcom/msm8994.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8994.dtsi b/arch/arm64/boot/dts/qcom/msm8994.dtsi index 0318d42c5736..1ac2913b182c 100644 --- a/arch/arm64/boot/dts/qcom/msm8994.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8994.dtsi @@ -100,7 +100,7 @@ CPU6: cpu@102 { device_type = "cpu"; compatible = "arm,cortex-a57"; - reg = <0x0 0x101>; + reg = <0x0 0x102>; enable-method = "psci"; next-level-cache = <&L2_1>; }; @@ -108,7 +108,7 @@ CPU7: cpu@103 { device_type = "cpu"; compatible = "arm,cortex-a57"; - reg = <0x0 0x101>; + reg = <0x0 0x103>; enable-method = "psci"; next-level-cache = <&L2_1>; }; From fc8b0b9b630df6de7415f527fe27c0c441b5dc70 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 2 May 2022 22:26:04 +0300 Subject: [PATCH 062/246] arm64: dts: qcom: sm8450 add ITS device tree node Add device tree node corresponding to the ITS part of GICv3. Reviewed-by: Vinod Koul Signed-off-by: Dmitry Baryshkov Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220502192604.272686-1-dmitry.baryshkov@linaro.org --- arch/arm64/boot/dts/qcom/sm8450.dtsi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi index b2accf996094..b87756bf1ce4 100644 --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi @@ -2853,6 +2853,16 @@ reg = <0x0 0x17100000 0x0 0x10000>, /* GICD */ <0x0 0x17180000 0x0 0x200000>; /* GICR * 8 */ interrupts = ; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gic_its: msi-controller@17140000 { + compatible = "arm,gic-v3-its"; + reg = <0x0 0x17140000 0x0 0x20000>; + msi-controller; + #msi-cells = <1>; + }; }; timer@17420000 { From 3ba500dee327e0261e728edec8a4f2f563d2760c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Tue, 31 May 2022 15:47:35 +0300 Subject: [PATCH 063/246] arm64: dts: qcom: sdm845: use dispcc AHB clock for mdss node It was noticed that on sdm845 after an MDSS suspend/resume cycle the driver can not read HW_REV registers properly (they will return 0 instead). Chaning the "iface" clock from <&gcc GCC_DISP_AHB_CLK> to <&dispcc DISP_CC_MDSS_AHB_CLK> fixes the issue. Fixes: 08c2a076d18f ("arm64: dts: qcom: sdm845: Add dpu to sdm845 dts file") Signed-off-by: Dmitry Baryshkov Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220531124735.1165582-1-dmitry.baryshkov@linaro.org --- arch/arm64/boot/dts/qcom/sdm845.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index 0692ae0e60a4..038538c8c614 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi @@ -4244,7 +4244,7 @@ power-domains = <&dispcc MDSS_GDSC>; - clocks = <&gcc GCC_DISP_AHB_CLK>, + clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, <&dispcc DISP_CC_MDSS_MDP_CLK>; clock-names = "iface", "core"; From d640974d1c4ee510fcc8f05f0ddaaf9d17b47643 Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 23 May 2022 23:03:04 +0200 Subject: [PATCH 064/246] MAINTAINERS: Add myself as a reviewer for Qualcomm ARM/64 support Signed-off-by: Konrad Dybcio Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220523210304.19125-1-konrad.dybcio@somainline.org --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index a6d3bd9d2a8d..524c1c434ed8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2537,6 +2537,7 @@ W: http://www.armlinux.org.uk/ ARM/QUALCOMM SUPPORT M: Andy Gross M: Bjorn Andersson +R: Konrad Dybcio L: linux-arm-msm@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git From ca76a761ea2497a250988fd67f12fd93524e611e Mon Sep 17 00:00:00 2001 From: Kaixu Xia Date: Sun, 19 Jun 2022 14:53:42 -0700 Subject: [PATCH 065/246] xfs: factor out the common lock flags assert There are similar lock flags assert in xfs_ilock(), xfs_ilock_nowait(), xfs_iunlock(), thus we can factor it out into a helper that is clear. Signed-off-by: Kaixu Xia Reviewed-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_inode.c | 60 ++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 52d6f2c7d58b..8b8bac7eba8c 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -131,6 +131,26 @@ xfs_ilock_attr_map_shared( return lock_mode; } +/* + * You can't set both SHARED and EXCL for the same lock, + * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_MMAPLOCK_SHARED, + * XFS_MMAPLOCK_EXCL, XFS_ILOCK_SHARED, XFS_ILOCK_EXCL are valid values + * to set in lock_flags. + */ +static inline void +xfs_lock_flags_assert( + uint lock_flags) +{ + ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) != + (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)); + ASSERT((lock_flags & (XFS_MMAPLOCK_SHARED | XFS_MMAPLOCK_EXCL)) != + (XFS_MMAPLOCK_SHARED | XFS_MMAPLOCK_EXCL)); + ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) != + (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); + ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_SUBCLASS_MASK)) == 0); + ASSERT(lock_flags != 0); +} + /* * In addition to i_rwsem in the VFS inode, the xfs inode contains 2 * multi-reader locks: invalidate_lock and the i_lock. This routine allows @@ -168,18 +188,7 @@ xfs_ilock( { trace_xfs_ilock(ip, lock_flags, _RET_IP_); - /* - * You can't set both SHARED and EXCL for the same lock, - * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED, - * and XFS_ILOCK_EXCL are valid values to set in lock_flags. - */ - ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) != - (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)); - ASSERT((lock_flags & (XFS_MMAPLOCK_SHARED | XFS_MMAPLOCK_EXCL)) != - (XFS_MMAPLOCK_SHARED | XFS_MMAPLOCK_EXCL)); - ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) != - (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); - ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_SUBCLASS_MASK)) == 0); + xfs_lock_flags_assert(lock_flags); if (lock_flags & XFS_IOLOCK_EXCL) { down_write_nested(&VFS_I(ip)->i_rwsem, @@ -222,18 +231,7 @@ xfs_ilock_nowait( { trace_xfs_ilock_nowait(ip, lock_flags, _RET_IP_); - /* - * You can't set both SHARED and EXCL for the same lock, - * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED, - * and XFS_ILOCK_EXCL are valid values to set in lock_flags. - */ - ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) != - (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)); - ASSERT((lock_flags & (XFS_MMAPLOCK_SHARED | XFS_MMAPLOCK_EXCL)) != - (XFS_MMAPLOCK_SHARED | XFS_MMAPLOCK_EXCL)); - ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) != - (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); - ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_SUBCLASS_MASK)) == 0); + xfs_lock_flags_assert(lock_flags); if (lock_flags & XFS_IOLOCK_EXCL) { if (!down_write_trylock(&VFS_I(ip)->i_rwsem)) @@ -291,19 +289,7 @@ xfs_iunlock( xfs_inode_t *ip, uint lock_flags) { - /* - * You can't set both SHARED and EXCL for the same lock, - * and only XFS_IOLOCK_SHARED, XFS_IOLOCK_EXCL, XFS_ILOCK_SHARED, - * and XFS_ILOCK_EXCL are valid values to set in lock_flags. - */ - ASSERT((lock_flags & (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)) != - (XFS_IOLOCK_SHARED | XFS_IOLOCK_EXCL)); - ASSERT((lock_flags & (XFS_MMAPLOCK_SHARED | XFS_MMAPLOCK_EXCL)) != - (XFS_MMAPLOCK_SHARED | XFS_MMAPLOCK_EXCL)); - ASSERT((lock_flags & (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)) != - (XFS_ILOCK_SHARED | XFS_ILOCK_EXCL)); - ASSERT((lock_flags & ~(XFS_LOCK_MASK | XFS_LOCK_SUBCLASS_MASK)) == 0); - ASSERT(lock_flags != 0); + xfs_lock_flags_assert(lock_flags); if (lock_flags & XFS_IOLOCK_EXCL) up_write(&VFS_I(ip)->i_rwsem); From 82af88063961da9425924d9aec3fb67a4ebade3e Mon Sep 17 00:00:00 2001 From: Kaixu Xia Date: Sun, 19 Jun 2022 14:53:43 -0700 Subject: [PATCH 066/246] xfs: use invalidate_lock to check the state of mmap_lock We should use invalidate_lock and XFS_MMAPLOCK_SHARED to check the state of mmap_lock rw_semaphore in xfs_isilocked(), rather than i_rwsem and XFS_IOLOCK_SHARED. Fixes: 2433480a7e1d ("xfs: Convert to use invalidate_lock") Signed-off-by: Kaixu Xia Reviewed-by: Dave Chinner Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 8b8bac7eba8c..3e1c62ffa4f7 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -365,8 +365,8 @@ xfs_isilocked( } if (lock_flags & (XFS_MMAPLOCK_EXCL|XFS_MMAPLOCK_SHARED)) { - return __xfs_rwsem_islocked(&VFS_I(ip)->i_rwsem, - (lock_flags & XFS_IOLOCK_SHARED)); + return __xfs_rwsem_islocked(&VFS_I(ip)->i_mapping->invalidate_lock, + (lock_flags & XFS_MMAPLOCK_SHARED)); } if (lock_flags & (XFS_IOLOCK_EXCL | XFS_IOLOCK_SHARED)) { From b822ea17fd15659b92cb86c48d018c9e43d0fd98 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 22 Jun 2022 16:57:07 -0700 Subject: [PATCH 067/246] xfs: always free xattri_leaf_bp when cancelling a deferred op While running the following fstest with logged xattrs DISabled, I noticed the following: # FSSTRESS_AVOID="-z -f unlink=1 -f rmdir=1 -f creat=2 -f mkdir=2 -f getfattr=3 -f listfattr=3 -f attr_remove=4 -f removefattr=4 -f setfattr=20 -f attr_set=60" ./check generic/475 INFO: task u9:1:40 blocked for more than 61 seconds. Tainted: G O 5.19.0-rc2-djwx #rc2 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. task:u9:1 state:D stack:12872 pid: 40 ppid: 2 flags:0x00004000 Workqueue: xfs-cil/dm-0 xlog_cil_push_work [xfs] Call Trace: __schedule+0x2db/0x1110 schedule+0x58/0xc0 schedule_timeout+0x115/0x160 __down_common+0x126/0x210 down+0x54/0x70 xfs_buf_lock+0x2d/0xe0 [xfs 0532c1cb1d67dd81d15cb79ac6e415c8dec58f73] xfs_buf_item_unpin+0x227/0x3a0 [xfs 0532c1cb1d67dd81d15cb79ac6e415c8dec58f73] xfs_trans_committed_bulk+0x18e/0x320 [xfs 0532c1cb1d67dd81d15cb79ac6e415c8dec58f73] xlog_cil_committed+0x2ea/0x360 [xfs 0532c1cb1d67dd81d15cb79ac6e415c8dec58f73] xlog_cil_push_work+0x60f/0x690 [xfs 0532c1cb1d67dd81d15cb79ac6e415c8dec58f73] process_one_work+0x1df/0x3c0 worker_thread+0x53/0x3b0 kthread+0xea/0x110 ret_from_fork+0x1f/0x30 This appears to be the result of shortform_to_leaf creating a new leaf buffer as part of adding an xattr to a file. The new leaf buffer is held and attached to the xfs_attr_intent structure, but then the filesystem shuts down. Instead of the usual path (which adds the attr to the held leaf buffer which releases the hold), we instead cancel the entire deferred operation. Unfortunately, xfs_attr_cancel_item doesn't release any attached leaf buffers, so we leak the locked buffer. The CIL cannot do anything about that, and hangs. Fix this by teaching it to release leaf buffers, and make XFS a little more careful about not leaving a dangling reference. The prologue of xfs_attri_item_recover is (in this author's opinion) a little hard to figure out, so I'll clean that up in the next patch. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_attr_item.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c index 135d44133477..4f37fb251fe7 100644 --- a/fs/xfs/xfs_attr_item.c +++ b/fs/xfs/xfs_attr_item.c @@ -455,6 +455,8 @@ static inline void xfs_attr_free_item( struct xfs_attr_intent *attr) { + ASSERT(attr->xattri_leaf_bp == NULL); + if (attr->xattri_da_state) xfs_da_state_free(attr->xattri_da_state); xfs_attri_log_nameval_put(attr->xattri_nameval); @@ -509,6 +511,10 @@ xfs_attr_cancel_item( struct xfs_attr_intent *attr; attr = container_of(item, struct xfs_attr_intent, xattri_list); + if (attr->xattri_leaf_bp) { + xfs_buf_relse(attr->xattri_leaf_bp); + attr->xattri_leaf_bp = NULL; + } xfs_attr_free_item(attr); } @@ -670,9 +676,21 @@ xfs_attri_item_recover( error = xfs_defer_ops_capture_and_commit(tp, capture_list); out_unlock: - if (attr->xattri_leaf_bp) + if (attr->xattri_leaf_bp) { xfs_buf_relse(attr->xattri_leaf_bp); + /* + * If there's more work to do to complete the attr intent, the + * defer capture structure will have taken its own reference to + * the attr leaf buffer and will give that to the continuation + * transaction. The attr intent struct drives the continuation + * work, so release our refcount on the attr leaf buffer but + * retain the pointer in the intent structure. + */ + if (ret != -EAGAIN) + attr->xattri_leaf_bp = NULL; + } + xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_irele(ip); out: From f94e08b602d45ec8ea69fb0aa1c85b712a6a4558 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Thu, 23 Jun 2022 09:26:38 -0700 Subject: [PATCH 068/246] xfs: clean up the end of xfs_attri_item_recover The end of this function could use some cleanup -- the EAGAIN conditionals make it harder to figure out what's going on with the disposal of xattri_leaf_bp, and the dual error/ret variables aren't needed. Turn the EAGAIN case into a separate block documenting all the subtleties of recovering in the middle of an xattr update chain, which makes the rest of the prologue much simpler. Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_attr_item.c | 45 ++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c index 4f37fb251fe7..6ee905a09eb2 100644 --- a/fs/xfs/xfs_attr_item.c +++ b/fs/xfs/xfs_attr_item.c @@ -582,7 +582,7 @@ xfs_attri_item_recover( struct xfs_trans_res tres; struct xfs_attri_log_format *attrp; struct xfs_attri_log_nameval *nv = attrip->attri_nameval; - int error, ret = 0; + int error; int total; int local; struct xfs_attrd_log_item *done_item = NULL; @@ -661,13 +661,31 @@ xfs_attri_item_recover( xfs_ilock(ip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, ip, 0); - ret = xfs_xattri_finish_update(attr, done_item); - if (ret == -EAGAIN) { - /* There's more work to do, so add it to this transaction */ + error = xfs_xattri_finish_update(attr, done_item); + if (error == -EAGAIN) { + /* + * There's more work to do, so add the intent item to this + * transaction so that we can continue it later. + */ xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_ATTR, &attr->xattri_list); - } else - error = ret; + error = xfs_defer_ops_capture_and_commit(tp, capture_list); + if (error) + goto out_unlock; + /* + * The defer capture structure took its own reference to the + * attr leaf buffer and will give that to the continuation + * transaction. The attr intent struct drives the continuation + * work, so release our refcount on the attr leaf buffer but + * retain the pointer in the intent structure. + */ + if (attr->xattri_leaf_bp) + xfs_buf_relse(attr->xattri_leaf_bp); + + xfs_iunlock(ip, XFS_ILOCK_EXCL); + xfs_irele(ip); + return 0; + } if (error) { xfs_trans_cancel(tp); goto out_unlock; @@ -678,24 +696,13 @@ xfs_attri_item_recover( out_unlock: if (attr->xattri_leaf_bp) { xfs_buf_relse(attr->xattri_leaf_bp); - - /* - * If there's more work to do to complete the attr intent, the - * defer capture structure will have taken its own reference to - * the attr leaf buffer and will give that to the continuation - * transaction. The attr intent struct drives the continuation - * work, so release our refcount on the attr leaf buffer but - * retain the pointer in the intent structure. - */ - if (ret != -EAGAIN) - attr->xattri_leaf_bp = NULL; + attr->xattri_leaf_bp = NULL; } xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_irele(ip); out: - if (ret != -EAGAIN) - xfs_attr_free_item(attr); + xfs_attr_free_item(attr); return error; } From 3fdd4ef444f99d25f524e68777d210d453757698 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Mon, 20 Jun 2022 11:20:44 +0800 Subject: [PATCH 069/246] arm64: dts: imx8mp: correct clock of pgc_ispdwp The deprecated DIV clk is previously part of the ISP composite clk, but there is still one child clk(IMX8MP_CLK_MEDIA_ISP_ROOT) sourcing from IMX8MP_CLK_MEDIA_ISP( previously IMX8MP_CLK_MEDIA_ISP_DIV) So IMX8MP_CLK_MEDIA_ISP_ROOT should be used, not IMX8MP_CLK_MEDIA_ISP_DIV. Fixes: 9d89189d5227 ("arm64: dts: imx8mp: Add MEDIAMIX power domains") Signed-off-by: Peng Fan Reviewed-by: Laurent Pinchart Tested-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 d9542dfff83f..410d0d5e6f1e 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi @@ -595,7 +595,7 @@ pgc_ispdwp: power-domain@18 { #power-domain-cells = <0>; reg = ; - clocks = <&clk IMX8MP_CLK_MEDIA_ISP_DIV>; + clocks = <&clk IMX8MP_CLK_MEDIA_ISP_ROOT>; }; }; }; From b10ef5f2ddb3a5a22ac0936c8d91a50ac5e55e77 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 21 Jun 2022 13:45:05 -0300 Subject: [PATCH 070/246] ARM: mxs_defconfig: Enable the framebuffer Currently, when booting Linux on a imx28-evk board there is no display activity. Enable CONFIG_FB which is nowadays required for CONFIG_DRM_PANEL_LVDS, CONFIG_DRM_PANEL_SIMPLE, CONFIG_DRM_PANEL_SEIKO_43WVF1G, CONFIG_FB_MODE_HELPERS, CONFIG_BACKLIGHT_PWM, CONFIG_BACKLIGHT_GPIO, CONFIG_FRAMEBUFFER_CONSOLE, CONFIG_LOGO, CONFIG_FONTS, CONFIG_FONT_8x8 and CONFIG_FONT_8x16. Based on commit c54467482ffd ("ARM: imx_v6_v7_defconfig: enable fb"). Fixes: f611b1e7624c ("drm: Avoid circular dependencies for CONFIG_FB") Signed-off-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/configs/mxs_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index ca32446b187f..f53086ddc48b 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig @@ -93,6 +93,7 @@ CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_DRM=y CONFIG_DRM_PANEL_SEIKO_43WVF1G=y CONFIG_DRM_MXSFB=y +CONFIG_FB=y CONFIG_FB_MODE_HELPERS=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_BACKLIGHT_CLASS_DEVICE=y From 01785f1f156511c4f285786b4192245d4f476bf1 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:13:57 +0800 Subject: [PATCH 071/246] arm64: dts: imx8mp-evk: correct mmc pad settings According to RM bit layout, BIT3 and BIT0 are reserved. 8 7 6 5 4 3 2 1 0 PE HYS PUE ODE FSEL X DSE X Not set reserved bit. Fixes: 9e847693c6f3 ("arm64: dts: freescale: Add i.MX8MP EVK board support") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts index 4c3ac4214a2c..f31cf778890d 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -500,7 +500,7 @@ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { fsl,pins = < - MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x41 + MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x40 >; }; @@ -525,7 +525,7 @@ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0 MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0 MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0 - MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0 >; }; @@ -537,7 +537,7 @@ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4 MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4 MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4 - MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0 >; }; @@ -549,7 +549,7 @@ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6 MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6 MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6 - MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0 >; }; From 2d4fb72b681205eed4553d8802632bd3270be3ba Mon Sep 17 00:00:00 2001 From: Sherry Sun Date: Wed, 22 Jun 2022 14:13:58 +0800 Subject: [PATCH 072/246] arm64: dts: imx8mp-evk: correct the uart2 pinctl value According to the IOMUXC_SW_PAD_CTL_PAD_UART2_RXD/TXD register define in imx8mp RM, bit0 and bit3 are reserved, and the uart2 rx/tx pin should enable the pull up, so need to set bit8 to 1. The original pinctl value 0x49 is incorrect and needs to be changed to 0x140, same as uart1 and uart3. Fixes: 9e847693c6f3 ("arm64: dts: freescale: Add i.MX8MP EVK board support") Reviewed-by: Haibo Chen Signed-off-by: Sherry Sun Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes 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 f31cf778890d..4ba31fc5d0a5 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -506,8 +506,8 @@ pinctrl_uart2: uart2grp { fsl,pins = < - MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x49 - MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x49 + MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140 + MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 >; }; From b838582ab8d5fb11b2c0275056a9f34e1d94fece Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:13:59 +0800 Subject: [PATCH 073/246] arm64: dts: imx8mp-evk: correct gpio-led pad settings 0x19 is not a valid setting. According to RM bit layout, BIT3 and BIT0 are reserved. 8 7 6 5 4 3 2 1 0 PE HYS PUE ODE FSEL X DSE X Correct setting with PE PUE set, DSE set to 0. Fixes: 50d336b12f34 ("arm64: dts: imx8mp-evk: Add GPIO LED support") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts index 4ba31fc5d0a5..4ff75c4cbddc 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -461,7 +461,7 @@ pinctrl_gpio_led: gpioledgrp { fsl,pins = < - MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x19 + MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x140 >; }; From e2c00820a99c55c9bb40642d5818a904a1e0d664 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:14:00 +0800 Subject: [PATCH 074/246] arm64: dts: imx8mp-evk: correct vbus pad settings 0x19 is not a valid setting. According to RM bit layout, BIT3 and BIT0 are reserved. 8 7 6 5 4 3 2 1 0 PE HYS PUE ODE FSEL X DSE X Not set reserved bit. Fixes: 43da4f92a611 ("arm64: dts: imx8mp-evk: enable usb1 as host mode") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts index 4ff75c4cbddc..a28ce8af61bd 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -513,7 +513,7 @@ pinctrl_usb1_vbus: usb1grp { fsl,pins = < - MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR 0x19 + MX8MP_IOMUXC_GPIO1_IO14__USB2_OTG_PWR 0x10 >; }; From e6e1bc0ec9e8ad212fa46d8878a6e17cd31fdf7b Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:14:01 +0800 Subject: [PATCH 075/246] arm64: dts: imx8mp-evk: correct eqos pad settings According to RM bit layout, BIT3 and BIT0 are reserved. 8 7 6 5 4 3 2 1 0 PE HYS PUE ODE FSEL X DSE X Although function is not broken, we should not set reserved bit. Fixes: dc6d5dc89bad ("arm64: dts: imx8mp-evk: enable EQOS ethernet") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 30 ++++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts index a28ce8af61bd..454856bd4f56 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -395,21 +395,21 @@ &iomuxc { pinctrl_eqos: eqosgrp { fsl,pins = < - MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3 - MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3 - MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91 - MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91 - MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91 - MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91 - MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91 - MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91 - MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f - MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f - MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f - MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f - MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f - MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f - MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x19 + MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x2 + MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x2 + MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x90 + MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x90 + MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x90 + MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x90 + MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x90 + MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x90 + MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x16 + MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x16 + MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x16 + MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x16 + MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x16 + MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x16 + MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x10 >; }; From 95587ecfcf25e1b9e7810ed91df084d823ee8023 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:14:02 +0800 Subject: [PATCH 076/246] arm64: dts: imx8mp-evk: correct vbus pad settings According to RM bit layout, BIT3 and BIT0 are reserved. 8 7 6 5 4 3 2 1 0 PE HYS PUE ODE FSEL X DSE X Not set reserved bit. Fixes: 9e847693c6f3 ("arm64: dts: freescale: Add i.MX8MP EVK board support") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp-evk.dts | 30 ++++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts index 454856bd4f56..c244a5cd1ac0 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -415,21 +415,21 @@ pinctrl_fec: fecgrp { fsl,pins = < - MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x3 - MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x3 - MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x91 - MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x91 - MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x91 - MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x91 - MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x91 - MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x91 - MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x1f - MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x1f - MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x1f - MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x1f - MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x1f - MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x1f - MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02 0x19 + MX8MP_IOMUXC_SAI1_RXD2__ENET1_MDC 0x2 + MX8MP_IOMUXC_SAI1_RXD3__ENET1_MDIO 0x2 + MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x90 + MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x90 + MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x90 + MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x90 + MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x90 + MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x90 + MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x16 + MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x16 + MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x16 + MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x16 + MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x16 + MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x16 + MX8MP_IOMUXC_SAI1_RXD0__GPIO4_IO02 0x10 >; }; From 8c214b78e149dc7209e38a031292fe21d7017561 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:14:03 +0800 Subject: [PATCH 077/246] arm64: dts: imx8mp-evk: correct I2C5 pad settings According to RM bit layout, BIT3 and BIT0 are reserved. 8 7 6 5 4 3 2 1 0 PE HYS PUE ODE FSEL X DSE X Although function is not broken, we should not set reserved bit. Fixes: 8134822db08d ("arm64: dts: imx8mp-evk: add support for I2C5") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes 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 c244a5cd1ac0..b2fd0af5d1e1 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -481,8 +481,8 @@ pinctrl_i2c5: i2c5grp { fsl,pins = < - MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA 0x400001c3 - MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL 0x400001c3 + MX8MP_IOMUXC_SPDIF_RX__I2C5_SDA 0x400001c2 + MX8MP_IOMUXC_SPDIF_TX__I2C5_SCL 0x400001c2 >; }; From 05a7f43478e890513d571f36660bfedc1482a588 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:14:04 +0800 Subject: [PATCH 078/246] arm64: dts: imx8mp-evk: correct I2C1 pad settings According to RM bit layout, BIT3 and BIT0 are reserved. 8 7 6 5 4 3 2 1 0 PE HYS PUE ODE FSEL X DSE X Although function is not broken, we should not set reserved bit. Fixes: 5497bc2a2bff ("arm64: dts: imx8mp-evk: Add PMIC device") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes 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 b2fd0af5d1e1..fb858a6eb0e5 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -467,8 +467,8 @@ pinctrl_i2c1: i2c1grp { fsl,pins = < - MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c3 - MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c3 + MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c2 + MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c2 >; }; From 0836de513ebaae5f03014641eac996290d67493d Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:14:05 +0800 Subject: [PATCH 079/246] arm64: dts: imx8mp-evk: correct I2C3 pad settings According to RM bit layout, BIT3 and BIT0 are reserved. 8 7 6 5 4 3 2 1 0 PE HYS PUE ODE FSEL X DSE X Although function is not broken, we should not set reserved bit. Fixes: 5e4a67ff7f69 ("arm64: dts: imx8mp-evk: Add i2c3 support") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes 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 fb858a6eb0e5..9a4de739e6a2 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-evk.dts @@ -474,8 +474,8 @@ pinctrl_i2c3: i2c3grp { fsl,pins = < - MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c3 - MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c3 + MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c2 + MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c2 >; }; From 843af59e577021bd9c975b7a17c237394f26b929 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:14:06 +0800 Subject: [PATCH 080/246] arm64: dts: imx8mp-venice-gw74xx: correct pad settings According to RM bit layout, BIT3 and BIT0 are reserved. 8 7 6 5 4 3 2 1 0 PE HYS PUE ODE FSEL X DSE X Should not set reserved bit. Fixes: 7899eb6cb15d ("arm64: dts: imx: Add i.MX8M Plus Gateworks gw7400 dts support") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes Signed-off-by: Shawn Guo --- .../dts/freescale/imx8mp-venice-gw74xx.dts | 116 +++++++++--------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts index 101d31147603..521215520a0f 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw74xx.dts @@ -622,15 +622,15 @@ pinctrl_hog: hoggrp { fsl,pins = < - MX8MP_IOMUXC_GPIO1_IO09__GPIO1_IO09 0x40000041 /* DIO0 */ - MX8MP_IOMUXC_GPIO1_IO11__GPIO1_IO11 0x40000041 /* DIO1 */ - MX8MP_IOMUXC_NAND_DQS__GPIO3_IO14 0x40000041 /* M2SKT_OFF# */ - MX8MP_IOMUXC_SD2_DATA2__GPIO2_IO17 0x40000159 /* PCIE1_WDIS# */ - MX8MP_IOMUXC_SD2_DATA3__GPIO2_IO18 0x40000159 /* PCIE2_WDIS# */ - MX8MP_IOMUXC_SD2_CMD__GPIO2_IO14 0x40000159 /* PCIE3_WDIS# */ - MX8MP_IOMUXC_NAND_DATA00__GPIO3_IO06 0x40000041 /* M2SKT_RST# */ - MX8MP_IOMUXC_SAI1_TXD6__GPIO4_IO18 0x40000159 /* M2SKT_WDIS# */ - MX8MP_IOMUXC_NAND_ALE__GPIO3_IO00 0x40000159 /* M2SKT_GDIS# */ + MX8MP_IOMUXC_GPIO1_IO09__GPIO1_IO09 0x40000040 /* DIO0 */ + MX8MP_IOMUXC_GPIO1_IO11__GPIO1_IO11 0x40000040 /* DIO1 */ + MX8MP_IOMUXC_NAND_DQS__GPIO3_IO14 0x40000040 /* M2SKT_OFF# */ + MX8MP_IOMUXC_SD2_DATA2__GPIO2_IO17 0x40000150 /* PCIE1_WDIS# */ + MX8MP_IOMUXC_SD2_DATA3__GPIO2_IO18 0x40000150 /* PCIE2_WDIS# */ + MX8MP_IOMUXC_SD2_CMD__GPIO2_IO14 0x40000150 /* PCIE3_WDIS# */ + MX8MP_IOMUXC_NAND_DATA00__GPIO3_IO06 0x40000040 /* M2SKT_RST# */ + MX8MP_IOMUXC_SAI1_TXD6__GPIO4_IO18 0x40000150 /* M2SKT_WDIS# */ + MX8MP_IOMUXC_NAND_ALE__GPIO3_IO00 0x40000150 /* M2SKT_GDIS# */ MX8MP_IOMUXC_SAI3_TXD__GPIO5_IO01 0x40000104 /* UART_TERM */ MX8MP_IOMUXC_SAI3_TXFS__GPIO4_IO31 0x40000104 /* UART_RS485 */ MX8MP_IOMUXC_SAI3_TXC__GPIO5_IO00 0x40000104 /* UART_HALF */ @@ -639,47 +639,47 @@ pinctrl_accel: accelgrp { fsl,pins = < - MX8MP_IOMUXC_GPIO1_IO07__GPIO1_IO07 0x159 + MX8MP_IOMUXC_GPIO1_IO07__GPIO1_IO07 0x150 >; }; pinctrl_eqos: eqosgrp { fsl,pins = < - MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3 - MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3 - MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91 - MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91 - MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91 - MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91 - MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91 - MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91 - MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f - MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f - MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f - MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f - MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f - MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f - MX8MP_IOMUXC_SAI3_RXD__GPIO4_IO30 0x141 /* RST# */ - MX8MP_IOMUXC_SAI3_RXFS__GPIO4_IO28 0x159 /* IRQ# */ + MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x2 + MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x2 + MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x90 + MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x90 + MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x90 + MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x90 + MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x90 + MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x90 + MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x16 + MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x16 + MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x16 + MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x16 + MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x16 + MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x16 + MX8MP_IOMUXC_SAI3_RXD__GPIO4_IO30 0x140 /* RST# */ + MX8MP_IOMUXC_SAI3_RXFS__GPIO4_IO28 0x150 /* IRQ# */ >; }; pinctrl_fec: fecgrp { fsl,pins = < - MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x91 - MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x91 - MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x91 - MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x91 - MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x91 - MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x91 - MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x1f - MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x1f - MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x1f - MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x1f - MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x1f - MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x1f - MX8MP_IOMUXC_SAI1_RXFS__ENET1_1588_EVENT0_IN 0x141 - MX8MP_IOMUXC_SAI1_RXC__ENET1_1588_EVENT0_OUT 0x141 + MX8MP_IOMUXC_SAI1_RXD4__ENET1_RGMII_RD0 0x90 + MX8MP_IOMUXC_SAI1_RXD5__ENET1_RGMII_RD1 0x90 + MX8MP_IOMUXC_SAI1_RXD6__ENET1_RGMII_RD2 0x90 + MX8MP_IOMUXC_SAI1_RXD7__ENET1_RGMII_RD3 0x90 + MX8MP_IOMUXC_SAI1_TXC__ENET1_RGMII_RXC 0x90 + MX8MP_IOMUXC_SAI1_TXFS__ENET1_RGMII_RX_CTL 0x90 + MX8MP_IOMUXC_SAI1_TXD0__ENET1_RGMII_TD0 0x16 + MX8MP_IOMUXC_SAI1_TXD1__ENET1_RGMII_TD1 0x16 + MX8MP_IOMUXC_SAI1_TXD2__ENET1_RGMII_TD2 0x16 + MX8MP_IOMUXC_SAI1_TXD3__ENET1_RGMII_TD3 0x16 + MX8MP_IOMUXC_SAI1_TXD4__ENET1_RGMII_TX_CTL 0x16 + MX8MP_IOMUXC_SAI1_TXD5__ENET1_RGMII_TXC 0x16 + MX8MP_IOMUXC_SAI1_RXFS__ENET1_1588_EVENT0_IN 0x140 + MX8MP_IOMUXC_SAI1_RXC__ENET1_1588_EVENT0_OUT 0x140 >; }; @@ -692,61 +692,61 @@ pinctrl_gsc: gscgrp { fsl,pins = < - MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x159 + MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x150 >; }; pinctrl_i2c1: i2c1grp { fsl,pins = < - MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c3 - MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c3 + MX8MP_IOMUXC_I2C1_SCL__I2C1_SCL 0x400001c2 + MX8MP_IOMUXC_I2C1_SDA__I2C1_SDA 0x400001c2 >; }; pinctrl_i2c2: i2c2grp { fsl,pins = < - MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c3 - MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c3 + MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c2 + MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c2 >; }; pinctrl_i2c3: i2c3grp { fsl,pins = < - MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c3 - MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c3 + MX8MP_IOMUXC_I2C3_SCL__I2C3_SCL 0x400001c2 + MX8MP_IOMUXC_I2C3_SDA__I2C3_SDA 0x400001c2 >; }; pinctrl_i2c4: i2c4grp { fsl,pins = < - MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001c3 - MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c3 + MX8MP_IOMUXC_I2C4_SCL__I2C4_SCL 0x400001c2 + MX8MP_IOMUXC_I2C4_SDA__I2C4_SDA 0x400001c2 >; }; pinctrl_ksz: kszgrp { fsl,pins = < - MX8MP_IOMUXC_SAI3_RXC__GPIO4_IO29 0x159 /* IRQ# */ - MX8MP_IOMUXC_SAI3_MCLK__GPIO5_IO02 0x141 /* RST# */ + MX8MP_IOMUXC_SAI3_RXC__GPIO4_IO29 0x150 /* IRQ# */ + MX8MP_IOMUXC_SAI3_MCLK__GPIO5_IO02 0x140 /* RST# */ >; }; pinctrl_gpio_leds: ledgrp { fsl,pins = < - MX8MP_IOMUXC_SD2_DATA0__GPIO2_IO15 0x19 - MX8MP_IOMUXC_SD2_DATA1__GPIO2_IO16 0x19 + MX8MP_IOMUXC_SD2_DATA0__GPIO2_IO15 0x10 + MX8MP_IOMUXC_SD2_DATA1__GPIO2_IO16 0x10 >; }; pinctrl_pmic: pmicgrp { fsl,pins = < - MX8MP_IOMUXC_NAND_DATA01__GPIO3_IO07 0x141 + MX8MP_IOMUXC_NAND_DATA01__GPIO3_IO07 0x140 >; }; pinctrl_pps: ppsgrp { fsl,pins = < - MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12 0x141 + MX8MP_IOMUXC_GPIO1_IO12__GPIO1_IO12 0x140 >; }; @@ -758,13 +758,13 @@ pinctrl_reg_usb2: regusb2grp { fsl,pins = < - MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06 0x141 + MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06 0x140 >; }; pinctrl_reg_wifi: regwifigrp { fsl,pins = < - MX8MP_IOMUXC_NAND_DATA03__GPIO3_IO09 0x119 + MX8MP_IOMUXC_NAND_DATA03__GPIO3_IO09 0x110 >; }; @@ -811,7 +811,7 @@ pinctrl_uart3_gpio: uart3gpiogrp { fsl,pins = < - MX8MP_IOMUXC_NAND_DATA02__GPIO3_IO08 0x119 + MX8MP_IOMUXC_NAND_DATA02__GPIO3_IO08 0x110 >; }; From e266c155bd88e95f9b86379d6b0add6ac6e5452e Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:14:07 +0800 Subject: [PATCH 081/246] arm64: dts: imx8mp-phyboard-pollux-rdk: correct uart pad settings BIT3 and BIT0 are reserved bits, should not touch. Fixes: 846f752866bd ("arm64: dts: imx8mp-phyboard-pollux-rdk: Change debug UART") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes Signed-off-by: Shawn Guo --- arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts index 984a6b9ded8d..e34076954897 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts @@ -156,8 +156,8 @@ pinctrl_uart1: uart1grp { fsl,pins = < - MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x49 - MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x49 + MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x40 + MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x40 >; }; From bae4de618efe1c41d34aa2e6cef8b08e46256667 Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:14:08 +0800 Subject: [PATCH 082/246] arm64: dts: imx8mp-phyboard-pollux-rdk: correct eqos pad settings BIT3 and BIT0 are reserved bits, should not touch. Fixes: 6f96852619d5 ("arm64: dts: freescale: Add support EQOS MAC on phyBOARD-Pollux-i.MX8MP") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes Signed-off-by: Shawn Guo --- .../freescale/imx8mp-phyboard-pollux-rdk.dts | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts index e34076954897..cefd3d36f93f 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts @@ -116,20 +116,20 @@ &iomuxc { pinctrl_eqos: eqosgrp { fsl,pins = < - MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3 - MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3 - MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91 - MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91 - MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91 - MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91 - MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91 - MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91 - MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f - MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f - MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f - MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f - MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f - MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f + MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x2 + MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x2 + MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x90 + MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x90 + MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x90 + MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x90 + MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x90 + MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x90 + MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x16 + MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x16 + MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x16 + MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x16 + MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x16 + MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x16 MX8MP_IOMUXC_SAI1_MCLK__GPIO4_IO20 0x10 >; }; From 242d8ee9111171a6e68249aaff62643c513be6ec Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:14:09 +0800 Subject: [PATCH 083/246] arm64: dts: imx8mp-phyboard-pollux-rdk: correct i2c2 & mmc settings BIT3 and BIT0 are reserved bits, should not touch. Fixes: 88f7f6bcca37 ("arm64: dts: freescale: Add support for phyBOARD-Pollux-i.MX8MP") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes Signed-off-by: Shawn Guo --- .../dts/freescale/imx8mp-phyboard-pollux-rdk.dts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts index cefd3d36f93f..6aa720bafe28 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-rdk.dts @@ -136,21 +136,21 @@ pinctrl_i2c2: i2c2grp { fsl,pins = < - MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c3 - MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c3 + MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c2 + MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c2 >; }; pinctrl_i2c2_gpio: i2c2gpiogrp { fsl,pins = < - MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16 0x1e3 - MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x1e3 + MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16 0x1e2 + MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x1e2 >; }; pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { fsl,pins = < - MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x41 + MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x40 >; }; @@ -175,7 +175,7 @@ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0 MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0 MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0 - MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0 >; }; @@ -187,7 +187,7 @@ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d4 MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d4 MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d4 - MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0 >; }; @@ -199,7 +199,7 @@ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d6 MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d6 MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d6 - MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0 >; }; }; From 8630354f42bef90f51e003a7ce62b69aceb735ca Mon Sep 17 00:00:00 2001 From: Peng Fan Date: Wed, 22 Jun 2022 14:14:10 +0800 Subject: [PATCH 084/246] arm64: dts: imx8mp-icore-mx8mp-edim2.2: correct pad settings BIT3 and BIT0 are reserved bits, should not touch. Fixes: aec8ad34f7f2 ("arm64: dts: imx8mp: Add Engicam i.Core MX8M Plus EDIMM2.2 Starter Kit") Signed-off-by: Peng Fan Reviewed-by: Rasmus Villemoes Signed-off-by: Shawn Guo --- .../freescale/imx8mp-icore-mx8mp-edimm2.2.dts | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dts b/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dts index 70a701a624a6..dd703b6a5e17 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dts @@ -110,28 +110,28 @@ &iomuxc { pinctrl_eqos: eqosgrp { fsl,pins = < - MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x3 - MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x3 - MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x91 - MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x91 - MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x91 - MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x91 - MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x91 - MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x91 - MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x1f - MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x1f - MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x1f - MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x1f - MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1f - MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1f - MX8MP_IOMUXC_NAND_DATA01__GPIO3_IO07 0x19 + MX8MP_IOMUXC_ENET_MDC__ENET_QOS_MDC 0x2 + MX8MP_IOMUXC_ENET_MDIO__ENET_QOS_MDIO 0x2 + MX8MP_IOMUXC_ENET_RD0__ENET_QOS_RGMII_RD0 0x90 + MX8MP_IOMUXC_ENET_RD1__ENET_QOS_RGMII_RD1 0x90 + MX8MP_IOMUXC_ENET_RD2__ENET_QOS_RGMII_RD2 0x90 + MX8MP_IOMUXC_ENET_RD3__ENET_QOS_RGMII_RD3 0x90 + MX8MP_IOMUXC_ENET_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x90 + MX8MP_IOMUXC_ENET_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x90 + MX8MP_IOMUXC_ENET_TD0__ENET_QOS_RGMII_TD0 0x16 + MX8MP_IOMUXC_ENET_TD1__ENET_QOS_RGMII_TD1 0x16 + MX8MP_IOMUXC_ENET_TD2__ENET_QOS_RGMII_TD2 0x16 + MX8MP_IOMUXC_ENET_TD3__ENET_QOS_RGMII_TD3 0x16 + MX8MP_IOMUXC_ENET_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x16 + MX8MP_IOMUXC_ENET_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x16 + MX8MP_IOMUXC_NAND_DATA01__GPIO3_IO07 0x10 >; }; pinctrl_uart2: uart2grp { fsl,pins = < - MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x49 - MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x49 + MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x40 + MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x40 >; }; @@ -151,7 +151,7 @@ MX8MP_IOMUXC_SD2_DATA1__USDHC2_DATA1 0x1d0 MX8MP_IOMUXC_SD2_DATA2__USDHC2_DATA2 0x1d0 MX8MP_IOMUXC_SD2_DATA3__USDHC2_DATA3 0x1d0 - MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc1 + MX8MP_IOMUXC_GPIO1_IO04__USDHC2_VSELECT 0xc0 >; }; @@ -163,13 +163,13 @@ pinctrl_reg_usb1: regusb1grp { fsl,pins = < - MX8MP_IOMUXC_GPIO1_IO14__GPIO1_IO14 0x19 + MX8MP_IOMUXC_GPIO1_IO14__GPIO1_IO14 0x10 >; }; pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { fsl,pins = < - MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x41 + MX8MP_IOMUXC_SD2_RESET_B__GPIO2_IO19 0x40 >; }; }; From cd4c1e65a32afd003b08ad4aafe1e4d3e4e8e61b Mon Sep 17 00:00:00 2001 From: Andrei Lalaev Date: Wed, 25 May 2022 22:04:25 +0300 Subject: [PATCH 085/246] pinctrl: sunxi: sunxi_pconf_set: use correct offset Some Allwinner SoCs have 2 pinctrls (PIO and R_PIO). Previous implementation used absolute pin numbering and it was incorrect for R_PIO pinctrl. It's necessary to take into account the base pin number. Fixes: 90be64e27621 ("pinctrl: sunxi: implement pin_config_set") Signed-off-by: Andrei Lalaev Reviewed-by: Samuel Holland Link: https://lore.kernel.org/r/20220525190423.410609-1-andrey.lalaev@gmail.com Signed-off-by: Linus Walleij --- drivers/pinctrl/sunxi/pinctrl-sunxi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index d9327d7d56ee..dd928402af99 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -544,6 +544,8 @@ static int sunxi_pconf_set(struct pinctrl_dev *pctldev, unsigned pin, struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); int i; + pin -= pctl->desc->pin_base; + for (i = 0; i < num_configs; i++) { enum pin_config_param param; unsigned long flags; From 75c8f430d8596cf16634337fec8aec50e7b0feed Mon Sep 17 00:00:00 2001 From: Vincent Guittot Date: Fri, 24 Jun 2022 09:45:49 +0200 Subject: [PATCH 086/246] firmware: arm_scmi: Fix response size warning for OPTEE transport Some protocols check the response size with the expected value but optee shared memory doesn't return such size whereas it is available in the optee output buffer. As an example, the base protocol compares the response size with the expected result when requesting the list of protocol which triggers a warning with optee shared memory: arm-scmi firmware:scmi0: Malformed reply - real_sz:116 calc_sz:4 (loop_num_ret:4) Save the output buffer length and use it when fetching the answer. Link: https://lore.kernel.org/r/20220624074549.3298-1-vincent.guittot@linaro.org Reviewed-by: Etienne Carriere Reviewed-by: Cristian Marussi Signed-off-by: Vincent Guittot Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/optee.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c index b503c22cfd32..8abace56b958 100644 --- a/drivers/firmware/arm_scmi/optee.c +++ b/drivers/firmware/arm_scmi/optee.c @@ -117,6 +117,7 @@ struct scmi_optee_channel { u32 channel_id; u32 tee_session; u32 caps; + u32 rx_len; struct mutex mu; struct scmi_chan_info *cinfo; union { @@ -302,6 +303,9 @@ static int invoke_process_msg_channel(struct scmi_optee_channel *channel, size_t return -EIO; } + /* Save response size */ + channel->rx_len = param[2].u.memref.size; + return 0; } @@ -353,6 +357,7 @@ static int setup_dynamic_shmem(struct device *dev, struct scmi_optee_channel *ch shbuf = tee_shm_get_va(channel->tee_shm, 0); memset(shbuf, 0, msg_size); channel->req.msg = shbuf; + channel->rx_len = msg_size; return 0; } @@ -508,7 +513,7 @@ static void scmi_optee_fetch_response(struct scmi_chan_info *cinfo, struct scmi_optee_channel *channel = cinfo->transport_info; if (channel->tee_shm) - msg_fetch_response(channel->req.msg, SCMI_OPTEE_MAX_MSG_SIZE, xfer); + msg_fetch_response(channel->req.msg, channel->rx_len, xfer); else shmem_fetch_response(channel->req.shmem, xfer); } From 5f701324c0fb6f9f5aaac3f8d1575321375f6d8f Mon Sep 17 00:00:00 2001 From: Maxime Ripard Date: Wed, 22 Jun 2022 10:02:43 +0200 Subject: [PATCH 087/246] drm/vc4: perfmon: Fix variable dereferenced before check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 30f8c74ca9b7 ("drm/vc4: Warn if some v3d code is run on BCM2711") introduced a check in vc4_perfmon_get() that dereferences a pointer before we checked whether that pointer is valid or not. Let's rework that function a bit to do things in the proper order. Reported-by: kernel test robot Reported-by: Dan Carpenter Fixes: 30f8c74ca9b7 ("drm/vc4: Warn if some v3d code is run on BCM2711") Signed-off-by: Maxime Ripard Reviewed-by: José Expósito Link: https://patchwork.freedesktop.org/patch/msgid/20220622080243.22119-1-maxime@cerno.tech --- drivers/gpu/drm/vc4/vc4_perfmon.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_perfmon.c b/drivers/gpu/drm/vc4/vc4_perfmon.c index c7f5adb6bcf8..79a74184d732 100644 --- a/drivers/gpu/drm/vc4/vc4_perfmon.c +++ b/drivers/gpu/drm/vc4/vc4_perfmon.c @@ -17,13 +17,16 @@ void vc4_perfmon_get(struct vc4_perfmon *perfmon) { - struct vc4_dev *vc4 = perfmon->dev; + struct vc4_dev *vc4; + if (!perfmon) + return; + + vc4 = perfmon->dev; if (WARN_ON_ONCE(vc4->is_vc5)) return; - if (perfmon) - refcount_inc(&perfmon->refcnt); + refcount_inc(&perfmon->refcnt); } void vc4_perfmon_put(struct vc4_perfmon *perfmon) From 8a9ffb8c857c2c99403bd6483a5a005fed5c0773 Mon Sep 17 00:00:00 2001 From: Alexey Khoroshilov Date: Sat, 25 Jun 2022 23:52:43 +0300 Subject: [PATCH 088/246] NFSD: restore EINVAL error translation in nfsd_commit() commit 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t") incidentally broke translation of -EINVAL to nfserr_notsupp. The patch restores that. Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Alexey Khoroshilov Fixes: 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t") Signed-off-by: Chuck Lever --- fs/nfsd/vfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 840e3af63a6f..1b09d7293bc5 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1173,6 +1173,7 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, u64 offset, nfsd_copy_write_verifier(verf, nn); err2 = filemap_check_wb_err(nf->nf_file->f_mapping, since); + err = nfserrno(err2); break; case -EINVAL: err = nfserr_notsupp; @@ -1180,8 +1181,8 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp, u64 offset, default: nfsd_reset_write_verifier(nn); trace_nfsd_writeverf_reset(nn, rqstp, err2); + err = nfserrno(err2); } - err = nfserrno(err2); } else nfsd_copy_write_verifier(verf, nn); From 9efdd519d001ee3e761f6ff80d5eb123387421c1 Mon Sep 17 00:00:00 2001 From: katrinzhou Date: Tue, 21 Jun 2022 13:49:26 +0100 Subject: [PATCH 089/246] drm/i915/gem: add missing else Add missing else in set_proto_ctx_param() to fix coverity issue. Addresses-Coverity: ("Unused value") Fixes: d4433c7600f7 ("drm/i915/gem: Use the proto-context to handle create parameters (v5)") Suggested-by: Tvrtko Ursulin Signed-off-by: katrinzhou [tursulin: fixup alignment] Signed-off-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20220621124926.615884-1-tvrtko.ursulin@linux.intel.com (cherry picked from commit 7482a65664c16cc88eb84d2b545a1fed887378a1) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gem/i915_gem_context.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index ab4c5ab28e4d..321af109d484 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -933,8 +933,9 @@ static int set_proto_ctx_param(struct drm_i915_file_private *fpriv, case I915_CONTEXT_PARAM_PERSISTENCE: if (args->size) ret = -EINVAL; - ret = proto_context_set_persistence(fpriv->dev_priv, pc, - args->value); + else + ret = proto_context_set_persistence(fpriv->dev_priv, pc, + args->value); break; case I915_CONTEXT_PARAM_PROTECTED_CONTENT: From 7d23a80dc9720a378707edc03a7275d5a372355f Mon Sep 17 00:00:00 2001 From: Anshuman Gupta Date: Thu, 16 Jun 2022 17:52:49 +0530 Subject: [PATCH 090/246] drm/i915/dgfx: Disable d3cold at gfx root port Currently i915 disables d3cold for i915 pci dev. This blocks D3 for i915 gfx pci upstream bridge (VSP). Let's disable d3cold at gfx root port to make sure that i915 gfx VSP can transition to D3 to save some power. We don't need to disable/enable d3cold in rpm, s2idle suspend/resume handlers. Disabling/Enabling d3cold at gfx root port in probe/remove phase is sufficient. Fixes: 1a085e23411d ("drm/i915: Disable D3Cold in s2idle and runtime pm") Cc: Rodrigo Vivi Signed-off-by: Anshuman Gupta Reviewed-by: Badal Nilawar Acked-by: Rodrigo Vivi Link: https://patchwork.freedesktop.org/patch/msgid/20220616122249.5007-1-anshuman.gupta@intel.com (cherry picked from commit 138c2fca6f408f397ea8fbbbf33203f244d96e01) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/i915_driver.c | 34 +++++++++++++----------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 90b0ce5051af..1041b5340465 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -530,6 +530,7 @@ mask_err: static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) { struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); + struct pci_dev *root_pdev; int ret; if (i915_inject_probe_failure(dev_priv)) @@ -641,6 +642,15 @@ static int i915_driver_hw_probe(struct drm_i915_private *dev_priv) intel_bw_init_hw(dev_priv); + /* + * FIXME: Temporary hammer to avoid freezing the machine on our DGFX + * This should be totally removed when we handle the pci states properly + * on runtime PM and on s2idle cases. + */ + root_pdev = pcie_find_root_port(pdev); + if (root_pdev) + pci_d3cold_disable(root_pdev); + return 0; err_msi: @@ -664,11 +674,16 @@ err_perf: static void i915_driver_hw_remove(struct drm_i915_private *dev_priv) { struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); + struct pci_dev *root_pdev; i915_perf_fini(dev_priv); if (pdev->msi_enabled) pci_disable_msi(pdev); + + root_pdev = pcie_find_root_port(pdev); + if (root_pdev) + pci_d3cold_enable(root_pdev); } /** @@ -1193,14 +1208,6 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation) goto out; } - /* - * FIXME: Temporary hammer to avoid freezing the machine on our DGFX - * This should be totally removed when we handle the pci states properly - * on runtime PM and on s2idle cases. - */ - if (suspend_to_idle(dev_priv)) - pci_d3cold_disable(pdev); - pci_disable_device(pdev); /* * During hibernation on some platforms the BIOS may try to access @@ -1365,8 +1372,6 @@ static int i915_drm_resume_early(struct drm_device *dev) pci_set_master(pdev); - pci_d3cold_enable(pdev); - disable_rpm_wakeref_asserts(&dev_priv->runtime_pm); ret = vlv_resume_prepare(dev_priv, false); @@ -1543,7 +1548,6 @@ static int intel_runtime_suspend(struct device *kdev) { struct drm_i915_private *dev_priv = kdev_to_i915(kdev); struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); int ret; if (drm_WARN_ON_ONCE(&dev_priv->drm, !HAS_RUNTIME_PM(dev_priv))) @@ -1589,12 +1593,6 @@ static int intel_runtime_suspend(struct device *kdev) drm_err(&dev_priv->drm, "Unclaimed access detected prior to suspending\n"); - /* - * FIXME: Temporary hammer to avoid freezing the machine on our DGFX - * This should be totally removed when we handle the pci states properly - * on runtime PM and on s2idle cases. - */ - pci_d3cold_disable(pdev); rpm->suspended = true; /* @@ -1633,7 +1631,6 @@ static int intel_runtime_resume(struct device *kdev) { struct drm_i915_private *dev_priv = kdev_to_i915(kdev); struct intel_runtime_pm *rpm = &dev_priv->runtime_pm; - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); int ret; if (drm_WARN_ON_ONCE(&dev_priv->drm, !HAS_RUNTIME_PM(dev_priv))) @@ -1646,7 +1643,6 @@ static int intel_runtime_resume(struct device *kdev) intel_opregion_notify_adapter(dev_priv, PCI_D0); rpm->suspended = false; - pci_d3cold_enable(pdev); if (intel_uncore_unclaimed_mmio(&dev_priv->uncore)) drm_dbg(&dev_priv->drm, "Unclaimed access during suspend, bios?\n"); From 79538490fd7ade244dba400923e792519a2bdfea Mon Sep 17 00:00:00 2001 From: Matthew Auld Date: Wed, 22 Jun 2022 16:59:19 +0100 Subject: [PATCH 091/246] drm/i915: tweak the ordering in cpu_write_needs_clflush MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For imported dma-buf objects we leave the object as cache_coherent = 0 across all platforms, which is reasonable given that have no clue what the memory underneath is, and its not like the driver can ever manually clflush the pages anyway (like with i915_gem_clflush_object) for such objects. However on discrete we choose to treat cache_dirty = true as a programmer error, leading to a warning. The simplest fix looks to be to just change the ordering in cpu_write_needs_clflush to prevent ever setting cache_dirty for dma-buf objects on discrete. Fixes: d028a7690d87 ("drm/i915/dmabuf: Fix prime_mmap to work when using LMEM") Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/5266 Signed-off-by: Matthew Auld Cc: Thomas Hellström Cc: Gwan-gyeong Mun Reviewed-by: Gwan-gyeong Mun Link: https://patchwork.freedesktop.org/patch/msgid/20220622155919.355081-1-matthew.auld@intel.com (cherry picked from commit 563aaf4a928def2d36d1b3de0a4b515e2477b4da) Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/gem/i915_gem_domain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/gem/i915_gem_domain.c b/drivers/gpu/drm/i915/gem/i915_gem_domain.c index 3e5d6057b3ef..1674b0c5802b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_domain.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_domain.c @@ -35,12 +35,12 @@ bool i915_gem_cpu_write_needs_clflush(struct drm_i915_gem_object *obj) if (obj->cache_dirty) return false; - if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE)) - return true; - if (IS_DGFX(i915)) return false; + if (!(obj->cache_coherent & I915_BO_CACHE_COHERENT_FOR_WRITE)) + return true; + /* Currently in use by HW (display engine)? Keep flushed. */ return i915_gem_object_is_framebuffer(obj); } From 4ce7e51dc712f8a006ce6abcc49f788c79287c03 Mon Sep 17 00:00:00 2001 From: Bo Liu Date: Thu, 16 Jun 2022 01:50:52 -0400 Subject: [PATCH 092/246] firmware: arm_scmi: Remove usage of the deprecated ida_simple_xxx API Replace the deprecated ida_simple_{get,remove} with ida_{alloc,free}. Link: https://lore.kernel.org/r/20220616055052.4559-1-liubo03@inspur.com Signed-off-by: Bo Liu [sudeep.holla: Replace ida_alloc_min with ida_alloc as suggested by Cristian] Signed-off-by: Sudeep Holla --- drivers/firmware/arm_scmi/bus.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index f6fe723ab869..d4e23101448a 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -181,7 +181,7 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol, return NULL; } - id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL); + id = ida_alloc_min(&scmi_bus_id, 1, GFP_KERNEL); if (id < 0) { kfree_const(scmi_dev->name); kfree(scmi_dev); @@ -204,7 +204,7 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol, put_dev: kfree_const(scmi_dev->name); put_device(&scmi_dev->dev); - ida_simple_remove(&scmi_bus_id, id); + ida_free(&scmi_bus_id, id); return NULL; } @@ -212,7 +212,7 @@ void scmi_device_destroy(struct scmi_device *scmi_dev) { kfree_const(scmi_dev->name); scmi_handle_put(scmi_dev->handle); - ida_simple_remove(&scmi_bus_id, scmi_dev->id); + ida_free(&scmi_bus_id, scmi_dev->id); device_unregister(&scmi_dev->dev); } From 96b80fcd2705fc50ebe1f7f3ce204e861b3099ab Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Mon, 27 Jun 2022 01:39:11 +0200 Subject: [PATCH 093/246] parisc/unaligned: Fix emulate_ldw() breakage The commit e8aa7b17fe41 broke the 32-bit load-word unalignment exception handler because it calculated the wrong amount of bits by which the value should be shifted. This patch fixes it. Signed-off-by: Helge Deller Fixes: e8aa7b17fe41 ("parisc/unaligned: Rewrite inline assembly of emulate_ldw()") Cc: stable@vger.kernel.org # v5.18 --- arch/parisc/kernel/unaligned.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c index ed1e88a74dc4..bac581b5ecfc 100644 --- a/arch/parisc/kernel/unaligned.c +++ b/arch/parisc/kernel/unaligned.c @@ -146,7 +146,7 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop) " depw %%r0,31,2,%4\n" "1: ldw 0(%%sr1,%4),%0\n" "2: ldw 4(%%sr1,%4),%3\n" -" subi 32,%4,%2\n" +" subi 32,%2,%2\n" " mtctl %2,11\n" " vshd %0,%3,%0\n" "3: \n" From 08de214138cdea438a0dfcb10d355a6650c6017c Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Fri, 24 Jun 2022 11:45:28 -0700 Subject: [PATCH 094/246] drm/msm/gem: Fix error return on fence id alloc fail This was a typo, we didn't actually want to return zero. Fixes: a61acbbe9cf8 ("drm/msm: Track "seqno" fences by idr") Signed-off-by: Rob Clark Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/491145/ Link: https://lore.kernel.org/r/20220624184528.4036837-1-robdclark@gmail.com --- drivers/gpu/drm/msm/msm_gem_submit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 286124008445..6b6feae1f7b6 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -928,7 +928,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, INT_MAX, GFP_KERNEL); } if (submit->fence_id < 0) { - ret = submit->fence_id = 0; + ret = submit->fence_id; submit->fence_id = 0; } From 5fb779558f1c97e2bf2794cb59553e569c38e2f9 Mon Sep 17 00:00:00 2001 From: Stephan Gerhold Date: Mon, 27 Jun 2022 15:59:38 +0200 Subject: [PATCH 095/246] arm64: dts: qcom: msm8992-*: Fix vdd_lvs1_2-supply typo "make dtbs_check" complains about the missing "-supply" suffix for vdd_lvs1_2 which is clearly a typo, originally introduced in the msm8994-smd-rpm.dtsi file and apparently later copied to msm8992-xiaomi-libra.dts: msm8992-lg-bullhead-rev-10/101.dtb: pm8994-regulators: 'vdd_lvs1_2' does not match any of the regexes: '.*-supply$', '^((s|l|lvs|5vs)[0-9]*)|(boost-bypass)|(bob)$', 'pinctrl-[0-9]+' From schema: regulator/qcom,smd-rpm-regulator.yaml msm8992-xiaomi-libra.dtb: pm8994-regulators: 'vdd_lvs1_2' does not match any of the regexes: '.*-supply$', '^((s|l|lvs|5vs)[0-9]*)|(boost-bypass)|(bob)$', 'pinctrl-[0-9]+' From schema: regulator/qcom,smd-rpm-regulator.yaml Reported-by: Rob Herring Cc: Konrad Dybcio Fixes: f3b2c99e73be ("arm64: dts: Enable onboard SDHCI on msm8992") Fixes: 0f5cdb31e850 ("arm64: dts: qcom: Add Xiaomi Libra (Mi 4C) device tree") Signed-off-by: Stephan Gerhold Reviewed-by: Konrad Dybcio Signed-off-by: Bjorn Andersson Link: https://lore.kernel.org/r/20220627135938.2901871-1-stephan.gerhold@kernkonzept.com --- arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi index 3b0cc85d6674..71e373b11de9 100644 --- a/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8992-lg-bullhead.dtsi @@ -74,7 +74,7 @@ vdd_l17_29-supply = <&vph_pwr>; vdd_l20_21-supply = <&vph_pwr>; vdd_l25-supply = <&pm8994_s5>; - vdd_lvs1_2 = <&pm8994_s4>; + vdd_lvs1_2-supply = <&pm8994_s4>; /* S1, S2, S6 and S12 are managed by RPMPD */ diff --git a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts index 7748b745a5df..afa91ca9a3dc 100644 --- a/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts +++ b/arch/arm64/boot/dts/qcom/msm8992-xiaomi-libra.dts @@ -171,7 +171,7 @@ vdd_l17_29-supply = <&vph_pwr>; vdd_l20_21-supply = <&vph_pwr>; vdd_l25-supply = <&pm8994_s5>; - vdd_lvs1_2 = <&pm8994_s4>; + vdd_lvs1_2-supply = <&pm8994_s4>; /* S1, S2, S6 and S12 are managed by RPMPD */ From 332bd0778775d0cf105c4b9e03e460b590749916 Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Tue, 28 Jun 2022 00:37:22 +0200 Subject: [PATCH 096/246] dm raid: fix accesses beyond end of raid member array On dm-raid table load (using raid_ctr), dm-raid allocates an array rs->devs[rs->raid_disks] for the raid device members. rs->raid_disks is defined by the number of raid metadata and image tupples passed into the target's constructor. In the case of RAID layout changes being requested, that number can be different from the current number of members for existing raid sets as defined in their superblocks. Example RAID layout changes include: - raid1 legs being added/removed - raid4/5/6/10 number of stripes changed (stripe reshaping) - takeover to higher raid level (e.g. raid5 -> raid6) When accessing array members, rs->raid_disks must be used in control loops instead of the potentially larger value in rs->md.raid_disks. Otherwise it will cause memory access beyond the end of the rs->devs array. Fix this by changing code that is prone to out-of-bounds access. Also fix validate_raid_redundancy() to validate all devices that are added. Also, use braces to help clean up raid_iterate_devices(). The out-of-bounds memory accesses was discovered using KASAN. This commit was verified to pass all LVM2 RAID tests (with KASAN enabled). Cc: stable@vger.kernel.org Signed-off-by: Heinz Mauelshagen Signed-off-by: Mike Snitzer --- drivers/md/dm-raid.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 9526ccbedafb..80c9f7134e9b 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -1001,12 +1001,13 @@ static int validate_region_size(struct raid_set *rs, unsigned long region_size) static int validate_raid_redundancy(struct raid_set *rs) { unsigned int i, rebuild_cnt = 0; - unsigned int rebuilds_per_group = 0, copies; + unsigned int rebuilds_per_group = 0, copies, raid_disks; unsigned int group_size, last_group_start; - for (i = 0; i < rs->md.raid_disks; i++) - if (!test_bit(In_sync, &rs->dev[i].rdev.flags) || - !rs->dev[i].rdev.sb_page) + for (i = 0; i < rs->raid_disks; i++) + if (!test_bit(FirstUse, &rs->dev[i].rdev.flags) && + ((!test_bit(In_sync, &rs->dev[i].rdev.flags) || + !rs->dev[i].rdev.sb_page))) rebuild_cnt++; switch (rs->md.level) { @@ -1046,8 +1047,9 @@ static int validate_raid_redundancy(struct raid_set *rs) * A A B B C * C D D E E */ + raid_disks = min(rs->raid_disks, rs->md.raid_disks); if (__is_raid10_near(rs->md.new_layout)) { - for (i = 0; i < rs->md.raid_disks; i++) { + for (i = 0; i < raid_disks; i++) { if (!(i % copies)) rebuilds_per_group = 0; if ((!rs->dev[i].rdev.sb_page || @@ -1070,10 +1072,10 @@ static int validate_raid_redundancy(struct raid_set *rs) * results in the need to treat the last (potentially larger) * set differently. */ - group_size = (rs->md.raid_disks / copies); - last_group_start = (rs->md.raid_disks / group_size) - 1; + group_size = (raid_disks / copies); + last_group_start = (raid_disks / group_size) - 1; last_group_start *= group_size; - for (i = 0; i < rs->md.raid_disks; i++) { + for (i = 0; i < raid_disks; i++) { if (!(i % copies) && !(i > last_group_start)) rebuilds_per_group = 0; if ((!rs->dev[i].rdev.sb_page || @@ -1588,7 +1590,7 @@ static sector_t __rdev_sectors(struct raid_set *rs) { int i; - for (i = 0; i < rs->md.raid_disks; i++) { + for (i = 0; i < rs->raid_disks; i++) { struct md_rdev *rdev = &rs->dev[i].rdev; if (!test_bit(Journal, &rdev->flags) && @@ -3766,13 +3768,13 @@ static int raid_iterate_devices(struct dm_target *ti, unsigned int i; int r = 0; - for (i = 0; !r && i < rs->md.raid_disks; i++) - if (rs->dev[i].data_dev) - r = fn(ti, - rs->dev[i].data_dev, - 0, /* No offset on data devs */ - rs->md.dev_sectors, - data); + for (i = 0; !r && i < rs->raid_disks; i++) { + if (rs->dev[i].data_dev) { + r = fn(ti, rs->dev[i].data_dev, + 0, /* No offset on data devs */ + rs->md.dev_sectors, data); + } + } return r; } From fce54ed027577517df1e74b7d54dc2b1bd536887 Mon Sep 17 00:00:00 2001 From: John Garry Date: Thu, 23 Jun 2022 20:41:59 +0800 Subject: [PATCH 097/246] scsi: hisi_sas: Limit max hw sectors for v3 HW If the controller is behind an IOMMU then the IOMMU IOVA caching range can affect performance, as discussed in [0]. Limit the max HW sectors to not exceed this limit. We need to hardcode the value until a proper DMA mapping API is available. [0] https://lore.kernel.org/linux-iommu/20210129092120.1482-1-thunder.leizhen@huawei.com/ Link: https://lore.kernel.org/r/1655988119-223714-1-git-send-email-john.garry@huawei.com Signed-off-by: John Garry Signed-off-by: Martin K. Petersen --- drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 7d819fc0395e..eb86afb21aab 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -2782,6 +2782,7 @@ static int slave_configure_v3_hw(struct scsi_device *sdev) struct hisi_hba *hisi_hba = shost_priv(shost); struct device *dev = hisi_hba->dev; int ret = sas_slave_configure(sdev); + unsigned int max_sectors; if (ret) return ret; @@ -2799,6 +2800,12 @@ static int slave_configure_v3_hw(struct scsi_device *sdev) } } + /* Set according to IOMMU IOVA caching limit */ + max_sectors = min_t(size_t, queue_max_hw_sectors(sdev->request_queue), + (PAGE_SIZE * 32) >> SECTOR_SHIFT); + + blk_queue_max_hw_sectors(sdev->request_queue, max_sectors); + return 0; } From 4ff5a9b6d95f3524bf6d27147df497eb21968300 Mon Sep 17 00:00:00 2001 From: Liang He Date: Wed, 15 Jun 2022 17:48:07 +0800 Subject: [PATCH 098/246] drivers: cpufreq: Add missing of_node_put() in qoriq-cpufreq.c In qoriq_cpufreq_probe(), of_find_matching_node() will return a node pointer with refcount incremented. We should use of_node_put() when it is not used anymore. Fixes: 157f527639da ("cpufreq: qoriq: convert to a platform driver") [ Viresh: Fixed Author's name in commit log ] Signed-off-by: Liang He Signed-off-by: Viresh Kumar --- drivers/cpufreq/qoriq-cpufreq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 6b6b20da2bcf..573b417e1483 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -275,6 +275,7 @@ static int qoriq_cpufreq_probe(struct platform_device *pdev) np = of_find_matching_node(NULL, qoriq_cpufreq_blacklist); if (np) { + of_node_put(np); dev_info(&pdev->dev, "Disabling due to erratum A-008083"); return -ENODEV; } From 668a7a12ded7077d4fd7ad1305667e559907e5bb Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Thu, 16 Jun 2022 15:45:31 -0700 Subject: [PATCH 099/246] cpufreq: qcom-hw: Don't do lmh things without a throttle interrupt Offlining cpu6 and cpu7 and then onlining cpu6 hangs on sc7180-trogdor-lazor because the throttle interrupt doesn't exist. Similarly, things go sideways when suspend/resume runs. That's because the qcom_cpufreq_hw_cpu_online() and qcom_cpufreq_hw_lmh_exit() functions are calling genirq APIs with an interrupt value of '-6', i.e. -ENXIO, and that isn't good. Check the value of the throttle interrupt like we already do in other functions in this file and bail out early from lmh code to fix the hang. Reported-by: Rob Clark Cc: Vladimir Zapolskiy Cc: Bjorn Andersson Cc: Dmitry Baryshkov Fixes: a1eb080a0447 ("cpufreq: qcom-hw: provide online/offline operations") Signed-off-by: Stephen Boyd Reviewed-by: Vladimir Zapolskiy Signed-off-by: Viresh Kumar --- drivers/cpufreq/qcom-cpufreq-hw.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index 0253731d6d25..36c79580fba2 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -442,6 +442,9 @@ static int qcom_cpufreq_hw_cpu_online(struct cpufreq_policy *policy) struct platform_device *pdev = cpufreq_get_driver_data(); int ret; + if (data->throttle_irq <= 0) + return 0; + ret = irq_set_affinity_hint(data->throttle_irq, policy->cpus); if (ret) dev_err(&pdev->dev, "Failed to set CPU affinity of %s[%d]\n", @@ -469,6 +472,9 @@ static int qcom_cpufreq_hw_cpu_offline(struct cpufreq_policy *policy) static void qcom_cpufreq_hw_lmh_exit(struct qcom_cpufreq_data *data) { + if (data->throttle_irq <= 0) + return; + free_irq(data->throttle_irq, data); } From ccd7567d4b6cf187fdfa55f003a9e461ee629e36 Mon Sep 17 00:00:00 2001 From: Liang He Date: Sat, 18 Jun 2022 10:25:45 +0800 Subject: [PATCH 100/246] cpufreq: pmac32-cpufreq: Fix refcount leak bug In pmac_cpufreq_init_MacRISC3(), we need to add corresponding of_node_put() for the three node pointers whose refcount have been incremented by of_find_node_by_name(). Signed-off-by: Liang He Signed-off-by: Viresh Kumar --- drivers/cpufreq/pmac32-cpufreq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/cpufreq/pmac32-cpufreq.c b/drivers/cpufreq/pmac32-cpufreq.c index 20f64a8b0a35..4b8ee2014da6 100644 --- a/drivers/cpufreq/pmac32-cpufreq.c +++ b/drivers/cpufreq/pmac32-cpufreq.c @@ -470,6 +470,10 @@ static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) if (slew_done_gpio_np) slew_done_gpio = read_gpio(slew_done_gpio_np); + of_node_put(volt_gpio_np); + of_node_put(freq_gpio_np); + of_node_put(slew_done_gpio_np); + /* If we use the frequency GPIOs, calculate the min/max speeds based * on the bus frequencies */ From be4b61ec45b3efe5e9077525fc92d544305eb2a6 Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Fri, 17 Jun 2022 13:09:26 +0200 Subject: [PATCH 101/246] cpufreq: Add MT8186 to cpufreq-dt-platdev blocklist This SoC shall use the mediatek-cpufreq driver, or the system will crash upon any clock scaling request: add it to the cpufreq-dt-platdev blocklist. Fixes: 39b360102f3a ("cpufreq: mediatek: Add support for MT8186") Signed-off-by: AngeloGioacchino Del Regno Reviewed-by: Matthias Brugger Signed-off-by: Viresh Kumar --- drivers/cpufreq/cpufreq-dt-platdev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c index 96de1536e1cb..2c96de3f2d83 100644 --- a/drivers/cpufreq/cpufreq-dt-platdev.c +++ b/drivers/cpufreq/cpufreq-dt-platdev.c @@ -127,6 +127,7 @@ static const struct of_device_id blocklist[] __initconst = { { .compatible = "mediatek,mt8173", }, { .compatible = "mediatek,mt8176", }, { .compatible = "mediatek,mt8183", }, + { .compatible = "mediatek,mt8186", }, { .compatible = "mediatek,mt8365", }, { .compatible = "mediatek,mt8516", }, From 8520501346ed8d1c4a6dfa751cb57328a9c843f1 Mon Sep 17 00:00:00 2001 From: Stafford Horne Date: Wed, 15 Jun 2022 08:54:26 +0900 Subject: [PATCH 102/246] irqchip: or1k-pic: Undefine mask_ack for level triggered hardware The mask_ack operation clears the interrupt by writing to the PICSR register. This we don't want for level triggered interrupt because it does not actually clear the interrupt on the source hardware. This was causing issues in qemu with multi core setups where interrupts would continue to fire even though they had been cleared in PICSR. Just remove the mask_ack operation. Acked-by: Marc Zyngier Signed-off-by: Stafford Horne --- drivers/irqchip/irq-or1k-pic.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/irqchip/irq-or1k-pic.c b/drivers/irqchip/irq-or1k-pic.c index 49b47e787644..f289ccd95291 100644 --- a/drivers/irqchip/irq-or1k-pic.c +++ b/drivers/irqchip/irq-or1k-pic.c @@ -66,7 +66,6 @@ static struct or1k_pic_dev or1k_pic_level = { .name = "or1k-PIC-level", .irq_unmask = or1k_pic_unmask, .irq_mask = or1k_pic_mask, - .irq_mask_ack = or1k_pic_mask_ack, }, .handle = handle_level_irq, .flags = IRQ_LEVEL | IRQ_NOPROBE, From 48bddb89d59eec27c3305d179b1832d5292e285d Mon Sep 17 00:00:00 2001 From: Xiang wangx Date: Thu, 2 Jun 2022 16:53:50 +0800 Subject: [PATCH 103/246] openrisc: unwinder: Fix grammar issue in comment Delete the redundant word 'the'. Signed-off-by: Xiang wangx Signed-off-by: Stafford Horne --- arch/openrisc/kernel/unwinder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/openrisc/kernel/unwinder.c b/arch/openrisc/kernel/unwinder.c index 8ae15c2c1845..c6ad6f867a6a 100644 --- a/arch/openrisc/kernel/unwinder.c +++ b/arch/openrisc/kernel/unwinder.c @@ -25,7 +25,7 @@ struct or1k_frameinfo { /* * Verify a frameinfo structure. The return address should be a valid text * address. The frame pointer may be null if its the last frame, otherwise - * the frame pointer should point to a location in the stack after the the + * the frame pointer should point to a location in the stack after the * top of the next frame up. */ static inline int or1k_frameinfo_valid(struct or1k_frameinfo *frameinfo) From ddc980da8043779119acaca106c6d9b445c9b65b Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 23 May 2022 12:24:19 +0300 Subject: [PATCH 104/246] ARM: at91: pm: use proper compatible for sama5d2's rtc Use proper compatible strings for SAMA5D2's RTC IPs. This is necessary for configuring wakeup sources for ULP1 PM mode. Fixes: d7484f5c6b3b ("ARM: at91: pm: configure wakeup sources for ULP1 mode") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220523092421.317345-2-claudiu.beznea@microchip.com --- arch/arm/mach-at91/pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index b1a43d7bc56c..4d62f686bd1e 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -202,7 +202,7 @@ static const struct wakeup_source_info ws_info[] = { static const struct of_device_id sama5d2_ws_ids[] = { { .compatible = "atmel,sama5d2-gem", .data = &ws_info[0] }, - { .compatible = "atmel,at91rm9200-rtc", .data = &ws_info[1] }, + { .compatible = "atmel,sama5d2-rtc", .data = &ws_info[1] }, { .compatible = "atmel,sama5d3-udc", .data = &ws_info[2] }, { .compatible = "atmel,at91rm9200-ohci", .data = &ws_info[2] }, { .compatible = "usb-ohci", .data = &ws_info[2] }, From 641522665dbb25ce117c78746df1aad8b58c80e5 Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 23 May 2022 12:24:20 +0300 Subject: [PATCH 105/246] ARM: at91: pm: use proper compatibles for sam9x60's rtc and rtt Use proper compatible strings for SAM9X60's RTC and RTT IPs. These are necessary for configuring wakeup sources for ULP1 PM mode. Fixes: eaedc0d379da ("ARM: at91: pm: add ULP1 support for SAM9X60") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220523092421.317345-3-claudiu.beznea@microchip.com --- arch/arm/mach-at91/pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 4d62f686bd1e..f017b2d1b11e 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -213,12 +213,12 @@ static const struct of_device_id sama5d2_ws_ids[] = { }; static const struct of_device_id sam9x60_ws_ids[] = { - { .compatible = "atmel,at91sam9x5-rtc", .data = &ws_info[1] }, + { .compatible = "microchip,sam9x60-rtc", .data = &ws_info[1] }, { .compatible = "atmel,at91rm9200-ohci", .data = &ws_info[2] }, { .compatible = "usb-ohci", .data = &ws_info[2] }, { .compatible = "atmel,at91sam9g45-ehci", .data = &ws_info[2] }, { .compatible = "usb-ehci", .data = &ws_info[2] }, - { .compatible = "atmel,at91sam9260-rtt", .data = &ws_info[4] }, + { .compatible = "microchip,sam9x60-rtt", .data = &ws_info[4] }, { .compatible = "cdns,sam9x60-macb", .data = &ws_info[5] }, { /* sentinel */ } }; From 1c40169b35ad58906814d53a517ac92db3d20d5f Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Mon, 23 May 2022 12:24:21 +0300 Subject: [PATCH 106/246] ARM: at91: pm: use proper compatibles for sama7g5's rtc and rtt Use proper compatible strings for SAMA7G5's RTC and RTT IPs. These are necessary for configuring wakeup sources for ULP1 PM mode. Fixes: 6501330f9f5e ("ARM: at91: pm: add pm support for SAMA7G5") Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220523092421.317345-4-claudiu.beznea@microchip.com --- arch/arm/mach-at91/pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index f017b2d1b11e..826fd56d2a17 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -224,13 +224,13 @@ static const struct of_device_id sam9x60_ws_ids[] = { }; static const struct of_device_id sama7g5_ws_ids[] = { - { .compatible = "atmel,at91sam9x5-rtc", .data = &ws_info[1] }, + { .compatible = "microchip,sama7g5-rtc", .data = &ws_info[1] }, { .compatible = "microchip,sama7g5-ohci", .data = &ws_info[2] }, { .compatible = "usb-ohci", .data = &ws_info[2] }, { .compatible = "atmel,at91sam9g45-ehci", .data = &ws_info[2] }, { .compatible = "usb-ehci", .data = &ws_info[2] }, { .compatible = "microchip,sama7g5-sdhci", .data = &ws_info[3] }, - { .compatible = "atmel,at91sam9260-rtt", .data = &ws_info[4] }, + { .compatible = "microchip,sama7g5-rtt", .data = &ws_info[4] }, { /* sentinel */ } }; From f2cbbc3f926316ccf8ef9363d8a60c1110afc1c7 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 7 Jun 2022 12:04:54 +0300 Subject: [PATCH 107/246] ARM: dts: at91: sam9x60ek: fix eeprom compatible and size The board has a microchip 24aa025e48 eeprom, which is a 2 Kbits memory, so it's compatible with at24c02 not at24c32. Also the size property is wrong, it's not 128 bytes, but 256 bytes. Thus removing and leaving it to the default (256). Fixes: 1e5f532c27371 ("ARM: dts: at91: sam9x60: add device tree for soc and board") Signed-off-by: Eugen Hristev Reviewed-by: Claudiu Beznea Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220607090455.80433-1-eugen.hristev@microchip.com --- arch/arm/boot/dts/at91-sam9x60ek.dts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts index 7719ea3d4933..81ccb0636a00 100644 --- a/arch/arm/boot/dts/at91-sam9x60ek.dts +++ b/arch/arm/boot/dts/at91-sam9x60ek.dts @@ -233,10 +233,9 @@ status = "okay"; eeprom@53 { - compatible = "atmel,24c32"; + compatible = "atmel,24c02"; reg = <0x53>; pagesize = <16>; - size = <128>; status = "okay"; }; }; From 416ce193d73a734ded6d09fe141017b38af1c567 Mon Sep 17 00:00:00 2001 From: Eugen Hristev Date: Tue, 7 Jun 2022 12:04:55 +0300 Subject: [PATCH 108/246] ARM: dts: at91: sama5d2_icp: fix eeprom compatibles The eeprom memories on the board are microchip 24aa025e48, which are 2 Kbits and are compatible with at24c02 not at24c32. Fixes: 68a95ef72cefe ("ARM: dts: at91: sama5d2-icp: add SAMA5D2-ICP") Signed-off-by: Eugen Hristev Reviewed-by: Claudiu Beznea Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220607090455.80433-2-eugen.hristev@microchip.com --- arch/arm/boot/dts/at91-sama5d2_icp.dts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/at91-sama5d2_icp.dts b/arch/arm/boot/dts/at91-sama5d2_icp.dts index 806eb1d911d7..164201a8fbf2 100644 --- a/arch/arm/boot/dts/at91-sama5d2_icp.dts +++ b/arch/arm/boot/dts/at91-sama5d2_icp.dts @@ -329,21 +329,21 @@ status = "okay"; eeprom@50 { - compatible = "atmel,24c32"; + compatible = "atmel,24c02"; reg = <0x50>; pagesize = <16>; status = "okay"; }; eeprom@52 { - compatible = "atmel,24c32"; + compatible = "atmel,24c02"; reg = <0x52>; pagesize = <16>; status = "disabled"; }; eeprom@53 { - compatible = "atmel,24c32"; + compatible = "atmel,24c02"; reg = <0x53>; pagesize = <16>; status = "disabled"; From 35074df65a8d8c5328a83e2eea948f7bbc8e6e08 Mon Sep 17 00:00:00 2001 From: Mihai Sain Date: Thu, 16 Jun 2022 11:13:44 +0300 Subject: [PATCH 109/246] ARM: at91: fix soc detection for SAM9X60 SiPs Fix SoC detection for SAM9X60 SiPs: SAM9X60D5M SAM9X60D1G SAM9X60D6K Fixes: af3a10513cd6 ("drivers: soc: atmel: add per soc id and version match masks") Signed-off-by: Mihai Sain Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220616081344.1978664-1-claudiu.beznea@microchip.com --- drivers/soc/atmel/soc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index b2d365ae0282..dae8a2e0f745 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -91,14 +91,14 @@ static const struct at91_soc socs[] __initconst = { AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK, AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, "sam9x60", "sam9x60"), - AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D5M_EXID_MATCH, - AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, + AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAM9X60_D5M_EXID_MATCH, "sam9x60 64MiB DDR2 SiP", "sam9x60"), - AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D1G_EXID_MATCH, - AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, + AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAM9X60_D1G_EXID_MATCH, "sam9x60 128MiB DDR2 SiP", "sam9x60"), - AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D6K_EXID_MATCH, - AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, + AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAM9X60_D6K_EXID_MATCH, "sam9x60 8MiB SDRAM SiP", "sam9x60"), #endif #ifdef CONFIG_SOC_SAMA5 From 91d60e259c0f58c855f88f3fe5b7909aec563525 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 22 Jun 2022 08:48:10 -0300 Subject: [PATCH 110/246] ARM: at91: pm: Mark at91_pm_secure_init as __init at91_pm_secure_init() is used inside sama5d2_pm_init(), which has the __init notation. Pass the __init notation to at91_pm_secure_init() as well to fix the following section mismatch warning: WARNING: modpost: vmlinux.o(.text.unlikely+0x2138): Section mismatch in reference from the function at91_pm_secure_init() to the (unknown reference) .init.rodata:(unknown) Fixes: f2f5cf78a333 ("ARM: at91: pm: add support for sama5d2 secure suspend") Signed-off-by: Fabio Estevam Signed-off-by: Claudiu Beznea Link: https://lore.kernel.org/r/20220622114810.1186330-1-festevam@gmail.com --- arch/arm/mach-at91/pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 826fd56d2a17..df6d673e83d5 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -1079,7 +1079,7 @@ securam_fail: return ret; } -static void at91_pm_secure_init(void) +static void __init at91_pm_secure_init(void) { int suspend_mode; struct arm_smccc_res res; From fbc24ebc65507feb9728dc38197f90486148dda0 Mon Sep 17 00:00:00 2001 From: Jacky Bai Date: Mon, 13 Jun 2022 11:18:54 +0800 Subject: [PATCH 111/246] pinctrl: imx: Add the zero base flag for imx93 On i.MX93, the pin mux reg offset is from 0x0, so need to add the 'ZERO_OFFSET_VALID' flag to make sure the pin at mux offset 0 can be found. Signed-off-by: Jacky Bai Link: https://lore.kernel.org/r/20220613031854.1571357-1-ping.bai@nxp.com Signed-off-by: Linus Walleij --- drivers/pinctrl/freescale/pinctrl-imx93.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pinctrl/freescale/pinctrl-imx93.c b/drivers/pinctrl/freescale/pinctrl-imx93.c index c0630f69e995..417e41b37a6f 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx93.c +++ b/drivers/pinctrl/freescale/pinctrl-imx93.c @@ -239,6 +239,7 @@ static const struct pinctrl_pin_desc imx93_pinctrl_pads[] = { static const struct imx_pinctrl_soc_info imx93_pinctrl_info = { .pins = imx93_pinctrl_pads, .npins = ARRAY_SIZE(imx93_pinctrl_pads), + .flags = ZERO_OFFSET_VALID, .gpr_compatible = "fsl,imx93-iomuxc-gpr", }; From a1d4ef1adf8bbd302067534ead671a94759687ed Mon Sep 17 00:00:00 2001 From: Fabien Dessenne Date: Mon, 27 Jun 2022 16:23:50 +0200 Subject: [PATCH 112/246] pinctrl: stm32: fix optional IRQ support to gpios To act as an interrupt controller, a gpio bank relies on the "interrupt-parent" of the pin controller. When this optional "interrupt-parent" misses, do not create any IRQ domain. This fixes a "NULL pointer in stm32_gpio_domain_alloc()" kernel crash when the interrupt-parent = property is not declared in the Device Tree. Fixes: 0eb9f683336d ("pinctrl: Add IRQ support to STM32 gpios") Signed-off-by: Fabien Dessenne Link: https://lore.kernel.org/r/20220627142350.742973-1-fabien.dessenne@foss.st.com Signed-off-by: Linus Walleij --- drivers/pinctrl/stm32/pinctrl-stm32.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 57a33fb0f2d7..14bcca73238a 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1338,16 +1338,18 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode bank->secure_control = pctl->match_data->secure_control; spin_lock_init(&bank->lock); - /* create irq hierarchical domain */ - bank->fwnode = fwnode; + if (pctl->domain) { + /* create irq hierarchical domain */ + bank->fwnode = fwnode; - bank->domain = irq_domain_create_hierarchy(pctl->domain, 0, - STM32_GPIO_IRQ_LINE, bank->fwnode, - &stm32_gpio_domain_ops, bank); + bank->domain = irq_domain_create_hierarchy(pctl->domain, 0, STM32_GPIO_IRQ_LINE, + bank->fwnode, &stm32_gpio_domain_ops, + bank); - if (!bank->domain) { - err = -ENODEV; - goto err_clk; + if (!bank->domain) { + err = -ENODEV; + goto err_clk; + } } err = gpiochip_add_data(&bank->gpio_chip, bank); @@ -1510,6 +1512,8 @@ int stm32_pctl_probe(struct platform_device *pdev) pctl->domain = stm32_pctrl_get_irq_domain(pdev); if (IS_ERR(pctl->domain)) return PTR_ERR(pctl->domain); + if (!pctl->domain) + dev_warn(dev, "pinctrl without interrupt support\n"); /* hwspinlock is optional */ hwlock_id = of_hwspin_lock_get_id(pdev->dev.of_node, 0); From d6838ec44b4513280a3f43fcc402e246d543fb53 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 24 Jun 2022 16:13:08 -0700 Subject: [PATCH 113/246] perf offcpu: Fix build failure on old kernels Old kernels have a 'struct task_struct' which contains a "state" field and newer kernels have "__state" instead. While the get_task_state() in the BPF code handles that in some way, it assumed the current kernel has the new definition and it caused a build error on old kernels. We should not assume anything and access them carefully. Do not use 'task struct' directly access it instead using new and old definitions in a row. Fixes: edc41a1099c2d08c ("perf record: Enable off-cpu analysis with BPF") Reported-by: Ian Rogers Signed-off-by: Namhyung Kim Cc: Blake Jones Cc: Hao Luo Cc: Jiri Olsa Cc: Milian Wolff Cc: Peter Zijlstra Cc: Song Liu Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20220624231313.367909-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf_skel/off_cpu.bpf.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/bpf_skel/off_cpu.bpf.c b/tools/perf/util/bpf_skel/off_cpu.bpf.c index 792ae2847080..cc6d7fd55118 100644 --- a/tools/perf/util/bpf_skel/off_cpu.bpf.c +++ b/tools/perf/util/bpf_skel/off_cpu.bpf.c @@ -71,6 +71,11 @@ struct { __uint(max_entries, 1); } cgroup_filter SEC(".maps"); +/* new kernel task_struct definition */ +struct task_struct___new { + long __state; +} __attribute__((preserve_access_index)); + /* old kernel task_struct definition */ struct task_struct___old { long state; @@ -93,14 +98,17 @@ const volatile bool uses_cgroup_v1 = false; */ static inline int get_task_state(struct task_struct *t) { - if (bpf_core_field_exists(t->__state)) - return BPF_CORE_READ(t, __state); + /* recast pointer to capture new type for compiler */ + struct task_struct___new *t_new = (void *)t; - /* recast pointer to capture task_struct___old type for compiler */ - struct task_struct___old *t_old = (void *)t; + if (bpf_core_field_exists(t_new->__state)) { + return BPF_CORE_READ(t_new, __state); + } else { + /* recast pointer to capture old type for compiler */ + struct task_struct___old *t_old = (void *)t; - /* now use old "state" name of the field */ - return BPF_CORE_READ(t_old, state); + return BPF_CORE_READ(t_old, state); + } } static inline __u64 get_cgroup_id(struct task_struct *t) From 49c692b7dfc9b6c06a1dc11359a8780575b16d4a Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 24 Jun 2022 16:13:09 -0700 Subject: [PATCH 114/246] perf offcpu: Accept allowed sample types only As offcpu-time event is synthesized at the end, it could not get the all the sample info. Define OFFCPU_SAMPLE_TYPES for allowed ones and mask out others in evsel__config() to prevent parse errors. Because perf sample parsing assumes a specific ordering with the sample types, setting unsupported one would make it fail to read data like perf record -d/--data. Fixes: edc41a1099c2d08c ("perf record: Enable off-cpu analysis with BPF") Signed-off-by: Namhyung Kim Cc: Blake Jones Cc: Hao Luo Cc: Ian Rogers Cc: Jiri Olsa Cc: Milian Wolff Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Song Liu Cc: bpf@vger.kernel.org Link: http://lore.kernel.org/lkml/20220624231313.367909-3-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf_off_cpu.c | 7 ++++++- tools/perf/util/evsel.c | 9 +++++++++ tools/perf/util/off_cpu.h | 9 +++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/bpf_off_cpu.c b/tools/perf/util/bpf_off_cpu.c index b73e84a02264..f289b7713598 100644 --- a/tools/perf/util/bpf_off_cpu.c +++ b/tools/perf/util/bpf_off_cpu.c @@ -265,6 +265,12 @@ int off_cpu_write(struct perf_session *session) sample_type = evsel->core.attr.sample_type; + if (sample_type & ~OFFCPU_SAMPLE_TYPES) { + pr_err("not supported sample type: %llx\n", + (unsigned long long)sample_type); + return -1; + } + if (sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER)) { if (evsel->core.id) sid = evsel->core.id[0]; @@ -319,7 +325,6 @@ int off_cpu_write(struct perf_session *session) } if (sample_type & PERF_SAMPLE_CGROUP) data.array[n++] = key.cgroup_id; - /* TODO: handle more sample types */ size = n * sizeof(u64); data.hdr.size = size; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index ce499c5da8d7..094b0a9c0bc0 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -48,6 +48,7 @@ #include "util.h" #include "hashmap.h" #include "pmu-hybrid.h" +#include "off_cpu.h" #include "../perf-sys.h" #include "util/parse-branch-options.h" #include @@ -1102,6 +1103,11 @@ static void evsel__set_default_freq_period(struct record_opts *opts, } } +static bool evsel__is_offcpu_event(struct evsel *evsel) +{ + return evsel__is_bpf_output(evsel) && !strcmp(evsel->name, OFFCPU_EVENT); +} + /* * The enable_on_exec/disabled value strategy: * @@ -1366,6 +1372,9 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts, */ if (evsel__is_dummy_event(evsel)) evsel__reset_sample_bit(evsel, BRANCH_STACK); + + if (evsel__is_offcpu_event(evsel)) + evsel->core.attr.sample_type &= OFFCPU_SAMPLE_TYPES; } int evsel__set_filter(struct evsel *evsel, const char *filter) diff --git a/tools/perf/util/off_cpu.h b/tools/perf/util/off_cpu.h index 548008f74d42..2dd67c60f211 100644 --- a/tools/perf/util/off_cpu.h +++ b/tools/perf/util/off_cpu.h @@ -1,6 +1,8 @@ #ifndef PERF_UTIL_OFF_CPU_H #define PERF_UTIL_OFF_CPU_H +#include + struct evlist; struct target; struct perf_session; @@ -8,6 +10,13 @@ struct record_opts; #define OFFCPU_EVENT "offcpu-time" +#define OFFCPU_SAMPLE_TYPES (PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_IP | \ + PERF_SAMPLE_TID | PERF_SAMPLE_TIME | \ + PERF_SAMPLE_ID | PERF_SAMPLE_CPU | \ + PERF_SAMPLE_PERIOD | PERF_SAMPLE_CALLCHAIN | \ + PERF_SAMPLE_CGROUP) + + #ifdef HAVE_BPF_SKEL int off_cpu_prepare(struct evlist *evlist, struct target *target, struct record_opts *opts); From 117c49505b5918388157321c68c6e5a58b67f649 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 21 Dec 2020 12:53:44 -0300 Subject: [PATCH 115/246] tools kvm headers arm64: Update KVM headers from the kernel sources To pick the changes from: 2cde51f1e10f2600 ("KVM: arm64: Hide KVM_REG_ARM_*_BMAP_BIT_COUNT from userspace") b22216e1a617ca55 ("KVM: arm64: Add vendor hypervisor firmware register") 428fd6788d4d0e0d ("KVM: arm64: Add standard hypervisor firmware register") 05714cab7d63b189 ("KVM: arm64: Setup a framework for hypercall bitmap firmware registers") 18f3976fdb5da2ba ("KVM: arm64: uapi: Add kvm_debug_exit_arch.hsr_high") a5905d6af492ee6a ("KVM: arm64: Allow SMCCC_ARCH_WORKAROUND_3 to be discovered and migrated") That don't causes any changes in tooling (when built on x86), 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: Alexandru Elisei Cc: Catalin Marinas Cc: Ian Rogers Cc: James Morse Cc: Jiri Olsa Cc: Marc Zyngier Cc: Namhyung Kim Cc: Raghavendra Rao Ananta Link: https://lore.kernel.org/lkml/YrsWcDQyJC+xsfmm@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/arch/arm64/include/uapi/asm/kvm.h | 36 +++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tools/arch/arm64/include/uapi/asm/kvm.h b/tools/arch/arm64/include/uapi/asm/kvm.h index c1b6ddc02d2f..3bb134355874 100644 --- a/tools/arch/arm64/include/uapi/asm/kvm.h +++ b/tools/arch/arm64/include/uapi/asm/kvm.h @@ -139,8 +139,10 @@ struct kvm_guest_debug_arch { __u64 dbg_wvr[KVM_ARM_MAX_DBG_REGS]; }; +#define KVM_DEBUG_ARCH_HSR_HIGH_VALID (1 << 0) struct kvm_debug_exit_arch { __u32 hsr; + __u32 hsr_high; /* ESR_EL2[61:32] */ __u64 far; /* used for watchpoints */ }; @@ -332,6 +334,40 @@ struct kvm_arm_copy_mte_tags { #define KVM_ARM64_SVE_VLS_WORDS \ ((KVM_ARM64_SVE_VQ_MAX - KVM_ARM64_SVE_VQ_MIN) / 64 + 1) +/* Bitmap feature firmware registers */ +#define KVM_REG_ARM_FW_FEAT_BMAP (0x0016 << KVM_REG_ARM_COPROC_SHIFT) +#define KVM_REG_ARM_FW_FEAT_BMAP_REG(r) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \ + KVM_REG_ARM_FW_FEAT_BMAP | \ + ((r) & 0xffff)) + +#define KVM_REG_ARM_STD_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(0) + +enum { + KVM_REG_ARM_STD_BIT_TRNG_V1_0 = 0, +#ifdef __KERNEL__ + KVM_REG_ARM_STD_BMAP_BIT_COUNT, +#endif +}; + +#define KVM_REG_ARM_STD_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(1) + +enum { + KVM_REG_ARM_STD_HYP_BIT_PV_TIME = 0, +#ifdef __KERNEL__ + KVM_REG_ARM_STD_HYP_BMAP_BIT_COUNT, +#endif +}; + +#define KVM_REG_ARM_VENDOR_HYP_BMAP KVM_REG_ARM_FW_FEAT_BMAP_REG(2) + +enum { + KVM_REG_ARM_VENDOR_HYP_BIT_FUNC_FEAT = 0, + KVM_REG_ARM_VENDOR_HYP_BIT_PTP = 1, +#ifdef __KERNEL__ + KVM_REG_ARM_VENDOR_HYP_BMAP_BIT_COUNT, +#endif +}; + /* Device Control API: ARM VGIC */ #define KVM_DEV_ARM_VGIC_GRP_ADDR 0 #define KVM_DEV_ARM_VGIC_GRP_DIST_REGS 1 From 579d6c6d77a7b55d74db8a506d5fc0c77fb1a5e1 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Mon, 13 Jun 2022 18:47:14 -0700 Subject: [PATCH 116/246] perf bpf: 8 byte align bpil data bpil data is accessed assuming 64-bit alignment resulting in undefined behavior as the data is just byte aligned. With an -fsanitize=undefined build the following errors are observed: $ sudo perf record -a sleep 1 util/bpf-event.c:310:22: runtime error: load of misaligned address 0x55f61084520f for type '__u64', which requires 8 byte alignment 0x55f61084520f: note: pointer points here a8 fe ff ff 3c 51 d3 c0 ff ff ff ff 04 84 d3 c0 ff ff ff ff d8 aa d3 c0 ff ff ff ff a4 c0 d3 c0 ^ util/bpf-event.c:311:20: runtime error: load of misaligned address 0x55f61084522f for type '__u32', which requires 4 byte alignment 0x55f61084522f: note: pointer points here ff ff ff ff c7 17 00 00 f1 02 00 00 1f 04 00 00 58 04 00 00 00 00 00 00 0f 00 00 00 63 02 00 00 ^ util/bpf-event.c:198:33: runtime error: member access within misaligned address 0x55f61084523f for type 'const struct bpf_func_info', which requires 4 byte alignment 0x55f61084523f: note: pointer points here 58 04 00 00 00 00 00 00 0f 00 00 00 63 02 00 00 3b 00 00 00 ab 02 00 00 44 00 00 00 14 03 00 00 Correct this by rouding up the data sizes and aligning the pointers. Signed-off-by: Ian Rogers Acked-by: Andrii Nakryiko Cc: Alexander Shishkin Cc: Alexei Starovoitov Cc: Daniel Borkmann Cc: Dave Marchevsky Cc: Ingo Molnar Cc: Jiri Olsa Cc: John Fastabend Cc: KP Singh Cc: Mark Rutland Cc: Martin KaFai Lau Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Quentin Monnet Cc: Song Liu Cc: Stephane Eranian Cc: Yonghong Song Cc: bpf@vger.kernel.org Cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20220614014714.1407239-1-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/bpf-utils.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/perf/util/bpf-utils.c b/tools/perf/util/bpf-utils.c index e271e05e51bc..80b1d2b3729b 100644 --- a/tools/perf/util/bpf-utils.c +++ b/tools/perf/util/bpf-utils.c @@ -149,11 +149,10 @@ get_bpf_prog_info_linear(int fd, __u64 arrays) count = bpf_prog_info_read_offset_u32(&info, desc->count_offset); size = bpf_prog_info_read_offset_u32(&info, desc->size_offset); - data_len += count * size; + data_len += roundup(count * size, sizeof(__u64)); } /* step 3: allocate continuous memory */ - data_len = roundup(data_len, sizeof(__u64)); info_linear = malloc(sizeof(struct perf_bpil) + data_len); if (!info_linear) return ERR_PTR(-ENOMEM); @@ -180,7 +179,7 @@ get_bpf_prog_info_linear(int fd, __u64 arrays) bpf_prog_info_set_offset_u64(&info_linear->info, desc->array_offset, ptr_to_u64(ptr)); - ptr += count * size; + ptr += roundup(count * size, sizeof(__u64)); } /* step 5: call syscall again to get required arrays */ From 32df6fe110c443763d6749a758f33a7117ec1270 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Mon, 27 Jun 2022 20:22:55 +0200 Subject: [PATCH 117/246] bpf, docs: Better scale maintenance of BPF subsystem The BPF subsystem consists of a large number of pieces. There is not a single person that understands it all. Yet reviews are crucially important for the BPF community to provide productive quality feedback to contributors in a timely manner and therefore to ultimately expand the number of active developers in the community. So far, the BPF community had a two-stage review system, that is, a weekly rotation among 7 developers (Alexei, Daniel, Andrii, Martin, Song, Yonghong, John) as a first-level review of all inbound patches accompanied by a BPF CI system which runs the in-tree BPF selftests to check for regressions for every new patch, and then, a final check by Alexei, Daniel, Andrii to apply the patches to either bpf or bpf-next trees. This system worked well for the last ~3.5 years, but clearly reaches its limits these days as it does not scale enough. Especially, as we also need to allow enough room for every developer to contribute patches themselves, integrate with their day to day job, and in particular avoid burnout. We want to better scale both horizontally and vertically going forward. On the horizontal scale, we are adding more developers (KP, Stan, Hao, Jiri) to the overall core reviewer team, thus growing to 11 people in total. The weekly rotation for the horizontal oncall reviewer is shortened to 1/2 week (Mo - Wed and Thur - Fri). Instead of just patches, the coverage however extends also generally to triage and reply to mailing list traffic (e.g. RFCs, questions, etc). On the vertical scale, there is clearly a need for deep expertise areas to assign dedicated maintainer/reviewer teams that are responsible for code reviews and help with design of individual building blocks. To some degree we have been doing this implicitly, but the point is to formalize the teams and commitment. There is an overlap between areas and boundaries are intentionally grey. These additional entries provide a guidance on who has to look at the patches. The patch series which span multiple areas will be looked at by multiple people. The vertical review with areas of deep expertise are bundled at the same time with the horizontal side. This patch cleans up a bit the BPF entries, adds mentioned developers to the horizontal scale and creates new sub-entries with teams for developers committing to the above outlined vertical scale. Also, pw.git tools we use for BPF tree maintenance have been updated with a new pw-schedule script to semi-automate vertical oncall review rotation. Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Signed-off-by: Daniel Borkmann Acked-by: Martin KaFai Lau Acked-by: Song Liu Acked-by: Yonghong Song Acked-by: Mykola Lysenko Acked-by: John Fastabend Acked-by: Jiri Olsa Acked-by: KP Singh Acked-by: Stanislav Fomichev Acked-by: Hao Luo Acked-by: Quentin Monnet Link: https://git.kernel.org/pub/scm/linux/kernel/git/dborkman/pw.git Link: https://lore.kernel.org/bpf/5bdc73e7f5a087299589944fa074563cdf2c2c1a.1656353995.git.daniel@iogearbox.net --- MAINTAINERS | 115 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 95 insertions(+), 20 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 15a2341936ea..ade0a42411e4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3614,16 +3614,18 @@ S: Maintained F: Documentation/devicetree/bindings/iio/accel/bosch,bma400.yaml F: drivers/iio/accel/bma400* -BPF (Safe dynamic programs and tools) +BPF [GENERAL] (Safe Dynamic Programs and Tools) M: Alexei Starovoitov M: Daniel Borkmann M: Andrii Nakryiko -R: Martin KaFai Lau -R: Song Liu +R: Martin KaFai Lau +R: Song Liu R: Yonghong Song R: John Fastabend R: KP Singh -L: netdev@vger.kernel.org +R: Stanislav Fomichev +R: Hao Luo +R: Jiri Olsa L: bpf@vger.kernel.org S: Supported W: https://bpf.io/ @@ -3655,12 +3657,9 @@ F: scripts/pahole-version.sh F: tools/bpf/ F: tools/lib/bpf/ F: tools/testing/selftests/bpf/ -N: bpf -K: bpf BPF JIT for ARM M: Shubham Bansal -L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Odd Fixes F: arch/arm/net/ @@ -3669,7 +3668,6 @@ BPF JIT for ARM64 M: Daniel Borkmann M: Alexei Starovoitov M: Zi Shen Lim -L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Supported F: arch/arm64/net/ @@ -3677,14 +3675,12 @@ F: arch/arm64/net/ BPF JIT for MIPS (32-BIT AND 64-BIT) M: Johan Almbladh M: Paul Burton -L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Maintained F: arch/mips/net/ BPF JIT for NFP NICs M: Jakub Kicinski -L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Odd Fixes F: drivers/net/ethernet/netronome/nfp/bpf/ @@ -3692,7 +3688,6 @@ F: drivers/net/ethernet/netronome/nfp/bpf/ BPF JIT for POWERPC (32-BIT AND 64-BIT) M: Naveen N. Rao M: Michael Ellerman -L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Supported F: arch/powerpc/net/ @@ -3700,7 +3695,6 @@ F: arch/powerpc/net/ BPF JIT for RISC-V (32-bit) M: Luke Nelson M: Xi Wang -L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Maintained F: arch/riscv/net/ @@ -3708,7 +3702,6 @@ X: arch/riscv/net/bpf_jit_comp64.c BPF JIT for RISC-V (64-bit) M: Björn Töpel -L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Maintained F: arch/riscv/net/ @@ -3718,7 +3711,6 @@ BPF JIT for S390 M: Ilya Leoshkevich M: Heiko Carstens M: Vasily Gorbik -L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Supported F: arch/s390/net/ @@ -3726,14 +3718,12 @@ X: arch/s390/net/pnet.c BPF JIT for SPARC (32-BIT AND 64-BIT) M: David S. Miller -L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Odd Fixes F: arch/sparc/net/ BPF JIT for X86 32-BIT M: Wang YanQing -L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Odd Fixes F: arch/x86/net/bpf_jit_comp32.c @@ -3741,13 +3731,60 @@ F: arch/x86/net/bpf_jit_comp32.c BPF JIT for X86 64-BIT M: Alexei Starovoitov M: Daniel Borkmann -L: netdev@vger.kernel.org L: bpf@vger.kernel.org S: Supported F: arch/x86/net/ X: arch/x86/net/bpf_jit_comp32.c -BPF LSM (Security Audit and Enforcement using BPF) +BPF [CORE] +M: Alexei Starovoitov +M: Daniel Borkmann +R: John Fastabend +L: bpf@vger.kernel.org +S: Maintained +F: kernel/bpf/verifier.c +F: kernel/bpf/tnum.c +F: kernel/bpf/core.c +F: kernel/bpf/syscall.c +F: kernel/bpf/dispatcher.c +F: kernel/bpf/trampoline.c +F: include/linux/bpf* +F: include/linux/filter.h + +BPF [BTF] +M: Martin KaFai Lau +L: bpf@vger.kernel.org +S: Maintained +F: kernel/bpf/btf.c +F: include/linux/btf* + +BPF [TRACING] +M: Song Liu +R: Jiri Olsa +L: bpf@vger.kernel.org +S: Maintained +F: kernel/trace/bpf_trace.c +F: kernel/bpf/stackmap.c + +BPF [NETWORKING] (tc BPF, sock_addr) +M: Martin KaFai Lau +M: Daniel Borkmann +R: John Fastabend +L: bpf@vger.kernel.org +L: netdev@vger.kernel.org +S: Maintained +F: net/core/filter.c +F: net/sched/act_bpf.c +F: net/sched/cls_bpf.c + +BPF [NETWORKING] (struct_ops, reuseport) +M: Martin KaFai Lau +L: bpf@vger.kernel.org +L: netdev@vger.kernel.org +S: Maintained +F: kernel/bpf/bpf_struct* + +BPF [SECURITY & LSM] (Security Audit and Enforcement using BPF) M: KP Singh R: Florent Revest R: Brendan Jackman @@ -3758,7 +3795,27 @@ F: include/linux/bpf_lsm.h F: kernel/bpf/bpf_lsm.c F: security/bpf/ -BPF L7 FRAMEWORK +BPF [STORAGE & CGROUPS] +M: Martin KaFai Lau +L: bpf@vger.kernel.org +S: Maintained +F: kernel/bpf/cgroup.c +F: kernel/bpf/*storage.c +F: kernel/bpf/bpf_lru* + +BPF [RINGBUF] +M: Andrii Nakryiko +L: bpf@vger.kernel.org +S: Maintained +F: kernel/bpf/ringbuf.c + +BPF [ITERATOR] +M: Yonghong Song +L: bpf@vger.kernel.org +S: Maintained +F: kernel/bpf/*iter.c + +BPF [L7 FRAMEWORK] (sockmap) M: John Fastabend M: Jakub Sitnicki L: netdev@vger.kernel.org @@ -3771,13 +3828,31 @@ F: net/ipv4/tcp_bpf.c F: net/ipv4/udp_bpf.c F: net/unix/unix_bpf.c -BPFTOOL +BPF [LIBRARY] (libbpf) +M: Andrii Nakryiko +L: bpf@vger.kernel.org +S: Maintained +F: tools/lib/bpf/ + +BPF [TOOLING] (bpftool) M: Quentin Monnet L: bpf@vger.kernel.org S: Maintained F: kernel/bpf/disasm.* F: tools/bpf/bpftool/ +BPF [SELFTESTS] (Test Runners & Infrastructure) +M: Andrii Nakryiko +R: Mykola Lysenko +L: bpf@vger.kernel.org +S: Maintained +F: tools/testing/selftests/bpf/ + +BPF [MISC] +L: bpf@vger.kernel.org +S: Odd Fixes +K: (?:\b|_)bpf(?:\b|_) + BROADCOM B44 10/100 ETHERNET DRIVER M: Michael Chan L: netdev@vger.kernel.org From 7fe718fb8f3f543da1f04ca08bf652dd2afb55f8 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 9 May 2021 09:39:02 -0300 Subject: [PATCH 118/246] tools headers UAPI: Sync linux/kvm.h with the kernel sources To pick the changes in: bfbab44568779e16 ("KVM: arm64: Implement PSCI SYSTEM_SUSPEND") 7b33a09d036ffd9a ("KVM: arm64: Add support for userspace to suspend a vCPU") ffbb61d09fc56c85 ("KVM: x86: Accept KVM_[GS]ET_TSC_KHZ as a VM ioctl.") 661a20fab7d156cf ("KVM: x86/xen: Advertise and document KVM_XEN_HVM_CONFIG_EVTCHN_SEND") fde0451be8fb3208 ("KVM: x86/xen: Support per-vCPU event channel upcall via local APIC") 28d1629f751c4a5f ("KVM: x86/xen: Kernel acceleration for XENVER_version") 536395260582be74 ("KVM: x86/xen: handle PV timers oneshot mode") 942c2490c23f2800 ("KVM: x86/xen: Add KVM_XEN_VCPU_ATTR_TYPE_VCPU_ID") 2fd6df2f2b47d430 ("KVM: x86/xen: intercept EVTCHNOP_send from guests") 35025735a79eaa89 ("KVM: x86/xen: Support direct injection of event channel events") That automatically adds support for this new ioctl: $ tools/perf/trace/beauty/kvm_ioctl.sh > before $ cp include/uapi/linux/kvm.h tools/include/uapi/linux/kvm.h $ tools/perf/trace/beauty/kvm_ioctl.sh > after $ diff -u before after --- before 2022-06-28 12:13:07.281150509 -0300 +++ after 2022-06-28 12:13:16.423392896 -0300 @@ -98,6 +98,7 @@ [0xcc] = "GET_SREGS2", [0xcd] = "SET_SREGS2", [0xce] = "GET_STATS_FD", + [0xd0] = "XEN_HVM_EVTCHN_SEND", [0xe0] = "CREATE_DEVICE", [0xe1] = "SET_DEVICE_ATTR", [0xe2] = "GET_DEVICE_ATTR", $ This silences these 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: Joao Martins Cc: Marc Zyngier Cc: Namhyung Kim Cc: Oliver Upton Cc: Paolo Bonzini Link: http://lore.kernel.org/lkml/Yrs4RE+qfgTaWdAt@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/include/uapi/linux/kvm.h | 54 ++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index 6a184d260c7f..5088bd9f1922 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h @@ -444,6 +444,9 @@ struct kvm_run { #define KVM_SYSTEM_EVENT_SHUTDOWN 1 #define KVM_SYSTEM_EVENT_RESET 2 #define KVM_SYSTEM_EVENT_CRASH 3 +#define KVM_SYSTEM_EVENT_WAKEUP 4 +#define KVM_SYSTEM_EVENT_SUSPEND 5 +#define KVM_SYSTEM_EVENT_SEV_TERM 6 __u32 type; __u32 ndata; union { @@ -646,6 +649,7 @@ struct kvm_vapic_addr { #define KVM_MP_STATE_OPERATING 7 #define KVM_MP_STATE_LOAD 8 #define KVM_MP_STATE_AP_RESET_HOLD 9 +#define KVM_MP_STATE_SUSPENDED 10 struct kvm_mp_state { __u32 mp_state; @@ -1150,8 +1154,9 @@ struct kvm_ppc_resize_hpt { #define KVM_CAP_S390_MEM_OP_EXTENSION 211 #define KVM_CAP_PMU_CAPABILITY 212 #define KVM_CAP_DISABLE_QUIRKS2 213 -/* #define KVM_CAP_VM_TSC_CONTROL 214 */ +#define KVM_CAP_VM_TSC_CONTROL 214 #define KVM_CAP_SYSTEM_EVENT_DATA 215 +#define KVM_CAP_ARM_SYSTEM_SUSPEND 216 #ifdef KVM_CAP_IRQ_ROUTING @@ -1240,6 +1245,7 @@ struct kvm_x86_mce { #define KVM_XEN_HVM_CONFIG_SHARED_INFO (1 << 2) #define KVM_XEN_HVM_CONFIG_RUNSTATE (1 << 3) #define KVM_XEN_HVM_CONFIG_EVTCHN_2LEVEL (1 << 4) +#define KVM_XEN_HVM_CONFIG_EVTCHN_SEND (1 << 5) struct kvm_xen_hvm_config { __u32 flags; @@ -1478,7 +1484,8 @@ struct kvm_s390_ucas_mapping { #define KVM_SET_PIT2 _IOW(KVMIO, 0xa0, struct kvm_pit_state2) /* Available with KVM_CAP_PPC_GET_PVINFO */ #define KVM_PPC_GET_PVINFO _IOW(KVMIO, 0xa1, struct kvm_ppc_pvinfo) -/* Available with KVM_CAP_TSC_CONTROL */ +/* Available with KVM_CAP_TSC_CONTROL for a vCPU, or with +* KVM_CAP_VM_TSC_CONTROL to set defaults for a VM */ #define KVM_SET_TSC_KHZ _IO(KVMIO, 0xa2) #define KVM_GET_TSC_KHZ _IO(KVMIO, 0xa3) /* Available with KVM_CAP_PCI_2_3 */ @@ -1694,6 +1701,32 @@ struct kvm_xen_hvm_attr { struct { __u64 gfn; } shared_info; + struct { + __u32 send_port; + __u32 type; /* EVTCHNSTAT_ipi / EVTCHNSTAT_interdomain */ + __u32 flags; +#define KVM_XEN_EVTCHN_DEASSIGN (1 << 0) +#define KVM_XEN_EVTCHN_UPDATE (1 << 1) +#define KVM_XEN_EVTCHN_RESET (1 << 2) + /* + * Events sent by the guest are either looped back to + * the guest itself (potentially on a different port#) + * or signalled via an eventfd. + */ + union { + struct { + __u32 port; + __u32 vcpu; + __u32 priority; + } port; + struct { + __u32 port; /* Zero for eventfd */ + __s32 fd; + } eventfd; + __u32 padding[4]; + } deliver; + } evtchn; + __u32 xen_version; __u64 pad[8]; } u; }; @@ -1702,11 +1735,17 @@ struct kvm_xen_hvm_attr { #define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0 #define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1 #define KVM_XEN_ATTR_TYPE_UPCALL_VECTOR 0x2 +/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */ +#define KVM_XEN_ATTR_TYPE_EVTCHN 0x3 +#define KVM_XEN_ATTR_TYPE_XEN_VERSION 0x4 /* Per-vCPU Xen attributes */ #define KVM_XEN_VCPU_GET_ATTR _IOWR(KVMIO, 0xca, struct kvm_xen_vcpu_attr) #define KVM_XEN_VCPU_SET_ATTR _IOW(KVMIO, 0xcb, struct kvm_xen_vcpu_attr) +/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */ +#define KVM_XEN_HVM_EVTCHN_SEND _IOW(KVMIO, 0xd0, struct kvm_irq_routing_xen_evtchn) + #define KVM_GET_SREGS2 _IOR(KVMIO, 0xcc, struct kvm_sregs2) #define KVM_SET_SREGS2 _IOW(KVMIO, 0xcd, struct kvm_sregs2) @@ -1724,6 +1763,13 @@ struct kvm_xen_vcpu_attr { __u64 time_blocked; __u64 time_offline; } runstate; + __u32 vcpu_id; + struct { + __u32 port; + __u32 priority; + __u64 expires_ns; + } timer; + __u8 vector; } u; }; @@ -1734,6 +1780,10 @@ struct kvm_xen_vcpu_attr { #define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT 0x3 #define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_DATA 0x4 #define KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADJUST 0x5 +/* Available with KVM_CAP_XEN_HVM / KVM_XEN_HVM_CONFIG_EVTCHN_SEND */ +#define KVM_XEN_VCPU_ATTR_TYPE_VCPU_ID 0x6 +#define KVM_XEN_VCPU_ATTR_TYPE_TIMER 0x7 +#define KVM_XEN_VCPU_ATTR_TYPE_UPCALL_VECTOR 0x8 /* Secure Encrypted Virtualization command */ enum sev_cmd_id { From 512d1999b8e94a5d43fba3afc73e774849674742 Mon Sep 17 00:00:00 2001 From: Ivan Malov Date: Tue, 28 Jun 2022 12:18:48 +0300 Subject: [PATCH 119/246] xsk: Clear page contiguity bit when unmapping pool When a XSK pool gets mapped, xp_check_dma_contiguity() adds bit 0x1 to pages' DMA addresses that go in ascending order and at 4K stride. The problem is that the bit does not get cleared before doing unmap. As a result, a lot of warnings from iommu_dma_unmap_page() are seen in dmesg, which indicates that lookups by iommu_iova_to_phys() fail. Fixes: 2b43470add8c ("xsk: Introduce AF_XDP buffer allocation API") Signed-off-by: Ivan Malov Signed-off-by: Daniel Borkmann Acked-by: Magnus Karlsson Link: https://lore.kernel.org/bpf/20220628091848.534803-1-ivan.malov@oktetlabs.ru --- net/xdp/xsk_buff_pool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c index 87bdd71c7bb6..f70112176b7c 100644 --- a/net/xdp/xsk_buff_pool.c +++ b/net/xdp/xsk_buff_pool.c @@ -332,6 +332,7 @@ static void __xp_dma_unmap(struct xsk_dma_map *dma_map, unsigned long attrs) for (i = 0; i < dma_map->dma_pages_cnt; i++) { dma = &dma_map->dma_pages[i]; if (*dma) { + *dma &= ~XSK_NEXT_PG_CONTIG_MASK; dma_unmap_page_attrs(dma_map->dev, *dma, PAGE_SIZE, DMA_BIDIRECTIONAL, attrs); *dma = 0; From 9e121040e54abef9ed5542e5fdfa87911cd96204 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 7 Jun 2022 20:23:34 +0200 Subject: [PATCH 120/246] firmware: sysfb: Make sysfb_create_simplefb() return a pdev pointer This function just returned 0 on success or an errno code on error, but it could be useful for sysfb_init() callers to have a pointer to the device. Signed-off-by: Javier Martinez Canillas Reviewed-by: Daniel Vetter Reviewed-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20220607182338.344270-2-javierm@redhat.com --- drivers/firmware/sysfb.c | 4 ++-- drivers/firmware/sysfb_simplefb.c | 16 ++++++++-------- include/linux/sysfb.h | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c index 2bfbb05f7d89..b032f40a92de 100644 --- a/drivers/firmware/sysfb.c +++ b/drivers/firmware/sysfb.c @@ -46,8 +46,8 @@ static __init int sysfb_init(void) /* try to create a simple-framebuffer device */ compatible = sysfb_parse_mode(si, &mode); if (compatible) { - ret = sysfb_create_simplefb(si, &mode); - if (!ret) + pd = sysfb_create_simplefb(si, &mode); + if (!IS_ERR(pd)) return 0; } diff --git a/drivers/firmware/sysfb_simplefb.c b/drivers/firmware/sysfb_simplefb.c index bda8712bfd8c..a353e27f83f5 100644 --- a/drivers/firmware/sysfb_simplefb.c +++ b/drivers/firmware/sysfb_simplefb.c @@ -57,8 +57,8 @@ __init bool sysfb_parse_mode(const struct screen_info *si, return false; } -__init int sysfb_create_simplefb(const struct screen_info *si, - const struct simplefb_platform_data *mode) +__init struct platform_device *sysfb_create_simplefb(const struct screen_info *si, + const struct simplefb_platform_data *mode) { struct platform_device *pd; struct resource res; @@ -76,7 +76,7 @@ __init int sysfb_create_simplefb(const struct screen_info *si, base |= (u64)si->ext_lfb_base << 32; if (!base || (u64)(resource_size_t)base != base) { printk(KERN_DEBUG "sysfb: inaccessible VRAM base\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } /* @@ -93,7 +93,7 @@ __init int sysfb_create_simplefb(const struct screen_info *si, length = mode->height * mode->stride; if (length > size) { printk(KERN_WARNING "sysfb: VRAM smaller than advertised\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } length = PAGE_ALIGN(length); @@ -104,11 +104,11 @@ __init int sysfb_create_simplefb(const struct screen_info *si, res.start = base; res.end = res.start + length - 1; if (res.end <= res.start) - return -EINVAL; + return ERR_PTR(-EINVAL); pd = platform_device_alloc("simple-framebuffer", 0); if (!pd) - return -ENOMEM; + return ERR_PTR(-ENOMEM); sysfb_apply_efi_quirks(pd); @@ -124,10 +124,10 @@ __init int sysfb_create_simplefb(const struct screen_info *si, if (ret) goto err_put_device; - return 0; + return pd; err_put_device: platform_device_put(pd); - return ret; + return ERR_PTR(ret); } diff --git a/include/linux/sysfb.h b/include/linux/sysfb.h index b0dcfa26d07b..708152e9037b 100644 --- a/include/linux/sysfb.h +++ b/include/linux/sysfb.h @@ -72,8 +72,8 @@ static inline void sysfb_apply_efi_quirks(struct platform_device *pd) bool sysfb_parse_mode(const struct screen_info *si, struct simplefb_platform_data *mode); -int sysfb_create_simplefb(const struct screen_info *si, - const struct simplefb_platform_data *mode); +struct platform_device *sysfb_create_simplefb(const struct screen_info *si, + const struct simplefb_platform_data *mode); #else /* CONFIG_SYSFB_SIMPLE */ @@ -83,10 +83,10 @@ static inline bool sysfb_parse_mode(const struct screen_info *si, return false; } -static inline int sysfb_create_simplefb(const struct screen_info *si, - const struct simplefb_platform_data *mode) +static inline struct platform_device *sysfb_create_simplefb(const struct screen_info *si, + const struct simplefb_platform_data *mode) { - return -EINVAL; + return ERR_PTR(-EINVAL); } #endif /* CONFIG_SYSFB_SIMPLE */ From bde376e9de3c0bc55eedc8956b0f114c05531595 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 7 Jun 2022 20:23:35 +0200 Subject: [PATCH 121/246] firmware: sysfb: Add sysfb_disable() helper function This can be used by subsystems to unregister a platform device registered by sysfb and also to disable future platform device registration in sysfb. Suggested-by: Daniel Vetter Signed-off-by: Javier Martinez Canillas Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20220607182338.344270-3-javierm@redhat.com --- .../driver-api/firmware/other_interfaces.rst | 6 +++ drivers/firmware/sysfb.c | 54 ++++++++++++++++--- include/linux/sysfb.h | 12 +++++ 3 files changed, 66 insertions(+), 6 deletions(-) diff --git a/Documentation/driver-api/firmware/other_interfaces.rst b/Documentation/driver-api/firmware/other_interfaces.rst index b81794e0cfbb..06ac89adaafb 100644 --- a/Documentation/driver-api/firmware/other_interfaces.rst +++ b/Documentation/driver-api/firmware/other_interfaces.rst @@ -13,6 +13,12 @@ EDD Interfaces .. kernel-doc:: drivers/firmware/edd.c :internal: +Generic System Framebuffers Interface +------------------------------------- + +.. kernel-doc:: drivers/firmware/sysfb.c + :export: + Intel Stratix10 SoC Service Layer --------------------------------- Some features of the Intel Stratix10 SoC require a level of privilege diff --git a/drivers/firmware/sysfb.c b/drivers/firmware/sysfb.c index b032f40a92de..1f276f108cc9 100644 --- a/drivers/firmware/sysfb.c +++ b/drivers/firmware/sysfb.c @@ -34,21 +34,59 @@ #include #include +static struct platform_device *pd; +static DEFINE_MUTEX(disable_lock); +static bool disabled; + +static bool sysfb_unregister(void) +{ + if (IS_ERR_OR_NULL(pd)) + return false; + + platform_device_unregister(pd); + pd = NULL; + + return true; +} + +/** + * sysfb_disable() - disable the Generic System Framebuffers support + * + * This disables the registration of system framebuffer devices that match the + * generic drivers that make use of the system framebuffer set up by firmware. + * + * It also unregisters a device if this was already registered by sysfb_init(). + * + * Context: The function can sleep. A @disable_lock mutex is acquired to serialize + * against sysfb_init(), that registers a system framebuffer device. + */ +void sysfb_disable(void) +{ + mutex_lock(&disable_lock); + sysfb_unregister(); + disabled = true; + mutex_unlock(&disable_lock); +} +EXPORT_SYMBOL_GPL(sysfb_disable); + static __init int sysfb_init(void) { struct screen_info *si = &screen_info; struct simplefb_platform_data mode; - struct platform_device *pd; const char *name; bool compatible; - int ret; + int ret = 0; + + mutex_lock(&disable_lock); + if (disabled) + goto unlock_mutex; /* try to create a simple-framebuffer device */ compatible = sysfb_parse_mode(si, &mode); if (compatible) { pd = sysfb_create_simplefb(si, &mode); if (!IS_ERR(pd)) - return 0; + goto unlock_mutex; } /* if the FB is incompatible, create a legacy framebuffer device */ @@ -60,8 +98,10 @@ static __init int sysfb_init(void) name = "platform-framebuffer"; pd = platform_device_alloc(name, 0); - if (!pd) - return -ENOMEM; + if (!pd) { + ret = -ENOMEM; + goto unlock_mutex; + } sysfb_apply_efi_quirks(pd); @@ -73,9 +113,11 @@ static __init int sysfb_init(void) if (ret) goto err; - return 0; + goto unlock_mutex; err: platform_device_put(pd); +unlock_mutex: + mutex_unlock(&disable_lock); return ret; } diff --git a/include/linux/sysfb.h b/include/linux/sysfb.h index 708152e9037b..8ba8b5be5567 100644 --- a/include/linux/sysfb.h +++ b/include/linux/sysfb.h @@ -55,6 +55,18 @@ struct efifb_dmi_info { int flags; }; +#ifdef CONFIG_SYSFB + +void sysfb_disable(void); + +#else /* CONFIG_SYSFB */ + +static inline void sysfb_disable(void) +{ +} + +#endif /* CONFIG_SYSFB */ + #ifdef CONFIG_EFI extern struct efifb_dmi_info efifb_dmi_list[]; From ee7a69aa38d87a3bbced7b8245c732c05ed0c6ec Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 7 Jun 2022 20:23:36 +0200 Subject: [PATCH 122/246] fbdev: Disable sysfb device registration when removing conflicting FBs The platform devices registered by sysfb match with firmware-based DRM or fbdev drivers, that are used to have early graphics using a framebuffer provided by the system firmware. DRM or fbdev drivers later are probed and remove conflicting framebuffers, leading to these platform devices for generic drivers to be unregistered. But the current solution has a race, since the sysfb_init() function could be called after a DRM or fbdev driver is probed and request to unregister the devices for drivers with conflicting framebuffes. To prevent this, disable any future sysfb platform device registration by calling sysfb_disable(), if a driver requests to remove the conflicting framebuffers. Suggested-by: Daniel Vetter Signed-off-by: Javier Martinez Canillas Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20220607182338.344270-4-javierm@redhat.com --- drivers/video/fbdev/core/fbmem.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index afa2863670f3..8afc4538558c 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -1752,6 +1753,17 @@ int remove_conflicting_framebuffers(struct apertures_struct *a, do_free = true; } + /* + * If a driver asked to unregister a platform device registered by + * sysfb, then can be assumed that this is a driver for a display + * that is set up by the system firmware and has a generic driver. + * + * Drivers for devices that don't have a generic driver will never + * ask for this, so let's assume that a real driver for the display + * was already probed and prevent sysfb to register devices later. + */ + sysfb_disable(); + mutex_lock(®istration_lock); do_remove_conflicting_framebuffers(a, name, primary); mutex_unlock(®istration_lock); From b21bd5a4b130f8370861478d2880985daace5913 Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Tue, 28 Jun 2022 00:41:19 +0530 Subject: [PATCH 123/246] powerpc/bpf: Fix use of user_pt_regs in uapi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trying to build a .c file that includes : $ cat test_bpf_headers.c #include throws the below error: /usr/include/linux/bpf_perf_event.h:14:28: error: field ‘regs’ has incomplete type 14 | bpf_user_pt_regs_t regs; | ^~~~ This is because we typedef bpf_user_pt_regs_t to 'struct user_pt_regs' in arch/powerpc/include/uaps/asm/bpf_perf_event.h, but 'struct user_pt_regs' is not exposed to userspace. Powerpc has both pt_regs and user_pt_regs structures. However, unlike arm64 and s390, we expose user_pt_regs to userspace as just 'pt_regs'. As such, we should typedef bpf_user_pt_regs_t to 'struct pt_regs' for userspace. Within the kernel though, we want to typedef bpf_user_pt_regs_t to 'struct user_pt_regs'. Remove arch/powerpc/include/uapi/asm/bpf_perf_event.h so that the uapi/asm-generic version of the header is exposed to userspace. Introduce arch/powerpc/include/asm/bpf_perf_event.h so that we can typedef bpf_user_pt_regs_t to 'struct user_pt_regs' for use within the kernel. Note that this was not showing up with the bpf selftest build since tools/include/uapi/asm/bpf_perf_event.h didn't include the powerpc variant. Fixes: a6460b03f945ee ("powerpc/bpf: Fix broken uapi for BPF_PROG_TYPE_PERF_EVENT") Cc: stable@vger.kernel.org # v4.20+ Signed-off-by: Naveen N. Rao [mpe: Use typical naming for header include guard] Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220627191119.142867-1-naveen.n.rao@linux.vnet.ibm.com --- arch/powerpc/include/asm/bpf_perf_event.h | 9 +++++++++ arch/powerpc/include/uapi/asm/bpf_perf_event.h | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 arch/powerpc/include/asm/bpf_perf_event.h delete mode 100644 arch/powerpc/include/uapi/asm/bpf_perf_event.h diff --git a/arch/powerpc/include/asm/bpf_perf_event.h b/arch/powerpc/include/asm/bpf_perf_event.h new file mode 100644 index 000000000000..e8a7b4ffb58c --- /dev/null +++ b/arch/powerpc/include/asm/bpf_perf_event.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_POWERPC_BPF_PERF_EVENT_H +#define _ASM_POWERPC_BPF_PERF_EVENT_H + +#include + +typedef struct user_pt_regs bpf_user_pt_regs_t; + +#endif /* _ASM_POWERPC_BPF_PERF_EVENT_H */ diff --git a/arch/powerpc/include/uapi/asm/bpf_perf_event.h b/arch/powerpc/include/uapi/asm/bpf_perf_event.h deleted file mode 100644 index 5e1e648aeec4..000000000000 --- a/arch/powerpc/include/uapi/asm/bpf_perf_event.h +++ /dev/null @@ -1,9 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#ifndef _UAPI__ASM_BPF_PERF_EVENT_H__ -#define _UAPI__ASM_BPF_PERF_EVENT_H__ - -#include - -typedef struct user_pt_regs bpf_user_pt_regs_t; - -#endif /* _UAPI__ASM_BPF_PERF_EVENT_H__ */ From ac790d09885d36143076e7e02825c541e8eee899 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Wed, 29 Jun 2022 10:39:25 +0530 Subject: [PATCH 124/246] powerpc/memhotplug: Add add_pages override for PPC With commit ffa0b64e3be5 ("powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit") the kernel now validate the addr against high_memory value. This results in the below BUG_ON with dax pfns. [ 635.798741][T26531] kernel BUG at mm/page_alloc.c:5521! 1:mon> e cpu 0x1: Vector: 700 (Program Check) at [c000000007287630] pc: c00000000055ed48: free_pages.part.0+0x48/0x110 lr: c00000000053ca70: tlb_finish_mmu+0x80/0xd0 sp: c0000000072878d0 msr: 800000000282b033 current = 0xc00000000afabe00 paca = 0xc00000037ffff300 irqmask: 0x03 irq_happened: 0x05 pid = 26531, comm = 50-landscape-sy kernel BUG at :5521! Linux version 5.19.0-rc3-14659-g4ec05be7c2e1 (kvaneesh@ltc-boston8) (gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #625 SMP Thu Jun 23 00:35:43 CDT 2022 1:mon> t [link register ] c00000000053ca70 tlb_finish_mmu+0x80/0xd0 [c0000000072878d0] c00000000053ca54 tlb_finish_mmu+0x64/0xd0 (unreliable) [c000000007287900] c000000000539424 exit_mmap+0xe4/0x2a0 [c0000000072879e0] c00000000019fc1c mmput+0xcc/0x210 [c000000007287a20] c000000000629230 begin_new_exec+0x5e0/0xf40 [c000000007287ae0] c00000000070b3cc load_elf_binary+0x3ac/0x1e00 [c000000007287c10] c000000000627af0 bprm_execve+0x3b0/0xaf0 [c000000007287cd0] c000000000628414 do_execveat_common.isra.0+0x1e4/0x310 [c000000007287d80] c00000000062858c sys_execve+0x4c/0x60 [c000000007287db0] c00000000002c1b0 system_call_exception+0x160/0x2c0 [c000000007287e10] c00000000000c53c system_call_common+0xec/0x250 The fix is to make sure we update high_memory on memory hotplug. This is similar to what x86 does in commit 3072e413e305 ("mm/memory_hotplug: introduce add_pages") Fixes: ffa0b64e3be5 ("powerpc: Fix virt_addr_valid() for 64-bit Book3E & 32-bit") Signed-off-by: Aneesh Kumar K.V Reviewed-by: Kefeng Wang Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20220629050925.31447-1-aneesh.kumar@linux.ibm.com --- arch/powerpc/Kconfig | 4 ++++ arch/powerpc/mm/mem.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index c2ce2e60c8f0..7aa12e88c580 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -358,6 +358,10 @@ config ARCH_SUSPEND_NONZERO_CPU def_bool y depends on PPC_POWERNV || PPC_PSERIES +config ARCH_HAS_ADD_PAGES + def_bool y + depends on ARCH_ENABLE_MEMORY_HOTPLUG + config PPC_DCR_NATIVE bool diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 52b77684acda..a97128a48817 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -105,6 +105,37 @@ void __ref arch_remove_linear_mapping(u64 start, u64 size) vm_unmap_aliases(); } +/* + * After memory hotplug the variables max_pfn, max_low_pfn and high_memory need + * updating. + */ +static void update_end_of_memory_vars(u64 start, u64 size) +{ + unsigned long end_pfn = PFN_UP(start + size); + + if (end_pfn > max_pfn) { + max_pfn = end_pfn; + max_low_pfn = end_pfn; + high_memory = (void *)__va(max_pfn * PAGE_SIZE - 1) + 1; + } +} + +int __ref add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages, + struct mhp_params *params) +{ + int ret; + + ret = __add_pages(nid, start_pfn, nr_pages, params); + if (ret) + return ret; + + /* update max_pfn, max_low_pfn and high_memory */ + update_end_of_memory_vars(start_pfn << PAGE_SHIFT, + nr_pages << PAGE_SHIFT); + + return ret; +} + int __ref arch_add_memory(int nid, u64 start, u64 size, struct mhp_params *params) { @@ -115,7 +146,7 @@ int __ref arch_add_memory(int nid, u64 start, u64 size, rc = arch_create_linear_mapping(nid, start, size, params); if (rc) return rc; - rc = __add_pages(nid, start_pfn, nr_pages, params); + rc = add_pages(nid, start_pfn, nr_pages, params); if (rc) arch_remove_linear_mapping(start, size); return rc; From ed0691cf55140ce0f3fb100225645d902cce904b Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Fri, 24 Jun 2022 00:49:53 +0300 Subject: [PATCH 125/246] nvmet-tcp: fix regression in data_digest calculation Data digest calculation iterates over command mapped iovec. However since commit bac04454ef9f we unmap the iovec before we handle the data digest, and since commit 69b85e1f1d1d we clear nr_mapped when we unmap the iov. Instead of open-coding the command iov traversal, simply call crypto_ahash_digest with the command sg that is already allocated (we already do that for the send path). Rename nvmet_tcp_send_ddgst to nvmet_tcp_calc_ddgst and call it from send and recv paths. Fixes: 69b85e1f1d1d ("nvmet-tcp: add an helper to free the cmd buffers") Fixes: bac04454ef9f ("nvmet-tcp: fix kmap leak when data digest in use") Signed-off-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/nvme/target/tcp.c | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index 2793554e622e..0a9542599ad1 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -405,7 +405,7 @@ err: return NVME_SC_INTERNAL; } -static void nvmet_tcp_send_ddgst(struct ahash_request *hash, +static void nvmet_tcp_calc_ddgst(struct ahash_request *hash, struct nvmet_tcp_cmd *cmd) { ahash_request_set_crypt(hash, cmd->req.sg, @@ -413,23 +413,6 @@ static void nvmet_tcp_send_ddgst(struct ahash_request *hash, crypto_ahash_digest(hash); } -static void nvmet_tcp_recv_ddgst(struct ahash_request *hash, - struct nvmet_tcp_cmd *cmd) -{ - struct scatterlist sg; - struct kvec *iov; - int i; - - crypto_ahash_init(hash); - for (i = 0, iov = cmd->iov; i < cmd->nr_mapped; i++, iov++) { - sg_init_one(&sg, iov->iov_base, iov->iov_len); - ahash_request_set_crypt(hash, &sg, NULL, iov->iov_len); - crypto_ahash_update(hash); - } - ahash_request_set_crypt(hash, NULL, (void *)&cmd->exp_ddgst, 0); - crypto_ahash_final(hash); -} - static void nvmet_setup_c2h_data_pdu(struct nvmet_tcp_cmd *cmd) { struct nvme_tcp_data_pdu *pdu = cmd->data_pdu; @@ -454,7 +437,7 @@ static void nvmet_setup_c2h_data_pdu(struct nvmet_tcp_cmd *cmd) if (queue->data_digest) { pdu->hdr.flags |= NVME_TCP_F_DDGST; - nvmet_tcp_send_ddgst(queue->snd_hash, cmd); + nvmet_tcp_calc_ddgst(queue->snd_hash, cmd); } if (cmd->queue->hdr_digest) { @@ -1137,7 +1120,7 @@ static void nvmet_tcp_prep_recv_ddgst(struct nvmet_tcp_cmd *cmd) { struct nvmet_tcp_queue *queue = cmd->queue; - nvmet_tcp_recv_ddgst(queue->rcv_hash, cmd); + nvmet_tcp_calc_ddgst(queue->rcv_hash, cmd); queue->offset = 0; queue->left = NVME_TCP_DIGEST_LENGTH; queue->rcv_state = NVMET_TCP_RECV_DDGST; From 41d07df7de841bfbc32725ce21d933ad358f2844 Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Sun, 26 Jun 2022 12:24:51 +0300 Subject: [PATCH 126/246] nvme-tcp: always fail a request when sending it failed queue stoppage and inflight requests cancellation is fully fenced from io_work and thus failing a request from this context. Hence we don't need to try to guess from the socket retcode if this failure is because the queue is about to be torn down or not. We are perfectly safe to just fail it, the request will not be cancelled later on. This solves possible very long shutdown delays when the users issues a 'nvme disconnect-all' Reported-by: Daniel Wagner Signed-off-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/nvme/host/tcp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index bb67538d241b..009c2cf3f106 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -1180,8 +1180,7 @@ done: } else if (ret < 0) { dev_err(queue->ctrl->ctrl.device, "failed to send request %d\n", ret); - if (ret != -EPIPE && ret != -ECONNRESET) - nvme_tcp_fail_request(queue->request); + nvme_tcp_fail_request(queue->request); nvme_tcp_done_send_req(queue); } return ret; From 1629de0e0373e04d68e88e6d9d3071fbf70b7ea8 Mon Sep 17 00:00:00 2001 From: Pablo Greco Date: Sat, 25 Jun 2022 09:15:02 -0300 Subject: [PATCH 127/246] nvme-pci: add NVME_QUIRK_BOGUS_NID for ADATA XPG SX6000LNP (AKA SPECTRIX S40G) ADATA XPG SPECTRIX S40G drives report bogus eui64 values that appear to be the same across drives in one system. Quirk them out so they are not marked as "non globally unique" duplicates. Before: [ 2.258919] nvme nvme1: pci function 0000:06:00.0 [ 2.264898] nvme nvme2: pci function 0000:05:00.0 [ 2.323235] nvme nvme1: failed to set APST feature (2) [ 2.326153] nvme nvme2: failed to set APST feature (2) [ 2.333935] nvme nvme1: allocated 64 MiB host memory buffer. [ 2.336492] nvme nvme2: allocated 64 MiB host memory buffer. [ 2.339611] nvme nvme1: 7/0/0 default/read/poll queues [ 2.341805] nvme nvme2: 7/0/0 default/read/poll queues [ 2.346114] nvme1n1: p1 [ 2.347197] nvme nvme2: globally duplicate IDs for nsid 1 After: [ 2.427715] nvme nvme1: pci function 0000:06:00.0 [ 2.427771] nvme nvme2: pci function 0000:05:00.0 [ 2.488154] nvme nvme2: failed to set APST feature (2) [ 2.489895] nvme nvme1: failed to set APST feature (2) [ 2.498773] nvme nvme2: allocated 64 MiB host memory buffer. [ 2.500587] nvme nvme1: allocated 64 MiB host memory buffer. [ 2.504113] nvme nvme2: 7/0/0 default/read/poll queues [ 2.507026] nvme nvme1: 7/0/0 default/read/poll queues [ 2.509467] nvme nvme2: Ignoring bogus Namespace Identifiers [ 2.512804] nvme nvme1: Ignoring bogus Namespace Identifiers [ 2.513698] nvme1n1: p1 Signed-off-by: Pablo Greco Reviewed-by: Keith Busch Reviewed-by: Chaitanya Kulkarni Cc: Signed-off-by: Christoph Hellwig --- drivers/nvme/host/pci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index d7b24ee17285..c9ebe6072498 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3470,7 +3470,8 @@ static const struct pci_device_id nvme_id_table[] = { .driver_data = NVME_QUIRK_NO_NS_DESC_LIST | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, { PCI_DEVICE(0x10ec, 0x5762), /* ADATA SX6000LNP */ - .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN | + NVME_QUIRK_BOGUS_NID, }, { PCI_DEVICE(0x1cc1, 0x8201), /* ADATA SX8200PNP 512GB */ .driver_data = NVME_QUIRK_NO_DEEPEST_PS | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, From f7f70f4aa09dc43d7455c060143e86a017c30548 Mon Sep 17 00:00:00 2001 From: Ruozhu Li Date: Thu, 23 Jun 2022 14:45:39 +0800 Subject: [PATCH 128/246] nvme: fix regression when disconnect a recovering ctrl We encountered a problem that the disconnect command hangs. After analyzing the log and stack, we found that the triggering process is as follows: CPU0 CPU1 nvme_rdma_error_recovery_work nvme_rdma_teardown_io_queues nvme_do_delete_ctrl nvme_stop_queues nvme_remove_namespaces --clear ctrl->namespaces nvme_start_queues --no ns in ctrl->namespaces nvme_ns_remove return(because ctrl is deleting) blk_freeze_queue blk_mq_freeze_queue_wait --wait for ns to unquiesce to clean infligt IO, hang forever This problem was not found in older kernels because we will flush err work in nvme_stop_ctrl before nvme_remove_namespaces.It does not seem to be modified for functional reasons, the patch can be revert to solve the problem. Revert commit 794a4cb3d2f7 ("nvme: remove the .stop_ctrl callout") Signed-off-by: Ruozhu Li Reviewed-by: Sagi Grimberg Signed-off-by: Christoph Hellwig --- drivers/nvme/host/core.c | 2 ++ drivers/nvme/host/nvme.h | 1 + drivers/nvme/host/rdma.c | 12 +++++++++--- drivers/nvme/host/tcp.c | 10 +++++++--- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index b3d9c29aba1e..ec6ac298d8de 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4595,6 +4595,8 @@ void nvme_stop_ctrl(struct nvme_ctrl *ctrl) nvme_stop_failfast_work(ctrl); flush_work(&ctrl->async_event_work); cancel_work_sync(&ctrl->fw_act_work); + if (ctrl->ops->stop_ctrl) + ctrl->ops->stop_ctrl(ctrl); } EXPORT_SYMBOL_GPL(nvme_stop_ctrl); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 0da94b233fed..5558f8812157 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -502,6 +502,7 @@ struct nvme_ctrl_ops { void (*free_ctrl)(struct nvme_ctrl *ctrl); void (*submit_async_event)(struct nvme_ctrl *ctrl); void (*delete_ctrl)(struct nvme_ctrl *ctrl); + void (*stop_ctrl)(struct nvme_ctrl *ctrl); int (*get_address)(struct nvme_ctrl *ctrl, char *buf, int size); void (*print_device_info)(struct nvme_ctrl *ctrl); }; diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index f2a5e1ea508a..46c2dcf72f7e 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -1048,6 +1048,14 @@ static void nvme_rdma_teardown_io_queues(struct nvme_rdma_ctrl *ctrl, } } +static void nvme_rdma_stop_ctrl(struct nvme_ctrl *nctrl) +{ + struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl); + + cancel_work_sync(&ctrl->err_work); + cancel_delayed_work_sync(&ctrl->reconnect_work); +} + static void nvme_rdma_free_ctrl(struct nvme_ctrl *nctrl) { struct nvme_rdma_ctrl *ctrl = to_rdma_ctrl(nctrl); @@ -2252,9 +2260,6 @@ static const struct blk_mq_ops nvme_rdma_admin_mq_ops = { static void nvme_rdma_shutdown_ctrl(struct nvme_rdma_ctrl *ctrl, bool shutdown) { - cancel_work_sync(&ctrl->err_work); - cancel_delayed_work_sync(&ctrl->reconnect_work); - nvme_rdma_teardown_io_queues(ctrl, shutdown); nvme_stop_admin_queue(&ctrl->ctrl); if (shutdown) @@ -2304,6 +2309,7 @@ static const struct nvme_ctrl_ops nvme_rdma_ctrl_ops = { .submit_async_event = nvme_rdma_submit_async_event, .delete_ctrl = nvme_rdma_delete_ctrl, .get_address = nvmf_get_address, + .stop_ctrl = nvme_rdma_stop_ctrl, }; /* diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 009c2cf3f106..7a9e6ffa2342 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -2193,9 +2193,6 @@ static void nvme_tcp_error_recovery_work(struct work_struct *work) static void nvme_tcp_teardown_ctrl(struct nvme_ctrl *ctrl, bool shutdown) { - cancel_work_sync(&to_tcp_ctrl(ctrl)->err_work); - cancel_delayed_work_sync(&to_tcp_ctrl(ctrl)->connect_work); - nvme_tcp_teardown_io_queues(ctrl, shutdown); nvme_stop_admin_queue(ctrl); if (shutdown) @@ -2235,6 +2232,12 @@ out_fail: nvme_tcp_reconnect_or_remove(ctrl); } +static void nvme_tcp_stop_ctrl(struct nvme_ctrl *ctrl) +{ + cancel_work_sync(&to_tcp_ctrl(ctrl)->err_work); + cancel_delayed_work_sync(&to_tcp_ctrl(ctrl)->connect_work); +} + static void nvme_tcp_free_ctrl(struct nvme_ctrl *nctrl) { struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); @@ -2556,6 +2559,7 @@ static const struct nvme_ctrl_ops nvme_tcp_ctrl_ops = { .submit_async_event = nvme_tcp_submit_async_event, .delete_ctrl = nvme_tcp_delete_ctrl, .get_address = nvmf_get_address, + .stop_ctrl = nvme_tcp_stop_ctrl, }; static bool From 7be3bd8856fba99f8b25b9c223250e42292c312e Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 24 Jun 2022 15:01:28 -0700 Subject: [PATCH 129/246] xfs: empty xattr leaf header blocks are not corruption TLDR: Revert commit 51e6104fdb95 ("xfs: detect empty attr leaf blocks in xfs_attr3_leaf_verify") because it was wrong. Every now and then we get a corruption report from the kernel or xfs_repair about empty leaf blocks in the extended attribute structure. We've long thought that these shouldn't be possible, but prior to 5.18 one would shake loose in the recoveryloop fstests about once a month. A new addition to the xattr leaf block verifier in 5.19-rc1 makes this happen every 7 minutes on my testing cloud. I added a ton of logging to detect any time we set the header count on an xattr leaf block to zero. This produced the following dmesg output on generic/388: XFS (sda4): ino 0x21fcbaf leaf 0x129bf78 hdcount==0! Call Trace: dump_stack_lvl+0x34/0x44 xfs_attr3_leaf_create+0x187/0x230 xfs_attr_shortform_to_leaf+0xd1/0x2f0 xfs_attr_set_iter+0x73e/0xa90 xfs_xattri_finish_update+0x45/0x80 xfs_attr_finish_item+0x1b/0xd0 xfs_defer_finish_noroll+0x19c/0x770 __xfs_trans_commit+0x153/0x3e0 xfs_attr_set+0x36b/0x740 xfs_xattr_set+0x89/0xd0 __vfs_setxattr+0x67/0x80 __vfs_setxattr_noperm+0x6e/0x120 vfs_setxattr+0x97/0x180 setxattr+0x88/0xa0 path_setxattr+0xc3/0xe0 __x64_sys_setxattr+0x27/0x30 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 So now we know that someone is creating empty xattr leaf blocks as part of converting a sf xattr structure into a leaf xattr structure. The conversion routine logs any existing sf attributes in the same transaction that creates the leaf block, so we know this is a setxattr to a file that has no attributes at all. Next, g/388 calls the shutdown ioctl and cycles the mount to trigger log recovery. I also augmented buffer item recovery to call ->verify_struct on any attr leaf blocks and complain if it finds a failure: XFS (sda4): Unmounting Filesystem XFS (sda4): Mounting V5 Filesystem XFS (sda4): Starting recovery (logdev: internal) XFS (sda4): xattr leaf daddr 0x129bf78 hdrcount == 0! Call Trace: dump_stack_lvl+0x34/0x44 xfs_attr3_leaf_verify+0x3b8/0x420 xlog_recover_buf_commit_pass2+0x60a/0x6c0 xlog_recover_items_pass2+0x4e/0xc0 xlog_recover_commit_trans+0x33c/0x350 xlog_recovery_process_trans+0xa5/0xe0 xlog_recover_process_data+0x8d/0x140 xlog_do_recovery_pass+0x19b/0x720 xlog_do_log_recovery+0x62/0xc0 xlog_do_recover+0x33/0x1d0 xlog_recover+0xda/0x190 xfs_log_mount+0x14c/0x360 xfs_mountfs+0x517/0xa60 xfs_fs_fill_super+0x6bc/0x950 get_tree_bdev+0x175/0x280 vfs_get_tree+0x1a/0x80 path_mount+0x6f5/0xaa0 __x64_sys_mount+0x103/0x140 do_syscall_64+0x35/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 RIP: 0033:0x7fc61e241eae And a moment later, the _delwri_submit of the recovered buffers trips the same verifier and recovery fails: XFS (sda4): Metadata corruption detected at xfs_attr3_leaf_verify+0x393/0x420 [xfs], xfs_attr3_leaf block 0x129bf78 XFS (sda4): Unmount and run xfs_repair XFS (sda4): First 128 bytes of corrupted metadata buffer: 00000000: 00 00 00 00 00 00 00 00 3b ee 00 00 00 00 00 00 ........;....... 00000010: 00 00 00 00 01 29 bf 78 00 00 00 00 00 00 00 00 .....).x........ 00000020: a5 1b d0 02 b2 9a 49 df 8e 9c fb 8d f8 31 3e 9d ......I......1>. 00000030: 00 00 00 00 02 1f cb af 00 00 00 00 10 00 00 00 ................ 00000040: 00 50 0f b0 00 00 00 00 00 00 00 00 00 00 00 00 .P.............. 00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ XFS (sda4): Corruption of in-memory data (0x8) detected at _xfs_buf_ioapply+0x37f/0x3b0 [xfs] (fs/xfs/xfs_buf.c:1518). Shutting down filesystem. XFS (sda4): Please unmount the filesystem and rectify the problem(s) XFS (sda4): log mount/recovery failed: error -117 XFS (sda4): log mount failed I think I see what's going on here -- setxattr is racing with something that shuts down the filesystem: Thread 1 Thread 2 -------- -------- xfs_attr_sf_addname xfs_attr_shortform_to_leaf xfs_trans_bhold(leaf) xattri_dela_state = XFS_DAS_LEAF_ADD xfs_trans_bhold_release(leaf) Thread 3 -------- xlog_recover_buf_commit_pass2 xlog_recover_do_reg_buffer xfs_buf_delwri_queue(leaf) xfs_buf_delwri_submit _xfs_buf_ioapply(leaf) xfs_attr3_leaf_write_verify As you can see, the bhold keeps the leaf buffer locked and thus prevents the *AIL* from tripping over the ichdr.count==0 check in the write verifier. Unfortunately, it doesn't prevent the log from getting flushed to disk, which sets up log recovery to fail. So. It's clear that the kernel has always had the ability to persist attr leaf blocks with ichdr.count==0, which means that it's part of the ondisk format now. Unfortunately, this check has been added and removed multiple times throughout history. It first appeared in[1] kernel 3.10 as part of the early V5 format patches. The check was later discovered to break log recovery and hence disabled[2] during log recovery in kernel 4.10. Simultaneously, the check was added[3] to xfs_repair 4.9.0 to try to weed out the empty leaf blocks. This was still not correct because log recovery would recover an empty attr leaf block successfully only for regular xattr operations to trip over the empty block during of the block during regular operation. Therefore, the check was removed entirely[4] in kernel 5.7 but removal of the xfs_repair check was forgotten. The continued complaints from xfs_repair lead to us mistakenly re-adding[5] the verifier check for kernel 5.19. Remove it once again. [1] 517c22207b04 ("xfs: add CRCs to attr leaf blocks") [2] 2e1d23370e75 ("xfs: ignore leaf attr ichdr.count in verifier during log replay") [3] f7140161 ("xfs_repair: junk leaf attribute if count == 0") [4] f28cef9e4dac ("xfs: don't fail verifier on empty attr3 leaf block") [5] 51e6104fdb95 ("xfs: detect empty attr leaf blocks in xfs_attr3_leaf_verify") Looking at the rest of the xattr code, it seems that files with empty leaf blocks behave as expected -- listxattr reports no attributes; getxattr on any xattr returns nothing as expected; removexattr does nothing; and setxattr can add attributes just fine. Original-bug: 517c22207b04 ("xfs: add CRCs to attr leaf blocks") Still-not-fixed-by: 2e1d23370e75 ("xfs: ignore leaf attr ichdr.count in verifier during log replay") Removed-in: f28cef9e4dac ("xfs: don't fail verifier on empty attr3 leaf block") Fixes: 51e6104fdb95 ("xfs: detect empty attr leaf blocks in xfs_attr3_leaf_verify") Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/libxfs/xfs_attr_leaf.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 37e7c33f6283..f6629960e17b 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -289,6 +289,23 @@ xfs_attr3_leaf_verify_entry( return NULL; } +/* + * Validate an attribute leaf block. + * + * Empty leaf blocks can occur under the following circumstances: + * + * 1. setxattr adds a new extended attribute to a file; + * 2. The file has zero existing attributes; + * 3. The attribute is too large to fit in the attribute fork; + * 4. The attribute is small enough to fit in a leaf block; + * 5. A log flush occurs after committing the transaction that creates + * the (empty) leaf block; and + * 6. The filesystem goes down after the log flush but before the new + * attribute can be committed to the leaf block. + * + * Hence we need to ensure that we don't fail the validation purely + * because the leaf is empty. + */ static xfs_failaddr_t xfs_attr3_leaf_verify( struct xfs_buf *bp) @@ -310,15 +327,6 @@ xfs_attr3_leaf_verify( if (fa) return fa; - /* - * Empty leaf blocks should never occur; they imply the existence of a - * software bug that needs fixing. xfs_repair also flags them as a - * corruption that needs fixing, so we should never let these go to - * disk. - */ - if (ichdr.count == 0) - return __this_address; - /* * firstused is the block offset of the first name info structure. * Make sure it doesn't go off the block or crash into the header. From e53bcffad0326c1ef4b4baec4262b5343e420c44 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sat, 25 Jun 2022 10:01:20 -0700 Subject: [PATCH 130/246] xfs: don't hold xattr leaf buffers across transaction rolls Now that we've established (again!) that empty xattr leaf buffers are ok, we no longer need to bhold them to transactions when we're creating new leaf blocks. Get rid of the entire mechanism, which should simplify the xattr code quite a bit. The original justification for using bhold here was to prevent the AIL from trying to write the empty leaf block into the fs during the brief time that we release the buffer lock. The reason for /that/ was to prevent recovery from tripping over the empty ondisk block. Reviewed-by: Dave Chinner Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_attr.c | 38 +++++++++-------------------------- fs/xfs/libxfs/xfs_attr.h | 5 ----- fs/xfs/libxfs/xfs_attr_leaf.c | 9 ++------- fs/xfs/libxfs/xfs_attr_leaf.h | 3 +-- fs/xfs/xfs_attr_item.c | 22 -------------------- 5 files changed, 12 insertions(+), 65 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index 1824f61621a2..224649a76cbb 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -50,7 +50,7 @@ STATIC int xfs_attr_shortform_addname(xfs_da_args_t *args); STATIC int xfs_attr_leaf_get(xfs_da_args_t *args); STATIC int xfs_attr_leaf_removename(xfs_da_args_t *args); STATIC int xfs_attr_leaf_hasname(struct xfs_da_args *args, struct xfs_buf **bp); -STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args, struct xfs_buf *bp); +STATIC int xfs_attr_leaf_try_add(struct xfs_da_args *args); /* * Internal routines when attribute list is more than one block. @@ -393,16 +393,10 @@ xfs_attr_sf_addname( * It won't fit in the shortform, transform to a leaf block. GROT: * another possible req'mt for a double-split btree op. */ - error = xfs_attr_shortform_to_leaf(args, &attr->xattri_leaf_bp); + error = xfs_attr_shortform_to_leaf(args); if (error) return error; - /* - * Prevent the leaf buffer from being unlocked so that a concurrent AIL - * push cannot grab the half-baked leaf buffer and run into problems - * with the write verifier. - */ - xfs_trans_bhold(args->trans, attr->xattri_leaf_bp); attr->xattri_dela_state = XFS_DAS_LEAF_ADD; out: trace_xfs_attr_sf_addname_return(attr->xattri_dela_state, args->dp); @@ -447,11 +441,9 @@ xfs_attr_leaf_addname( /* * Use the leaf buffer we may already hold locked as a result of - * a sf-to-leaf conversion. The held buffer is no longer valid - * after this call, regardless of the result. + * a sf-to-leaf conversion. */ - error = xfs_attr_leaf_try_add(args, attr->xattri_leaf_bp); - attr->xattri_leaf_bp = NULL; + error = xfs_attr_leaf_try_add(args); if (error == -ENOSPC) { error = xfs_attr3_leaf_to_node(args); @@ -497,8 +489,6 @@ xfs_attr_node_addname( struct xfs_da_args *args = attr->xattri_da_args; int error; - ASSERT(!attr->xattri_leaf_bp); - error = xfs_attr_node_addname_find_attr(attr); if (error) return error; @@ -1215,24 +1205,14 @@ xfs_attr_restore_rmt_blk( */ STATIC int xfs_attr_leaf_try_add( - struct xfs_da_args *args, - struct xfs_buf *bp) + struct xfs_da_args *args) { + struct xfs_buf *bp; int error; - /* - * If the caller provided a buffer to us, it is locked and held in - * the transaction because it just did a shortform to leaf conversion. - * Hence we don't need to read it again. Otherwise read in the leaf - * buffer. - */ - if (bp) { - xfs_trans_bhold_release(args->trans, bp); - } else { - error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp); - if (error) - return error; - } + error = xfs_attr3_leaf_read(args->trans, args->dp, 0, &bp); + if (error) + return error; /* * Look up the xattr name to set the insertion point for the new xattr. diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h index b4a2fc77017e..dfb47fa63c6d 100644 --- a/fs/xfs/libxfs/xfs_attr.h +++ b/fs/xfs/libxfs/xfs_attr.h @@ -515,11 +515,6 @@ struct xfs_attr_intent { */ struct xfs_attri_log_nameval *xattri_nameval; - /* - * Used by xfs_attr_set to hold a leaf buffer across a transaction roll - */ - struct xfs_buf *xattri_leaf_bp; - /* Used to keep track of current state of delayed operation */ enum xfs_delattr_state xattri_dela_state; diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index f6629960e17b..8f47396f8dd2 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c @@ -930,14 +930,10 @@ xfs_attr_shortform_getvalue( return -ENOATTR; } -/* - * Convert from using the shortform to the leaf. On success, return the - * buffer so that we can keep it locked until we're totally done with it. - */ +/* Convert from using the shortform to the leaf format. */ int xfs_attr_shortform_to_leaf( - struct xfs_da_args *args, - struct xfs_buf **leaf_bp) + struct xfs_da_args *args) { struct xfs_inode *dp; struct xfs_attr_shortform *sf; @@ -999,7 +995,6 @@ xfs_attr_shortform_to_leaf( sfe = xfs_attr_sf_nextentry(sfe); } error = 0; - *leaf_bp = bp; out: kmem_free(tmpbuffer); return error; diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h index efa757f1e912..368f4d9fa1d5 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.h +++ b/fs/xfs/libxfs/xfs_attr_leaf.h @@ -49,8 +49,7 @@ void xfs_attr_shortform_create(struct xfs_da_args *args); void xfs_attr_shortform_add(struct xfs_da_args *args, int forkoff); int xfs_attr_shortform_lookup(struct xfs_da_args *args); int xfs_attr_shortform_getvalue(struct xfs_da_args *args); -int xfs_attr_shortform_to_leaf(struct xfs_da_args *args, - struct xfs_buf **leaf_bp); +int xfs_attr_shortform_to_leaf(struct xfs_da_args *args); int xfs_attr_sf_removename(struct xfs_da_args *args); int xfs_attr_sf_findname(struct xfs_da_args *args, struct xfs_attr_sf_entry **sfep, diff --git a/fs/xfs/xfs_attr_item.c b/fs/xfs/xfs_attr_item.c index 6ee905a09eb2..5077a7ad5646 100644 --- a/fs/xfs/xfs_attr_item.c +++ b/fs/xfs/xfs_attr_item.c @@ -455,8 +455,6 @@ static inline void xfs_attr_free_item( struct xfs_attr_intent *attr) { - ASSERT(attr->xattri_leaf_bp == NULL); - if (attr->xattri_da_state) xfs_da_state_free(attr->xattri_da_state); xfs_attri_log_nameval_put(attr->xattri_nameval); @@ -511,10 +509,6 @@ xfs_attr_cancel_item( struct xfs_attr_intent *attr; attr = container_of(item, struct xfs_attr_intent, xattri_list); - if (attr->xattri_leaf_bp) { - xfs_buf_relse(attr->xattri_leaf_bp); - attr->xattri_leaf_bp = NULL; - } xfs_attr_free_item(attr); } @@ -672,16 +666,6 @@ xfs_attri_item_recover( if (error) goto out_unlock; - /* - * The defer capture structure took its own reference to the - * attr leaf buffer and will give that to the continuation - * transaction. The attr intent struct drives the continuation - * work, so release our refcount on the attr leaf buffer but - * retain the pointer in the intent structure. - */ - if (attr->xattri_leaf_bp) - xfs_buf_relse(attr->xattri_leaf_bp); - xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_irele(ip); return 0; @@ -692,13 +676,7 @@ xfs_attri_item_recover( } error = xfs_defer_ops_capture_and_commit(tp, capture_list); - out_unlock: - if (attr->xattri_leaf_bp) { - xfs_buf_relse(attr->xattri_leaf_bp); - attr->xattri_leaf_bp = NULL; - } - xfs_iunlock(ip, XFS_ILOCK_EXCL); xfs_irele(ip); out: From 8944c6fb8add384154b784a90ceca88a51a8c364 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Sat, 25 Jun 2022 10:47:45 -0700 Subject: [PATCH 131/246] xfs: dont treat rt extents beyond EOF as eofblocks to be cleared On a system with a realtime volume and a 28k realtime extent, generic/491 fails because the test opens a file on a frozen filesystem and closing it causes xfs_release -> xfs_can_free_eofblocks to mistakenly think that the the blocks of the realtime extent beyond EOF are posteof blocks to be freed. Realtime extents cannot be partially unmapped, so this is pointless. Worse yet, this triggers posteof cleanup, which stalls on a transaction allocation, which is why the test fails. Teach the predicate to account for realtime extents properly. Reviewed-by: Dave Chinner Signed-off-by: Darrick J. Wong Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_bmap_util.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 52be58372c63..85e1a26c92e8 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -686,6 +686,8 @@ xfs_can_free_eofblocks( * forever. */ end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip)); + if (XFS_IS_REALTIME_INODE(ip) && mp->m_sb.sb_rextsize > 1) + end_fsb = roundup_64(end_fsb, mp->m_sb.sb_rextsize); last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes); if (last_fsb <= end_fsb) return false; From 8692969e9164c15474b356b9898e5b9b21a85643 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Mon, 6 Jun 2022 19:31:42 -0400 Subject: [PATCH 132/246] ceph: wait on async create before checking caps for syncfs Currently, we'll call ceph_check_caps, but if we're still waiting on the reply, we'll end up spinning around on the same inode in flush_dirty_session_caps. Wait for the async create reply before flushing caps. Cc: stable@vger.kernel.org URL: https://tracker.ceph.com/issues/55823 Fixes: fbed7045f552 ("ceph: wait for async create reply before sending any cap messages") Signed-off-by: Jeff Layton Reviewed-by: Xiubo Li Signed-off-by: Ilya Dryomov --- fs/ceph/caps.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 38c930384d41..ac8fd5e7f540 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -4377,6 +4377,7 @@ static void flush_dirty_session_caps(struct ceph_mds_session *s) ihold(inode); dout("flush_dirty_caps %llx.%llx\n", ceph_vinop(inode)); spin_unlock(&mdsc->cap_dirty_lock); + ceph_wait_on_async_create(inode); ceph_check_caps(ci, CHECK_CAPS_FLUSH, NULL); iput(inode); spin_lock(&mdsc->cap_dirty_lock); From bbba251577b27422ebe173e1bd006424d6a8cfb3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 16 Jun 2022 16:52:01 -0400 Subject: [PATCH 133/246] drm/amdgpu: fix adev variable used in amdgpu_device_gpu_recover() Use the correct adev variable for the drm_fb_helper in amdgpu_device_gpu_recover(). Noticed by inspection. Fixes: 087451f372bf ("drm/amdgpu: use generic fb helpers instead of setting up AMD own's.") Reviewed-by: Guchun Chen Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 625424f3082b..58df107e3beb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -5164,7 +5164,7 @@ int amdgpu_device_gpu_recover_imp(struct amdgpu_device *adev, */ amdgpu_unregister_gpu_instance(tmp_adev); - drm_fb_helper_set_suspend_unlocked(adev_to_drm(adev)->fb_helper, true); + drm_fb_helper_set_suspend_unlocked(adev_to_drm(tmp_adev)->fb_helper, true); /* disable ras on ALL IPs */ if (!need_emergency_restart && From 20b8264394b33adb1640a485a62a84bc1388b6a3 Mon Sep 17 00:00:00 2001 From: Carlos Llamas Date: Tue, 21 Jun 2022 20:39:21 +0000 Subject: [PATCH 134/246] drm/fourcc: fix integer type usage in uapi header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kernel uapi headers are supposed to use __[us]{8,16,32,64} types defined by as opposed to 'uint32_t' and similar. See [1] for the relevant discussion about this topic. In this particular case, the usage of 'uint64_t' escaped headers_check as these macros are not being called here. However, the following program triggers a compilation error: #include int main() { unsigned long x = AMD_FMT_MOD_CLEAR(RB); return 0; } gcc error: drm.c:5:27: error: ‘uint64_t’ undeclared (first use in this function) 5 | unsigned long x = AMD_FMT_MOD_CLEAR(RB); | ^~~~~~~~~~~~~~~~~ This patch changes AMD_FMT_MOD_{SET,CLEAR} macros to use the correct integer types, which fixes the above issue. [1] https://lkml.org/lkml/2019/6/5/18 Fixes: 8ba16d599374 ("drm/fourcc: Add AMD DRM modifiers.") Signed-off-by: Carlos Llamas Reviewed-by: Simon Ser Signed-off-by: Alex Deucher --- include/uapi/drm/drm_fourcc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index f1972154a594..0980678d502d 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -1444,11 +1444,11 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier) #define AMD_FMT_MOD_PIPE_MASK 0x7 #define AMD_FMT_MOD_SET(field, value) \ - ((uint64_t)(value) << AMD_FMT_MOD_##field##_SHIFT) + ((__u64)(value) << AMD_FMT_MOD_##field##_SHIFT) #define AMD_FMT_MOD_GET(field, value) \ (((value) >> AMD_FMT_MOD_##field##_SHIFT) & AMD_FMT_MOD_##field##_MASK) #define AMD_FMT_MOD_CLEAR(field) \ - (~((uint64_t)AMD_FMT_MOD_##field##_MASK << AMD_FMT_MOD_##field##_SHIFT)) + (~((__u64)AMD_FMT_MOD_##field##_MASK << AMD_FMT_MOD_##field##_SHIFT)) #if defined(__cplusplus) } From 5cb0e3fb2c54eabfb3f932a1574bff1774946bc0 Mon Sep 17 00:00:00 2001 From: Ruili Ji Date: Wed, 22 Jun 2022 14:20:22 +0800 Subject: [PATCH 135/246] drm/amdgpu: To flush tlb for MMHUB of RAVEN series amdgpu: [mmhub0] no-retry page fault (src_id:0 ring:40 vmid:8 pasid:32769, for process test_basic pid 3305 thread test_basic pid 3305) amdgpu: in page starting at address 0x00007ff990003000 from IH client 0x12 (VMC) amdgpu: VM_L2_PROTECTION_FAULT_STATUS:0x00840051 amdgpu: Faulty UTCL2 client ID: MP1 (0x0) amdgpu: MORE_FAULTS: 0x1 amdgpu: WALKER_ERROR: 0x0 amdgpu: PERMISSION_FAULTS: 0x5 amdgpu: MAPPING_ERROR: 0x0 amdgpu: RW: 0x1 When memory is allocated by kfd, no one triggers the tlb flush for MMHUB0. There is page fault from MMHUB0. v2:fix indentation v3:change subject and fix indentation Signed-off-by: Ruili Ji Reviewed-by: Philip Yang Reviewed-by: Aaron Liu Acked-by: Alex Deucher Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 1f8161cd507f..3b1c675aba34 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -714,7 +714,8 @@ int amdgpu_amdkfd_flush_gpu_tlb_pasid(struct amdgpu_device *adev, { bool all_hub = false; - if (adev->family == AMDGPU_FAMILY_AI) + if (adev->family == AMDGPU_FAMILY_AI || + adev->family == AMDGPU_FAMILY_RV) all_hub = true; return amdgpu_gmc_flush_gpu_tlb_pasid(adev, pasid, flush_type, all_hub); From a775e4e4941bf2f326aa36c58f67bd6c96cac717 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 20 Jun 2022 18:29:39 -0400 Subject: [PATCH 136/246] Revert "drm/amdgpu/display: set vblank_disable_immediate for DC" This reverts commit 92020e81ddbeac351ea4a19bcf01743f32b9c800. This causes stuttering and timeouts with DMCUB for some users so revert it until we understand why and safely enable it to save power. Bug: https://gitlab.freedesktop.org/drm/amd/-/issues/1887 Acked-by: Harry Wentland Signed-off-by: Alex Deucher Cc: Nicholas Kazlauskas Cc: stable@vger.kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 1 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index b4cf8717f554..89011bae7588 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -320,6 +320,7 @@ int amdgpu_irq_init(struct amdgpu_device *adev) if (!amdgpu_device_has_dc_support(adev)) { if (!adev->enable_virtual_display) /* Disable vblank IRQs aggressively for power-saving */ + /* XXX: can this be enabled for DC? */ adev_to_drm(adev)->vblank_disable_immediate = true; r = drm_vblank_init(adev_to_drm(adev), adev->mode_info.num_crtc); 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 39b425d83bb1..9dd2e0601ea8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4259,9 +4259,6 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) } } - /* Disable vblank IRQs aggressively for power-saving. */ - adev_to_drm(adev)->vblank_disable_immediate = true; - /* loops over all connectors on the board */ for (i = 0; i < link_cnt; i++) { struct dc_link *link = NULL; From 57e00b40033a376de3f3cf0bb9bf7590d2dd679d Mon Sep 17 00:00:00 2001 From: Christian 'Ansuel' Marangi Date: Tue, 14 Jun 2022 13:06:59 +0200 Subject: [PATCH 137/246] PM / devfreq: Fix kernel panic with cpu based scaling to passive gov The cpufreq passive register notifier can PROBE_DEFER and the devfreq struct is freed and then reallocaed on probe retry. The current logic assume that the code can't PROBE_DEFER so the devfreq struct in the this variable in devfreq_passive_data is assumed to be (if already set) always correct. This cause kernel panic as the code try to access the wrong address. To correctly handle this, update the this variable in devfreq_passive_data to the devfreq reallocated struct. Fixes: a03dacb0316f ("PM / devfreq: Add cpu based scaling support to passive governor") Signed-off-by: Christian 'Ansuel' Marangi Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 72c67979ebe1..091a69e1f487 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -407,8 +407,7 @@ static int devfreq_passive_event_handler(struct devfreq *devfreq, if (!p_data) return -EINVAL; - if (!p_data->this) - p_data->this = devfreq; + p_data->this = devfreq; switch (event) { case DEVFREQ_GOV_START: From e52b045fe07d7874474665c843befa7521853234 Mon Sep 17 00:00:00 2001 From: Christian 'Ansuel' Marangi Date: Wed, 15 Jun 2022 01:09:50 +0200 Subject: [PATCH 138/246] PM / devfreq: Mute warning on governor PROBE_DEFER Don't print warning when a governor PROBE_DEFER as it's not a real GOV_START fail. Fixes: a03dacb0316f ("PM / devfreq: Add cpu based scaling support to passive governor") Signed-off-by: Christian 'Ansuel' Marangi Signed-off-by: Chanwoo Choi --- drivers/devfreq/devfreq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 01474daf4548..80a1235ef8fb 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -932,8 +932,9 @@ struct devfreq *devfreq_add_device(struct device *dev, err = devfreq->governor->event_handler(devfreq, DEVFREQ_GOV_START, NULL); if (err) { - dev_err(dev, "%s: Unable to start governor for the device\n", - __func__); + dev_err_probe(dev, err, + "%s: Unable to start governor for the device\n", + __func__); goto err_init; } create_sysfs_files(devfreq, devfreq->governor); From 0cca7e8dcfa9e6fe7ba697e534a732571f1689d0 Mon Sep 17 00:00:00 2001 From: Christian 'Ansuel' Marangi Date: Wed, 15 Jun 2022 01:09:47 +0200 Subject: [PATCH 139/246] PM / devfreq: Fix cpufreq passive unregister erroring on PROBE_DEFER With the passive governor, the cpu based scaling can PROBE_DEFER due to the fact that CPU policy are not ready. The cpufreq passive unregister notifier is called both from the GOV_START errors and for the GOV_STOP and assume the notifier is successfully registred every time. With GOV_START failing it's wrong to loop over each possible CPU since the register path has failed for some CPU policy not ready. Change the logic and unregister the notifer based on the current allocated parent_cpu_data list to correctly handle errors and the governor unregister path. Fixes: a03dacb0316f ("PM / devfreq: Add cpu based scaling support to passive governor") Signed-off-by: Christian 'Ansuel' Marangi Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 39 +++++++++++++----------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 091a69e1f487..a35b39ac656c 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -34,6 +34,20 @@ get_parent_cpu_data(struct devfreq_passive_data *p_data, return NULL; } +static void delete_parent_cpu_data(struct devfreq_passive_data *p_data) +{ + struct devfreq_cpu_data *parent_cpu_data, *tmp; + + list_for_each_entry_safe(parent_cpu_data, tmp, &p_data->cpu_data_list, node) { + list_del(&parent_cpu_data->node); + + if (parent_cpu_data->opp_table) + dev_pm_opp_put_opp_table(parent_cpu_data->opp_table); + + kfree(parent_cpu_data); + } +} + static unsigned long get_target_freq_by_required_opp(struct device *p_dev, struct opp_table *p_opp_table, struct opp_table *opp_table, @@ -222,8 +236,7 @@ static int cpufreq_passive_unregister_notifier(struct devfreq *devfreq) { struct devfreq_passive_data *p_data = (struct devfreq_passive_data *)devfreq->data; - struct devfreq_cpu_data *parent_cpu_data; - int cpu, ret = 0; + int ret; if (p_data->nb.notifier_call) { ret = cpufreq_unregister_notifier(&p_data->nb, @@ -232,27 +245,9 @@ static int cpufreq_passive_unregister_notifier(struct devfreq *devfreq) return ret; } - for_each_possible_cpu(cpu) { - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - if (!policy) { - ret = -EINVAL; - continue; - } + delete_parent_cpu_data(p_data); - parent_cpu_data = get_parent_cpu_data(p_data, policy); - if (!parent_cpu_data) { - cpufreq_cpu_put(policy); - continue; - } - - list_del(&parent_cpu_data->node); - if (parent_cpu_data->opp_table) - dev_pm_opp_put_opp_table(parent_cpu_data->opp_table); - kfree(parent_cpu_data); - cpufreq_cpu_put(policy); - } - - return ret; + return 0; } static int cpufreq_passive_register_notifier(struct devfreq *devfreq) From 20e6c3cc90c0a86dba659dd9e7d60b429d88746d Mon Sep 17 00:00:00 2001 From: Yicong Yang Date: Fri, 10 Jun 2022 15:54:28 +0800 Subject: [PATCH 140/246] PM / devfreq: passive: Use HZ_PER_KHZ macro in units.h HZ macros has been centralized in units.h since [1]. Use it to avoid duplicated definition. [1] commit e2c77032fcbe ("units: add the HZ macros") Signed-off-by: Yicong Yang Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index a35b39ac656c..69e06725d92b 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -14,10 +14,9 @@ #include #include #include +#include #include "governor.h" -#define HZ_PER_KHZ 1000 - static struct devfreq_cpu_data * get_parent_cpu_data(struct devfreq_passive_data *p_data, struct cpufreq_policy *policy) From f44b799603a9b5d2e375b0b2d54dd0b791eddfc2 Mon Sep 17 00:00:00 2001 From: Miaoqian Lin Date: Thu, 26 May 2022 12:28:56 +0400 Subject: [PATCH 141/246] PM / devfreq: exynos-ppmu: Fix refcount leak in of_get_devfreq_events of_get_child_by_name() returns a node pointer with refcount incremented, we should use of_node_put() on it when done. This function only calls of_node_put() in normal path, missing it in error paths. Add missing of_node_put() to avoid refcount leak. Fixes: f262f28c1470 ("PM / devfreq: event: Add devfreq_event class") Signed-off-by: Miaoqian Lin Signed-off-by: Chanwoo Choi --- drivers/devfreq/event/exynos-ppmu.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c index 9b849d781116..a443e7c42daf 100644 --- a/drivers/devfreq/event/exynos-ppmu.c +++ b/drivers/devfreq/event/exynos-ppmu.c @@ -519,15 +519,19 @@ static int of_get_devfreq_events(struct device_node *np, count = of_get_child_count(events_np); desc = devm_kcalloc(dev, count, sizeof(*desc), GFP_KERNEL); - if (!desc) + if (!desc) { + of_node_put(events_np); return -ENOMEM; + } info->num_events = count; of_id = of_match_device(exynos_ppmu_id_match, dev); if (of_id) info->ppmu_type = (enum exynos_ppmu_type)of_id->data; - else + else { + of_node_put(events_np); return -EINVAL; + } j = 0; for_each_child_of_node(events_np, node) { From b5d281f6c16dd432b618bdfd36ddba1a58d5b603 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 20 Jun 2022 00:03:51 +0200 Subject: [PATCH 142/246] PM / devfreq: Rework freq_table to be local to devfreq struct On a devfreq PROBE_DEFER, the freq_table in the driver profile struct, is never reset and may be leaved in an undefined state. This comes from the fact that we store the freq_table in the driver profile struct that is commonly defined as static and not reset on PROBE_DEFER. We currently skip the reinit of the freq_table if we found it's already defined since a driver may declare his own freq_table. This logic is flawed in the case devfreq core generate a freq_table, set it in the profile struct and then PROBE_DEFER, freeing the freq_table. In this case devfreq will found a NOT NULL freq_table that has been freed, skip the freq_table generation and probe the driver based on the wrong table. To fix this and correctly handle PROBE_DEFER, use a local freq_table and max_state in the devfreq struct and never modify the freq_table present in the profile struct if it does provide it. Fixes: 0ec09ac2cebe ("PM / devfreq: Set the freq_table of devfreq device") Cc: stable@vger.kernel.org Signed-off-by: Christian Marangi Signed-off-by: Chanwoo Choi --- drivers/devfreq/devfreq.c | 71 ++++++++++++++---------------- drivers/devfreq/governor_passive.c | 14 +++--- include/linux/devfreq.h | 5 +++ 3 files changed, 46 insertions(+), 44 deletions(-) diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 80a1235ef8fb..9602141bb8ec 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -123,7 +123,7 @@ void devfreq_get_freq_range(struct devfreq *devfreq, unsigned long *min_freq, unsigned long *max_freq) { - unsigned long *freq_table = devfreq->profile->freq_table; + unsigned long *freq_table = devfreq->freq_table; s32 qos_min_freq, qos_max_freq; lockdep_assert_held(&devfreq->lock); @@ -133,11 +133,11 @@ void devfreq_get_freq_range(struct devfreq *devfreq, * The devfreq drivers can initialize this in either ascending or * descending order and devfreq core supports both. */ - if (freq_table[0] < freq_table[devfreq->profile->max_state - 1]) { + if (freq_table[0] < freq_table[devfreq->max_state - 1]) { *min_freq = freq_table[0]; - *max_freq = freq_table[devfreq->profile->max_state - 1]; + *max_freq = freq_table[devfreq->max_state - 1]; } else { - *min_freq = freq_table[devfreq->profile->max_state - 1]; + *min_freq = freq_table[devfreq->max_state - 1]; *max_freq = freq_table[0]; } @@ -169,8 +169,8 @@ static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq) { int lev; - for (lev = 0; lev < devfreq->profile->max_state; lev++) - if (freq == devfreq->profile->freq_table[lev]) + for (lev = 0; lev < devfreq->max_state; lev++) + if (freq == devfreq->freq_table[lev]) return lev; return -EINVAL; @@ -178,7 +178,6 @@ static int devfreq_get_freq_level(struct devfreq *devfreq, unsigned long freq) static int set_freq_table(struct devfreq *devfreq) { - struct devfreq_dev_profile *profile = devfreq->profile; struct dev_pm_opp *opp; unsigned long freq; int i, count; @@ -188,25 +187,22 @@ static int set_freq_table(struct devfreq *devfreq) if (count <= 0) return -EINVAL; - profile->max_state = count; - profile->freq_table = devm_kcalloc(devfreq->dev.parent, - profile->max_state, - sizeof(*profile->freq_table), - GFP_KERNEL); - if (!profile->freq_table) { - profile->max_state = 0; + devfreq->max_state = count; + devfreq->freq_table = devm_kcalloc(devfreq->dev.parent, + devfreq->max_state, + sizeof(*devfreq->freq_table), + GFP_KERNEL); + if (!devfreq->freq_table) return -ENOMEM; - } - for (i = 0, freq = 0; i < profile->max_state; i++, freq++) { + for (i = 0, freq = 0; i < devfreq->max_state; i++, freq++) { opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq); if (IS_ERR(opp)) { - devm_kfree(devfreq->dev.parent, profile->freq_table); - profile->max_state = 0; + devm_kfree(devfreq->dev.parent, devfreq->freq_table); return PTR_ERR(opp); } dev_pm_opp_put(opp); - profile->freq_table[i] = freq; + devfreq->freq_table[i] = freq; } return 0; @@ -246,7 +242,7 @@ int devfreq_update_status(struct devfreq *devfreq, unsigned long freq) if (lev != prev_lev) { devfreq->stats.trans_table[ - (prev_lev * devfreq->profile->max_state) + lev]++; + (prev_lev * devfreq->max_state) + lev]++; devfreq->stats.total_trans++; } @@ -835,6 +831,9 @@ struct devfreq *devfreq_add_device(struct device *dev, if (err < 0) goto err_dev; mutex_lock(&devfreq->lock); + } else { + devfreq->freq_table = devfreq->profile->freq_table; + devfreq->max_state = devfreq->profile->max_state; } devfreq->scaling_min_freq = find_available_min_freq(devfreq); @@ -870,8 +869,8 @@ struct devfreq *devfreq_add_device(struct device *dev, devfreq->stats.trans_table = devm_kzalloc(&devfreq->dev, array3_size(sizeof(unsigned int), - devfreq->profile->max_state, - devfreq->profile->max_state), + devfreq->max_state, + devfreq->max_state), GFP_KERNEL); if (!devfreq->stats.trans_table) { mutex_unlock(&devfreq->lock); @@ -880,7 +879,7 @@ struct devfreq *devfreq_add_device(struct device *dev, } devfreq->stats.time_in_state = devm_kcalloc(&devfreq->dev, - devfreq->profile->max_state, + devfreq->max_state, sizeof(*devfreq->stats.time_in_state), GFP_KERNEL); if (!devfreq->stats.time_in_state) { @@ -1666,9 +1665,9 @@ static ssize_t available_frequencies_show(struct device *d, mutex_lock(&df->lock); - for (i = 0; i < df->profile->max_state; i++) + for (i = 0; i < df->max_state; i++) count += scnprintf(&buf[count], (PAGE_SIZE - count - 2), - "%lu ", df->profile->freq_table[i]); + "%lu ", df->freq_table[i]); mutex_unlock(&df->lock); /* Truncate the trailing space */ @@ -1691,7 +1690,7 @@ static ssize_t trans_stat_show(struct device *dev, if (!df->profile) return -EINVAL; - max_state = df->profile->max_state; + max_state = df->max_state; if (max_state == 0) return sprintf(buf, "Not Supported.\n"); @@ -1708,19 +1707,17 @@ static ssize_t trans_stat_show(struct device *dev, len += sprintf(buf + len, " :"); for (i = 0; i < max_state; i++) len += sprintf(buf + len, "%10lu", - df->profile->freq_table[i]); + df->freq_table[i]); len += sprintf(buf + len, " time(ms)\n"); for (i = 0; i < max_state; i++) { - if (df->profile->freq_table[i] - == df->previous_freq) { + if (df->freq_table[i] == df->previous_freq) len += sprintf(buf + len, "*"); - } else { + else len += sprintf(buf + len, " "); - } - len += sprintf(buf + len, "%10lu:", - df->profile->freq_table[i]); + + len += sprintf(buf + len, "%10lu:", df->freq_table[i]); for (j = 0; j < max_state; j++) len += sprintf(buf + len, "%10u", df->stats.trans_table[(i * max_state) + j]); @@ -1744,7 +1741,7 @@ static ssize_t trans_stat_store(struct device *dev, if (!df->profile) return -EINVAL; - if (df->profile->max_state == 0) + if (df->max_state == 0) return count; err = kstrtoint(buf, 10, &value); @@ -1752,11 +1749,11 @@ static ssize_t trans_stat_store(struct device *dev, return -EINVAL; mutex_lock(&df->lock); - memset(df->stats.time_in_state, 0, (df->profile->max_state * + memset(df->stats.time_in_state, 0, (df->max_state * sizeof(*df->stats.time_in_state))); memset(df->stats.trans_table, 0, array3_size(sizeof(unsigned int), - df->profile->max_state, - df->profile->max_state)); + df->max_state, + df->max_state)); df->stats.total_trans = 0; df->stats.last_update = get_jiffies_64(); mutex_unlock(&df->lock); diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 69e06725d92b..406ef79c0c46 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -144,18 +144,18 @@ static int get_target_freq_with_devfreq(struct devfreq *devfreq, goto out; /* Use interpolation if required opps is not available */ - for (i = 0; i < parent_devfreq->profile->max_state; i++) - if (parent_devfreq->profile->freq_table[i] == *freq) + for (i = 0; i < parent_devfreq->max_state; i++) + if (parent_devfreq->freq_table[i] == *freq) break; - if (i == parent_devfreq->profile->max_state) + if (i == parent_devfreq->max_state) return -EINVAL; - if (i < devfreq->profile->max_state) { - child_freq = devfreq->profile->freq_table[i]; + if (i < devfreq->max_state) { + child_freq = devfreq->freq_table[i]; } else { - count = devfreq->profile->max_state; - child_freq = devfreq->profile->freq_table[count - 1]; + count = devfreq->max_state; + child_freq = devfreq->freq_table[count - 1]; } out: diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index dc10bee75a72..34aab4dd336c 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -148,6 +148,8 @@ struct devfreq_stats { * reevaluate operable frequencies. Devfreq users may use * devfreq.nb to the corresponding register notifier call chain. * @work: delayed work for load monitoring. + * @freq_table: current frequency table used by the devfreq driver. + * @max_state: count of entry present in the frequency table. * @previous_freq: previously configured frequency value. * @last_status: devfreq user device info, performance statistics * @data: Private data of the governor. The devfreq framework does not @@ -185,6 +187,9 @@ struct devfreq { struct notifier_block nb; struct delayed_work work; + unsigned long *freq_table; + unsigned int max_state; + unsigned long previous_freq; struct devfreq_dev_status last_status; From 82c66d2bbbeda9e493487e7413769087a0b46250 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 20 Jun 2022 00:29:39 +0200 Subject: [PATCH 143/246] PM / devfreq: Fix kernel warning with cpufreq passive register fail Remove cpufreq_passive_unregister_notifier from cpufreq_passive_register_notifier in case of error as devfreq core already call unregister on GOV_START fail. This fix the kernel always printing a WARN on governor PROBE_DEFER as cpufreq_passive_unregister_notifier is called two times and return error on the second call as the cpufreq is already unregistered. Fixes: a03dacb0316f ("PM / devfreq: Add cpu based scaling support to passive governor") Signed-off-by: Christian Marangi Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 406ef79c0c46..bce487cc8f3e 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -330,7 +330,6 @@ err_free_cpu_data: err_put_policy: cpufreq_cpu_put(policy); err: - WARN_ON(cpufreq_passive_unregister_notifier(devfreq)); return ret; } From f08fe6fcbe13f83558ecccc4acaf5af3dce71a1f Mon Sep 17 00:00:00 2001 From: Lukas Bulwahn Date: Tue, 28 Jun 2022 07:34:11 +0200 Subject: [PATCH 144/246] PM / devfreq: passive: revert an editing accident in SPDX-License line Commit 26984d9d581e ("PM / devfreq: passive: Keep cpufreq_policy for possible cpus") reworked governor_passive.c, and accidently added a tab in the first line, i.e., the SPDX-License-Identifier line. The checkpatch script warns with the SPDX_LICENSE_TAG warning, and hence pointed this issue out while investigating checkpatch warnings. Revert this editing accident. No functional change. Signed-off-by: Lukas Bulwahn Signed-off-by: Chanwoo Choi --- drivers/devfreq/governor_passive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index bce487cc8f3e..953cf9a1e9f7 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -1,4 +1,4 @@ - // SPDX-License-Identifier: GPL-2.0-only +// SPDX-License-Identifier: GPL-2.0-only /* * linux/drivers/devfreq/governor_passive.c * From 1bbb2809040a1f9c7c53c9f06c21aa83275ed27b Mon Sep 17 00:00:00 2001 From: Eddie James Date: Tue, 28 Jun 2022 15:30:29 -0500 Subject: [PATCH 145/246] hwmon: (occ) Prevent power cap command overwriting poll response Currently, the response to the power cap command overwrites the first eight bytes of the poll response, since the commands use the same buffer. This means that user's get the wrong data between the time of sending the power cap and the next poll response update. Fix this by specifying a different buffer for the power cap command response. Fixes: 5b5513b88002 ("hwmon: Add On-Chip Controller (OCC) hwmon driver") Signed-off-by: Eddie James Link: https://lore.kernel.org/r/20220628203029.51747-1-eajames@linux.ibm.com Signed-off-by: Guenter Roeck --- drivers/hwmon/occ/common.c | 5 +++-- drivers/hwmon/occ/common.h | 3 ++- drivers/hwmon/occ/p8_i2c.c | 13 +++++++------ drivers/hwmon/occ/p9_sbe.c | 7 +++---- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/hwmon/occ/common.c b/drivers/hwmon/occ/common.c index ea070b91e5b9..157b73a3da29 100644 --- a/drivers/hwmon/occ/common.c +++ b/drivers/hwmon/occ/common.c @@ -145,7 +145,7 @@ static int occ_poll(struct occ *occ) cmd[6] = 0; /* checksum lsb */ /* mutex should already be locked if necessary */ - rc = occ->send_cmd(occ, cmd, sizeof(cmd)); + rc = occ->send_cmd(occ, cmd, sizeof(cmd), &occ->resp, sizeof(occ->resp)); if (rc) { occ->last_error = rc; if (occ->error_count++ > OCC_ERROR_COUNT_THRESHOLD) @@ -182,6 +182,7 @@ static int occ_set_user_power_cap(struct occ *occ, u16 user_power_cap) { int rc; u8 cmd[8]; + u8 resp[8]; __be16 user_power_cap_be = cpu_to_be16(user_power_cap); cmd[0] = 0; /* sequence number */ @@ -198,7 +199,7 @@ static int occ_set_user_power_cap(struct occ *occ, u16 user_power_cap) if (rc) return rc; - rc = occ->send_cmd(occ, cmd, sizeof(cmd)); + rc = occ->send_cmd(occ, cmd, sizeof(cmd), resp, sizeof(resp)); mutex_unlock(&occ->lock); diff --git a/drivers/hwmon/occ/common.h b/drivers/hwmon/occ/common.h index 64d5ec7e169b..7ac4b2febce6 100644 --- a/drivers/hwmon/occ/common.h +++ b/drivers/hwmon/occ/common.h @@ -96,7 +96,8 @@ struct occ { int powr_sample_time_us; /* average power sample time */ u8 poll_cmd_data; /* to perform OCC poll command */ - int (*send_cmd)(struct occ *occ, u8 *cmd, size_t len); + int (*send_cmd)(struct occ *occ, u8 *cmd, size_t len, void *resp, + size_t resp_len); unsigned long next_update; struct mutex lock; /* lock OCC access */ diff --git a/drivers/hwmon/occ/p8_i2c.c b/drivers/hwmon/occ/p8_i2c.c index da39ea28df31..b221be1f35f3 100644 --- a/drivers/hwmon/occ/p8_i2c.c +++ b/drivers/hwmon/occ/p8_i2c.c @@ -111,7 +111,8 @@ static int p8_i2c_occ_putscom_be(struct i2c_client *client, u32 address, be32_to_cpu(data1)); } -static int p8_i2c_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len) +static int p8_i2c_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len, + void *resp, size_t resp_len) { int i, rc; unsigned long start; @@ -120,7 +121,7 @@ static int p8_i2c_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len) const long wait_time = msecs_to_jiffies(OCC_CMD_IN_PRG_WAIT_MS); struct p8_i2c_occ *ctx = to_p8_i2c_occ(occ); struct i2c_client *client = ctx->client; - struct occ_response *resp = &occ->resp; + struct occ_response *or = (struct occ_response *)resp; start = jiffies; @@ -151,7 +152,7 @@ static int p8_i2c_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len) return rc; /* wait for OCC */ - if (resp->return_status == OCC_RESP_CMD_IN_PRG) { + if (or->return_status == OCC_RESP_CMD_IN_PRG) { rc = -EALREADY; if (time_after(jiffies, start + timeout)) @@ -163,7 +164,7 @@ static int p8_i2c_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len) } while (rc); /* check the OCC response */ - switch (resp->return_status) { + switch (or->return_status) { case OCC_RESP_CMD_IN_PRG: rc = -ETIMEDOUT; break; @@ -192,8 +193,8 @@ static int p8_i2c_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len) if (rc < 0) return rc; - data_length = get_unaligned_be16(&resp->data_length); - if (data_length > OCC_RESP_DATA_BYTES) + data_length = get_unaligned_be16(&or->data_length); + if ((data_length + 7) > resp_len) return -EMSGSIZE; /* fetch the rest of the response data */ diff --git a/drivers/hwmon/occ/p9_sbe.c b/drivers/hwmon/occ/p9_sbe.c index 42fc7b97bb34..a91937e28e12 100644 --- a/drivers/hwmon/occ/p9_sbe.c +++ b/drivers/hwmon/occ/p9_sbe.c @@ -78,11 +78,10 @@ done: return notify; } -static int p9_sbe_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len) +static int p9_sbe_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len, + void *resp, size_t resp_len) { - struct occ_response *resp = &occ->resp; struct p9_sbe_occ *ctx = to_p9_sbe_occ(occ); - size_t resp_len = sizeof(*resp); int rc; rc = fsi_occ_submit(ctx->sbe, cmd, len, resp, &resp_len); @@ -96,7 +95,7 @@ static int p9_sbe_occ_send_cmd(struct occ *occ, u8 *cmd, size_t len) return rc; } - switch (resp->return_status) { + switch (((struct occ_response *)resp)->return_status) { case OCC_RESP_CMD_IN_PRG: rc = -ETIMEDOUT; break; From f0aa153b6ce8018a052d9c05dc1b8483ac3a0f1a Mon Sep 17 00:00:00 2001 From: Jiang Jian Date: Wed, 22 Jun 2022 14:32:31 +0800 Subject: [PATCH 146/246] hwmon: (pmbus/ucd9200) fix typos in comments Drop the redundant word 'the' in the comments following /* * Set PHASE registers on all pages to 0xff to ensure that phase * specific commands will apply to all phases of a given page (rail). * This only affects the READ_IOUT and READ_TEMPERATURE2 registers. * READ_IOUT will return the sum of currents of all phases of a rail, * and READ_TEMPERATURE2 will return the maximum temperature detected * for the [the - DROP] phases of the rail. */ Signed-off-by: Jiang Jian Link: https://lore.kernel.org/r/20220622063231.20612-1-jiangjian@cdjrlc.com Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/ucd9200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hwmon/pmbus/ucd9200.c b/drivers/hwmon/pmbus/ucd9200.c index 6bc3273e31e7..3ad375a76f3e 100644 --- a/drivers/hwmon/pmbus/ucd9200.c +++ b/drivers/hwmon/pmbus/ucd9200.c @@ -148,7 +148,7 @@ static int ucd9200_probe(struct i2c_client *client) * This only affects the READ_IOUT and READ_TEMPERATURE2 registers. * READ_IOUT will return the sum of currents of all phases of a rail, * and READ_TEMPERATURE2 will return the maximum temperature detected - * for the the phases of the rail. + * for the phases of the rail. */ for (i = 0; i < info->pages; i++) { /* From 32788beb103f7f71e0192dce701f387070914651 Mon Sep 17 00:00:00 2001 From: John Garry Date: Wed, 29 Jun 2022 17:18:44 +0800 Subject: [PATCH 147/246] ata: pata_cs5535: Fix W=1 warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit x86_64 allmodconfig build with W=1 gives these warnings: drivers/ata/pata_cs5535.c: In function ‘cs5535_set_piomode’: drivers/ata/pata_cs5535.c:93:11: error: variable ‘dummy’ set but not used [-Werror=unused-but-set-variable] u32 reg, dummy; ^~~~~ drivers/ata/pata_cs5535.c: In function ‘cs5535_set_dmamode’: drivers/ata/pata_cs5535.c:132:11: error: variable ‘dummy’ set but not used [-Werror=unused-but-set-variable] u32 reg, dummy; ^~~~~ cc1: all warnings being treated as errors Mark variables 'dummy' as "maybe unused" as they are only ever written in rdmsr() calls. Signed-off-by: John Garry Reviewed-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_cs5535.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c index 6725931f3c35..c2c3238ff84b 100644 --- a/drivers/ata/pata_cs5535.c +++ b/drivers/ata/pata_cs5535.c @@ -90,7 +90,7 @@ static void cs5535_set_piomode(struct ata_port *ap, struct ata_device *adev) static const u16 pio_cmd_timings[5] = { 0xF7F4, 0x53F3, 0x13F1, 0x5131, 0x1131 }; - u32 reg, dummy; + u32 reg, __maybe_unused dummy; struct ata_device *pair = ata_dev_pair(adev); int mode = adev->pio_mode - XFER_PIO_0; @@ -129,7 +129,7 @@ static void cs5535_set_dmamode(struct ata_port *ap, struct ata_device *adev) static const u32 mwdma_timings[3] = { 0x7F0FFFF3, 0x7F035352, 0x7F024241 }; - u32 reg, dummy; + u32 reg, __maybe_unused dummy; int mode = adev->dma_mode; rdmsr(ATAC_CH0D0_DMA + 2 * adev->devno, reg, dummy); From 1ebc2cec0b7dd8dad0812449110803bd875ac816 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 29 Jun 2022 13:40:01 -0400 Subject: [PATCH 148/246] dm raid: fix KASAN warning in raid5_remove_disk There's a KASAN warning in raid5_remove_disk when running the LVM testsuite. We fix this warning by verifying that the "number" variable is within limits. Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer --- drivers/md/raid5.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 5d09256d7f81..ba289411f26f 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -7933,7 +7933,7 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev) int err = 0; int number = rdev->raid_disk; struct md_rdev __rcu **rdevp; - struct disk_info *p = conf->disks + number; + struct disk_info *p; struct md_rdev *tmp; print_raid5_conf(conf); @@ -7952,6 +7952,9 @@ static int raid5_remove_disk(struct mddev *mddev, struct md_rdev *rdev) log_exit(conf); return 0; } + if (unlikely(number >= conf->pool_size)) + return 0; + p = conf->disks + number; if (rdev == rcu_access_pointer(p->rdev)) rdevp = &p->rdev; else if (rdev == rcu_access_pointer(p->replacement)) From 617b365872a247480e9dcd50a32c8d1806b21861 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 29 Jun 2022 13:40:57 -0400 Subject: [PATCH 149/246] dm raid: fix KASAN warning in raid5_add_disks There's a KASAN warning in raid5_add_disk when running the LVM testsuite. The warning happens in the test lvconvert-raid-reshape-linear_to_raid6-single-type.sh. We fix the warning by verifying that rdev->saved_raid_disk is within limits. Cc: stable@vger.kernel.org Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer --- drivers/md/raid5.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index ba289411f26f..20e53b167f81 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -8065,6 +8065,7 @@ static int raid5_add_disk(struct mddev *mddev, struct md_rdev *rdev) */ if (rdev->saved_raid_disk >= 0 && rdev->saved_raid_disk >= first && + rdev->saved_raid_disk <= last && conf->disks[rdev->saved_raid_disk].rdev == NULL) first = rdev->saved_raid_disk; From 34ad61514c4c3657df21a058f9961c3bb2f84ff2 Mon Sep 17 00:00:00 2001 From: Alan Adamson Date: Mon, 27 Jun 2022 16:25:43 -0700 Subject: [PATCH 150/246] nvmet: add a clear_ids attribute for passthru targets If the clear_ids attribute is set to true, the EUI/GUID/UUID is cleared for the passthru target. By default, loop targets will set clear_ids to true. This resolves an issue where a connect to a passthru target fails when using a trtype of 'loop' because EUI/GUID/UUID is not unique. Fixes: 2079f41ec6ff ("nvme: check that EUI/GUID/UUID are globally unique") Signed-off-by: Alan Adamson Reviewed-by: Keith Busch Reviewed-by: Chaitanya Kulkarni Signed-off-by: Christoph Hellwig --- drivers/nvme/target/configfs.c | 20 +++++++++++++ drivers/nvme/target/core.c | 6 ++++ drivers/nvme/target/nvmet.h | 1 + drivers/nvme/target/passthru.c | 55 ++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+) diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index e44b2988759e..ff77c3d2354f 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -773,11 +773,31 @@ static ssize_t nvmet_passthru_io_timeout_store(struct config_item *item, } CONFIGFS_ATTR(nvmet_passthru_, io_timeout); +static ssize_t nvmet_passthru_clear_ids_show(struct config_item *item, + char *page) +{ + return sprintf(page, "%u\n", to_subsys(item->ci_parent)->clear_ids); +} + +static ssize_t nvmet_passthru_clear_ids_store(struct config_item *item, + const char *page, size_t count) +{ + struct nvmet_subsys *subsys = to_subsys(item->ci_parent); + unsigned int clear_ids; + + if (kstrtouint(page, 0, &clear_ids)) + return -EINVAL; + subsys->clear_ids = clear_ids; + return count; +} +CONFIGFS_ATTR(nvmet_passthru_, clear_ids); + static struct configfs_attribute *nvmet_passthru_attrs[] = { &nvmet_passthru_attr_device_path, &nvmet_passthru_attr_enable, &nvmet_passthru_attr_admin_timeout, &nvmet_passthru_attr_io_timeout, + &nvmet_passthru_attr_clear_ids, NULL, }; diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 90e75324dae0..c27660a660d9 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -1374,6 +1374,12 @@ u16 nvmet_alloc_ctrl(const char *subsysnqn, const char *hostnqn, ctrl->port = req->port; ctrl->ops = req->ops; +#ifdef CONFIG_NVME_TARGET_PASSTHRU + /* By default, set loop targets to clear IDS by default */ + if (ctrl->port->disc_addr.trtype == NVMF_TRTYPE_LOOP) + subsys->clear_ids = 1; +#endif + INIT_WORK(&ctrl->async_event_work, nvmet_async_event_work); INIT_LIST_HEAD(&ctrl->async_events); INIT_RADIX_TREE(&ctrl->p2p_ns_map, GFP_KERNEL); diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index 69818752a33a..2b3e5719f24e 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -249,6 +249,7 @@ struct nvmet_subsys { struct config_group passthru_group; unsigned int admin_timeout; unsigned int io_timeout; + unsigned int clear_ids; #endif /* CONFIG_NVME_TARGET_PASSTHRU */ #ifdef CONFIG_BLK_DEV_ZONED diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c index b1f7efab3918..6f39a29828b1 100644 --- a/drivers/nvme/target/passthru.c +++ b/drivers/nvme/target/passthru.c @@ -30,6 +30,53 @@ void nvmet_passthrough_override_cap(struct nvmet_ctrl *ctrl) ctrl->cap &= ~(1ULL << 43); } +static u16 nvmet_passthru_override_id_descs(struct nvmet_req *req) +{ + struct nvmet_ctrl *ctrl = req->sq->ctrl; + u16 status = NVME_SC_SUCCESS; + int pos, len; + bool csi_seen = false; + void *data; + u8 csi; + + if (!ctrl->subsys->clear_ids) + return status; + + data = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL); + if (!data) + return NVME_SC_INTERNAL; + + status = nvmet_copy_from_sgl(req, 0, data, NVME_IDENTIFY_DATA_SIZE); + if (status) + goto out_free; + + for (pos = 0; pos < NVME_IDENTIFY_DATA_SIZE; pos += len) { + struct nvme_ns_id_desc *cur = data + pos; + + if (cur->nidl == 0) + break; + if (cur->nidt == NVME_NIDT_CSI) { + memcpy(&csi, cur + 1, NVME_NIDT_CSI_LEN); + csi_seen = true; + break; + } + len = sizeof(struct nvme_ns_id_desc) + cur->nidl; + } + + memset(data, 0, NVME_IDENTIFY_DATA_SIZE); + if (csi_seen) { + struct nvme_ns_id_desc *cur = data; + + cur->nidt = NVME_NIDT_CSI; + cur->nidl = NVME_NIDT_CSI_LEN; + memcpy(cur + 1, &csi, NVME_NIDT_CSI_LEN); + } + status = nvmet_copy_to_sgl(req, 0, data, NVME_IDENTIFY_DATA_SIZE); +out_free: + kfree(data); + return status; +} + static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req) { struct nvmet_ctrl *ctrl = req->sq->ctrl; @@ -152,6 +199,11 @@ static u16 nvmet_passthru_override_id_ns(struct nvmet_req *req) */ id->mc = 0; + if (req->sq->ctrl->subsys->clear_ids) { + memset(id->nguid, 0, NVME_NIDT_NGUID_LEN); + memset(id->eui64, 0, NVME_NIDT_EUI64_LEN); + } + status = nvmet_copy_to_sgl(req, 0, id, sizeof(*id)); out_free: @@ -176,6 +228,9 @@ static void nvmet_passthru_execute_cmd_work(struct work_struct *w) case NVME_ID_CNS_NS: nvmet_passthru_override_id_ns(req); break; + case NVME_ID_CNS_NS_DESC_LIST: + nvmet_passthru_override_id_descs(req); + break; } } else if (status < 0) status = NVME_SC_INTERNAL; From e1c70d79346356bb1ede3f79436df80917845ab9 Mon Sep 17 00:00:00 2001 From: Lamarque Vieira Souza Date: Wed, 29 Jun 2022 21:30:53 -0300 Subject: [PATCH 151/246] nvme-pci: add NVME_QUIRK_BOGUS_NID for ADATA IM2P33F8ABR1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ADATA IM2P33F8ABR1 reports bogus eui64 values that appear to be the same across all drives. Quirk them out so they are not marked as "non globally unique" duplicates. Co-developed-by: Felipe de Jesus Araujo da Conceição Signed-off-by: Felipe de Jesus Araujo da Conceição Signed-off-by: Lamarque V. Souza Cc: stable@vger.kernel.org Signed-off-by: Christoph Hellwig --- drivers/nvme/host/pci.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index c9ebe6072498..e7af2234e53b 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -3469,6 +3469,8 @@ static const struct pci_device_id nvme_id_table[] = { { PCI_DEVICE(0x1b4b, 0x1092), /* Lexar 256 GB SSD */ .driver_data = NVME_QUIRK_NO_NS_DESC_LIST | NVME_QUIRK_IGNORE_DEV_SUBNQN, }, + { PCI_DEVICE(0x1cc1, 0x33f8), /* ADATA IM2P33F8ABR1 1 TB */ + .driver_data = NVME_QUIRK_BOGUS_NID, }, { PCI_DEVICE(0x10ec, 0x5762), /* ADATA SX6000LNP */ .driver_data = NVME_QUIRK_IGNORE_DEV_SUBNQN | NVME_QUIRK_BOGUS_NID, }, From 25deecb21c18ee29e3be8ac6177b2a9504c33d2d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jun 2022 02:09:00 +0900 Subject: [PATCH 152/246] s390: remove unneeded 'select BUILD_BIN2C' Since commit 4c0f032d4963 ("s390/purgatory: Omit use of bin2c"), s390 builds the purgatory without using bin2c. Remove 'select BUILD_BIN2C' to avoid the unneeded build of bin2c. Fixes: 4c0f032d4963 ("s390/purgatory: Omit use of bin2c") Signed-off-by: Masahiro Yamada Link: https://lore.kernel.org/r/20220613170902.1775211-1-masahiroy@kernel.org Signed-off-by: Alexander Gordeev --- arch/s390/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 91c0b80a8bf0..8cd9e56c629b 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -484,7 +484,6 @@ config KEXEC config KEXEC_FILE bool "kexec file based system call" select KEXEC_CORE - select BUILD_BIN2C depends on CRYPTO depends on CRYPTO_SHA256 depends on CRYPTO_SHA256_S390 From b9a56c113f907b19b91dc5c2383b0169831e15a4 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jun 2022 02:09:01 +0900 Subject: [PATCH 153/246] s390/purgatory: hard-code obj-y in Makefile The purgatory/ directory is entirely guarded in arch/s390/Kbuild. CONFIG_ARCH_HAS_KEXEC_PURGATORY is bool type. $(CONFIG_ARCH_HAS_KEXEC_PURGATORY) is always 'y' when Kbuild visits this Makefile for building. Signed-off-by: Masahiro Yamada Link: https://lore.kernel.org/r/20220613170902.1775211-2-masahiroy@kernel.org Signed-off-by: Alexander Gordeev --- arch/s390/purgatory/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/purgatory/Makefile b/arch/s390/purgatory/Makefile index 360ada80d20c..3e2c17ba04de 100644 --- a/arch/s390/purgatory/Makefile +++ b/arch/s390/purgatory/Makefile @@ -51,4 +51,4 @@ $(obj)/purgatory.ro: $(obj)/purgatory $(obj)/purgatory.chk FORCE $(obj)/kexec-purgatory.o: $(obj)/kexec-purgatory.S $(obj)/purgatory.ro FORCE $(call if_changed_rule,as_o_S) -obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += kexec-purgatory.o +obj-y += kexec-purgatory.o From 20159e287a031bd6a28429675ccc66b06372fa3c Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 14 Jun 2022 02:09:02 +0900 Subject: [PATCH 154/246] s390/purgatory: remove duplicated build rule of kexec-purgatory.o This is equivalent to the pattern rule in scripts/Makefile.build. Having the dependency on $(obj)/purgatory.ro is enough. Signed-off-by: Masahiro Yamada Link: https://lore.kernel.org/r/20220613170902.1775211-3-masahiroy@kernel.org Signed-off-by: Alexander Gordeev --- arch/s390/purgatory/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/s390/purgatory/Makefile b/arch/s390/purgatory/Makefile index 3e2c17ba04de..d237bc6841cb 100644 --- a/arch/s390/purgatory/Makefile +++ b/arch/s390/purgatory/Makefile @@ -48,7 +48,6 @@ OBJCOPYFLAGS_purgatory.ro += --remove-section='.note.*' $(obj)/purgatory.ro: $(obj)/purgatory $(obj)/purgatory.chk FORCE $(call if_changed,objcopy) -$(obj)/kexec-purgatory.o: $(obj)/kexec-purgatory.S $(obj)/purgatory.ro FORCE - $(call if_changed_rule,as_o_S) +$(obj)/kexec-purgatory.o: $(obj)/purgatory.ro obj-y += kexec-purgatory.o From 29c1ac230e6056b26846c66881802b581a78ad72 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Thu, 30 Jun 2022 13:25:57 +0100 Subject: [PATCH 155/246] io_uring: keep sendrecv flags in ioprio We waste a u64 SQE field for flags even though we don't need as many bits and it can be used for something more useful later. Store io_uring specific send/recv flags in sqe->ioprio instead of ->addr2. Signed-off-by: Pavel Begunkov Fixes: 0455d4ccec54 ("io_uring: add POLL_FIRST support for send/sendmsg and recv/recvmsg") [axboe: change comment in io_uring.h as well] Signed-off-by: Jens Axboe --- fs/io_uring.c | 12 ++++++++---- include/uapi/linux/io_uring.h | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 5ff2cdb425bc..aeb042ba5cc5 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -1183,6 +1183,7 @@ static const struct io_op_def io_op_defs[] = { .unbound_nonreg_file = 1, .pollout = 1, .needs_async_setup = 1, + .ioprio = 1, .async_size = sizeof(struct io_async_msghdr), }, [IORING_OP_RECVMSG] = { @@ -1191,6 +1192,7 @@ static const struct io_op_def io_op_defs[] = { .pollin = 1, .buffer_select = 1, .needs_async_setup = 1, + .ioprio = 1, .async_size = sizeof(struct io_async_msghdr), }, [IORING_OP_TIMEOUT] = { @@ -1266,6 +1268,7 @@ static const struct io_op_def io_op_defs[] = { .unbound_nonreg_file = 1, .pollout = 1, .audit_skip = 1, + .ioprio = 1, }, [IORING_OP_RECV] = { .needs_file = 1, @@ -1273,6 +1276,7 @@ static const struct io_op_def io_op_defs[] = { .pollin = 1, .buffer_select = 1, .audit_skip = 1, + .ioprio = 1, }, [IORING_OP_OPENAT2] = { }, @@ -6075,12 +6079,12 @@ static int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_sr_msg *sr = &req->sr_msg; - if (unlikely(sqe->file_index)) + if (unlikely(sqe->file_index || sqe->addr2)) return -EINVAL; sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr)); sr->len = READ_ONCE(sqe->len); - sr->flags = READ_ONCE(sqe->addr2); + sr->flags = READ_ONCE(sqe->ioprio); if (sr->flags & ~IORING_RECVSEND_POLL_FIRST) return -EINVAL; sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL; @@ -6311,12 +6315,12 @@ static int io_recvmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) { struct io_sr_msg *sr = &req->sr_msg; - if (unlikely(sqe->file_index)) + if (unlikely(sqe->file_index || sqe->addr2)) return -EINVAL; sr->umsg = u64_to_user_ptr(READ_ONCE(sqe->addr)); sr->len = READ_ONCE(sqe->len); - sr->flags = READ_ONCE(sqe->addr2); + sr->flags = READ_ONCE(sqe->ioprio); if (sr->flags & ~IORING_RECVSEND_POLL_FIRST) return -EINVAL; sr->msg_flags = READ_ONCE(sqe->msg_flags) | MSG_NOSIGNAL; diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 53e7dae92e42..f10b59d6693e 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -244,7 +244,7 @@ enum io_uring_op { #define IORING_ASYNC_CANCEL_ANY (1U << 2) /* - * send/sendmsg and recv/recvmsg flags (sqe->addr2) + * send/sendmsg and recv/recvmsg flags (sqe->ioprio) * * IORING_RECVSEND_POLL_FIRST If set, instead of first attempting to send * or receive and arm poll if that yields an From 09007af2b627f0f195c6c53c4829b285cc3990ec Mon Sep 17 00:00:00 2001 From: Dylan Yudaken Date: Thu, 30 Jun 2022 06:20:06 -0700 Subject: [PATCH 156/246] io_uring: fix provided buffer import io_import_iovec uses the s pointer, but this was changed immediately after the iovec was re-imported and so it was imported into the wrong place. Change the ordering. Fixes: 2be2eb02e2f5 ("io_uring: ensure reads re-import for selected buffers") Signed-off-by: Dylan Yudaken Link: https://lore.kernel.org/r/20220630132006.2825668-1-dylany@fb.com [axboe: ensure we don't half-import as well] Signed-off-by: Jens Axboe --- fs/io_uring.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index aeb042ba5cc5..0d491ad15b66 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -4318,18 +4318,19 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags) if (unlikely(ret < 0)) return ret; } else { + rw = req->async_data; + s = &rw->s; + /* * Safe and required to re-import if we're using provided * buffers, as we dropped the selected one before retry. */ - if (req->flags & REQ_F_BUFFER_SELECT) { + if (io_do_buffer_select(req)) { ret = io_import_iovec(READ, req, &iovec, s, issue_flags); if (unlikely(ret < 0)) return ret; } - rw = req->async_data; - s = &rw->s; /* * We come here from an earlier attempt, restore our state to * match in case it doesn't. It's cheap enough that we don't From e4f74400308cb8abde5fdc9cad609c2aba32110c Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Sat, 11 Jun 2022 00:20:23 +0200 Subject: [PATCH 157/246] s390/archrandom: simplify back to earlier design and initialize earlier s390x appears to present two RNG interfaces: - a "TRNG" that gathers entropy using some hardware function; and - a "DRBG" that takes in a seed and expands it. Previously, the TRNG was wired up to arch_get_random_{long,int}(), but it was observed that this was being called really frequently, resulting in high overhead. So it was changed to be wired up to arch_get_random_ seed_{long,int}(), which was a reasonable decision. Later on, the DRBG was then wired up to arch_get_random_{long,int}(), with a complicated buffer filling thread, to control overhead and rate. Fortunately, none of the performance issues matter much now. The RNG always attempts to use arch_get_random_seed_{long,int}() first, which means a complicated implementation of arch_get_random_{long,int}() isn't really valuable or useful to have around. And it's only used when reseeding, which means it won't hit the high throughput complications that were faced before. So this commit returns to an earlier design of just calling the TRNG in arch_get_random_seed_{long,int}(), and returning false in arch_get_ random_{long,int}(). Part of what makes the simplification possible is that the RNG now seeds itself using the TRNG at bootup. But this only works if the TRNG is detected early in boot, before random_init() is called. So this commit also causes that check to happen in setup_arch(). Cc: stable@vger.kernel.org Cc: Harald Freudenberger Cc: Ingo Franzki Cc: Juergen Christ Cc: Heiko Carstens Signed-off-by: Jason A. Donenfeld Link: https://lore.kernel.org/r/20220610222023.378448-1-Jason@zx2c4.com Reviewed-by: Harald Freudenberger Acked-by: Heiko Carstens Signed-off-by: Alexander Gordeev --- arch/s390/crypto/arch_random.c | 217 ----------------------------- arch/s390/include/asm/archrandom.h | 14 +- arch/s390/kernel/setup.c | 5 + 3 files changed, 12 insertions(+), 224 deletions(-) diff --git a/arch/s390/crypto/arch_random.c b/arch/s390/crypto/arch_random.c index 56007c763902..1f2d40993c4d 100644 --- a/arch/s390/crypto/arch_random.c +++ b/arch/s390/crypto/arch_random.c @@ -4,232 +4,15 @@ * * Copyright IBM Corp. 2017, 2020 * Author(s): Harald Freudenberger - * - * The s390_arch_random_generate() function may be called from random.c - * in interrupt context. So this implementation does the best to be very - * fast. There is a buffer of random data which is asynchronously checked - * and filled by a workqueue thread. - * If there are enough bytes in the buffer the s390_arch_random_generate() - * just delivers these bytes. Otherwise false is returned until the - * worker thread refills the buffer. - * The worker fills the rng buffer by pulling fresh entropy from the - * high quality (but slow) true hardware random generator. This entropy - * is then spread over the buffer with an pseudo random generator PRNG. - * As the arch_get_random_seed_long() fetches 8 bytes and the calling - * function add_interrupt_randomness() counts this as 1 bit entropy the - * distribution needs to make sure there is in fact 1 bit entropy contained - * in 8 bytes of the buffer. The current values pull 32 byte entropy - * and scatter this into a 2048 byte buffer. So 8 byte in the buffer - * will contain 1 bit of entropy. - * The worker thread is rescheduled based on the charge level of the - * buffer but at least with 500 ms delay to avoid too much CPU consumption. - * So the max. amount of rng data delivered via arch_get_random_seed is - * limited to 4k bytes per second. */ #include #include #include -#include #include -#include -#include #include DEFINE_STATIC_KEY_FALSE(s390_arch_random_available); atomic64_t s390_arch_random_counter = ATOMIC64_INIT(0); EXPORT_SYMBOL(s390_arch_random_counter); - -#define ARCH_REFILL_TICKS (HZ/2) -#define ARCH_PRNG_SEED_SIZE 32 -#define ARCH_RNG_BUF_SIZE 2048 - -static DEFINE_SPINLOCK(arch_rng_lock); -static u8 *arch_rng_buf; -static unsigned int arch_rng_buf_idx; - -static void arch_rng_refill_buffer(struct work_struct *); -static DECLARE_DELAYED_WORK(arch_rng_work, arch_rng_refill_buffer); - -bool s390_arch_random_generate(u8 *buf, unsigned int nbytes) -{ - /* max hunk is ARCH_RNG_BUF_SIZE */ - if (nbytes > ARCH_RNG_BUF_SIZE) - return false; - - /* lock rng buffer */ - if (!spin_trylock(&arch_rng_lock)) - return false; - - /* try to resolve the requested amount of bytes from the buffer */ - arch_rng_buf_idx -= nbytes; - if (arch_rng_buf_idx < ARCH_RNG_BUF_SIZE) { - memcpy(buf, arch_rng_buf + arch_rng_buf_idx, nbytes); - atomic64_add(nbytes, &s390_arch_random_counter); - spin_unlock(&arch_rng_lock); - return true; - } - - /* not enough bytes in rng buffer, refill is done asynchronously */ - spin_unlock(&arch_rng_lock); - - return false; -} -EXPORT_SYMBOL(s390_arch_random_generate); - -static void arch_rng_refill_buffer(struct work_struct *unused) -{ - unsigned int delay = ARCH_REFILL_TICKS; - - spin_lock(&arch_rng_lock); - if (arch_rng_buf_idx > ARCH_RNG_BUF_SIZE) { - /* buffer is exhausted and needs refill */ - u8 seed[ARCH_PRNG_SEED_SIZE]; - u8 prng_wa[240]; - /* fetch ARCH_PRNG_SEED_SIZE bytes of entropy */ - cpacf_trng(NULL, 0, seed, sizeof(seed)); - /* blow this entropy up to ARCH_RNG_BUF_SIZE with PRNG */ - memset(prng_wa, 0, sizeof(prng_wa)); - cpacf_prno(CPACF_PRNO_SHA512_DRNG_SEED, - &prng_wa, NULL, 0, seed, sizeof(seed)); - cpacf_prno(CPACF_PRNO_SHA512_DRNG_GEN, - &prng_wa, arch_rng_buf, ARCH_RNG_BUF_SIZE, NULL, 0); - arch_rng_buf_idx = ARCH_RNG_BUF_SIZE; - } - delay += (ARCH_REFILL_TICKS * arch_rng_buf_idx) / ARCH_RNG_BUF_SIZE; - spin_unlock(&arch_rng_lock); - - /* kick next check */ - queue_delayed_work(system_long_wq, &arch_rng_work, delay); -} - -/* - * Here follows the implementation of s390_arch_get_random_long(). - * - * The random longs to be pulled by arch_get_random_long() are - * prepared in an 4K buffer which is filled from the NIST 800-90 - * compliant s390 drbg. By default the random long buffer is refilled - * 256 times before the drbg itself needs a reseed. The reseed of the - * drbg is done with 32 bytes fetched from the high quality (but slow) - * trng which is assumed to deliver 100% entropy. So the 32 * 8 = 256 - * bits of entropy are spread over 256 * 4KB = 1MB serving 131072 - * arch_get_random_long() invocations before reseeded. - * - * How often the 4K random long buffer is refilled with the drbg - * before the drbg is reseeded can be adjusted. There is a module - * parameter 's390_arch_rnd_long_drbg_reseed' accessible via - * /sys/module/arch_random/parameters/rndlong_drbg_reseed - * or as kernel command line parameter - * arch_random.rndlong_drbg_reseed= - * This parameter tells how often the drbg fills the 4K buffer before - * it is re-seeded by fresh entropy from the trng. - * A value of 16 results in reseeding the drbg at every 16 * 4 KB = 64 - * KB with 32 bytes of fresh entropy pulled from the trng. So a value - * of 16 would result in 256 bits entropy per 64 KB. - * A value of 256 results in 1MB of drbg output before a reseed of the - * drbg is done. So this would spread the 256 bits of entropy among 1MB. - * Setting this parameter to 0 forces the reseed to take place every - * time the 4K buffer is depleted, so the entropy rises to 256 bits - * entropy per 4K or 0.5 bit entropy per arch_get_random_long(). With - * setting this parameter to negative values all this effort is - * disabled, arch_get_random long() returns false and thus indicating - * that the arch_get_random_long() feature is disabled at all. - */ - -static unsigned long rndlong_buf[512]; -static DEFINE_SPINLOCK(rndlong_lock); -static int rndlong_buf_index; - -static int rndlong_drbg_reseed = 256; -module_param_named(rndlong_drbg_reseed, rndlong_drbg_reseed, int, 0600); -MODULE_PARM_DESC(rndlong_drbg_reseed, "s390 arch_get_random_long() drbg reseed"); - -static inline void refill_rndlong_buf(void) -{ - static u8 prng_ws[240]; - static int drbg_counter; - - if (--drbg_counter < 0) { - /* need to re-seed the drbg */ - u8 seed[32]; - - /* fetch seed from trng */ - cpacf_trng(NULL, 0, seed, sizeof(seed)); - /* seed drbg */ - memset(prng_ws, 0, sizeof(prng_ws)); - cpacf_prno(CPACF_PRNO_SHA512_DRNG_SEED, - &prng_ws, NULL, 0, seed, sizeof(seed)); - /* re-init counter for drbg */ - drbg_counter = rndlong_drbg_reseed; - } - - /* fill the arch_get_random_long buffer from drbg */ - cpacf_prno(CPACF_PRNO_SHA512_DRNG_GEN, &prng_ws, - (u8 *) rndlong_buf, sizeof(rndlong_buf), - NULL, 0); -} - -bool s390_arch_get_random_long(unsigned long *v) -{ - bool rc = false; - unsigned long flags; - - /* arch_get_random_long() disabled ? */ - if (rndlong_drbg_reseed < 0) - return false; - - /* try to lock the random long lock */ - if (!spin_trylock_irqsave(&rndlong_lock, flags)) - return false; - - if (--rndlong_buf_index >= 0) { - /* deliver next long value from the buffer */ - *v = rndlong_buf[rndlong_buf_index]; - rc = true; - goto out; - } - - /* buffer is depleted and needs refill */ - if (in_interrupt()) { - /* delay refill in interrupt context to next caller */ - rndlong_buf_index = 0; - goto out; - } - - /* refill random long buffer */ - refill_rndlong_buf(); - rndlong_buf_index = ARRAY_SIZE(rndlong_buf); - - /* and provide one random long */ - *v = rndlong_buf[--rndlong_buf_index]; - rc = true; - -out: - spin_unlock_irqrestore(&rndlong_lock, flags); - return rc; -} -EXPORT_SYMBOL(s390_arch_get_random_long); - -static int __init s390_arch_random_init(void) -{ - /* all the needed PRNO subfunctions available ? */ - if (cpacf_query_func(CPACF_PRNO, CPACF_PRNO_TRNG) && - cpacf_query_func(CPACF_PRNO, CPACF_PRNO_SHA512_DRNG_GEN)) { - - /* alloc arch random working buffer */ - arch_rng_buf = kmalloc(ARCH_RNG_BUF_SIZE, GFP_KERNEL); - if (!arch_rng_buf) - return -ENOMEM; - - /* kick worker queue job to fill the random buffer */ - queue_delayed_work(system_long_wq, - &arch_rng_work, ARCH_REFILL_TICKS); - - /* enable arch random to the outside world */ - static_branch_enable(&s390_arch_random_available); - } - - return 0; -} -arch_initcall(s390_arch_random_init); diff --git a/arch/s390/include/asm/archrandom.h b/arch/s390/include/asm/archrandom.h index 5dc712fde3c7..2c6e1c6ecbe7 100644 --- a/arch/s390/include/asm/archrandom.h +++ b/arch/s390/include/asm/archrandom.h @@ -15,17 +15,13 @@ #include #include +#include DECLARE_STATIC_KEY_FALSE(s390_arch_random_available); extern atomic64_t s390_arch_random_counter; -bool s390_arch_get_random_long(unsigned long *v); -bool s390_arch_random_generate(u8 *buf, unsigned int nbytes); - static inline bool __must_check arch_get_random_long(unsigned long *v) { - if (static_branch_likely(&s390_arch_random_available)) - return s390_arch_get_random_long(v); return false; } @@ -37,7 +33,9 @@ static inline bool __must_check arch_get_random_int(unsigned int *v) static inline bool __must_check arch_get_random_seed_long(unsigned long *v) { if (static_branch_likely(&s390_arch_random_available)) { - return s390_arch_random_generate((u8 *)v, sizeof(*v)); + cpacf_trng(NULL, 0, (u8 *)v, sizeof(*v)); + atomic64_add(sizeof(*v), &s390_arch_random_counter); + return true; } return false; } @@ -45,7 +43,9 @@ static inline bool __must_check arch_get_random_seed_long(unsigned long *v) static inline bool __must_check arch_get_random_seed_int(unsigned int *v) { if (static_branch_likely(&s390_arch_random_available)) { - return s390_arch_random_generate((u8 *)v, sizeof(*v)); + cpacf_trng(NULL, 0, (u8 *)v, sizeof(*v)); + atomic64_add(sizeof(*v), &s390_arch_random_counter); + return true; } return false; } diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 8d91eccc0963..0a37f5de2863 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -875,6 +875,11 @@ static void __init setup_randomness(void) if (stsi(vmms, 3, 2, 2) == 0 && vmms->count) add_device_randomness(&vmms->vm, sizeof(vmms->vm[0]) * vmms->count); memblock_free(vmms, PAGE_SIZE); + +#ifdef CONFIG_ARCH_RANDOM + if (cpacf_query_func(CPACF_PRNO, CPACF_PRNO_TRNG)) + static_branch_enable(&s390_arch_random_available); +#endif } /* From d608f45ed3cfd411a409cec93fa64232181752ff Mon Sep 17 00:00:00 2001 From: Jiang Jian Date: Wed, 22 Jun 2022 22:27:13 +0800 Subject: [PATCH 158/246] s390/sclp: Fix typo in comments Remove the repeated word 'and' from comments Signed-off-by: Jiang Jian Reviewed-by: Kees Cook Link: https://lore.kernel.org/r/20220622142713.14187-1-jiangjian@cdjrlc.com Signed-off-by: Alexander Gordeev --- drivers/s390/char/sclp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index cb2491761958..ae1d6ee382a5 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -60,7 +60,7 @@ static LIST_HEAD(sclp_reg_list); /* List of queued requests. */ static LIST_HEAD(sclp_req_queue); -/* Data for read and and init requests. */ +/* Data for read and init requests. */ static struct sclp_req sclp_read_req; static struct sclp_req sclp_init_req; static void *sclp_read_sccb; From d7d488f41b41a1b7a1df3c74f2f65eb4585f5d55 Mon Sep 17 00:00:00 2001 From: Zhang Jiaming Date: Thu, 23 Jun 2022 14:05:43 +0800 Subject: [PATCH 159/246] s390/qdio: Fix spelling mistake Change 'defineable' to 'definable'. Change 'paramater' to 'parameter'. Signed-off-by: Zhang Jiaming Reviewed-by: Benjamin Block Link: https://lore.kernel.org/r/20220623060543.12870-1-jiaming@nfschina.com Signed-off-by: Alexander Gordeev --- arch/s390/include/asm/qdio.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h index 54ae2dc65e3b..2f983e0b95e0 100644 --- a/arch/s390/include/asm/qdio.h +++ b/arch/s390/include/asm/qdio.h @@ -133,9 +133,9 @@ struct slibe { * @sb_count: number of storage blocks * @sba: storage block element addresses * @dcount: size of storage block elements - * @user0: user defineable value - * @res4: reserved paramater - * @user1: user defineable value + * @user0: user definable value + * @res4: reserved parameter + * @user1: user definable value */ struct qaob { u64 res0[6]; From 62f46fc7b8c639bc97cc9c69e063c40970b6e14c Mon Sep 17 00:00:00 2001 From: Sumeet Pawnikar Date: Fri, 6 May 2022 19:20:09 +0530 Subject: [PATCH 160/246] thermal: intel_tcc_cooling: Add TCC cooling support for RaptorLake Add RaptorLake to the list of processor models supported by the Intel TCC cooling driver. Signed-off-by: Sumeet Pawnikar [ rjw: Subject edits, new changelog ] Signed-off-by: Rafael J. Wysocki --- drivers/thermal/intel/intel_tcc_cooling.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/thermal/intel/intel_tcc_cooling.c b/drivers/thermal/intel/intel_tcc_cooling.c index cd80c7db4073..a9596e7562ea 100644 --- a/drivers/thermal/intel/intel_tcc_cooling.c +++ b/drivers/thermal/intel/intel_tcc_cooling.c @@ -81,6 +81,7 @@ static const struct x86_cpu_id tcc_ids[] __initconst = { X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE, NULL), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE, NULL), X86_MATCH_INTEL_FAM6_MODEL(ALDERLAKE_L, NULL), + X86_MATCH_INTEL_FAM6_MODEL(RAPTORLAKE, NULL), {} }; From 1adb1563e7b7ec659379a18e607e8bc3522d8a78 Mon Sep 17 00:00:00 2001 From: Lukasz Cieplicki Date: Tue, 31 May 2022 12:54:20 +0200 Subject: [PATCH 161/246] i40e: Fix dropped jumbo frames statistics Dropped packets caused by too large frames were not included in dropped RX packets statistics. Issue was caused by not reading the GL_RXERR1 register. That register stores count of packet which was have been dropped due to too large size. Fix it by reading GL_RXERR1 register for each interface. Repro steps: Send a packet larger than the set MTU to SUT Observe rx statists: ethtool -S | grep rx | grep -v ": 0" Fixes: 41a9e55c89be ("i40e: add missing VSI statistics") Signed-off-by: Lukasz Cieplicki Signed-off-by: Jedrzej Jagielski Tested-by: Gurucharan (A Contingent worker at Intel) Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/i40e/i40e.h | 16 ++++ drivers/net/ethernet/intel/i40e/i40e_main.c | 73 +++++++++++++++++++ .../net/ethernet/intel/i40e/i40e_register.h | 13 ++++ drivers/net/ethernet/intel/i40e/i40e_type.h | 1 + 4 files changed, 103 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 18558a019353..407fe8f340a0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -37,6 +37,7 @@ #include #include #include +#include #include "i40e_type.h" #include "i40e_prototype.h" #include @@ -1092,6 +1093,21 @@ static inline void i40e_write_fd_input_set(struct i40e_pf *pf, (u32)(val & 0xFFFFFFFFULL)); } +/** + * i40e_get_pf_count - get PCI PF count. + * @hw: pointer to a hw. + * + * Reports the function number of the highest PCI physical + * function plus 1 as it is loaded from the NVM. + * + * Return: PCI PF count. + **/ +static inline u32 i40e_get_pf_count(struct i40e_hw *hw) +{ + return FIELD_GET(I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK, + rd32(hw, I40E_GLGEN_PCIFCNCNT)); +} + /* needed by i40e_ethtool.c */ int i40e_up(struct i40e_vsi *vsi); void i40e_down(struct i40e_vsi *vsi); diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 72576bb3e94d..aa786fd55951 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -550,6 +550,47 @@ void i40e_pf_reset_stats(struct i40e_pf *pf) pf->hw_csum_rx_error = 0; } +/** + * i40e_compute_pci_to_hw_id - compute index form PCI function. + * @vsi: ptr to the VSI to read from. + * @hw: ptr to the hardware info. + **/ +static u32 i40e_compute_pci_to_hw_id(struct i40e_vsi *vsi, struct i40e_hw *hw) +{ + int pf_count = i40e_get_pf_count(hw); + + if (vsi->type == I40E_VSI_SRIOV) + return (hw->port * BIT(7)) / pf_count + vsi->vf_id; + + return hw->port + BIT(7); +} + +/** + * i40e_stat_update64 - read and update a 64 bit stat from the chip. + * @hw: ptr to the hardware info. + * @hireg: the high 32 bit reg to read. + * @loreg: the low 32 bit reg to read. + * @offset_loaded: has the initial offset been loaded yet. + * @offset: ptr to current offset value. + * @stat: ptr to the stat. + * + * Since the device stats are not reset at PFReset, they will not + * be zeroed when the driver starts. We'll save the first values read + * and use them as offsets to be subtracted from the raw values in order + * to report stats that count from zero. + **/ +static void i40e_stat_update64(struct i40e_hw *hw, u32 hireg, u32 loreg, + bool offset_loaded, u64 *offset, u64 *stat) +{ + u64 new_data; + + new_data = rd64(hw, loreg); + + if (!offset_loaded || new_data < *offset) + *offset = new_data; + *stat = new_data - *offset; +} + /** * i40e_stat_update48 - read and update a 48 bit stat from the chip * @hw: ptr to the hardware info @@ -621,6 +662,34 @@ static void i40e_stat_update_and_clear32(struct i40e_hw *hw, u32 reg, u64 *stat) *stat += new_data; } +/** + * i40e_stats_update_rx_discards - update rx_discards. + * @vsi: ptr to the VSI to be updated. + * @hw: ptr to the hardware info. + * @stat_idx: VSI's stat_counter_idx. + * @offset_loaded: ptr to the VSI's stat_offsets_loaded. + * @stat_offset: ptr to stat_offset to store first read of specific register. + * @stat: ptr to VSI's stat to be updated. + **/ +static void +i40e_stats_update_rx_discards(struct i40e_vsi *vsi, struct i40e_hw *hw, + int stat_idx, bool offset_loaded, + struct i40e_eth_stats *stat_offset, + struct i40e_eth_stats *stat) +{ + u64 rx_rdpc, rx_rxerr; + + i40e_stat_update32(hw, I40E_GLV_RDPC(stat_idx), offset_loaded, + &stat_offset->rx_discards, &rx_rdpc); + i40e_stat_update64(hw, + I40E_GL_RXERR1H(i40e_compute_pci_to_hw_id(vsi, hw)), + I40E_GL_RXERR1L(i40e_compute_pci_to_hw_id(vsi, hw)), + offset_loaded, &stat_offset->rx_discards_other, + &rx_rxerr); + + stat->rx_discards = rx_rdpc + rx_rxerr; +} + /** * i40e_update_eth_stats - Update VSI-specific ethernet statistics counters. * @vsi: the VSI to be updated @@ -680,6 +749,10 @@ void i40e_update_eth_stats(struct i40e_vsi *vsi) I40E_GLV_BPTCL(stat_idx), vsi->stat_offsets_loaded, &oes->tx_broadcast, &es->tx_broadcast); + + i40e_stats_update_rx_discards(vsi, hw, stat_idx, + vsi->stat_offsets_loaded, oes, es); + vsi->stat_offsets_loaded = true; } diff --git a/drivers/net/ethernet/intel/i40e/i40e_register.h b/drivers/net/ethernet/intel/i40e/i40e_register.h index 1908eed4fa5e..7339003aa17c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_register.h +++ b/drivers/net/ethernet/intel/i40e/i40e_register.h @@ -211,6 +211,11 @@ #define I40E_GLGEN_MSRWD_MDIWRDATA_SHIFT 0 #define I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT 16 #define I40E_GLGEN_MSRWD_MDIRDDATA_MASK I40E_MASK(0xFFFF, I40E_GLGEN_MSRWD_MDIRDDATA_SHIFT) +#define I40E_GLGEN_PCIFCNCNT 0x001C0AB4 /* Reset: PCIR */ +#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT 0 +#define I40E_GLGEN_PCIFCNCNT_PCIPFCNT_MASK I40E_MASK(0x1F, I40E_GLGEN_PCIFCNCNT_PCIPFCNT_SHIFT) +#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT 16 +#define I40E_GLGEN_PCIFCNCNT_PCIVFCNT_MASK I40E_MASK(0xFF, I40E_GLGEN_PCIFCNCNT_PCIVFCNT_SHIFT) #define I40E_GLGEN_RSTAT 0x000B8188 /* Reset: POR */ #define I40E_GLGEN_RSTAT_DEVSTATE_SHIFT 0 #define I40E_GLGEN_RSTAT_DEVSTATE_MASK I40E_MASK(0x3, I40E_GLGEN_RSTAT_DEVSTATE_SHIFT) @@ -643,6 +648,14 @@ #define I40E_VFQF_HKEY1_MAX_INDEX 12 #define I40E_VFQF_HLUT1(_i, _VF) (0x00220000 + ((_i) * 1024 + (_VF) * 4)) /* _i=0...15, _VF=0...127 */ /* Reset: CORER */ #define I40E_VFQF_HLUT1_MAX_INDEX 15 +#define I40E_GL_RXERR1H(_i) (0x00318004 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */ +#define I40E_GL_RXERR1H_MAX_INDEX 143 +#define I40E_GL_RXERR1H_RXERR1H_SHIFT 0 +#define I40E_GL_RXERR1H_RXERR1H_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1H_RXERR1H_SHIFT) +#define I40E_GL_RXERR1L(_i) (0x00318000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */ +#define I40E_GL_RXERR1L_MAX_INDEX 143 +#define I40E_GL_RXERR1L_RXERR1L_SHIFT 0 +#define I40E_GL_RXERR1L_RXERR1L_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1L_RXERR1L_SHIFT) #define I40E_GLPRT_BPRCH(_i) (0x003005E4 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */ #define I40E_GLPRT_BPRCL(_i) (0x003005E0 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */ #define I40E_GLPRT_BPTCH(_i) (0x00300A04 + ((_i) * 8)) /* _i=0...3 */ /* Reset: CORER */ diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index 36a4ca1ffb1a..7b3f30beb757 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -1172,6 +1172,7 @@ struct i40e_eth_stats { u64 tx_broadcast; /* bptc */ u64 tx_discards; /* tdpc */ u64 tx_errors; /* tepc */ + u64 rx_discards_other; /* rxerr1 */ }; /* Statistics collected per VEB per TC */ From fed0d9f13266a22ce1fc9a97521ef9cdc6271a23 Mon Sep 17 00:00:00 2001 From: Norbert Zulinski Date: Wed, 8 Jun 2022 11:10:56 +0200 Subject: [PATCH 162/246] i40e: Fix VF's MAC Address change on VM Clear VF MAC from parent PF and remove VF filter from VSI when both conditions are true: -VIRTCHNL_VF_OFFLOAD_USO is not used -VM MAC was not set from PF level It affects older version of IAVF and it allow them to change MAC Address on VM, newer IAVF won't change their behaviour. Previously it wasn't possible to change VF's MAC Address on VM because there is flag on IAVF driver that won't allow to change MAC Address if this address is given from PF driver. Fixes: 155f0ac2c96b ("iavf: allow permanent MAC address to change") Signed-off-by: Norbert Zulinski Signed-off-by: Jan Sokolowski Tested-by: Konrad Jankowski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 033ea71763e3..86b0f21287dc 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -2147,6 +2147,10 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg) /* VFs only use TC 0 */ vfres->vsi_res[0].qset_handle = le16_to_cpu(vsi->info.qs_handle[0]); + if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) { + i40e_del_mac_filter(vsi, vf->default_lan_addr.addr); + eth_zero_addr(vf->default_lan_addr.addr); + } ether_addr_copy(vfres->vsi_res[0].default_mac_addr, vf->default_lan_addr.addr); } From 080abad71e99d2becf38c978572982130b927a28 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 23 Jun 2022 14:47:34 +1000 Subject: [PATCH 163/246] NFS: restore module put when manager exits. Commit f49169c97fce ("NFSD: Remove svc_serv_ops::svo_module") removed calls to module_put_and_kthread_exit() from threads that acted as SUNRPC servers and had a related svc_serv_ops structure. This was correct. It ALSO removed the module_put_and_kthread_exit() call from nfs4_run_state_manager() which is NOT a SUNRPC service. Consequently every time the NFSv4 state manager runs the module count increments and won't be decremented. So the nfsv4 module cannot be unloaded. So restore the module_put_and_kthread_exit() call. Fixes: f49169c97fce ("NFSD: Remove svc_serv_ops::svo_module") Signed-off-by: NeilBrown Signed-off-by: Anna Schumaker --- fs/nfs/nfs4state.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 2540b35ec187..9bab3e9c702a 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -2753,5 +2753,6 @@ again: goto again; nfs_put_client(clp); + module_put_and_kthread_exit(0); return 0; } From 4f40a5b5544618b096d1611a18219dd91fd57f80 Mon Sep 17 00:00:00 2001 From: Scott Mayhew Date: Mon, 27 Jun 2022 17:31:29 -0400 Subject: [PATCH 164/246] NFSv4: Add an fattr allocation to _nfs4_discover_trunking() This was missed in c3ed222745d9 ("NFSv4: Fix free of uninitialized nfs4_label on referral lookup.") and causes a panic when mounting with '-o trunkdiscovery': PID: 1604 TASK: ffff93dac3520000 CPU: 3 COMMAND: "mount.nfs" #0 [ffffb79140f738f8] machine_kexec at ffffffffaec64bee #1 [ffffb79140f73950] __crash_kexec at ffffffffaeda67fd #2 [ffffb79140f73a18] crash_kexec at ffffffffaeda76ed #3 [ffffb79140f73a30] oops_end at ffffffffaec2658d #4 [ffffb79140f73a50] general_protection at ffffffffaf60111e [exception RIP: nfs_fattr_init+0x5] RIP: ffffffffc0c18265 RSP: ffffb79140f73b08 RFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff93dac304a800 RCX: 0000000000000000 RDX: ffffb79140f73bb0 RSI: ffff93dadc8cbb40 RDI: d03ee11cfaf6bd50 RBP: ffffb79140f73be8 R8: ffffffffc0691560 R9: 0000000000000006 R10: ffff93db3ffd3df8 R11: 0000000000000000 R12: ffff93dac4040000 R13: ffff93dac2848e00 R14: ffffb79140f73b60 R15: ffffb79140f73b30 ORIG_RAX: ffffffffffffffff CS: 0010 SS: 0018 #5 [ffffb79140f73b08] _nfs41_proc_get_locations at ffffffffc0c73d53 [nfsv4] #6 [ffffb79140f73bf0] nfs4_proc_get_locations at ffffffffc0c83e90 [nfsv4] #7 [ffffb79140f73c60] nfs4_discover_trunking at ffffffffc0c83fb7 [nfsv4] #8 [ffffb79140f73cd8] nfs_probe_fsinfo at ffffffffc0c0f95f [nfs] #9 [ffffb79140f73da0] nfs_probe_server at ffffffffc0c1026a [nfs] RIP: 00007f6254fce26e RSP: 00007ffc69496ac8 RFLAGS: 00000246 RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f6254fce26e RDX: 00005600220a82a0 RSI: 00005600220a64d0 RDI: 00005600220a6520 RBP: 00007ffc69496c50 R8: 00005600220a8710 R9: 003035322e323231 R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffc69496c50 R13: 00005600220a8440 R14: 0000000000000010 R15: 0000560020650ef9 ORIG_RAX: 00000000000000a5 CS: 0033 SS: 002b Fixes: c3ed222745d9 ("NFSv4: Fix free of uninitialized nfs4_label on referral lookup.") Signed-off-by: Scott Mayhew Signed-off-by: Anna Schumaker --- fs/nfs/nfs4proc.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index c0fdcf8c0032..bb0e84a46d61 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4012,22 +4012,29 @@ static int _nfs4_discover_trunking(struct nfs_server *server, } page = alloc_page(GFP_KERNEL); + if (!page) + return -ENOMEM; locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL); - if (page == NULL || locations == NULL) - goto out; + if (!locations) + goto out_free; + locations->fattr = nfs_alloc_fattr(); + if (!locations->fattr) + goto out_free_2; status = nfs4_proc_get_locations(server, fhandle, locations, page, cred); if (status) - goto out; + goto out_free_3; for (i = 0; i < locations->nlocations; i++) test_fs_location_for_trunking(&locations->locations[i], clp, server); -out: - if (page) - __free_page(page); +out_free_3: + kfree(locations->fattr); +out_free_2: kfree(locations); +out_free: + __free_page(page); return status; } From a23dd544debcda4ee4a549ec7de59e85c3c8345c Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 30 Jun 2022 16:48:18 -0400 Subject: [PATCH 165/246] SUNRPC: Fix READ_PLUS crasher Looks like there are still cases when "space_left - frag1bytes" can legitimately exceed PAGE_SIZE. Ensure that xdr->end always remains within the current encode buffer. Reported-by: Bruce Fields Reported-by: Zorro Lang Link: https://bugzilla.kernel.org/show_bug.cgi?id=216151 Fixes: 6c254bf3b637 ("SUNRPC: Fix the calculation of xdr->end in xdr_get_next_encode_buffer()") Signed-off-by: Chuck Lever --- net/sunrpc/xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index f87a2d8f23a7..5d2b3e6979fb 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -984,7 +984,7 @@ static noinline __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, p = page_address(*xdr->page_ptr); xdr->p = p + frag2bytes; space_left = xdr->buf->buflen - xdr->buf->len; - if (space_left - nbytes >= PAGE_SIZE) + if (space_left - frag1bytes >= PAGE_SIZE) xdr->end = p + PAGE_SIZE; else xdr->end = p + space_left - frag1bytes; From 2f446ffe9d737e9a844b97887919c4fda18246e7 Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Fri, 1 Jul 2022 08:23:54 +0200 Subject: [PATCH 166/246] xen/blkfront: fix leaking data in shared pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When allocating pages to be used for shared communication with the backend always zero them, this avoids leaking unintended data present on the pages. This is CVE-2022-26365, part of XSA-403. Signed-off-by: Roger Pau Monné Reviewed-by: Jan Beulich Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- drivers/block/xen-blkfront.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 33f04ef78984..4b3bef6ace68 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -311,7 +311,7 @@ static int fill_grant_buffer(struct blkfront_ring_info *rinfo, int num) goto out_of_memory; if (info->feature_persistent) { - granted_page = alloc_page(GFP_NOIO); + granted_page = alloc_page(GFP_NOIO | __GFP_ZERO); if (!granted_page) { kfree(gnt_list_entry); goto out_of_memory; @@ -2183,7 +2183,8 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo) BUG_ON(!list_empty(&rinfo->indirect_pages)); for (i = 0; i < num; i++) { - struct page *indirect_page = alloc_page(GFP_KERNEL); + struct page *indirect_page = alloc_page(GFP_KERNEL | + __GFP_ZERO); if (!indirect_page) goto out_of_memory; list_add(&indirect_page->lru, &rinfo->indirect_pages); From 307c8de2b02344805ebead3440d8feed28f2f010 Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Wed, 6 Apr 2022 17:38:04 +0200 Subject: [PATCH 167/246] xen/netfront: fix leaking data in shared pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When allocating pages to be used for shared communication with the backend always zero them, this avoids leaking unintended data present on the pages. This is CVE-2022-33740, part of XSA-403. Signed-off-by: Roger Pau Monné Reviewed-by: Jan Beulich Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- drivers/net/xen-netfront.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 8c0b9546d5a2..e3165139629d 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -271,7 +271,8 @@ static struct sk_buff *xennet_alloc_one_rx_buffer(struct netfront_queue *queue) if (unlikely(!skb)) return NULL; - page = page_pool_dev_alloc_pages(queue->page_pool); + page = page_pool_alloc_pages(queue->page_pool, + GFP_ATOMIC | __GFP_NOWARN | __GFP_ZERO); if (unlikely(!page)) { kfree_skb(skb); return NULL; From 4491001c2e0fa69efbb748c96ec96b100a5cdb7e Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Thu, 7 Apr 2022 12:20:06 +0200 Subject: [PATCH 168/246] xen/netfront: force data bouncing when backend is untrusted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bounce all data on the skbs to be transmitted into zeroed pages if the backend is untrusted. This avoids leaking data present in the pages shared with the backend but not part of the skb fragments. This requires introducing a new helper in order to allocate skbs with a size multiple of XEN_PAGE_SIZE so we don't leak contiguous data on the granted pages. Reporting whether the backend is to be trusted can be done using a module parameter, or from the xenstore frontend path as set by the toolstack when adding the device. This is CVE-2022-33741, part of XSA-403. Signed-off-by: Roger Pau Monné Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- drivers/net/xen-netfront.c | 49 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index e3165139629d..87f6df77bfbf 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -66,6 +66,10 @@ module_param_named(max_queues, xennet_max_queues, uint, 0644); MODULE_PARM_DESC(max_queues, "Maximum number of queues per virtual interface"); +static bool __read_mostly xennet_trusted = true; +module_param_named(trusted, xennet_trusted, bool, 0644); +MODULE_PARM_DESC(trusted, "Is the backend trusted"); + #define XENNET_TIMEOUT (5 * HZ) static const struct ethtool_ops xennet_ethtool_ops; @@ -173,6 +177,9 @@ struct netfront_info { /* Is device behaving sane? */ bool broken; + /* Should skbs be bounced into a zeroed buffer? */ + bool bounce; + atomic_t rx_gso_checksum_fixup; }; @@ -666,6 +673,33 @@ static int xennet_xdp_xmit(struct net_device *dev, int n, return nxmit; } +struct sk_buff *bounce_skb(const struct sk_buff *skb) +{ + unsigned int headerlen = skb_headroom(skb); + /* Align size to allocate full pages and avoid contiguous data leaks */ + unsigned int size = ALIGN(skb_end_offset(skb) + skb->data_len, + XEN_PAGE_SIZE); + struct sk_buff *n = alloc_skb(size, GFP_ATOMIC | __GFP_ZERO); + + if (!n) + return NULL; + + if (!IS_ALIGNED((uintptr_t)n->head, XEN_PAGE_SIZE)) { + WARN_ONCE(1, "misaligned skb allocated\n"); + kfree_skb(n); + return NULL; + } + + /* Set the data pointer */ + skb_reserve(n, headerlen); + /* Set the tail pointer and length */ + skb_put(n, skb->len); + + BUG_ON(skb_copy_bits(skb, -headerlen, n->head, headerlen + skb->len)); + + skb_copy_header(n, skb); + return n; +} #define MAX_XEN_SKB_FRAGS (65536 / XEN_PAGE_SIZE + 1) @@ -719,9 +753,13 @@ static netdev_tx_t xennet_start_xmit(struct sk_buff *skb, struct net_device *dev /* The first req should be at least ETH_HLEN size or the packet will be * dropped by netback. + * + * If the backend is not trusted bounce all data to zeroed pages to + * avoid exposing contiguous data on the granted page not belonging to + * the skb. */ - if (unlikely(PAGE_SIZE - offset < ETH_HLEN)) { - nskb = skb_copy(skb, GFP_ATOMIC); + if (np->bounce || unlikely(PAGE_SIZE - offset < ETH_HLEN)) { + nskb = bounce_skb(skb); if (!nskb) goto drop; dev_consume_skb_any(skb); @@ -2215,6 +2253,10 @@ static int talk_to_netback(struct xenbus_device *dev, info->netdev->irq = 0; + /* Check if backend is trusted. */ + info->bounce = !xennet_trusted || + !xenbus_read_unsigned(dev->nodename, "trusted", 1); + /* Check if backend supports multiple queues */ max_queues = xenbus_read_unsigned(info->xbdev->otherend, "multi-queue-max-queues", 1); @@ -2382,6 +2424,9 @@ static int xennet_connect(struct net_device *dev) return err; if (np->netback_has_xdp_headroom) pr_info("backend supports XDP headroom\n"); + if (np->bounce) + dev_info(&np->xbdev->dev, + "bouncing transmitted data to zeroed pages\n"); /* talk_to_netback() sets the correct number of queues */ num_queues = dev->real_num_tx_queues; From 2400617da7eebf9167d71a46122828bc479d64c9 Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Thu, 7 Apr 2022 13:04:24 +0200 Subject: [PATCH 169/246] xen/blkfront: force data bouncing when backend is untrusted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split the current bounce buffering logic used with persistent grants into it's own option, and allow enabling it independently of persistent grants. This allows to reuse the same code paths to perform the bounce buffering required to avoid leaking contiguous data in shared pages not part of the request fragments. Reporting whether the backend is to be trusted can be done using a module parameter, or from the xenstore frontend path as set by the toolstack when adding the device. This is CVE-2022-33742, part of XSA-403. Signed-off-by: Roger Pau Monné Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- drivers/block/xen-blkfront.c | 49 +++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 4b3bef6ace68..3646c0cae672 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -152,6 +152,10 @@ static unsigned int xen_blkif_max_ring_order; module_param_named(max_ring_page_order, xen_blkif_max_ring_order, int, 0444); MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the shared ring"); +static bool __read_mostly xen_blkif_trusted = true; +module_param_named(trusted, xen_blkif_trusted, bool, 0644); +MODULE_PARM_DESC(trusted, "Is the backend trusted"); + #define BLK_RING_SIZE(info) \ __CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages) @@ -210,6 +214,7 @@ struct blkfront_info unsigned int feature_discard:1; unsigned int feature_secdiscard:1; unsigned int feature_persistent:1; + unsigned int bounce:1; unsigned int discard_granularity; unsigned int discard_alignment; /* Number of 4KB segments handled */ @@ -310,7 +315,7 @@ static int fill_grant_buffer(struct blkfront_ring_info *rinfo, int num) if (!gnt_list_entry) goto out_of_memory; - if (info->feature_persistent) { + if (info->bounce) { granted_page = alloc_page(GFP_NOIO | __GFP_ZERO); if (!granted_page) { kfree(gnt_list_entry); @@ -330,7 +335,7 @@ out_of_memory: list_for_each_entry_safe(gnt_list_entry, n, &rinfo->grants, node) { list_del(&gnt_list_entry->node); - if (info->feature_persistent) + if (info->bounce) __free_page(gnt_list_entry->page); kfree(gnt_list_entry); i--; @@ -376,7 +381,7 @@ static struct grant *get_grant(grant_ref_t *gref_head, /* Assign a gref to this page */ gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); BUG_ON(gnt_list_entry->gref == -ENOSPC); - if (info->feature_persistent) + if (info->bounce) grant_foreign_access(gnt_list_entry, info); else { /* Grant access to the GFN passed by the caller */ @@ -400,7 +405,7 @@ static struct grant *get_indirect_grant(grant_ref_t *gref_head, /* Assign a gref to this page */ gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); BUG_ON(gnt_list_entry->gref == -ENOSPC); - if (!info->feature_persistent) { + if (!info->bounce) { struct page *indirect_page; /* Fetch a pre-allocated page to use for indirect grefs */ @@ -703,7 +708,7 @@ static int blkif_queue_rw_req(struct request *req, struct blkfront_ring_info *ri .grant_idx = 0, .segments = NULL, .rinfo = rinfo, - .need_copy = rq_data_dir(req) && info->feature_persistent, + .need_copy = rq_data_dir(req) && info->bounce, }; /* @@ -981,11 +986,12 @@ static void xlvbd_flush(struct blkfront_info *info) { blk_queue_write_cache(info->rq, info->feature_flush ? true : false, info->feature_fua ? true : false); - pr_info("blkfront: %s: %s %s %s %s %s\n", + pr_info("blkfront: %s: %s %s %s %s %s %s %s\n", info->gd->disk_name, flush_info(info), "persistent grants:", info->feature_persistent ? "enabled;" : "disabled;", "indirect descriptors:", - info->max_indirect_segments ? "enabled;" : "disabled;"); + info->max_indirect_segments ? "enabled;" : "disabled;", + "bounce buffer:", info->bounce ? "enabled" : "disabled;"); } static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) @@ -1207,7 +1213,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) if (!list_empty(&rinfo->indirect_pages)) { struct page *indirect_page, *n; - BUG_ON(info->feature_persistent); + BUG_ON(info->bounce); list_for_each_entry_safe(indirect_page, n, &rinfo->indirect_pages, lru) { list_del(&indirect_page->lru); __free_page(indirect_page); @@ -1224,7 +1230,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) NULL); rinfo->persistent_gnts_c--; } - if (info->feature_persistent) + if (info->bounce) __free_page(persistent_gnt->page); kfree(persistent_gnt); } @@ -1245,7 +1251,7 @@ static void blkif_free_ring(struct blkfront_ring_info *rinfo) for (j = 0; j < segs; j++) { persistent_gnt = rinfo->shadow[i].grants_used[j]; gnttab_end_foreign_access(persistent_gnt->gref, NULL); - if (info->feature_persistent) + if (info->bounce) __free_page(persistent_gnt->page); kfree(persistent_gnt); } @@ -1428,7 +1434,7 @@ static int blkif_completion(unsigned long *id, data.s = s; num_sg = s->num_sg; - if (bret->operation == BLKIF_OP_READ && info->feature_persistent) { + if (bret->operation == BLKIF_OP_READ && info->bounce) { for_each_sg(s->sg, sg, num_sg, i) { BUG_ON(sg->offset + sg->length > PAGE_SIZE); @@ -1487,7 +1493,7 @@ static int blkif_completion(unsigned long *id, * Add the used indirect page back to the list of * available pages for indirect grefs. */ - if (!info->feature_persistent) { + if (!info->bounce) { indirect_page = s->indirect_grants[i]->page; list_add(&indirect_page->lru, &rinfo->indirect_pages); } @@ -1764,6 +1770,10 @@ static int talk_to_blkback(struct xenbus_device *dev, if (!info) return -ENODEV; + /* Check if backend is trusted. */ + info->bounce = !xen_blkif_trusted || + !xenbus_read_unsigned(dev->nodename, "trusted", 1); + max_page_order = xenbus_read_unsigned(info->xbdev->otherend, "max-ring-page-order", 0); ring_page_order = min(xen_blkif_max_ring_order, max_page_order); @@ -2173,10 +2183,10 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo) if (err) goto out_of_memory; - if (!info->feature_persistent && info->max_indirect_segments) { + if (!info->bounce && info->max_indirect_segments) { /* - * We are using indirect descriptors but not persistent - * grants, we need to allocate a set of pages that can be + * We are using indirect descriptors but don't have a bounce + * buffer, we need to allocate a set of pages that can be * used for mapping indirect grefs */ int num = INDIRECT_GREFS(grants) * BLK_RING_SIZE(info); @@ -2277,6 +2287,8 @@ static void blkfront_gather_backend_features(struct blkfront_info *info) info->feature_persistent = !!xenbus_read_unsigned(info->xbdev->otherend, "feature-persistent", 0); + if (info->feature_persistent) + info->bounce = true; indirect_segments = xenbus_read_unsigned(info->xbdev->otherend, "feature-max-indirect-segments", 0); @@ -2548,6 +2560,13 @@ static void blkfront_delay_work(struct work_struct *work) struct blkfront_info *info; bool need_schedule_work = false; + /* + * Note that when using bounce buffers but not persistent grants + * there's no need to run blkfront_delay_work because grants are + * revoked in blkif_completion or else an error is reported and the + * connection is closed. + */ + mutex_lock(&blkfront_mutex); list_for_each_entry(info, &info_list, info_list) { From f63c2c2032c2e3caad9add3b82cc6e91c376fd26 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 1 Jul 2022 08:56:52 +0200 Subject: [PATCH 170/246] xen-netfront: restore __skb_queue_tail() positioning in xennet_get_responses() The commit referenced below moved the invocation past the "next" label, without any explanation. In fact this allows misbehaving backends undue control over the domain the frontend runs in, as earlier detected errors require the skb to not be freed (it may be retained for later processing via xennet_move_rx_slot(), or it may simply be unsafe to have it freed). This is CVE-2022-33743 / XSA-405. Fixes: 6c5aa6fc4def ("xen networking: add basic XDP support for xen-netfront") Signed-off-by: Jan Beulich Reviewed-by: Juergen Gross Signed-off-by: Juergen Gross --- drivers/net/xen-netfront.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 87f6df77bfbf..2409007f1fd9 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1092,8 +1092,10 @@ static int xennet_get_responses(struct netfront_queue *queue, } } rcu_read_unlock(); -next: + __skb_queue_tail(list, skb); + +next: if (!(rx->flags & XEN_NETRXF_more_data)) break; From b75cd218274e01d026dc5240e86fdeb44bbed0c8 Mon Sep 17 00:00:00 2001 From: Oleksandr Tyshchenko Date: Fri, 1 Jul 2022 08:57:44 +0200 Subject: [PATCH 171/246] xen/arm: Fix race in RB-tree based P2M accounting During the PV driver life cycle the mappings are added to the RB-tree by set_foreign_p2m_mapping(), which is called from gnttab_map_refs() and are removed by clear_foreign_p2m_mapping() which is called from gnttab_unmap_refs(). As both functions end up calling __set_phys_to_machine_multi() which updates the RB-tree, this function can be called concurrently. There is already a "p2m_lock" to protect against concurrent accesses, but the problem is that the first read of "phys_to_mach.rb_node" in __set_phys_to_machine_multi() is not covered by it, so this might lead to the incorrect mappings update (removing in our case) in RB-tree. In my environment the related issue happens rarely and only when PV net backend is running, the xen_add_phys_to_mach_entry() claims that it cannot add new pfn <-> mfn mapping to the tree since it is already exists which results in a failure when mapping foreign pages. But there might be other bad consequences related to the non-protected root reads such use-after-free, etc. While at it, also fix the similar usage in __pfn_to_mfn(), so initialize "struct rb_node *n" with the "p2m_lock" held in both functions to avoid possible bad consequences. This is CVE-2022-33744 / XSA-406. Signed-off-by: Oleksandr Tyshchenko Reviewed-by: Stefano Stabellini Signed-off-by: Juergen Gross --- arch/arm/xen/p2m.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c index 84a1cea1f43b..309648c17f48 100644 --- a/arch/arm/xen/p2m.c +++ b/arch/arm/xen/p2m.c @@ -63,11 +63,12 @@ out: unsigned long __pfn_to_mfn(unsigned long pfn) { - struct rb_node *n = phys_to_mach.rb_node; + struct rb_node *n; struct xen_p2m_entry *entry; unsigned long irqflags; read_lock_irqsave(&p2m_lock, irqflags); + n = phys_to_mach.rb_node; while (n) { entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys); if (entry->pfn <= pfn && @@ -152,10 +153,11 @@ bool __set_phys_to_machine_multi(unsigned long pfn, int rc; unsigned long irqflags; struct xen_p2m_entry *p2m_entry; - struct rb_node *n = phys_to_mach.rb_node; + struct rb_node *n; if (mfn == INVALID_P2M_ENTRY) { write_lock_irqsave(&p2m_lock, irqflags); + n = phys_to_mach.rb_node; while (n) { p2m_entry = rb_entry(n, struct xen_p2m_entry, rbnode_phys); if (p2m_entry->pfn <= pfn && From 8dfeee9dc52cb979cf520f6b345e7baa6b29ecb4 Mon Sep 17 00:00:00 2001 From: Li kunyu Date: Fri, 1 Jul 2022 14:47:23 +0800 Subject: [PATCH 172/246] net: usb: Fix typo in code Remove the repeated ';' from code. Signed-off-by: Li kunyu Signed-off-by: David S. Miller --- drivers/net/usb/catc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index e7fe9c0f63a9..1a376ed45d7a 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c @@ -781,7 +781,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id intf->altsetting->desc.bInterfaceNumber, 1)) { dev_err(dev, "Can't set altsetting 1.\n"); ret = -EIO; - goto fail_mem;; + goto fail_mem; } netdev = alloc_etherdev(sizeof(struct catc)); From 620f83b8326ce9706b1118334f0257ae028ce045 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 26 Jun 2022 09:43:15 +0200 Subject: [PATCH 173/246] soc: ixp4xx/npe: Fix unused match warning The kernel test robot found this inconsistency: drivers/soc/ixp4xx/ixp4xx-npe.c:737:34: warning: 'ixp4xx_npe_of_match' defined but not used [-Wunused-const-variable=] 737 | static const struct of_device_id ixp4xx_npe_of_match[] = { This is because the match is enclosed in the of_match_ptr() which compiles into NULL when OF is disabled and this is unnecessary. Fix it by dropping of_match_ptr() around the match. Signed-off-by: Linus Walleij Link: https://lore.kernel.org/r/20220626074315.61209-1-linus.walleij@linaro.org' Signed-off-by: Arnd Bergmann --- drivers/soc/ixp4xx/ixp4xx-npe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c index 613935cb6a48..58240e320c13 100644 --- a/drivers/soc/ixp4xx/ixp4xx-npe.c +++ b/drivers/soc/ixp4xx/ixp4xx-npe.c @@ -758,7 +758,7 @@ static const struct of_device_id ixp4xx_npe_of_match[] = { static struct platform_driver ixp4xx_npe_driver = { .driver = { .name = "ixp4xx-npe", - .of_match_table = of_match_ptr(ixp4xx_npe_of_match), + .of_match_table = ixp4xx_npe_of_match, }, .probe = ixp4xx_npe_probe, .remove = ixp4xx_npe_remove, From 7561cea5dbb97fecb952548a0fb74fb105bf4664 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Fri, 1 Jul 2022 09:08:33 -0700 Subject: [PATCH 174/246] xfs: prevent a UAF when log IO errors race with unmount KASAN reported the following use after free bug when running generic/475: XFS (dm-0): Mounting V5 Filesystem XFS (dm-0): Starting recovery (logdev: internal) XFS (dm-0): Ending recovery (logdev: internal) Buffer I/O error on dev dm-0, logical block 20639616, async page read Buffer I/O error on dev dm-0, logical block 20639617, async page read XFS (dm-0): log I/O error -5 XFS (dm-0): Filesystem has been shut down due to log error (0x2). XFS (dm-0): Unmounting Filesystem XFS (dm-0): Please unmount the filesystem and rectify the problem(s). ================================================================== BUG: KASAN: use-after-free in do_raw_spin_lock+0x246/0x270 Read of size 4 at addr ffff888109dd84c4 by task 3:1H/136 CPU: 3 PID: 136 Comm: 3:1H Not tainted 5.19.0-rc4-xfsx #rc4 8e53ab5ad0fddeb31cee5e7063ff9c361915a9c4 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 Workqueue: xfs-log/dm-0 xlog_ioend_work [xfs] Call Trace: dump_stack_lvl+0x34/0x44 print_report.cold+0x2b8/0x661 ? do_raw_spin_lock+0x246/0x270 kasan_report+0xab/0x120 ? do_raw_spin_lock+0x246/0x270 do_raw_spin_lock+0x246/0x270 ? rwlock_bug.part.0+0x90/0x90 xlog_force_shutdown+0xf6/0x370 [xfs 4ad76ae0d6add7e8183a553e624c31e9ed567318] xlog_ioend_work+0x100/0x190 [xfs 4ad76ae0d6add7e8183a553e624c31e9ed567318] process_one_work+0x672/0x1040 worker_thread+0x59b/0xec0 ? __kthread_parkme+0xc6/0x1f0 ? process_one_work+0x1040/0x1040 ? process_one_work+0x1040/0x1040 kthread+0x29e/0x340 ? kthread_complete_and_exit+0x20/0x20 ret_from_fork+0x1f/0x30 Allocated by task 154099: kasan_save_stack+0x1e/0x40 __kasan_kmalloc+0x81/0xa0 kmem_alloc+0x8d/0x2e0 [xfs] xlog_cil_init+0x1f/0x540 [xfs] xlog_alloc_log+0xd1e/0x1260 [xfs] xfs_log_mount+0xba/0x640 [xfs] xfs_mountfs+0xf2b/0x1d00 [xfs] xfs_fs_fill_super+0x10af/0x1910 [xfs] get_tree_bdev+0x383/0x670 vfs_get_tree+0x7d/0x240 path_mount+0xdb7/0x1890 __x64_sys_mount+0x1fa/0x270 do_syscall_64+0x2b/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 Freed by task 154151: kasan_save_stack+0x1e/0x40 kasan_set_track+0x21/0x30 kasan_set_free_info+0x20/0x30 ____kasan_slab_free+0x110/0x190 slab_free_freelist_hook+0xab/0x180 kfree+0xbc/0x310 xlog_dealloc_log+0x1b/0x2b0 [xfs] xfs_unmountfs+0x119/0x200 [xfs] xfs_fs_put_super+0x6e/0x2e0 [xfs] generic_shutdown_super+0x12b/0x3a0 kill_block_super+0x95/0xd0 deactivate_locked_super+0x80/0x130 cleanup_mnt+0x329/0x4d0 task_work_run+0xc5/0x160 exit_to_user_mode_prepare+0xd4/0xe0 syscall_exit_to_user_mode+0x1d/0x40 entry_SYSCALL_64_after_hwframe+0x46/0xb0 This appears to be a race between the unmount process, which frees the CIL and waits for in-flight iclog IO; and the iclog IO completion. When generic/475 runs, it starts fsstress in the background, waits a few seconds, and substitutes a dm-error device to simulate a disk falling out of a machine. If the fsstress encounters EIO on a pure data write, it will exit but the filesystem will still be online. The next thing the test does is unmount the filesystem, which tries to clean the log, free the CIL, and wait for iclog IO completion. If an iclog was being written when the dm-error switch occurred, it can race with log unmounting as follows: Thread 1 Thread 2 xfs_log_unmount xfs_log_clean xfs_log_quiesce xlog_ioend_work xlog_force_shutdown test_and_set_bit(XLOG_IOERROR) xfs_log_force xfs_log_umount_write xlog_dealloc_log xlog_cil_destroy spin_lock(&log->l_cilp->xc_push_lock) Therefore, free the CIL after waiting for the iclogs to complete. I /think/ this race has existed for quite a few years now, though I don't remember the ~2014 era logging code well enough to know if it was a real threat then or if the actual race was exposed only more recently. Fixes: ac983517ec59 ("xfs: don't sleep in xlog_cil_force_lsn on shutdown") Signed-off-by: Darrick J. Wong Reviewed-by: Dave Chinner --- fs/xfs/xfs_log.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 1e972f884a81..ae904b21e9cc 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -2092,8 +2092,6 @@ xlog_dealloc_log( xlog_in_core_t *iclog, *next_iclog; int i; - xlog_cil_destroy(log); - /* * Cycle all the iclogbuf locks to make sure all log IO completion * is done before we tear down these buffers. @@ -2105,6 +2103,13 @@ xlog_dealloc_log( iclog = iclog->ic_next; } + /* + * Destroy the CIL after waiting for iclog IO completion because an + * iclog EIO error will try to shut down the log, which accesses the + * CIL to wake up the waiters. + */ + xlog_cil_destroy(log); + iclog = log->l_iclog; for (i = 0; i < log->l_iclog_bufs; i++) { next_iclog = iclog->ic_next; From 410982303772993a86bb7a9cfa7ece34522b2636 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Wed, 29 Jun 2022 10:53:49 +0100 Subject: [PATCH 175/246] arm64: hugetlb: Restore TLB invalidation for BBM on contiguous ptes Commit fb396bb459c1 ("arm64/hugetlb: Drop TLB flush from get_clear_flush()") removed TLB invalidation from get_clear_flush() [now get_clear_contig()] on the basis that the core TLB invalidation code is aware of hugetlb mappings backed by contiguous page-table entries and will cover the correct virtual address range. However, this change also resulted in the TLB invalidation being removed from the "break" step in the break-before-make (BBM) sequence used internally by huge_ptep_set_{access_flags,wrprotect}(), therefore making the BBM sequence unsafe irrespective of later invalidation. Although the architecture is desperately unclear about how exactly contiguous ptes should be updated in a live page-table, restore TLB invalidation to our BBM sequence under the assumption that BBM is the right thing to be doing in the first place. Fixes: fb396bb459c1 ("arm64/hugetlb: Drop TLB flush from get_clear_flush()") Cc: Ard Biesheuvel Cc: Steve Capper Cc: Anshuman Khandual Cc: Mike Kravetz Cc: Marc Zyngier Signed-off-by: Will Deacon Reviewed-by: Catalin Marinas Reviewed-by: Anshuman Khandual Link: https://lore.kernel.org/r/20220629095349.25748-1-will@kernel.org Signed-off-by: Catalin Marinas --- arch/arm64/mm/hugetlbpage.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index e2a5ec9fdc0d..3618ef3f6d81 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -214,6 +214,19 @@ static pte_t get_clear_contig(struct mm_struct *mm, return orig_pte; } +static pte_t get_clear_contig_flush(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, + unsigned long pgsize, + unsigned long ncontig) +{ + pte_t orig_pte = get_clear_contig(mm, addr, ptep, pgsize, ncontig); + struct vm_area_struct vma = TLB_FLUSH_VMA(mm, 0); + + flush_tlb_range(&vma, addr, addr + (pgsize * ncontig)); + return orig_pte; +} + /* * Changing some bits of contiguous entries requires us to follow a * Break-Before-Make approach, breaking the whole contiguous set @@ -447,19 +460,20 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma, int ncontig, i; size_t pgsize = 0; unsigned long pfn = pte_pfn(pte), dpfn; + struct mm_struct *mm = vma->vm_mm; pgprot_t hugeprot; pte_t orig_pte; if (!pte_cont(pte)) return ptep_set_access_flags(vma, addr, ptep, pte, dirty); - ncontig = find_num_contig(vma->vm_mm, addr, ptep, &pgsize); + ncontig = find_num_contig(mm, addr, ptep, &pgsize); dpfn = pgsize >> PAGE_SHIFT; if (!__cont_access_flags_changed(ptep, pte, ncontig)) return 0; - orig_pte = get_clear_contig(vma->vm_mm, addr, ptep, pgsize, ncontig); + orig_pte = get_clear_contig_flush(mm, addr, ptep, pgsize, ncontig); /* Make sure we don't lose the dirty or young state */ if (pte_dirty(orig_pte)) @@ -470,7 +484,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma, hugeprot = pte_pgprot(pte); for (i = 0; i < ncontig; i++, ptep++, addr += pgsize, pfn += dpfn) - set_pte_at(vma->vm_mm, addr, ptep, pfn_pte(pfn, hugeprot)); + set_pte_at(mm, addr, ptep, pfn_pte(pfn, hugeprot)); return 1; } @@ -492,7 +506,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm, ncontig = find_num_contig(mm, addr, ptep, &pgsize); dpfn = pgsize >> PAGE_SHIFT; - pte = get_clear_contig(mm, addr, ptep, pgsize, ncontig); + pte = get_clear_contig_flush(mm, addr, ptep, pgsize, ncontig); pte = pte_wrprotect(pte); hugeprot = pte_pgprot(pte); @@ -505,17 +519,15 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm, pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { + struct mm_struct *mm = vma->vm_mm; size_t pgsize; int ncontig; - pte_t orig_pte; if (!pte_cont(READ_ONCE(*ptep))) return ptep_clear_flush(vma, addr, ptep); - ncontig = find_num_contig(vma->vm_mm, addr, ptep, &pgsize); - orig_pte = get_clear_contig(vma->vm_mm, addr, ptep, pgsize, ncontig); - flush_tlb_range(vma, addr, addr + pgsize * ncontig); - return orig_pte; + ncontig = find_num_contig(mm, addr, ptep, &pgsize); + return get_clear_contig_flush(mm, addr, ptep, pgsize, ncontig); } static int __init hugetlbpage_init(void) From d0e51022a025ca5350fafb8e413a6fe5d4baf833 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Fri, 1 Jul 2022 15:41:53 +0800 Subject: [PATCH 176/246] hwmon: (ibmaem) don't call platform_device_del() if platform_device_add() fails If platform_device_add() fails, it no need to call platform_device_del(), split platform_device_unregister() into platform_device_del/put(), so platform_device_put() can be called separately. Fixes: 8808a793f052 ("ibmaem: new driver for power/energy/temp meters in IBM System X hardware") Reported-by: Hulk Robot Signed-off-by: Yang Yingliang Link: https://lore.kernel.org/r/20220701074153.4021556-1-yangyingliang@huawei.com Signed-off-by: Guenter Roeck --- drivers/hwmon/ibmaem.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index 5c4cf742f5ae..157e232aace0 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c @@ -550,7 +550,7 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) res = platform_device_add(data->pdev); if (res) - goto ipmi_err; + goto dev_add_err; platform_set_drvdata(data->pdev, data); @@ -598,7 +598,9 @@ hwmon_reg_err: ipmi_destroy_user(data->ipmi.user); ipmi_err: platform_set_drvdata(data->pdev, NULL); - platform_device_unregister(data->pdev); + platform_device_del(data->pdev); +dev_add_err: + platform_device_put(data->pdev); dev_err: ida_free(&aem_ida, data->id); id_err: @@ -690,7 +692,7 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, res = platform_device_add(data->pdev); if (res) - goto ipmi_err; + goto dev_add_err; platform_set_drvdata(data->pdev, data); @@ -738,7 +740,9 @@ hwmon_reg_err: ipmi_destroy_user(data->ipmi.user); ipmi_err: platform_set_drvdata(data->pdev, NULL); - platform_device_unregister(data->pdev); + platform_device_del(data->pdev); +dev_add_err: + platform_device_put(data->pdev); dev_err: ida_free(&aem_ida, data->id); id_err: From a12ca6277eca6aeeccf66e840c23a2b520e24c8f Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Fri, 1 Jul 2022 14:47:24 +0200 Subject: [PATCH 177/246] bpf: Fix incorrect verifier simulation around jmp32's jeq/jne Kuee reported a quirk in the jmp32's jeq/jne simulation, namely that the register value does not match expectations for the fall-through path. For example: Before fix: 0: R1=ctx(off=0,imm=0) R10=fp0 0: (b7) r2 = 0 ; R2_w=P0 1: (b7) r6 = 563 ; R6_w=P563 2: (87) r2 = -r2 ; R2_w=Pscalar() 3: (87) r2 = -r2 ; R2_w=Pscalar() 4: (4c) w2 |= w6 ; R2_w=Pscalar(umin=563,umax=4294967295,var_off=(0x233; 0xfffffdcc),s32_min=-2147483085) R6_w=P563 5: (56) if w2 != 0x8 goto pc+1 ; R2_w=P571 <--- [*] 6: (95) exit R0 !read_ok After fix: 0: R1=ctx(off=0,imm=0) R10=fp0 0: (b7) r2 = 0 ; R2_w=P0 1: (b7) r6 = 563 ; R6_w=P563 2: (87) r2 = -r2 ; R2_w=Pscalar() 3: (87) r2 = -r2 ; R2_w=Pscalar() 4: (4c) w2 |= w6 ; R2_w=Pscalar(umin=563,umax=4294967295,var_off=(0x233; 0xfffffdcc),s32_min=-2147483085) R6_w=P563 5: (56) if w2 != 0x8 goto pc+1 ; R2_w=P8 <--- [*] 6: (95) exit R0 !read_ok As can be seen on line 5 for the branch fall-through path in R2 [*] is that given condition w2 != 0x8 is false, verifier should conclude that r2 = 8 as upper 32 bit are known to be zero. However, verifier incorrectly concludes that r2 = 571 which is far off. The problem is it only marks false{true}_reg as known in the switch for JE/NE case, but at the end of the function, it uses {false,true}_{64,32}off to update {false,true}_reg->var_off and they still hold the prior value of {false,true}_reg->var_off before it got marked as known. The subsequent __reg_combine_32_into_64() then propagates this old var_off and derives new bounds. The information between min/max bounds on {false,true}_reg from setting the register to known const combined with the {false,true}_reg->var_off based on the old information then derives wrong register data. Fix it by detangling the BPF_JEQ/BPF_JNE cases and updating relevant {false,true}_{64,32}off tnums along with the register marking to known constant. Fixes: 3f50f132d840 ("bpf: Verifier, do explicit ALU32 bounds tracking") Reported-by: Kuee K1r0a Signed-off-by: Daniel Borkmann Signed-off-by: Andrii Nakryiko Acked-by: John Fastabend Link: https://lore.kernel.org/bpf/20220701124727.11153-1-daniel@iogearbox.net --- kernel/bpf/verifier.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index aedac2ac02b9..ec164b3c0fa2 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -9577,26 +9577,33 @@ static void reg_set_min_max(struct bpf_reg_state *true_reg, return; switch (opcode) { + /* JEQ/JNE comparison doesn't change the register equivalence. + * + * r1 = r2; + * if (r1 == 42) goto label; + * ... + * label: // here both r1 and r2 are known to be 42. + * + * Hence when marking register as known preserve it's ID. + */ case BPF_JEQ: - case BPF_JNE: - { - struct bpf_reg_state *reg = - opcode == BPF_JEQ ? true_reg : false_reg; - - /* JEQ/JNE comparison doesn't change the register equivalence. - * r1 = r2; - * if (r1 == 42) goto label; - * ... - * label: // here both r1 and r2 are known to be 42. - * - * Hence when marking register as known preserve it's ID. - */ - if (is_jmp32) - __mark_reg32_known(reg, val32); - else - ___mark_reg_known(reg, val); + if (is_jmp32) { + __mark_reg32_known(true_reg, val32); + true_32off = tnum_subreg(true_reg->var_off); + } else { + ___mark_reg_known(true_reg, val); + true_64off = true_reg->var_off; + } + break; + case BPF_JNE: + if (is_jmp32) { + __mark_reg32_known(false_reg, val32); + false_32off = tnum_subreg(false_reg->var_off); + } else { + ___mark_reg_known(false_reg, val); + false_64off = false_reg->var_off; + } break; - } case BPF_JSET: if (is_jmp32) { false_32off = tnum_and(false_32off, tnum_const(~val32)); From 3844d153a41adea718202c10ae91dc96b37453b5 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Fri, 1 Jul 2022 14:47:25 +0200 Subject: [PATCH 178/246] bpf: Fix insufficient bounds propagation from adjust_scalar_min_max_vals Kuee reported a corner case where the tnum becomes constant after the call to __reg_bound_offset(), but the register's bounds are not, that is, its min bounds are still not equal to the register's max bounds. This in turn allows to leak pointers through turning a pointer register as is into an unknown scalar via adjust_ptr_min_max_vals(). Before: func#0 @0 0: R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) 0: (b7) r0 = 1 ; R0_w=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) 1: (b7) r3 = 0 ; R3_w=scalar(imm=0,umax=0,var_off=(0x0; 0x0)) 2: (87) r3 = -r3 ; R3_w=scalar() 3: (87) r3 = -r3 ; R3_w=scalar() 4: (47) r3 |= 32767 ; R3_w=scalar(smin=-9223372036854743041,umin=32767,var_off=(0x7fff; 0xffffffffffff8000),s32_min=-2147450881) 5: (75) if r3 s>= 0x0 goto pc+1 ; R3_w=scalar(umin=9223372036854808575,var_off=(0x8000000000007fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767) 6: (95) exit from 5 to 7: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) 7: (d5) if r3 s<= 0x8000 goto pc+1 ; R3=scalar(umin=32769,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767) 8: (95) exit from 7 to 9: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=32768,var_off=(0x7fff; 0x8000)) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) 9: (07) r3 += -32767 ; R3_w=scalar(imm=0,umax=1,var_off=(0x0; 0x0)) <--- [*] 10: (95) exit What can be seen here is that R3=scalar(umin=32767,umax=32768,var_off=(0x7fff; 0x8000)) after the operation R3 += -32767 results in a 'malformed' constant, that is, R3_w=scalar(imm=0,umax=1,var_off=(0x0; 0x0)). Intersecting with var_off has not been done at that point via __update_reg_bounds(), which would have improved the umax to be equal to umin. Refactor the tnum <> min/max bounds information flow into a reg_bounds_sync() helper and use it consistently everywhere. After the fix, bounds have been corrected to R3_w=scalar(imm=0,umax=0,var_off=(0x0; 0x0)) and thus the register is regarded as a 'proper' constant scalar of 0. After: func#0 @0 0: R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) 0: (b7) r0 = 1 ; R0_w=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) 1: (b7) r3 = 0 ; R3_w=scalar(imm=0,umax=0,var_off=(0x0; 0x0)) 2: (87) r3 = -r3 ; R3_w=scalar() 3: (87) r3 = -r3 ; R3_w=scalar() 4: (47) r3 |= 32767 ; R3_w=scalar(smin=-9223372036854743041,umin=32767,var_off=(0x7fff; 0xffffffffffff8000),s32_min=-2147450881) 5: (75) if r3 s>= 0x0 goto pc+1 ; R3_w=scalar(umin=9223372036854808575,var_off=(0x8000000000007fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767) 6: (95) exit from 5 to 7: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) 7: (d5) if r3 s<= 0x8000 goto pc+1 ; R3=scalar(umin=32769,umax=9223372036854775807,var_off=(0x7fff; 0x7fffffffffff8000),s32_min=-2147450881,u32_min=32767) 8: (95) exit from 7 to 9: R0=scalar(imm=1,umin=1,umax=1,var_off=(0x1; 0x0)) R1=ctx(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) R3=scalar(umin=32767,umax=32768,var_off=(0x7fff; 0x8000)) R10=fp(off=0,imm=0,umax=0,var_off=(0x0; 0x0)) 9: (07) r3 += -32767 ; R3_w=scalar(imm=0,umax=0,var_off=(0x0; 0x0)) <--- [*] 10: (95) exit Fixes: b03c9f9fdc37 ("bpf/verifier: track signed and unsigned min/max values") Reported-by: Kuee K1r0a Signed-off-by: Daniel Borkmann Signed-off-by: Andrii Nakryiko Acked-by: John Fastabend Link: https://lore.kernel.org/bpf/20220701124727.11153-2-daniel@iogearbox.net --- kernel/bpf/verifier.c | 72 ++++++++++++++----------------------------- 1 file changed, 23 insertions(+), 49 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index ec164b3c0fa2..0efbac0fd126 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1562,6 +1562,21 @@ static void __reg_bound_offset(struct bpf_reg_state *reg) reg->var_off = tnum_or(tnum_clear_subreg(var64_off), var32_off); } +static void reg_bounds_sync(struct bpf_reg_state *reg) +{ + /* We might have learned new bounds from the var_off. */ + __update_reg_bounds(reg); + /* We might have learned something about the sign bit. */ + __reg_deduce_bounds(reg); + /* We might have learned some bits from the bounds. */ + __reg_bound_offset(reg); + /* Intersecting with the old var_off might have improved our bounds + * slightly, e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc), + * then new var_off is (0; 0x7f...fc) which improves our umax. + */ + __update_reg_bounds(reg); +} + static bool __reg32_bound_s64(s32 a) { return a >= 0 && a <= S32_MAX; @@ -1603,16 +1618,8 @@ static void __reg_combine_32_into_64(struct bpf_reg_state *reg) * so they do not impact tnum bounds calculation. */ __mark_reg64_unbounded(reg); - __update_reg_bounds(reg); } - - /* Intersecting with the old var_off might have improved our bounds - * slightly. e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc), - * then new var_off is (0; 0x7f...fc) which improves our umax. - */ - __reg_deduce_bounds(reg); - __reg_bound_offset(reg); - __update_reg_bounds(reg); + reg_bounds_sync(reg); } static bool __reg64_bound_s32(s64 a) @@ -1628,7 +1635,6 @@ static bool __reg64_bound_u32(u64 a) static void __reg_combine_64_into_32(struct bpf_reg_state *reg) { __mark_reg32_unbounded(reg); - if (__reg64_bound_s32(reg->smin_value) && __reg64_bound_s32(reg->smax_value)) { reg->s32_min_value = (s32)reg->smin_value; reg->s32_max_value = (s32)reg->smax_value; @@ -1637,14 +1643,7 @@ static void __reg_combine_64_into_32(struct bpf_reg_state *reg) reg->u32_min_value = (u32)reg->umin_value; reg->u32_max_value = (u32)reg->umax_value; } - - /* Intersecting with the old var_off might have improved our bounds - * slightly. e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc), - * then new var_off is (0; 0x7f...fc) which improves our umax. - */ - __reg_deduce_bounds(reg); - __reg_bound_offset(reg); - __update_reg_bounds(reg); + reg_bounds_sync(reg); } /* Mark a register as having a completely unknown (scalar) value. */ @@ -6943,9 +6942,7 @@ static void do_refine_retval_range(struct bpf_reg_state *regs, int ret_type, ret_reg->s32_max_value = meta->msize_max_value; ret_reg->smin_value = -MAX_ERRNO; ret_reg->s32_min_value = -MAX_ERRNO; - __reg_deduce_bounds(ret_reg); - __reg_bound_offset(ret_reg); - __update_reg_bounds(ret_reg); + reg_bounds_sync(ret_reg); } static int @@ -8202,11 +8199,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, if (!check_reg_sane_offset(env, dst_reg, ptr_reg->type)) return -EINVAL; - - __update_reg_bounds(dst_reg); - __reg_deduce_bounds(dst_reg); - __reg_bound_offset(dst_reg); - + reg_bounds_sync(dst_reg); if (sanitize_check_bounds(env, insn, dst_reg) < 0) return -EACCES; if (sanitize_needed(opcode)) { @@ -8944,10 +8937,7 @@ static int adjust_scalar_min_max_vals(struct bpf_verifier_env *env, /* ALU32 ops are zero extended into 64bit register */ if (alu32) zext_32_to_64(dst_reg); - - __update_reg_bounds(dst_reg); - __reg_deduce_bounds(dst_reg); - __reg_bound_offset(dst_reg); + reg_bounds_sync(dst_reg); return 0; } @@ -9136,10 +9126,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) insn->dst_reg); } zext_32_to_64(dst_reg); - - __update_reg_bounds(dst_reg); - __reg_deduce_bounds(dst_reg); - __reg_bound_offset(dst_reg); + reg_bounds_sync(dst_reg); } } else { /* case: R = imm @@ -9742,21 +9729,8 @@ static void __reg_combine_min_max(struct bpf_reg_state *src_reg, dst_reg->smax_value); src_reg->var_off = dst_reg->var_off = tnum_intersect(src_reg->var_off, dst_reg->var_off); - /* We might have learned new bounds from the var_off. */ - __update_reg_bounds(src_reg); - __update_reg_bounds(dst_reg); - /* We might have learned something about the sign bit. */ - __reg_deduce_bounds(src_reg); - __reg_deduce_bounds(dst_reg); - /* We might have learned some bits from the bounds. */ - __reg_bound_offset(src_reg); - __reg_bound_offset(dst_reg); - /* Intersecting with the old var_off might have improved our bounds - * slightly. e.g. if umax was 0x7f...f and var_off was (0; 0xf...fc), - * then new var_off is (0; 0x7f...fc) which improves our umax. - */ - __update_reg_bounds(src_reg); - __update_reg_bounds(dst_reg); + reg_bounds_sync(src_reg); + reg_bounds_sync(dst_reg); } static void reg_combine_min_max(struct bpf_reg_state *true_src, From 73c4936f916de73fa3faec204a4deb37c25e18c1 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Fri, 1 Jul 2022 14:47:26 +0200 Subject: [PATCH 179/246] bpf, selftests: Add verifier test case for imm=0,umin=0,umax=1 scalar Add a test case to trigger the constant scalar issue which leaves the register in scalar(imm=0,umin=0,umax=1,var_off=(0x0; 0x0)) state. Make use of dead code elimination, so that we can see the verifier bailing out on unfixed kernels. For the condition, we use jle given it checks on umax bound. Before: # ./test_verifier 743 #743/p jump & dead code elimination FAIL Failed to load prog 'Permission denied'! R4 !read_ok verification time 11 usec stack depth 0 processed 13 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 1 Summary: 0 PASSED, 0 SKIPPED, 1 FAILED After: # ./test_verifier 743 #743/p jump & dead code elimination OK Summary: 1 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Daniel Borkmann Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20220701124727.11153-3-daniel@iogearbox.net --- tools/testing/selftests/bpf/verifier/jump.c | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tools/testing/selftests/bpf/verifier/jump.c b/tools/testing/selftests/bpf/verifier/jump.c index 6f951d1ff0a4..497fe17d2eaf 100644 --- a/tools/testing/selftests/bpf/verifier/jump.c +++ b/tools/testing/selftests/bpf/verifier/jump.c @@ -373,3 +373,25 @@ .result = ACCEPT, .retval = 3, }, +{ + "jump & dead code elimination", + .insns = { + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_MOV64_IMM(BPF_REG_3, 0), + BPF_ALU64_IMM(BPF_NEG, BPF_REG_3, 0), + BPF_ALU64_IMM(BPF_NEG, BPF_REG_3, 0), + BPF_ALU64_IMM(BPF_OR, BPF_REG_3, 32767), + BPF_JMP_IMM(BPF_JSGE, BPF_REG_3, 0, 1), + BPF_EXIT_INSN(), + BPF_JMP_IMM(BPF_JSLE, BPF_REG_3, 0x8000, 1), + BPF_EXIT_INSN(), + BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, -32767), + BPF_MOV64_IMM(BPF_REG_0, 2), + BPF_JMP_IMM(BPF_JLE, BPF_REG_3, 0, 1), + BPF_MOV64_REG(BPF_REG_0, BPF_REG_4), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_SCHED_CLS, + .result = ACCEPT, + .retval = 2, +}, From a49b8ce7306cf8031361a6a4f7f6bc7a775a39c8 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Fri, 1 Jul 2022 14:47:27 +0200 Subject: [PATCH 180/246] bpf, selftests: Add verifier test case for jmp32's jeq/jne Add a test case to trigger the verifier's incorrect conclusion in the case of jmp32's jeq/jne. Also here, make use of dead code elimination, so that we can see the verifier bailing out on unfixed kernels. Before: # ./test_verifier 724 #724/p jeq32/jne32: bounds checking FAIL Failed to load prog 'Permission denied'! R4 !read_ok verification time 8 usec stack depth 0 processed 8 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 0 Summary: 0 PASSED, 0 SKIPPED, 1 FAILED After: # ./test_verifier 724 #724/p jeq32/jne32: bounds checking OK Summary: 1 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Daniel Borkmann Signed-off-by: Andrii Nakryiko Link: https://lore.kernel.org/bpf/20220701124727.11153-4-daniel@iogearbox.net --- tools/testing/selftests/bpf/verifier/jmp32.c | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tools/testing/selftests/bpf/verifier/jmp32.c b/tools/testing/selftests/bpf/verifier/jmp32.c index 6ddc418fdfaf..1a27a6210554 100644 --- a/tools/testing/selftests/bpf/verifier/jmp32.c +++ b/tools/testing/selftests/bpf/verifier/jmp32.c @@ -864,3 +864,24 @@ .result = ACCEPT, .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, }, +{ + "jeq32/jne32: bounds checking", + .insns = { + BPF_MOV64_IMM(BPF_REG_6, 563), + BPF_MOV64_IMM(BPF_REG_2, 0), + BPF_ALU64_IMM(BPF_NEG, BPF_REG_2, 0), + BPF_ALU64_IMM(BPF_NEG, BPF_REG_2, 0), + BPF_ALU32_REG(BPF_OR, BPF_REG_2, BPF_REG_6), + BPF_JMP32_IMM(BPF_JNE, BPF_REG_2, 8, 5), + BPF_JMP_IMM(BPF_JSGE, BPF_REG_2, 500, 2), + BPF_MOV64_IMM(BPF_REG_0, 2), + BPF_EXIT_INSN(), + BPF_MOV64_REG(BPF_REG_0, BPF_REG_4), + BPF_EXIT_INSN(), + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN(), + }, + .prog_type = BPF_PROG_TYPE_SCHED_CLS, + .result = ACCEPT, + .retval = 1, +}, From d28b25a62a47a8c8aa19bd543863aab6717e68c9 Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Thu, 30 Jun 2022 14:22:28 +0800 Subject: [PATCH 181/246] selftests/net: fix section name when using xdp_dummy.o Since commit 8fffa0e3451a ("selftests/bpf: Normalize XDP section names in selftests") the xdp_dummy.o's section name has changed to xdp. But some tests are still using "section xdp_dummy", which make the tests failed. Fix them by updating to the new section name. Fixes: 8fffa0e3451a ("selftests/bpf: Normalize XDP section names in selftests") Signed-off-by: Hangbin Liu Acked-by: Andrii Nakryiko Link: https://lore.kernel.org/r/20220630062228.3453016-1-liuhangbin@gmail.com Signed-off-by: Jakub Kicinski --- tools/testing/selftests/net/udpgro.sh | 2 +- tools/testing/selftests/net/udpgro_bench.sh | 2 +- tools/testing/selftests/net/udpgro_frglist.sh | 2 +- tools/testing/selftests/net/udpgro_fwd.sh | 2 +- tools/testing/selftests/net/veth.sh | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/net/udpgro.sh b/tools/testing/selftests/net/udpgro.sh index f8a19f548ae9..ebbd0b282432 100755 --- a/tools/testing/selftests/net/udpgro.sh +++ b/tools/testing/selftests/net/udpgro.sh @@ -34,7 +34,7 @@ cfg_veth() { ip -netns "${PEER_NS}" addr add dev veth1 192.168.1.1/24 ip -netns "${PEER_NS}" addr add dev veth1 2001:db8::1/64 nodad ip -netns "${PEER_NS}" link set dev veth1 up - ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy + ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp } run_one() { diff --git a/tools/testing/selftests/net/udpgro_bench.sh b/tools/testing/selftests/net/udpgro_bench.sh index 820bc50f6b68..fad2d1a71cac 100755 --- a/tools/testing/selftests/net/udpgro_bench.sh +++ b/tools/testing/selftests/net/udpgro_bench.sh @@ -34,7 +34,7 @@ run_one() { ip -netns "${PEER_NS}" addr add dev veth1 2001:db8::1/64 nodad ip -netns "${PEER_NS}" link set dev veth1 up - ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy + ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} -r & ip netns exec "${PEER_NS}" ./udpgso_bench_rx -t ${rx_args} -r & diff --git a/tools/testing/selftests/net/udpgro_frglist.sh b/tools/testing/selftests/net/udpgro_frglist.sh index 807b74c8fd80..832c738cc3c2 100755 --- a/tools/testing/selftests/net/udpgro_frglist.sh +++ b/tools/testing/selftests/net/udpgro_frglist.sh @@ -36,7 +36,7 @@ run_one() { ip netns exec "${PEER_NS}" ethtool -K veth1 rx-gro-list on - ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp_dummy + ip -n "${PEER_NS}" link set veth1 xdp object ../bpf/xdp_dummy.o section xdp tc -n "${PEER_NS}" qdisc add dev veth1 clsact tc -n "${PEER_NS}" filter add dev veth1 ingress prio 4 protocol ipv6 bpf object-file ../bpf/nat6to4.o section schedcls/ingress6/nat_6 direct-action tc -n "${PEER_NS}" filter add dev veth1 egress prio 4 protocol ip bpf object-file ../bpf/nat6to4.o section schedcls/egress4/snat4 direct-action diff --git a/tools/testing/selftests/net/udpgro_fwd.sh b/tools/testing/selftests/net/udpgro_fwd.sh index 6f05e06f6761..1bcd82e1f662 100755 --- a/tools/testing/selftests/net/udpgro_fwd.sh +++ b/tools/testing/selftests/net/udpgro_fwd.sh @@ -46,7 +46,7 @@ create_ns() { ip -n $BASE$ns addr add dev veth$ns $BM_NET_V4$ns/24 ip -n $BASE$ns addr add dev veth$ns $BM_NET_V6$ns/64 nodad done - ip -n $NS_DST link set veth$DST xdp object ../bpf/xdp_dummy.o section xdp_dummy 2>/dev/null + ip -n $NS_DST link set veth$DST xdp object ../bpf/xdp_dummy.o section xdp 2>/dev/null } create_vxlan_endpoint() { diff --git a/tools/testing/selftests/net/veth.sh b/tools/testing/selftests/net/veth.sh index 19eac3e44c06..430895d1a2b6 100755 --- a/tools/testing/selftests/net/veth.sh +++ b/tools/testing/selftests/net/veth.sh @@ -289,14 +289,14 @@ if [ $CPUS -gt 1 ]; then ip netns exec $NS_SRC ethtool -L veth$SRC rx 1 tx 2 2>/dev/null printf "%-60s" "bad setting: XDP with RX nr less than TX" ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o \ - section xdp_dummy 2>/dev/null &&\ + section xdp 2>/dev/null &&\ echo "fail - set operation successful ?!?" || echo " ok " # the following tests will run with multiple channels active ip netns exec $NS_SRC ethtool -L veth$SRC rx 2 ip netns exec $NS_DST ethtool -L veth$DST rx 2 ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o \ - section xdp_dummy 2>/dev/null + section xdp 2>/dev/null printf "%-60s" "bad setting: reducing RX nr below peer TX with XDP set" ip netns exec $NS_DST ethtool -L veth$DST rx 1 2>/dev/null &&\ echo "fail - set operation successful ?!?" || echo " ok " @@ -311,7 +311,7 @@ if [ $CPUS -gt 2 ]; then chk_channels "setting invalid channels nr" $DST 2 2 fi -ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o section xdp_dummy 2>/dev/null +ip -n $NS_DST link set dev veth$DST xdp object ../bpf/xdp_dummy.o section xdp 2>/dev/null chk_gro_flag "with xdp attached - gro flag" $DST on chk_gro_flag " - peer gro flag" $SRC off chk_tso_flag " - tso flag" $SRC off From 5eb502b2e1ae1ab052cdf6bdd7615217e8517360 Mon Sep 17 00:00:00 2001 From: Ivan Babrou Date: Fri, 1 Jul 2022 11:20:46 -0700 Subject: [PATCH 182/246] perf unwind: Fix unitialized 'offset' variable on aarch64 Commit dc2cf4ca866f5715 ("perf unwind: Fix segbase for ld.lld linked objects") uncovered the following issue on aarch64: util/unwind-libunwind-local.c: In function 'find_proc_info': util/unwind-libunwind-local.c:386:28: error: 'offset' may be used uninitialized in this function [-Werror=maybe-uninitialized] 386 | if (ofs > 0) { | ^ util/unwind-libunwind-local.c:199:22: note: 'offset' was declared here 199 | u64 address, offset; | ^~~~~~ util/unwind-libunwind-local.c:371:20: error: 'offset' may be used uninitialized in this function [-Werror=maybe-uninitialized] 371 | if (ofs <= 0) { | ^ util/unwind-libunwind-local.c:199:22: note: 'offset' was declared here 199 | u64 address, offset; | ^~~~~~ util/unwind-libunwind-local.c:363:20: error: 'offset' may be used uninitialized in this function [-Werror=maybe-uninitialized] 363 | if (ofs <= 0) { | ^ util/unwind-libunwind-local.c:199:22: note: 'offset' was declared here 199 | u64 address, offset; | ^~~~~~ In file included from util/libunwind/arm64.c:37: Fixes: dc2cf4ca866f5715 ("perf unwind: Fix segbase for ld.lld linked objects") Signed-off-by: Ivan Babrou Cc: Alexander Shishkin Cc: Fangrui Song Cc: Ian Rogers Cc: James Clark Cc: Jiri Olsa Cc: kernel-team@cloudflare.com Cc: Mark Rutland Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20220701182046.12589-1-ivan@cloudflare.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/unwind-libunwind-local.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 6e5b8cce47bf..81b6bd6e1536 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -197,7 +197,7 @@ out_err: #ifndef NO_LIBUNWIND_DEBUG_FRAME static u64 elf_section_offset(int fd, const char *name) { - u64 address, offset; + u64 address, offset = 0; if (elf_section_address_and_offset(fd, name, &address, &offset)) return 0; From 363afa3aef24f5e08df6a539f5dc3aae4cddcc1a Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 1 Jul 2022 13:54:57 -0700 Subject: [PATCH 183/246] perf synthetic-events: Don't sort the task scan result from /proc It should not sort the result as procfs already returns a proper ordering of tasks. Actually sorting the order caused problems that it doesn't guararantee to process the main thread first. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20220701205458.985106-1-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/synthetic-events.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 27acdc5e5723..a068f42833c3 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -754,7 +754,7 @@ static int __event__synthesize_thread(union perf_event *comm_event, snprintf(filename, sizeof(filename), "%s/proc/%d/task", machine->root_dir, pid); - n = scandir(filename, &dirent, filter_task, alphasort); + n = scandir(filename, &dirent, filter_task, NULL); if (n < 0) return n; @@ -987,7 +987,7 @@ int perf_event__synthesize_threads(struct perf_tool *tool, return 0; snprintf(proc_path, sizeof(proc_path), "%s/proc", machine->root_dir); - n = scandir(proc_path, &dirent, filter_task, alphasort); + n = scandir(proc_path, &dirent, filter_task, NULL); if (n < 0) return err; From ff898552fb32d255517fb0676f9fa500664c484d Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 1 Jul 2022 13:54:58 -0700 Subject: [PATCH 184/246] perf synthetic-events: Ignore dead threads during event synthesis When it synthesize various task events, it scans the list of task first and then accesses later. There's a window threads can die between the two and proc entries may not be available. Instead of bailing out, we can ignore that thread and move on. Signed-off-by: Namhyung Kim Acked-by: Ian Rogers Cc: Jiri Olsa Cc: Peter Zijlstra Link: http://lore.kernel.org/lkml/20220701205458.985106-2-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/synthetic-events.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index a068f42833c3..84d17bd4efae 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -767,11 +767,12 @@ static int __event__synthesize_thread(union perf_event *comm_event, if (*end) continue; - rc = -1; + /* some threads may exit just after scan, ignore it */ if (perf_event__prepare_comm(comm_event, pid, _pid, machine, &tgid, &ppid, &kernel_thread) != 0) - break; + continue; + rc = -1; if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, ppid, process, machine) < 0) break; From 3d5a2a396f19874b02196268a567a529ad5c7448 Mon Sep 17 00:00:00 2001 From: Karsten Graul Date: Fri, 1 Jul 2022 20:41:43 +0200 Subject: [PATCH 185/246] MAINTAINERS: add Wenjia as SMC maintainer Add Wenjia as maintainer for Shared Memory Communications (SMC) Sockets. Acked-by: Wenjia Zhang Acked-by: Alexandra Winter Signed-off-by: Karsten Graul Signed-off-by: David S. Miller --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index e41bee2952bd..ffb682773404 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18179,6 +18179,7 @@ F: drivers/misc/sgi-xp/ SHARED MEMORY COMMUNICATIONS (SMC) SOCKETS M: Karsten Graul +M: Wenjia Zhang L: linux-s390@vger.kernel.org S: Supported W: http://www.ibm.com/developerworks/linux/linux390/ From aa78fa905b4431c432071a878da99c2b37fc0e79 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 1 Jul 2022 09:00:41 +0200 Subject: [PATCH 186/246] parisc: Fix vDSO signal breakage on 32-bit kernel Addition of vDSO support for parisc in kernel v5.18 suddenly broke glibc signal testcases on a 32-bit kernel. The trampoline code (sigtramp.S) which is mapped into userspace includes an offset to the context data on the stack, which is used by gdb and glibc to get access to registers. In a 32-bit kernel we used by mistake the offset into the compat context (which is valid on a 64-bit kernel only) instead of the offset into the "native" 32-bit context. Reported-by: John David Anglin Tested-by: John David Anglin Fixes: df24e1783e6e ("parisc: Add vDSO support") CC: stable@vger.kernel.org # 5.18 Signed-off-by: Helge Deller --- arch/parisc/kernel/asm-offsets.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c index 2673d57eeb00..94652e13c260 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c @@ -224,8 +224,13 @@ int main(void) BLANK(); DEFINE(ASM_SIGFRAME_SIZE, PARISC_RT_SIGFRAME_SIZE); DEFINE(SIGFRAME_CONTEXT_REGS, offsetof(struct rt_sigframe, uc.uc_mcontext) - PARISC_RT_SIGFRAME_SIZE); +#ifdef CONFIG_64BIT DEFINE(ASM_SIGFRAME_SIZE32, PARISC_RT_SIGFRAME_SIZE32); DEFINE(SIGFRAME_CONTEXT_REGS32, offsetof(struct compat_rt_sigframe, uc.uc_mcontext) - PARISC_RT_SIGFRAME_SIZE32); +#else + DEFINE(ASM_SIGFRAME_SIZE32, PARISC_RT_SIGFRAME_SIZE); + DEFINE(SIGFRAME_CONTEXT_REGS32, offsetof(struct rt_sigframe, uc.uc_mcontext) - PARISC_RT_SIGFRAME_SIZE); +#endif BLANK(); DEFINE(ICACHE_BASE, offsetof(struct pdc_cache_info, ic_base)); DEFINE(ICACHE_STRIDE, offsetof(struct pdc_cache_info, ic_stride)); From 7e6bc1f6cabcd30aba0b11219d8e01b952eacbb6 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 2 Jul 2022 04:16:30 +0200 Subject: [PATCH 187/246] netfilter: nf_tables: stricter validation of element data Make sure element data type and length do not mismatch the one specified by the set declaration. Fixes: 7d7402642eaf ("netfilter: nf_tables: variable sized set element keys / data") Reported-by: Hugues ANGUELKOV Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nf_tables_api.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 51144fc66889..d6b59beab3a9 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -5213,13 +5213,20 @@ static int nft_setelem_parse_data(struct nft_ctx *ctx, struct nft_set *set, struct nft_data *data, struct nlattr *attr) { + u32 dtype; int err; err = nft_data_init(ctx, data, NFT_DATA_VALUE_MAXLEN, desc, attr); if (err < 0) return err; - if (desc->type != NFT_DATA_VERDICT && desc->len != set->dlen) { + if (set->dtype == NFT_DATA_VERDICT) + dtype = NFT_DATA_VERDICT; + else + dtype = NFT_DATA_VALUE; + + if (dtype != desc->type || + set->dlen != desc->len) { nft_data_release(data, desc->type); return -EINVAL; } From 9827a0e6e23bf43003cd3d5b7fb11baf59a35e1e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 2 Jul 2022 04:16:31 +0200 Subject: [PATCH 188/246] netfilter: nft_set_pipapo: release elements in clone from abort path New elements that reside in the clone are not released in case that the transaction is aborted. [16302.231754] ------------[ cut here ]------------ [16302.231756] WARNING: CPU: 0 PID: 100509 at net/netfilter/nf_tables_api.c:1864 nf_tables_chain_destroy+0x26/0x127 [nf_tables] [...] [16302.231882] CPU: 0 PID: 100509 Comm: nft Tainted: G W 5.19.0-rc3+ #155 [...] [16302.231887] RIP: 0010:nf_tables_chain_destroy+0x26/0x127 [nf_tables] [16302.231899] Code: f3 fe ff ff 41 55 41 54 55 53 48 8b 6f 10 48 89 fb 48 c7 c7 82 96 d9 a0 8b 55 50 48 8b 75 58 e8 de f5 92 e0 83 7d 50 00 74 09 <0f> 0b 5b 5d 41 5c 41 5d c3 4c 8b 65 00 48 8b 7d 08 49 39 fc 74 05 [...] [16302.231917] Call Trace: [16302.231919] [16302.231921] __nf_tables_abort.cold+0x23/0x28 [nf_tables] [16302.231934] nf_tables_abort+0x30/0x50 [nf_tables] [16302.231946] nfnetlink_rcv_batch+0x41a/0x840 [nfnetlink] [16302.231952] ? __nla_validate_parse+0x48/0x190 [16302.231959] nfnetlink_rcv+0x110/0x129 [nfnetlink] [16302.231963] netlink_unicast+0x211/0x340 [16302.231969] netlink_sendmsg+0x21e/0x460 Add nft_set_pipapo_match_destroy() helper function to release the elements in the lookup tables. Stefano Brivio says: "We additionally look for elements pointers in the cloned matching data if priv->dirty is set, because that means that cloned data might point to additional elements we did not commit to the working copy yet (such as the abort path case, but perhaps not limited to it)." Fixes: 3c4287f62044 ("nf_tables: Add set type for arbitrary concatenation of ranges") Reviewed-by: Stefano Brivio Signed-off-by: Pablo Neira Ayuso --- net/netfilter/nft_set_pipapo.c | 48 +++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c index 2c8051d8cca6..4f9299b9dcdd 100644 --- a/net/netfilter/nft_set_pipapo.c +++ b/net/netfilter/nft_set_pipapo.c @@ -2124,6 +2124,32 @@ out_scratch: return err; } +/** + * nft_set_pipapo_match_destroy() - Destroy elements from key mapping array + * @set: nftables API set representation + * @m: matching data pointing to key mapping array + */ +static void nft_set_pipapo_match_destroy(const struct nft_set *set, + struct nft_pipapo_match *m) +{ + struct nft_pipapo_field *f; + int i, r; + + for (i = 0, f = m->f; i < m->field_count - 1; i++, f++) + ; + + for (r = 0; r < f->rules; r++) { + struct nft_pipapo_elem *e; + + if (r < f->rules - 1 && f->mt[r + 1].e == f->mt[r].e) + continue; + + e = f->mt[r].e; + + nft_set_elem_destroy(set, e, true); + } +} + /** * nft_pipapo_destroy() - Free private data for set and all committed elements * @set: nftables API set representation @@ -2132,26 +2158,13 @@ static void nft_pipapo_destroy(const struct nft_set *set) { struct nft_pipapo *priv = nft_set_priv(set); struct nft_pipapo_match *m; - struct nft_pipapo_field *f; - int i, r, cpu; + int cpu; m = rcu_dereference_protected(priv->match, true); if (m) { rcu_barrier(); - for (i = 0, f = m->f; i < m->field_count - 1; i++, f++) - ; - - for (r = 0; r < f->rules; r++) { - struct nft_pipapo_elem *e; - - if (r < f->rules - 1 && f->mt[r + 1].e == f->mt[r].e) - continue; - - e = f->mt[r].e; - - nft_set_elem_destroy(set, e, true); - } + nft_set_pipapo_match_destroy(set, m); #ifdef NFT_PIPAPO_ALIGN free_percpu(m->scratch_aligned); @@ -2165,6 +2178,11 @@ static void nft_pipapo_destroy(const struct nft_set *set) } if (priv->clone) { + m = priv->clone; + + if (priv->dirty) + nft_set_pipapo_match_destroy(set, m); + #ifdef NFT_PIPAPO_ALIGN free_percpu(priv->clone->scratch_aligned); #endif From 4a557a5d1a6145ea586dc9b17a9b4e5190c9c017 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 30 Jun 2022 09:34:10 -0700 Subject: [PATCH 189/246] sparse: introduce conditional lock acquire function attribute The kernel tends to try to avoid conditional locking semantics because it makes it harder to think about and statically check locking rules, but we do have a few fundamental locking primitives that take locks conditionally - most obviously the 'trylock' functions. That has always been a problem for 'sparse' checking for locking imbalance, and we've had a special '__cond_lock()' macro that we've used to let sparse know how the locking works: # define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) so that you can then use this to tell sparse that (for example) the spinlock trylock macro ends up acquiring the lock when it succeeds, but not when it fails: #define raw_spin_trylock(lock) __cond_lock(lock, _raw_spin_trylock(lock)) and then sparse can follow along the locking rules when you have code like if (!spin_trylock(&dentry->d_lock)) return LRU_SKIP; .. sparse sees that the lock is held here.. spin_unlock(&dentry->d_lock); and sparse ends up happy about the lock contexts. However, this '__cond_lock()' use does result in very ugly header files, and requires you to basically wrap the real function with that macro that uses '__cond_lock'. Which has made PeterZ NAK things that try to fix sparse warnings over the years [1]. To solve this, there is now a very experimental patch to sparse that basically does the exact same thing as '__cond_lock()' did, but using a function attribute instead. That seems to make PeterZ happy [2]. Note that this does not replace existing use of '__cond_lock()', but only exposes the new proposed attribute and uses it for the previously unannotated 'refcount_dec_and_lock()' family of functions. For existing sparse installations, this will make no difference (a negative output context was ignored), but if you have the experimental sparse patch it will make sparse now understand code that uses those functions, the same way '__cond_lock()' makes sparse understand the very similar 'atomic_dec_and_lock()' uses that have the old '__cond_lock()' annotations. Note that in some cases this will silence existing context imbalance warnings. But in other cases it may end up exposing new sparse warnings for code that sparse just didn't see the locking for at all before. This is a trial, in other words. I'd expect that if it ends up being successful, and new sparse releases end up having this new attribute, we'll migrate the old-style '__cond_lock()' users to use the new-style '__cond_acquires' function attribute. The actual experimental sparse patch was posted in [3]. Link: https://lore.kernel.org/all/20130930134434.GC12926@twins.programming.kicks-ass.net/ [1] Link: https://lore.kernel.org/all/Yr60tWxN4P568x3W@worktop.programming.kicks-ass.net/ [2] Link: https://lore.kernel.org/all/CAHk-=wjZfO9hGqJ2_hGQG3U_XzSh9_XaXze=HgPdvJbgrvASfA@mail.gmail.com/ [3] Acked-by: Peter Zijlstra Cc: Alexander Aring Cc: Luc Van Oostenryck Signed-off-by: Linus Torvalds --- include/linux/compiler_types.h | 2 ++ include/linux/refcount.h | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index d08dfcb0ac68..4f2a819fd60a 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -24,6 +24,7 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { } /* context/locking */ # define __must_hold(x) __attribute__((context(x,1,1))) # define __acquires(x) __attribute__((context(x,0,1))) +# define __cond_acquires(x) __attribute__((context(x,0,-1))) # define __releases(x) __attribute__((context(x,1,0))) # define __acquire(x) __context__(x,1) # define __release(x) __context__(x,-1) @@ -50,6 +51,7 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { } /* context/locking */ # define __must_hold(x) # define __acquires(x) +# define __cond_acquires(x) # define __releases(x) # define __acquire(x) (void)0 # define __release(x) (void)0 diff --git a/include/linux/refcount.h b/include/linux/refcount.h index b8a6e387f8f9..a62fcca97486 100644 --- a/include/linux/refcount.h +++ b/include/linux/refcount.h @@ -361,9 +361,9 @@ static inline void refcount_dec(refcount_t *r) extern __must_check bool refcount_dec_if_one(refcount_t *r); extern __must_check bool refcount_dec_not_one(refcount_t *r); -extern __must_check bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock); -extern __must_check bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock); +extern __must_check bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock) __cond_acquires(lock); +extern __must_check bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock) __cond_acquires(lock); extern __must_check bool refcount_dec_and_lock_irqsave(refcount_t *r, spinlock_t *lock, - unsigned long *flags); + unsigned long *flags) __cond_acquires(lock); #endif /* _LINUX_REFCOUNT_H */ From b8d5109f50969ead9d49c3e8bd78ec1f82e548e3 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 3 Jul 2022 14:40:28 -0700 Subject: [PATCH 190/246] lockref: remove unused 'lockref_get_or_lock()' function Looking at the conditional lock acquire functions in the kernel due to the new sparse support (see commit 4a557a5d1a61 "sparse: introduce conditional lock acquire function attribute"), it became obvious that the lockref code has a couple of them, but they don't match the usual naming convention for the other ones, and their return value logic is also reversed. In the other very similar places, the naming pattern is '*_and_lock()' (eg 'atomic_put_and_lock()' and 'refcount_dec_and_lock()'), and the function returns true when the lock is taken. The lockref code is superficially very similar to the refcount code, only with the special "atomic wrt the embedded lock" semantics. But instead of the '*_and_lock()' naming it uses '*_or_lock()'. And instead of returning true in case it took the lock, it returns true if it *didn't* take the lock. Now, arguably the reflock code is quite logical: it really is a "either decrement _or_ lock" kind of situation - and the return value is about whether the operation succeeded without any special care needed. So despite the similarities, the differences do make some sense, and maybe it's not worth trying to unify the different conditional locking primitives in this area. But while looking at this all, it did become obvious that the 'lockref_get_or_lock()' function hasn't actually had any users for almost a decade. The only user it ever had was the shortlived 'd_rcu_to_refcount()' function, and it got removed and replaced with 'lockref_get_not_dead()' back in 2013 in commits 0d98439ea3c6 ("vfs: use lockred 'dead' flag to mark unrecoverably dead dentries") and e5c832d55588 ("vfs: fix dentry RCU to refcounting possibly sleeping dput()") In fact, that single use was removed less than a week after the whole function was introduced in commit b3abd80250c1 ("lockref: add 'lockref_get_or_lock() helper") so this function has been around for a decade, but only had a user for six days. Let's just put this mis-designed and unused function out of its misery. We can think about the naming and semantic oddities of the remaining 'lockref_put_or_lock()' later, but at least that function has users. And while the naming is different and the return value doesn't match, that function matches the whole '{atomic,refcount}_dec_and_test()' pattern much better (ie the magic happens when the count goes down to zero, not when it is incremented from zero). Signed-off-by: Linus Torvalds --- include/linux/lockref.h | 1 - lib/lockref.c | 25 ------------------------- 2 files changed, 26 deletions(-) diff --git a/include/linux/lockref.h b/include/linux/lockref.h index 99f17cc8e163..c3a1f78bc884 100644 --- a/include/linux/lockref.h +++ b/include/linux/lockref.h @@ -38,7 +38,6 @@ extern void lockref_get(struct lockref *); extern int lockref_put_return(struct lockref *); extern int lockref_get_not_zero(struct lockref *); extern int lockref_put_not_zero(struct lockref *); -extern int lockref_get_or_lock(struct lockref *); extern int lockref_put_or_lock(struct lockref *); extern void lockref_mark_dead(struct lockref *); diff --git a/lib/lockref.c b/lib/lockref.c index c6f0b183b937..45e93ece8ba0 100644 --- a/lib/lockref.c +++ b/lib/lockref.c @@ -110,31 +110,6 @@ int lockref_put_not_zero(struct lockref *lockref) } EXPORT_SYMBOL(lockref_put_not_zero); -/** - * lockref_get_or_lock - Increments count unless the count is 0 or dead - * @lockref: pointer to lockref structure - * Return: 1 if count updated successfully or 0 if count was zero - * and we got the lock instead. - */ -int lockref_get_or_lock(struct lockref *lockref) -{ - CMPXCHG_LOOP( - new.count++; - if (old.count <= 0) - break; - , - return 1; - ); - - spin_lock(&lockref->lock); - if (lockref->count <= 0) - return 0; - lockref->count++; - spin_unlock(&lockref->lock); - return 1; -} -EXPORT_SYMBOL(lockref_get_or_lock); - /** * lockref_put_return - Decrement reference count if possible * @lockref: pointer to lockref structure From 88084a3df1672e131ddc1b4e39eeacfd39864acf Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sun, 3 Jul 2022 15:39:28 -0700 Subject: [PATCH 191/246] Linux 5.19-rc5 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8973b285ce6c..990d2ee79186 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION = 5 PATCHLEVEL = 19 SUBLEVEL = 0 -EXTRAVERSION = -rc4 +EXTRAVERSION = -rc5 NAME = Superb Owl # *DOCUMENTATION* From a34b42f8690ce2b8360971ca5b886786ee1781af Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Fri, 24 Jun 2022 11:00:55 +0200 Subject: [PATCH 192/246] ARM: dts: stm32: fix pwr regulators references to use scmi Fixes stm32mp15*-scmi DTS files introduced in [1] to also access PWR regulators through SCMI service. This is needed since enabling secure only access to RCC clock and reset controllers also enables secure access only on PWR voltage regulators reg11, reg18 and usb33 hence these must also be accessed through SCMI Voltage Domain protocol. This change applies on commit [2] that already corrects issues from commit [1]. Cc: Alexandre Torgue Link: [1] https://lore.kernel.org/linux-arm-kernel/20220422150952.20587-7-alexandre.torgue@foss.st.com Link: [2] https://lore.kernel.org/linux-arm-kernel/20220613071920.5463-1-alexandre.torgue@foss.st.com Signed-off-by: Etienne Carriere Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp15-scmi.dtsi | 52 ++++++++++++++++++++++ arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts | 1 + arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts | 1 + 3 files changed, 54 insertions(+) diff --git a/arch/arm/boot/dts/stm32mp15-scmi.dtsi b/arch/arm/boot/dts/stm32mp15-scmi.dtsi index e90cf3acd0b3..d2afb6667479 100644 --- a/arch/arm/boot/dts/stm32mp15-scmi.dtsi +++ b/arch/arm/boot/dts/stm32mp15-scmi.dtsi @@ -27,6 +27,37 @@ reg = <0x16>; #reset-cells = <1>; }; + + scmi_voltd: protocol@17 { + reg = <0x17>; + + scmi_reguls: regulators { + #address-cells = <1>; + #size-cells = <0>; + + scmi_reg11: reg11@0 { + reg = <0>; + regulator-name = "reg11"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + }; + + scmi_reg18: reg18@1 { + voltd-name = "reg18"; + reg = <1>; + regulator-name = "reg18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + scmi_usb33: usb33@2 { + reg = <2>; + regulator-name = "usb33"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + }; + }; }; }; @@ -45,3 +76,24 @@ }; }; }; + +®11 { + status = "disabled"; +}; + +®18 { + status = "disabled"; +}; + +&usb33 { + status = "disabled"; +}; + +&usbotg_hs { + usb33d-supply = <&scmi_usb33>; +}; + +&usbphyc { + vdda1v1-supply = <&scmi_reg11>; + vdda1v8-supply = <&scmi_reg18>; +}; diff --git a/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts b/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts index 03226a596904..97e4f94b0a24 100644 --- a/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts +++ b/arch/arm/boot/dts/stm32mp157c-dk2-scmi.dts @@ -35,6 +35,7 @@ }; &dsi { + phy-dsi-supply = <&scmi_reg18>; clocks = <&rcc DSI_K>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>; }; diff --git a/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts b/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts index 7842384ddbe4..3b9dd6f4ccc9 100644 --- a/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts +++ b/arch/arm/boot/dts/stm32mp157c-ev1-scmi.dts @@ -36,6 +36,7 @@ }; &dsi { + phy-dsi-supply = <&scmi_reg18>; clocks = <&rcc DSI_K>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>; }; From 78ece8cce1ba0c3f3e5a7c6c1b914b3794f04c44 Mon Sep 17 00:00:00 2001 From: Gabriel Fernandez Date: Fri, 24 Jun 2022 11:27:13 +0200 Subject: [PATCH 193/246] ARM: dts: stm32: use the correct clock source for CEC on stm32mp151 The peripheral clock of CEC is not LSE but CEC. Signed-off-by: Gabriel Fernandez Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp151.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi index 7fdc324b3cf9..c50f38f539f2 100644 --- a/arch/arm/boot/dts/stm32mp151.dtsi +++ b/arch/arm/boot/dts/stm32mp151.dtsi @@ -565,7 +565,7 @@ compatible = "st,stm32-cec"; reg = <0x40016000 0x400>; interrupts = ; - clocks = <&rcc CEC_K>, <&clk_lse>; + clocks = <&rcc CEC_K>, <&rcc CEC>; clock-names = "cec", "hdmi-cec"; status = "disabled"; }; From cfd7ea394cd3b70ba4d9d87ee7b88e37459036b0 Mon Sep 17 00:00:00 2001 From: Gabriel Fernandez Date: Fri, 24 Jun 2022 11:27:14 +0200 Subject: [PATCH 194/246] ARM: dts: stm32: DSI should use LSE SCMI clock on DK1/ED1 STM32 board LSE clock is provided by SCMI. Signed-off-by: Gabriel Fernandez Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts | 4 ++++ arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts b/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts index 36371d6ed660..e539cc80bef8 100644 --- a/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts +++ b/arch/arm/boot/dts/stm32mp157a-dk1-scmi.dts @@ -29,6 +29,10 @@ clocks = <&scmi_clk CK_SCMI_MPU>; }; +&dsi { + clocks = <&rcc DSI_K>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>; +}; + &gpioz { clocks = <&scmi_clk CK_SCMI_GPIOZ>; }; diff --git a/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts b/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts index c1a79272c068..9cf0a44d2f47 100644 --- a/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts +++ b/arch/arm/boot/dts/stm32mp157c-ed1-scmi.dts @@ -34,6 +34,10 @@ resets = <&scmi_reset RST_SCMI_CRYP1>; }; +&dsi { + clocks = <&rcc DSI_K>, <&scmi_clk CK_SCMI_HSE>, <&rcc DSI_PX>; +}; + &gpioz { clocks = <&scmi_clk CK_SCMI_GPIOZ>; }; From bf74181e75c93a1b2b000ebf3c8b4c8c17cd59da Mon Sep 17 00:00:00 2001 From: Gabriel Fernandez Date: Fri, 24 Jun 2022 11:27:15 +0200 Subject: [PATCH 195/246] ARM: dts: stm32: delete fixed clock node on STM32MP15-SCMI Delete the node fixed clock managed by secure world with SCMI. Signed-off-by: Gabriel Fernandez Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp15-scmi.dtsi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/boot/dts/stm32mp15-scmi.dtsi b/arch/arm/boot/dts/stm32mp15-scmi.dtsi index d2afb6667479..543f24c2f4f6 100644 --- a/arch/arm/boot/dts/stm32mp15-scmi.dtsi +++ b/arch/arm/boot/dts/stm32mp15-scmi.dtsi @@ -97,3 +97,9 @@ vdda1v1-supply = <&scmi_reg11>; vdda1v8-supply = <&scmi_reg18>; }; + +/delete-node/ &clk_hse; +/delete-node/ &clk_hsi; +/delete-node/ &clk_lse; +/delete-node/ &clk_lsi; +/delete-node/ &clk_csi; From 1d0c1aadf1fd9f3de95d1532b3651e8634546e71 Mon Sep 17 00:00:00 2001 From: Fabrice Gasnier Date: Tue, 21 Jun 2022 10:45:09 +0200 Subject: [PATCH 196/246] ARM: dts: stm32: add missing usbh clock and fix clk order on stm32mp15 The USBH composed of EHCI and OHCI controllers needs the PHY clock to be initialized first, before enabling (gating) them. The reverse is also required when going to suspend. So, add USBPHY clock as 1st entry in both controllers, so the USBPHY PLL gets enabled 1st upon controller init. Upon suspend/resume, this also makes the clock to be disabled/re-enabled in the correct order. This fixes some IRQ storm conditions seen when going to low-power, due to PHY PLL being disabled before all clocks are cleanly gated. Fixes: 949a0c0dec85 ("ARM: dts: stm32: add USB Host (USBH) support to stm32mp157c") Fixes: db7be2cb87ae ("ARM: dts: stm32: use usbphyc ck_usbo_48m as USBH OHCI clock on stm32mp151") Signed-off-by: Fabrice Gasnier Signed-off-by: Alexandre Torgue --- arch/arm/boot/dts/stm32mp151.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/stm32mp151.dtsi b/arch/arm/boot/dts/stm32mp151.dtsi index c50f38f539f2..e04dda5ddd95 100644 --- a/arch/arm/boot/dts/stm32mp151.dtsi +++ b/arch/arm/boot/dts/stm32mp151.dtsi @@ -1474,7 +1474,7 @@ usbh_ohci: usb@5800c000 { compatible = "generic-ohci"; reg = <0x5800c000 0x1000>; - clocks = <&rcc USBH>, <&usbphyc>; + clocks = <&usbphyc>, <&rcc USBH>; resets = <&rcc USBH_R>; interrupts = ; status = "disabled"; @@ -1483,7 +1483,7 @@ usbh_ehci: usb@5800d000 { compatible = "generic-ehci"; reg = <0x5800d000 0x1000>; - clocks = <&rcc USBH>; + clocks = <&usbphyc>, <&rcc USBH>; resets = <&rcc USBH_R>; interrupts = ; companion = <&usbh_ohci>; From f1b4e32aca0811aa011c76e5d6cf2fa19224b386 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Fri, 20 May 2022 20:32:39 +0200 Subject: [PATCH 197/246] can: bcm: use call_rcu() instead of costly synchronize_rcu() In commit d5f9023fa61e ("can: bcm: delay release of struct bcm_op after synchronize_rcu()") Thadeu Lima de Souza Cascardo introduced two synchronize_rcu() calls in bcm_release() (only once at socket close) and in bcm_delete_rx_op() (called on removal of each single bcm_op). Unfortunately this slow removal of the bcm_op's affects user space applications like cansniffer where the modification of a filter removes 2048 bcm_op's which blocks the cansniffer application for 40(!) seconds. In commit 181d4447905d ("can: gw: use call_rcu() instead of costly synchronize_rcu()") Eric Dumazet replaced the synchronize_rcu() calls with several call_rcu()'s to safely remove the data structures after the removal of CAN ID subscriptions with can_rx_unregister() calls. This patch adopts Erics approach for the can-bcm which should be applicable since the removal of tasklet_kill() in bcm_remove_op() and the introduction of the HRTIMER_MODE_SOFT timer handling in Linux 5.4. Fixes: d5f9023fa61e ("can: bcm: delay release of struct bcm_op after synchronize_rcu()") # >= 5.4 Link: https://lore.kernel.org/all/20220520183239.19111-1-socketcan@hartkopp.net Cc: stable@vger.kernel.org Cc: Eric Dumazet Cc: Norbert Slusarek Cc: Thadeu Lima de Souza Cascardo Signed-off-by: Oliver Hartkopp Signed-off-by: Marc Kleine-Budde --- net/can/bcm.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/net/can/bcm.c b/net/can/bcm.c index 65ee1b784a30..e60161bec850 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -100,6 +100,7 @@ static inline u64 get_u64(const struct canfd_frame *cp, int offset) struct bcm_op { struct list_head list; + struct rcu_head rcu; int ifindex; canid_t can_id; u32 flags; @@ -718,10 +719,9 @@ static struct bcm_op *bcm_find_op(struct list_head *ops, return NULL; } -static void bcm_remove_op(struct bcm_op *op) +static void bcm_free_op_rcu(struct rcu_head *rcu_head) { - hrtimer_cancel(&op->timer); - hrtimer_cancel(&op->thrtimer); + struct bcm_op *op = container_of(rcu_head, struct bcm_op, rcu); if ((op->frames) && (op->frames != &op->sframe)) kfree(op->frames); @@ -732,6 +732,14 @@ static void bcm_remove_op(struct bcm_op *op) kfree(op); } +static void bcm_remove_op(struct bcm_op *op) +{ + hrtimer_cancel(&op->timer); + hrtimer_cancel(&op->thrtimer); + + call_rcu(&op->rcu, bcm_free_op_rcu); +} + static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op) { if (op->rx_reg_dev == dev) { @@ -757,6 +765,9 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh, if ((op->can_id == mh->can_id) && (op->ifindex == ifindex) && (op->flags & CAN_FD_FRAME) == (mh->flags & CAN_FD_FRAME)) { + /* disable automatic timer on frame reception */ + op->flags |= RX_NO_AUTOTIMER; + /* * Don't care if we're bound or not (due to netdev * problems) can_rx_unregister() is always a save @@ -785,7 +796,6 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh, bcm_rx_handler, op); list_del(&op->list); - synchronize_rcu(); bcm_remove_op(op); return 1; /* done */ } From 02514a067fad6df27c4b21c316c1af93066af06e Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 1 Jul 2022 20:12:07 -0700 Subject: [PATCH 198/246] docs: netdev: document that patch series length limit We had been asking people to avoid massive patch series but it does not appear in the FAQ. Signed-off-by: Jakub Kicinski Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- Documentation/process/maintainer-netdev.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Documentation/process/maintainer-netdev.rst b/Documentation/process/maintainer-netdev.rst index c456b5225d66..79a10d05031e 100644 --- a/Documentation/process/maintainer-netdev.rst +++ b/Documentation/process/maintainer-netdev.rst @@ -136,6 +136,20 @@ it to the maintainer to figure out what is the most recent and current version that should be applied. If there is any doubt, the maintainer will reply and ask what should be done. +How do I divide my work into patches? +------------------------------------- + +Put yourself in the shoes of the reviewer. Each patch is read separately +and therefore should constitute a comprehensible step towards your stated +goal. + +Avoid sending series longer than 15 patches. Larger series takes longer +to review as reviewers will defer looking at it until they find a large +chunk of time. A small series can be reviewed in a short time, so Maintainers +just do it. As a result, a sequence of smaller series gets merged quicker and +with better review coverage. Re-posting large series also increases the mailing +list traffic. + I made changes to only a few patches in a patch series should I resend only those changed? ------------------------------------------------------------------------------------------ No, please resend the entire patch series and make sure you do number your From a24875641143fce726529e6d550b313c53eb5821 Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 1 Jul 2022 20:12:08 -0700 Subject: [PATCH 199/246] docs: netdev: document reverse xmas tree Similarly to the 15 patch rule the reverse xmas tree is not documented. Signed-off-by: Jakub Kicinski Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- Documentation/process/maintainer-netdev.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Documentation/process/maintainer-netdev.rst b/Documentation/process/maintainer-netdev.rst index 79a10d05031e..8a9dae7a0524 100644 --- a/Documentation/process/maintainer-netdev.rst +++ b/Documentation/process/maintainer-netdev.rst @@ -197,6 +197,19 @@ it is requested that you make it look like this:: * another line of text */ +What is "reverse xmas tree"? +---------------------------- + +Netdev has a convention for ordering local variables in functions. +Order the variable declaration lines longest to shortest, e.g.:: + + struct scatterlist *sg; + struct sk_buff *skb; + int err, i; + +If there are dependencies between the variables preventing the ordering +move the initialization out of line. + I am working in existing code which uses non-standard formatting. Which formatting should I use? ------------------------------------------------------------------------------------------------ Make your code follow the most recent guidelines, so that eventually all code From 5d407ca7389261c002c49068e4a11ed3bff0fc8e Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Fri, 1 Jul 2022 20:12:09 -0700 Subject: [PATCH 200/246] docs: netdev: add a cheat sheet for the rules Summarize the rules we see broken most often and which may be less familiar to kernel devs who are used to working outside of netdev. Signed-off-by: Jakub Kicinski Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- Documentation/process/maintainer-netdev.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/process/maintainer-netdev.rst b/Documentation/process/maintainer-netdev.rst index 8a9dae7a0524..d14007081595 100644 --- a/Documentation/process/maintainer-netdev.rst +++ b/Documentation/process/maintainer-netdev.rst @@ -6,6 +6,15 @@ netdev FAQ ========== +tl;dr +----- + + - designate your patch to a tree - ``[PATCH net]`` or ``[PATCH net-next]`` + - for fixes the ``Fixes:`` tag is required, regardless of the tree + - don't post large series (> 15 patches), break them up + - don't repost your patches within one 24h period + - reverse xmas tree + What is netdev? --------------- It is a mailing list for all network-related Linux stuff. This From c6da4590fe819dfe28a4f8037a8dc1e056542fb4 Mon Sep 17 00:00:00 2001 From: Srinivas Neeli Date: Thu, 9 Jun 2022 13:54:32 +0530 Subject: [PATCH 201/246] Revert "can: xilinx_can: Limit CANFD brp to 2" This reverts commit 05ca14fdb6fe65614e0652d03e44b02748d25af7. On early silicon engineering samples observed bit shrinking issue when we use brp as 1. Hence updated brp_min as 2. As in production silicon this issue is fixed, so reverting the patch. Link: https://lore.kernel.org/all/20220609082433.1191060-2-srinivas.neeli@xilinx.com Signed-off-by: Srinivas Neeli Signed-off-by: Marc Kleine-Budde --- drivers/net/can/xilinx_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c index 8a3b7b103ca4..e179d311aa28 100644 --- a/drivers/net/can/xilinx_can.c +++ b/drivers/net/can/xilinx_can.c @@ -258,7 +258,7 @@ static const struct can_bittiming_const xcan_bittiming_const_canfd2 = { .tseg2_min = 1, .tseg2_max = 128, .sjw_max = 128, - .brp_min = 2, + .brp_min = 1, .brp_max = 256, .brp_inc = 1, }; @@ -271,7 +271,7 @@ static const struct can_bittiming_const xcan_data_bittiming_const_canfd2 = { .tseg2_min = 1, .tseg2_max = 16, .sjw_max = 16, - .brp_min = 2, + .brp_min = 1, .brp_max = 256, .brp_inc = 1, }; From 374e11f1bde91545674233459e5a0416ba842b69 Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Mon, 4 Jul 2022 16:46:11 +0900 Subject: [PATCH 202/246] can: rcar_canfd: Fix data transmission failed on R-Car V3U On R-Car V3U, this driver should use suitable register offset instead of other SoCs' one. Otherwise, data transmission failed on R-Car V3U. Fixes: 45721c406dcf ("can: rcar_canfd: Add support for r8a779a0 SoC") Link: https://lore.kernel.org/all/20220704074611.957191-1-yoshihiro.shimoda.uh@renesas.com Reviewed-by: Geert Uytterhoeven Signed-off-by: Duy Nguyen Signed-off-by: Yoshihiro Shimoda Signed-off-by: Marc Kleine-Budde --- drivers/net/can/rcar/rcar_canfd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c index 40a11445d021..ba42cef10a53 100644 --- a/drivers/net/can/rcar/rcar_canfd.c +++ b/drivers/net/can/rcar/rcar_canfd.c @@ -1332,7 +1332,10 @@ static void rcar_canfd_set_bittiming(struct net_device *dev) cfg = (RCANFD_DCFG_DTSEG1(gpriv, tseg1) | RCANFD_DCFG_DBRP(brp) | RCANFD_DCFG_DSJW(sjw) | RCANFD_DCFG_DTSEG2(gpriv, tseg2)); - rcar_canfd_write(priv->base, RCANFD_F_DCFG(ch), cfg); + if (is_v3u(gpriv)) + rcar_canfd_write(priv->base, RCANFD_V3U_DCFG(ch), cfg); + else + rcar_canfd_write(priv->base, RCANFD_F_DCFG(ch), cfg); netdev_dbg(priv->ndev, "drate: brp %u, sjw %u, tseg1 %u, tseg2 %u\n", brp, sjw, tseg1, tseg2); } else { From 2bda24ef95c0311ab93bda00db40486acf30bd0a Mon Sep 17 00:00:00 2001 From: Rhett Aultman Date: Sun, 3 Jul 2022 19:33:06 +0200 Subject: [PATCH 203/246] can: gs_usb: gs_usb_open/close(): fix memory leak The gs_usb driver appears to suffer from a malady common to many USB CAN adapter drivers in that it performs usb_alloc_coherent() to allocate a number of USB request blocks (URBs) for RX, and then later relies on usb_kill_anchored_urbs() to free them, but this doesn't actually free them. As a result, this may be leaking DMA memory that's been used by the driver. This commit is an adaptation of the techniques found in the esd_usb2 driver where a similar design pattern led to a memory leak. It explicitly frees the RX URBs and their DMA memory via a call to usb_free_coherent(). Since the RX URBs were allocated in the gs_can_open(), we remove them in gs_can_close() rather than in the disconnect function as was done in esd_usb2. For more information, see the 928150fad41b ("can: esd_usb2: fix memory leak"). Link: https://lore.kernel.org/all/alpine.DEB.2.22.394.2206031547001.1630869@thelappy Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") Cc: stable@vger.kernel.org Signed-off-by: Rhett Aultman Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/gs_usb.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index b29ba9138866..d3a658b444b5 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -268,6 +268,8 @@ struct gs_can { struct usb_anchor tx_submitted; atomic_t active_tx_urbs; + void *rxbuf[GS_MAX_RX_URBS]; + dma_addr_t rxbuf_dma[GS_MAX_RX_URBS]; }; /* usb interface struct */ @@ -742,6 +744,7 @@ static int gs_can_open(struct net_device *netdev) for (i = 0; i < GS_MAX_RX_URBS; i++) { struct urb *urb; u8 *buf; + dma_addr_t buf_dma; /* alloc rx urb */ urb = usb_alloc_urb(0, GFP_KERNEL); @@ -752,7 +755,7 @@ static int gs_can_open(struct net_device *netdev) buf = usb_alloc_coherent(dev->udev, dev->parent->hf_size_rx, GFP_KERNEL, - &urb->transfer_dma); + &buf_dma); if (!buf) { netdev_err(netdev, "No memory left for USB buffer\n"); @@ -760,6 +763,8 @@ static int gs_can_open(struct net_device *netdev) return -ENOMEM; } + urb->transfer_dma = buf_dma; + /* fill, anchor, and submit rx urb */ usb_fill_bulk_urb(urb, dev->udev, @@ -781,10 +786,17 @@ static int gs_can_open(struct net_device *netdev) "usb_submit failed (err=%d)\n", rc); usb_unanchor_urb(urb); + usb_free_coherent(dev->udev, + sizeof(struct gs_host_frame), + buf, + buf_dma); usb_free_urb(urb); break; } + dev->rxbuf[i] = buf; + dev->rxbuf_dma[i] = buf_dma; + /* Drop reference, * USB core will take care of freeing it */ @@ -842,13 +854,20 @@ static int gs_can_close(struct net_device *netdev) int rc; struct gs_can *dev = netdev_priv(netdev); struct gs_usb *parent = dev->parent; + unsigned int i; netif_stop_queue(netdev); /* Stop polling */ parent->active_channels--; - if (!parent->active_channels) + if (!parent->active_channels) { usb_kill_anchored_urbs(&parent->rx_submitted); + for (i = 0; i < GS_MAX_RX_URBS; i++) + usb_free_coherent(dev->udev, + sizeof(struct gs_host_frame), + dev->rxbuf[i], + dev->rxbuf_dma[i]); + } /* Stop sending URBs */ usb_kill_anchored_urbs(&dev->tx_submitted); From 562fed945ea482833667f85496eeda766d511386 Mon Sep 17 00:00:00 2001 From: Liang He Date: Sun, 19 Jun 2022 15:02:57 +0800 Subject: [PATCH 204/246] can: grcan: grcan_probe(): remove extra of_node_get() In grcan_probe(), of_find_node_by_path() has already increased the refcount. There is no need to call of_node_get() again, so remove it. Link: https://lore.kernel.org/all/20220619070257.4067022-1-windhl@126.com Fixes: 1e93ed26acf0 ("can: grcan: grcan_probe(): fix broken system id check for errata workaround needs") Cc: stable@vger.kernel.org # v5.18 Cc: Andreas Larsson Signed-off-by: Liang He Signed-off-by: Marc Kleine-Budde --- drivers/net/can/grcan.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c index 76df4807d366..4c47c1055eff 100644 --- a/drivers/net/can/grcan.c +++ b/drivers/net/can/grcan.c @@ -1646,7 +1646,6 @@ static int grcan_probe(struct platform_device *ofdev) */ sysid_parent = of_find_node_by_path("/ambapp0"); if (sysid_parent) { - of_node_get(sysid_parent); err = of_property_read_u32(sysid_parent, "systemid", &sysid); if (!err && ((sysid & GRLIB_VERSION_MASK) >= GRCAN_TXBUG_SAFE_GRLIB_VERSION)) From 5b12933de4e76ec164031c18ce8e0904abf530d7 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 23 May 2022 17:18:33 +0200 Subject: [PATCH 205/246] can: m_can: m_can_chip_config(): actually enable internal timestamping In commit df06fd678260 ("can: m_can: m_can_chip_config(): enable and configure internal timestamps") the timestamping in the m_can core should be enabled. In peripheral mode, the RX'ed CAN frames, TX compete frames and error events are sorted by the timestamp. The above mentioned commit however forgot to enable the timestamping. Add the missing bits to enable the timestamp counter to the write of the Timestamp Counter Configuration register. Link: https://lore.kernel.org/all/20220612212708.4081756-1-mkl@pengutronix.de Fixes: df06fd678260 ("can: m_can: m_can_chip_config(): enable and configure internal timestamps") Cc: # 5.13 Cc: Torin Cooper-Bennun Reviewed-by: Chandrasekar Ramakrishnan Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 5d0c82d8b9a9..03a22d493cf6 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -1351,7 +1351,9 @@ static void m_can_chip_config(struct net_device *dev) /* enable internal timestamp generation, with a prescalar of 16. The * prescalar is applied to the nominal bit timing */ - m_can_write(cdev, M_CAN_TSCC, FIELD_PREP(TSCC_TCP_MASK, 0xf)); + m_can_write(cdev, M_CAN_TSCC, + FIELD_PREP(TSCC_TCP_MASK, 0xf) | + FIELD_PREP(TSCC_TSS_MASK, TSCC_TSS_INTERNAL)); m_can_config_endisable(cdev, false); From 4c3333693f07313f5f0145a922f14a7d3c0f4f21 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 30 May 2022 19:30:28 +0200 Subject: [PATCH 206/246] can: m_can: m_can_{read_fifo,echo_tx_event}(): shift timestamp to full 32 bits In commit 1be37d3b0414 ("can: m_can: fix periph RX path: use rx-offload to ensure skbs are sent from softirq context") the RX path for peripheral devices was switched to RX-offload. Received CAN frames are pushed to RX-offload together with a timestamp. RX-offload is designed to handle overflows of the timestamp correctly, if 32 bit timestamps are provided. The timestamps of m_can core are only 16 bits wide. So this patch shifts them to full 32 bit before passing them to RX-offload. Link: https://lore.kernel.org/all/20220612211410.4081390-1-mkl@pengutronix.de Fixes: 1be37d3b0414 ("can: m_can: fix periph RX path: use rx-offload to ensure skbs are sent from softirq context") Cc: # 5.13 Cc: Torin Cooper-Bennun Reviewed-by: Chandrasekar Ramakrishnan Signed-off-by: Marc Kleine-Budde --- drivers/net/can/m_can/m_can.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c index 03a22d493cf6..7931f9c71ef3 100644 --- a/drivers/net/can/m_can/m_can.c +++ b/drivers/net/can/m_can/m_can.c @@ -529,7 +529,7 @@ static int m_can_read_fifo(struct net_device *dev, u32 rxfs) /* acknowledge rx fifo 0 */ m_can_write(cdev, M_CAN_RXF0A, fgi); - timestamp = FIELD_GET(RX_BUF_RXTS_MASK, fifo_header.dlc); + timestamp = FIELD_GET(RX_BUF_RXTS_MASK, fifo_header.dlc) << 16; m_can_receive_skb(cdev, skb, timestamp); @@ -1030,7 +1030,7 @@ static int m_can_echo_tx_event(struct net_device *dev) } msg_mark = FIELD_GET(TX_EVENT_MM_MASK, txe); - timestamp = FIELD_GET(TX_EVENT_TXTS_MASK, txe); + timestamp = FIELD_GET(TX_EVENT_TXTS_MASK, txe) << 16; /* ack txe element */ m_can_write(cdev, M_CAN_TXEFA, FIELD_PREP(TXEFA_EFAI_MASK, From 1b18f09d31cfa7148df15a7d5c5e0e86f105f7d1 Mon Sep 17 00:00:00 2001 From: Rick Lindsley Date: Sat, 2 Jul 2022 03:37:12 -0700 Subject: [PATCH 207/246] ibmvnic: Properly dispose of all skbs during a failover. During a reset, there may have been transmits in flight that are no longer valid and cannot be fulfilled. Resetting and clearing the queues is insufficient; each skb also needs to be explicitly freed so that upper levels are not left waiting for confirmation of a transmit that will never happen. If this happens frequently enough, the apparent backlog will cause TCP to begin "congestion control" unnecessarily, culminating in permanently decreased throughput. Fixes: d7c0ef36bde03 ("ibmvnic: Free and re-allocate scrqs when tx/rx scrqs change") Tested-by: Nick Child Reviewed-by: Brian King Signed-off-by: Rick Lindsley Signed-off-by: David S. Miller --- drivers/net/ethernet/ibm/ibmvnic.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 7e7fe5bdf1f8..5ab7c0f81e9a 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -5981,6 +5981,15 @@ static int ibmvnic_reset_init(struct ibmvnic_adapter *adapter, bool reset) release_sub_crqs(adapter, 0); rc = init_sub_crqs(adapter); } else { + /* no need to reinitialize completely, but we do + * need to clean up transmits that were in flight + * when we processed the reset. Failure to do so + * will confound the upper layer, usually TCP, by + * creating the illusion of transmits that are + * awaiting completion. + */ + clean_tx_pools(adapter); + rc = reset_sub_crq_queues(adapter); } } else { From 49f274c72357d2d74cba70b172cf369768909707 Mon Sep 17 00:00:00 2001 From: Jimmy Assarsson Date: Fri, 3 Jun 2022 10:38:18 +0200 Subject: [PATCH 208/246] can: kvaser_usb: replace run-time checks with struct kvaser_usb_driver_info Unify and move compile-time known information into new struct kvaser_usb_driver_info, in favor of run-time checks. All Kvaser USBcanII supports listen-only mode and error counter reporting. Link: https://lore.kernel.org/all/20220603083820.800246-2-extja@kvaser.com Suggested-by: Marc Kleine-Budde Cc: stable@vger.kernel.org Signed-off-by: Jimmy Assarsson [mkl: move struct kvaser_usb_driver_info into kvaser_usb_core.c] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 22 +- .../net/can/usb/kvaser_usb/kvaser_usb_core.c | 274 ++++++++++-------- .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 24 +- 3 files changed, 172 insertions(+), 148 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h index 3a49257f9fa6..39d5bfd70ff4 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h @@ -35,9 +35,9 @@ #define KVASER_USB_RX_BUFFER_SIZE 3072 #define KVASER_USB_MAX_NET_DEVICES 5 -/* USB devices features */ -#define KVASER_USB_HAS_SILENT_MODE BIT(0) -#define KVASER_USB_HAS_TXRX_ERRORS BIT(1) +/* Kvaser USB device quirks */ +#define KVASER_USB_QUIRK_HAS_SILENT_MODE BIT(0) +#define KVASER_USB_QUIRK_HAS_TXRX_ERRORS BIT(1) /* Device capabilities */ #define KVASER_USB_CAP_BERR_CAP 0x01 @@ -65,12 +65,7 @@ struct kvaser_usb_dev_card_data_hydra { struct kvaser_usb_dev_card_data { u32 ctrlmode_supported; u32 capabilities; - union { - struct { - enum kvaser_usb_leaf_family family; - } leaf; - struct kvaser_usb_dev_card_data_hydra hydra; - }; + struct kvaser_usb_dev_card_data_hydra hydra; }; /* Context for an outstanding, not yet ACKed, transmission */ @@ -83,7 +78,7 @@ struct kvaser_usb { struct usb_device *udev; struct usb_interface *intf; struct kvaser_usb_net_priv *nets[KVASER_USB_MAX_NET_DEVICES]; - const struct kvaser_usb_dev_ops *ops; + const struct kvaser_usb_driver_info *driver_info; const struct kvaser_usb_dev_cfg *cfg; struct usb_endpoint_descriptor *bulk_in, *bulk_out; @@ -165,6 +160,12 @@ struct kvaser_usb_dev_ops { u16 transid); }; +struct kvaser_usb_driver_info { + u32 quirks; + enum kvaser_usb_leaf_family family; + const struct kvaser_usb_dev_ops *ops; +}; + struct kvaser_usb_dev_cfg { const struct can_clock clock; const unsigned int timestamp_freq; @@ -184,4 +185,5 @@ int kvaser_usb_send_cmd_async(struct kvaser_usb_net_priv *priv, void *cmd, int len); int kvaser_usb_can_rx_over_error(struct net_device *netdev); + #endif /* KVASER_USB_H */ diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index e67658b53d02..d5b293e673d8 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -61,8 +61,6 @@ #define USB_USBCAN_R_V2_PRODUCT_ID 294 #define USB_LEAF_LIGHT_R_V2_PRODUCT_ID 295 #define USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID 296 -#define USB_LEAF_PRODUCT_ID_END \ - USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID /* Kvaser USBCan-II devices product ids */ #define USB_USBCAN_REVB_PRODUCT_ID 2 @@ -89,116 +87,144 @@ #define USB_USBCAN_PRO_4HS_PRODUCT_ID 276 #define USB_HYBRID_CANLIN_PRODUCT_ID 277 #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID 278 -#define USB_HYDRA_PRODUCT_ID_END \ - USB_HYBRID_PRO_CANLIN_PRODUCT_ID -static inline bool kvaser_is_leaf(const struct usb_device_id *id) -{ - return (id->idProduct >= USB_LEAF_DEVEL_PRODUCT_ID && - id->idProduct <= USB_CAN_R_PRODUCT_ID) || - (id->idProduct >= USB_LEAF_LITE_V2_PRODUCT_ID && - id->idProduct <= USB_LEAF_PRODUCT_ID_END); -} +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = { + .quirks = 0, + .ops = &kvaser_usb_hydra_dev_ops, +}; -static inline bool kvaser_is_usbcan(const struct usb_device_id *id) -{ - return id->idProduct >= USB_USBCAN_REVB_PRODUCT_ID && - id->idProduct <= USB_MEMORATOR_PRODUCT_ID; -} +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_usbcan = { + .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | + KVASER_USB_QUIRK_HAS_SILENT_MODE, + .family = KVASER_USBCAN, + .ops = &kvaser_usb_leaf_dev_ops, +}; -static inline bool kvaser_is_hydra(const struct usb_device_id *id) -{ - return id->idProduct >= USB_BLACKBIRD_V2_PRODUCT_ID && - id->idProduct <= USB_HYDRA_PRODUCT_ID_END; -} +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf = { + .quirks = 0, + .family = KVASER_LEAF, + .ops = &kvaser_usb_leaf_dev_ops, +}; + +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = { + .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS, + .family = KVASER_LEAF, + .ops = &kvaser_usb_leaf_dev_ops, +}; + +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_listen = { + .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | + KVASER_USB_QUIRK_HAS_SILENT_MODE, + .family = KVASER_LEAF, + .ops = &kvaser_usb_leaf_dev_ops, +}; static const struct usb_device_id kvaser_usb_table[] = { /* Leaf USB product IDs */ - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID) }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LS_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_SWC_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LIN_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_LS_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_SWC_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_DEVEL_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSHS_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_UPRO_HSHS_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID) }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_OBDII_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS | - KVASER_USB_HAS_SILENT_MODE }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen }, { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSLS_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_CH_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, { USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_SPRO_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, { USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_MERCURY_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, { USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_LEAF_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, { USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID) }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, /* USBCANII USB product IDs */ { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_REVB_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMORATOR_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, { USB_DEVICE(KVASER_VENDOR_ID, USB_VCI2_PRODUCT_ID), - .driver_info = KVASER_USB_HAS_TXRX_ERRORS }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan }, /* Minihydra USB product IDs */ - { USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_2CANLIN_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_2CANLIN_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_U100_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_U100P_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_U100S_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_4HS_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID) }, - { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID) }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_2CANLIN_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_2CANLIN_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_U100_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_U100P_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_U100S_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_4HS_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, + { USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID), + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra }, { } }; MODULE_DEVICE_TABLE(usb, kvaser_usb_table); @@ -285,6 +311,7 @@ int kvaser_usb_can_rx_over_error(struct net_device *netdev) static void kvaser_usb_read_bulk_callback(struct urb *urb) { struct kvaser_usb *dev = urb->context; + const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; int err; unsigned int i; @@ -301,8 +328,8 @@ static void kvaser_usb_read_bulk_callback(struct urb *urb) goto resubmit_urb; } - dev->ops->dev_read_bulk_callback(dev, urb->transfer_buffer, - urb->actual_length); + ops->dev_read_bulk_callback(dev, urb->transfer_buffer, + urb->actual_length); resubmit_urb: usb_fill_bulk_urb(urb, dev->udev, @@ -396,6 +423,7 @@ static int kvaser_usb_open(struct net_device *netdev) { struct kvaser_usb_net_priv *priv = netdev_priv(netdev); struct kvaser_usb *dev = priv->dev; + const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; int err; err = open_candev(netdev); @@ -406,11 +434,11 @@ static int kvaser_usb_open(struct net_device *netdev) if (err) goto error; - err = dev->ops->dev_set_opt_mode(priv); + err = ops->dev_set_opt_mode(priv); if (err) goto error; - err = dev->ops->dev_start_chip(priv); + err = ops->dev_start_chip(priv); if (err) { netdev_warn(netdev, "Cannot start device, error %d\n", err); goto error; @@ -467,22 +495,23 @@ static int kvaser_usb_close(struct net_device *netdev) { struct kvaser_usb_net_priv *priv = netdev_priv(netdev); struct kvaser_usb *dev = priv->dev; + const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; int err; netif_stop_queue(netdev); - err = dev->ops->dev_flush_queue(priv); + err = ops->dev_flush_queue(priv); if (err) netdev_warn(netdev, "Cannot flush queue, error %d\n", err); - if (dev->ops->dev_reset_chip) { - err = dev->ops->dev_reset_chip(dev, priv->channel); + if (ops->dev_reset_chip) { + err = ops->dev_reset_chip(dev, priv->channel); if (err) netdev_warn(netdev, "Cannot reset card, error %d\n", err); } - err = dev->ops->dev_stop_chip(priv); + err = ops->dev_stop_chip(priv); if (err) netdev_warn(netdev, "Cannot stop device, error %d\n", err); @@ -521,6 +550,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, { struct kvaser_usb_net_priv *priv = netdev_priv(netdev); struct kvaser_usb *dev = priv->dev; + const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops; struct net_device_stats *stats = &netdev->stats; struct kvaser_usb_tx_urb_context *context = NULL; struct urb *urb; @@ -563,8 +593,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb, goto freeurb; } - buf = dev->ops->dev_frame_to_cmd(priv, skb, &cmd_len, - context->echo_index); + buf = ops->dev_frame_to_cmd(priv, skb, &cmd_len, context->echo_index); if (!buf) { stats->tx_dropped++; dev_kfree_skb(skb); @@ -648,15 +677,16 @@ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev) } } -static int kvaser_usb_init_one(struct kvaser_usb *dev, - const struct usb_device_id *id, int channel) +static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel) { struct net_device *netdev; struct kvaser_usb_net_priv *priv; + const struct kvaser_usb_driver_info *driver_info = dev->driver_info; + const struct kvaser_usb_dev_ops *ops = driver_info->ops; int err; - if (dev->ops->dev_reset_chip) { - err = dev->ops->dev_reset_chip(dev, channel); + if (ops->dev_reset_chip) { + err = ops->dev_reset_chip(dev, channel); if (err) return err; } @@ -685,20 +715,19 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, priv->can.state = CAN_STATE_STOPPED; priv->can.clock.freq = dev->cfg->clock.freq; priv->can.bittiming_const = dev->cfg->bittiming_const; - priv->can.do_set_bittiming = dev->ops->dev_set_bittiming; - priv->can.do_set_mode = dev->ops->dev_set_mode; - if ((id->driver_info & KVASER_USB_HAS_TXRX_ERRORS) || + priv->can.do_set_bittiming = ops->dev_set_bittiming; + priv->can.do_set_mode = ops->dev_set_mode; + if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) || (priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP)) - priv->can.do_get_berr_counter = dev->ops->dev_get_berr_counter; - if (id->driver_info & KVASER_USB_HAS_SILENT_MODE) + priv->can.do_get_berr_counter = ops->dev_get_berr_counter; + if (driver_info->quirks & KVASER_USB_QUIRK_HAS_SILENT_MODE) priv->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY; priv->can.ctrlmode_supported |= dev->card_data.ctrlmode_supported; if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { priv->can.data_bittiming_const = dev->cfg->data_bittiming_const; - priv->can.do_set_data_bittiming = - dev->ops->dev_set_data_bittiming; + priv->can.do_set_data_bittiming = ops->dev_set_data_bittiming; } netdev->flags |= IFF_ECHO; @@ -729,29 +758,22 @@ static int kvaser_usb_probe(struct usb_interface *intf, struct kvaser_usb *dev; int err; int i; + const struct kvaser_usb_driver_info *driver_info; + const struct kvaser_usb_dev_ops *ops; + + driver_info = (const struct kvaser_usb_driver_info *)id->driver_info; + if (!driver_info) + return -ENODEV; dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; - if (kvaser_is_leaf(id)) { - dev->card_data.leaf.family = KVASER_LEAF; - dev->ops = &kvaser_usb_leaf_dev_ops; - } else if (kvaser_is_usbcan(id)) { - dev->card_data.leaf.family = KVASER_USBCAN; - dev->ops = &kvaser_usb_leaf_dev_ops; - } else if (kvaser_is_hydra(id)) { - dev->ops = &kvaser_usb_hydra_dev_ops; - } else { - dev_err(&intf->dev, - "Product ID (%d) is not a supported Kvaser USB device\n", - id->idProduct); - return -ENODEV; - } - dev->intf = intf; + dev->driver_info = driver_info; + ops = driver_info->ops; - err = dev->ops->dev_setup_endpoints(dev); + err = ops->dev_setup_endpoints(dev); if (err) { dev_err(&intf->dev, "Cannot get usb endpoint(s)"); return err; @@ -765,22 +787,22 @@ static int kvaser_usb_probe(struct usb_interface *intf, dev->card_data.ctrlmode_supported = 0; dev->card_data.capabilities = 0; - err = dev->ops->dev_init_card(dev); + err = ops->dev_init_card(dev); if (err) { dev_err(&intf->dev, "Failed to initialize card, error %d\n", err); return err; } - err = dev->ops->dev_get_software_info(dev); + err = ops->dev_get_software_info(dev); if (err) { dev_err(&intf->dev, "Cannot get software info, error %d\n", err); return err; } - if (dev->ops->dev_get_software_details) { - err = dev->ops->dev_get_software_details(dev); + if (ops->dev_get_software_details) { + err = ops->dev_get_software_details(dev); if (err) { dev_err(&intf->dev, "Cannot get software details, error %d\n", err); @@ -798,14 +820,14 @@ static int kvaser_usb_probe(struct usb_interface *intf, dev_dbg(&intf->dev, "Max outstanding tx = %d URBs\n", dev->max_tx_urbs); - err = dev->ops->dev_get_card_info(dev); + err = ops->dev_get_card_info(dev); if (err) { dev_err(&intf->dev, "Cannot get card info, error %d\n", err); return err; } - if (dev->ops->dev_get_capabilities) { - err = dev->ops->dev_get_capabilities(dev); + if (ops->dev_get_capabilities) { + err = ops->dev_get_capabilities(dev); if (err) { dev_err(&intf->dev, "Cannot get capabilities, error %d\n", err); @@ -815,7 +837,7 @@ static int kvaser_usb_probe(struct usb_interface *intf, } for (i = 0; i < dev->nchannels; i++) { - err = kvaser_usb_init_one(dev, id, i); + err = kvaser_usb_init_one(dev, i); if (err) { kvaser_usb_remove_interfaces(dev); return err; diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c index c805b999c543..5cf940ba3f7f 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -404,7 +404,7 @@ kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv, sizeof(struct kvaser_cmd_tx_can); cmd->u.tx_can.channel = priv->channel; - switch (dev->card_data.leaf.family) { + switch (dev->driver_info->family) { case KVASER_LEAF: cmd_tx_can_flags = &cmd->u.tx_can.leaf.flags; break; @@ -550,7 +550,7 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev) if (err) return err; - switch (dev->card_data.leaf.family) { + switch (dev->driver_info->family) { case KVASER_LEAF: kvaser_usb_leaf_get_software_info_leaf(dev, &cmd.u.leaf.softinfo); break; @@ -597,7 +597,7 @@ static int kvaser_usb_leaf_get_card_info(struct kvaser_usb *dev) dev->nchannels = cmd.u.cardinfo.nchannels; if (dev->nchannels > KVASER_USB_MAX_NET_DEVICES || - (dev->card_data.leaf.family == KVASER_USBCAN && + (dev->driver_info->family == KVASER_USBCAN && dev->nchannels > MAX_USBCAN_NET_DEVICES)) return -EINVAL; @@ -730,7 +730,7 @@ kvaser_usb_leaf_rx_error_update_can_state(struct kvaser_usb_net_priv *priv, new_state < CAN_STATE_BUS_OFF) priv->can.can_stats.restarts++; - switch (dev->card_data.leaf.family) { + switch (dev->driver_info->family) { case KVASER_LEAF: if (es->leaf.error_factor) { priv->can.can_stats.bus_error++; @@ -809,7 +809,7 @@ static void kvaser_usb_leaf_rx_error(const struct kvaser_usb *dev, } } - switch (dev->card_data.leaf.family) { + switch (dev->driver_info->family) { case KVASER_LEAF: if (es->leaf.error_factor) { cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; @@ -999,7 +999,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, stats = &priv->netdev->stats; if ((cmd->u.rx_can_header.flag & MSG_FLAG_ERROR_FRAME) && - (dev->card_data.leaf.family == KVASER_LEAF && + (dev->driver_info->family == KVASER_LEAF && cmd->id == CMD_LEAF_LOG_MESSAGE)) { kvaser_usb_leaf_leaf_rx_error(dev, cmd); return; @@ -1015,7 +1015,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, return; } - switch (dev->card_data.leaf.family) { + switch (dev->driver_info->family) { case KVASER_LEAF: rx_data = cmd->u.leaf.rx_can.data; break; @@ -1030,7 +1030,7 @@ static void kvaser_usb_leaf_rx_can_msg(const struct kvaser_usb *dev, return; } - if (dev->card_data.leaf.family == KVASER_LEAF && cmd->id == + if (dev->driver_info->family == KVASER_LEAF && cmd->id == CMD_LEAF_LOG_MESSAGE) { cf->can_id = le32_to_cpu(cmd->u.leaf.log_message.id); if (cf->can_id & KVASER_EXTENDED_FRAME) @@ -1128,14 +1128,14 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, break; case CMD_LEAF_LOG_MESSAGE: - if (dev->card_data.leaf.family != KVASER_LEAF) + if (dev->driver_info->family != KVASER_LEAF) goto warn; kvaser_usb_leaf_rx_can_msg(dev, cmd); break; case CMD_CHIP_STATE_EVENT: case CMD_CAN_ERROR_EVENT: - if (dev->card_data.leaf.family == KVASER_LEAF) + if (dev->driver_info->family == KVASER_LEAF) kvaser_usb_leaf_leaf_rx_error(dev, cmd); else kvaser_usb_leaf_usbcan_rx_error(dev, cmd); @@ -1147,12 +1147,12 @@ static void kvaser_usb_leaf_handle_command(const struct kvaser_usb *dev, /* Ignored commands */ case CMD_USBCAN_CLOCK_OVERFLOW_EVENT: - if (dev->card_data.leaf.family != KVASER_USBCAN) + if (dev->driver_info->family != KVASER_USBCAN) goto warn; break; case CMD_FLUSH_QUEUE_REPLY: - if (dev->card_data.leaf.family != KVASER_LEAF) + if (dev->driver_info->family != KVASER_LEAF) goto warn; break; From e6c80e601053ffdac5709f11ff3ec1e19ed05f7b Mon Sep 17 00:00:00 2001 From: Jimmy Assarsson Date: Fri, 3 Jun 2022 10:38:19 +0200 Subject: [PATCH 209/246] can: kvaser_usb: kvaser_usb_leaf: fix CAN clock frequency regression The firmware of M32C based Leaf devices expects bittiming parameters calculated for 16MHz clock. Since we use the actual clock frequency of the device, the device may end up with wrong bittiming parameters, depending on user requested parameters. This regression affects M32C based Leaf devices with non-16MHz clock. Fixes: fb12797ab1fe ("can: kvaser_usb: get CAN clock frequency from device") Link: https://lore.kernel.org/all/20220603083820.800246-3-extja@kvaser.com Cc: stable@vger.kernel.org Signed-off-by: Jimmy Assarsson Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 1 + .../net/can/usb/kvaser_usb/kvaser_usb_core.c | 33 ++++++++++++------- .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 25 +++++++++----- 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h index 39d5bfd70ff4..c1f66cef2c3f 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h @@ -38,6 +38,7 @@ /* Kvaser USB device quirks */ #define KVASER_USB_QUIRK_HAS_SILENT_MODE BIT(0) #define KVASER_USB_QUIRK_HAS_TXRX_ERRORS BIT(1) +#define KVASER_USB_QUIRK_IGNORE_CLK_FREQ BIT(2) /* Device capabilities */ #define KVASER_USB_CAP_BERR_CAP 0x01 diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c index d5b293e673d8..f211bfcb1d97 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c @@ -101,26 +101,33 @@ static const struct kvaser_usb_driver_info kvaser_usb_driver_info_usbcan = { }; static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf = { - .quirks = 0, + .quirks = KVASER_USB_QUIRK_IGNORE_CLK_FREQ, .family = KVASER_LEAF, .ops = &kvaser_usb_leaf_dev_ops, }; static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = { - .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS, + .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | + KVASER_USB_QUIRK_IGNORE_CLK_FREQ, .family = KVASER_LEAF, .ops = &kvaser_usb_leaf_dev_ops, }; static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_listen = { .quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS | - KVASER_USB_QUIRK_HAS_SILENT_MODE, + KVASER_USB_QUIRK_HAS_SILENT_MODE | + KVASER_USB_QUIRK_IGNORE_CLK_FREQ, .family = KVASER_LEAF, .ops = &kvaser_usb_leaf_dev_ops, }; +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = { + .quirks = 0, + .ops = &kvaser_usb_leaf_dev_ops, +}; + static const struct usb_device_id kvaser_usb_table[] = { - /* Leaf USB product IDs */ + /* Leaf M32C USB product IDs */ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID), .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID), @@ -161,22 +168,24 @@ static const struct usb_device_id kvaser_usb_table[] = { .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, { USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID), .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err }, + + /* Leaf i.MX28 USB product IDs */ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID), - .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID), - .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID), - .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID), - .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID), - .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_R_V2_PRODUCT_ID), - .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_R_V2_PRODUCT_ID), - .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM2_PRODUCT_ID), - .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf }, + .driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx }, /* USBCANII USB product IDs */ { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID), diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c index 5cf940ba3f7f..957144cee414 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -524,16 +524,23 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev, dev->fw_version = le32_to_cpu(softinfo->fw_version); dev->max_tx_urbs = le16_to_cpu(softinfo->max_outstanding_tx); - switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { - case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: + if (dev->driver_info->quirks & KVASER_USB_QUIRK_IGNORE_CLK_FREQ) { + /* Firmware expects bittiming parameters calculated for 16MHz + * clock, regardless of the actual clock + */ dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz; - break; - case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK: - dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz; - break; - case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK: - dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz; - break; + } else { + switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { + case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: + dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz; + break; + case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK: + dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz; + break; + case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK: + dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz; + break; + } } } From b3b6df2c56d80b8c6740433cff5f016668b8de70 Mon Sep 17 00:00:00 2001 From: Jimmy Assarsson Date: Fri, 3 Jun 2022 10:38:20 +0200 Subject: [PATCH 210/246] can: kvaser_usb: kvaser_usb_leaf: fix bittiming limits Use correct bittiming limits depending on device. For devices based on USBcanII, Leaf M32C or Leaf i.MX28. Fixes: 080f40a6fa28 ("can: kvaser_usb: Add support for Kvaser CAN/USB devices") Fixes: b4f20130af23 ("can: kvaser_usb: add support for Kvaser Leaf v2 and usb mini PCIe") Fixes: f5d4abea3ce0 ("can: kvaser_usb: Add support for the USBcan-II family") Link: https://lore.kernel.org/all/20220603083820.800246-4-extja@kvaser.com Cc: stable@vger.kernel.org Signed-off-by: Jimmy Assarsson [mkl: remove stray netlink.h include] [mkl: keep struct can_bittiming_const kvaser_usb_flexc_bittiming_const in kvaser_usb_hydra.c] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/kvaser_usb/kvaser_usb.h | 2 + .../net/can/usb/kvaser_usb/kvaser_usb_hydra.c | 4 +- .../net/can/usb/kvaser_usb/kvaser_usb_leaf.c | 76 +++++++++++-------- 3 files changed, 47 insertions(+), 35 deletions(-) diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h index c1f66cef2c3f..eefcbe3aadce 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb.h +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb.h @@ -187,4 +187,6 @@ int kvaser_usb_send_cmd_async(struct kvaser_usb_net_priv *priv, void *cmd, int kvaser_usb_can_rx_over_error(struct net_device *netdev); +extern const struct can_bittiming_const kvaser_usb_flexc_bittiming_const; + #endif /* KVASER_USB_H */ diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c index a26823c5b62a..5d70844ac030 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c @@ -375,7 +375,7 @@ static const struct can_bittiming_const kvaser_usb_hydra_kcan_bittiming_c = { .brp_inc = 1, }; -static const struct can_bittiming_const kvaser_usb_hydra_flexc_bittiming_c = { +const struct can_bittiming_const kvaser_usb_flexc_bittiming_const = { .name = "kvaser_usb_flex", .tseg1_min = 4, .tseg1_max = 16, @@ -2052,7 +2052,7 @@ static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_flexc = { .freq = 24 * MEGA /* Hz */, }, .timestamp_freq = 1, - .bittiming_const = &kvaser_usb_hydra_flexc_bittiming_c, + .bittiming_const = &kvaser_usb_flexc_bittiming_const, }; static const struct kvaser_usb_dev_cfg kvaser_usb_hydra_dev_cfg_rt = { diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c index 957144cee414..cc809ecd1e62 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -101,16 +101,6 @@ #define USBCAN_ERROR_STATE_RX_ERROR BIT(1) #define USBCAN_ERROR_STATE_BUSERROR BIT(2) -/* bittiming parameters */ -#define KVASER_USB_TSEG1_MIN 1 -#define KVASER_USB_TSEG1_MAX 16 -#define KVASER_USB_TSEG2_MIN 1 -#define KVASER_USB_TSEG2_MAX 8 -#define KVASER_USB_SJW_MAX 4 -#define KVASER_USB_BRP_MIN 1 -#define KVASER_USB_BRP_MAX 64 -#define KVASER_USB_BRP_INC 1 - /* ctrl modes */ #define KVASER_CTRL_MODE_NORMAL 1 #define KVASER_CTRL_MODE_SILENT 2 @@ -343,48 +333,68 @@ struct kvaser_usb_err_summary { }; }; -static const struct can_bittiming_const kvaser_usb_leaf_bittiming_const = { - .name = "kvaser_usb", - .tseg1_min = KVASER_USB_TSEG1_MIN, - .tseg1_max = KVASER_USB_TSEG1_MAX, - .tseg2_min = KVASER_USB_TSEG2_MIN, - .tseg2_max = KVASER_USB_TSEG2_MAX, - .sjw_max = KVASER_USB_SJW_MAX, - .brp_min = KVASER_USB_BRP_MIN, - .brp_max = KVASER_USB_BRP_MAX, - .brp_inc = KVASER_USB_BRP_INC, +static const struct can_bittiming_const kvaser_usb_leaf_m16c_bittiming_const = { + .name = "kvaser_usb_ucii", + .tseg1_min = 4, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 1, + .brp_max = 16, + .brp_inc = 1, }; -static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_8mhz = { +static const struct can_bittiming_const kvaser_usb_leaf_m32c_bittiming_const = { + .name = "kvaser_usb_leaf", + .tseg1_min = 3, + .tseg1_max = 16, + .tseg2_min = 2, + .tseg2_max = 8, + .sjw_max = 4, + .brp_min = 2, + .brp_max = 128, + .brp_inc = 2, +}; + +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_usbcan_dev_cfg = { .clock = { .freq = 8 * MEGA /* Hz */, }, .timestamp_freq = 1, - .bittiming_const = &kvaser_usb_leaf_bittiming_const, + .bittiming_const = &kvaser_usb_leaf_m16c_bittiming_const, }; -static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_16mhz = { +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_m32c_dev_cfg = { .clock = { .freq = 16 * MEGA /* Hz */, }, .timestamp_freq = 1, - .bittiming_const = &kvaser_usb_leaf_bittiming_const, + .bittiming_const = &kvaser_usb_leaf_m32c_bittiming_const, }; -static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_24mhz = { +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_16mhz = { + .clock = { + .freq = 16 * MEGA /* Hz */, + }, + .timestamp_freq = 1, + .bittiming_const = &kvaser_usb_flexc_bittiming_const, +}; + +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_24mhz = { .clock = { .freq = 24 * MEGA /* Hz */, }, .timestamp_freq = 1, - .bittiming_const = &kvaser_usb_leaf_bittiming_const, + .bittiming_const = &kvaser_usb_flexc_bittiming_const, }; -static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_dev_cfg_32mhz = { +static const struct kvaser_usb_dev_cfg kvaser_usb_leaf_imx_dev_cfg_32mhz = { .clock = { .freq = 32 * MEGA /* Hz */, }, .timestamp_freq = 1, - .bittiming_const = &kvaser_usb_leaf_bittiming_const, + .bittiming_const = &kvaser_usb_flexc_bittiming_const, }; static void * @@ -528,17 +538,17 @@ static void kvaser_usb_leaf_get_software_info_leaf(struct kvaser_usb *dev, /* Firmware expects bittiming parameters calculated for 16MHz * clock, regardless of the actual clock */ - dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz; + dev->cfg = &kvaser_usb_leaf_m32c_dev_cfg; } else { switch (sw_options & KVASER_USB_LEAF_SWOPTION_FREQ_MASK) { case KVASER_USB_LEAF_SWOPTION_FREQ_16_MHZ_CLK: - dev->cfg = &kvaser_usb_leaf_dev_cfg_16mhz; + dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_16mhz; break; case KVASER_USB_LEAF_SWOPTION_FREQ_24_MHZ_CLK: - dev->cfg = &kvaser_usb_leaf_dev_cfg_24mhz; + dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_24mhz; break; case KVASER_USB_LEAF_SWOPTION_FREQ_32_MHZ_CLK: - dev->cfg = &kvaser_usb_leaf_dev_cfg_32mhz; + dev->cfg = &kvaser_usb_leaf_imx_dev_cfg_32mhz; break; } } @@ -565,7 +575,7 @@ static int kvaser_usb_leaf_get_software_info_inner(struct kvaser_usb *dev) dev->fw_version = le32_to_cpu(cmd.u.usbcan.softinfo.fw_version); dev->max_tx_urbs = le16_to_cpu(cmd.u.usbcan.softinfo.max_outstanding_tx); - dev->cfg = &kvaser_usb_leaf_dev_cfg_8mhz; + dev->cfg = &kvaser_usb_leaf_usbcan_dev_cfg; break; } From 406cc9cdb3e8d644b15e8028948f091b82abdbca Mon Sep 17 00:00:00 2001 From: Thomas Kopp Date: Tue, 21 Dec 2021 22:24:52 +0000 Subject: [PATCH 211/246] can: mcp251xfd: mcp251xfd_regmap_crc_read(): improve workaround handling for mcp2517fd The mcp251xfd compatible chips have an erratum ([1], [2]), where the received CRC doesn't match the calculated CRC. In commit c7eb923c3caf ("can: mcp251xfd: mcp251xfd_regmap_crc_read(): work around broken CRC on TBC register") the following workaround was implementierend. - If a CRC read error on the TBC register is detected and the first byte is 0x00 or 0x80, the most significant bit of the first byte is flipped and the CRC is calculated again. - If the CRC now matches, the _original_ data is passed to the reader. For now we assume transferred data was OK. Measurements on the mcp2517fd show that the workaround is applicable not only of the lowest byte is 0x00 or 0x80, but also if 3 least significant bits are set. Update check on 1st data byte and workaround description accordingly. [1] mcp2517fd: DS80000792C: "Incorrect CRC for certain READ_CRC commands" [2] mcp2518fd: DS80000789C: "Incorrect CRC for certain READ_CRC commands" Link: https://lore.kernel.org/all/DM4PR11MB53901D49578FE265B239E55AFB7C9@DM4PR11MB5390.namprd11.prod.outlook.com Fixes: c7eb923c3caf ("can: mcp251xfd: mcp251xfd_regmap_crc_read(): work around broken CRC on TBC register") Cc: stable@vger.kernel.org Reported-by: Pavel Modilaynen Signed-off-by: Thomas Kopp [mkl: split into 2 patches, update patch description and documentation] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c index 217510c12af5..211edd9ef0c9 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c @@ -334,10 +334,12 @@ mcp251xfd_regmap_crc_read(void *context, * register. It increments once per SYS clock tick, * which is 20 or 40 MHz. * - * Observation shows that if the lowest byte (which is - * transferred first on the SPI bus) of that register - * is 0x00 or 0x80 the calculated CRC doesn't always - * match the transferred one. + * Observation on the mcp2518fd shows that if the + * lowest byte (which is transferred first on the SPI + * bus) of that register is 0x00 or 0x80 the + * calculated CRC doesn't always match the transferred + * one. On the mcp2517fd this problem is not limited + * to the first byte being 0x00 or 0x80. * * If the highest bit in the lowest byte is flipped * the transferred CRC matches the calculated one. We @@ -346,7 +348,8 @@ mcp251xfd_regmap_crc_read(void *context, * correct. */ if (reg == MCP251XFD_REG_TBC && - (buf_rx->data[0] == 0x0 || buf_rx->data[0] == 0x80)) { + ((buf_rx->data[0] & 0xf8) == 0x0 || + (buf_rx->data[0] & 0xf8) == 0x80)) { /* Flip highest bit in lowest byte of le32 */ buf_rx->data[0] ^= 0x80; From e3d4ee7d5f7f5256dfe89219afcc7a2d553b731f Mon Sep 17 00:00:00 2001 From: Thomas Kopp Date: Tue, 21 Dec 2021 22:24:52 +0000 Subject: [PATCH 212/246] can: mcp251xfd: mcp251xfd_regmap_crc_read(): update workaround broken CRC on TBC register The mcp251xfd compatible chips have an erratum ([1], [2]), where the received CRC doesn't match the calculated CRC. In commit c7eb923c3caf ("can: mcp251xfd: mcp251xfd_regmap_crc_read(): work around broken CRC on TBC register") the following workaround was implementierend. - If a CRC read error on the TBC register is detected and the first byte is 0x00 or 0x80, the most significant bit of the first byte is flipped and the CRC is calculated again. - If the CRC now matches, the _original_ data is passed to the reader. For now we assume transferred data was OK. New investigations and simulations indicate that the CRC send by the device is calculated on correct data, and the data is incorrectly received by the SPI host controller. Use flipped instead of original data and update workaround description in mcp251xfd_regmap_crc_read(). [1] mcp2517fd: DS80000792C: "Incorrect CRC for certain READ_CRC commands" [2] mcp2518fd: DS80000789C: "Incorrect CRC for certain READ_CRC commands" Link: https://lore.kernel.org/all/DM4PR11MB53901D49578FE265B239E55AFB7C9@DM4PR11MB5390.namprd11.prod.outlook.com Fixes: c7eb923c3caf ("can: mcp251xfd: mcp251xfd_regmap_crc_read(): work around broken CRC on TBC register") Cc: stable@vger.kernel.org Signed-off-by: Thomas Kopp [mkl: split into 2 patches, update patch description and documentation] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c index 211edd9ef0c9..92b7bc7f14b9 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-regmap.c @@ -343,9 +343,8 @@ mcp251xfd_regmap_crc_read(void *context, * * If the highest bit in the lowest byte is flipped * the transferred CRC matches the calculated one. We - * assume for now the CRC calculation in the chip - * works on wrong data and the transferred data is - * correct. + * assume for now the CRC operates on the correct + * data. */ if (reg == MCP251XFD_REG_TBC && ((buf_rx->data[0] & 0xf8) == 0x0 || @@ -359,10 +358,8 @@ mcp251xfd_regmap_crc_read(void *context, val_len); if (!err) { /* If CRC is now correct, assume - * transferred data was OK, flip bit - * back to original value. + * flipped data is OK. */ - buf_rx->data[0] ^= 0x80; goto out; } } From d5a972f561a003e302e4267340c57e8fbd096fa4 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 6 Jun 2022 14:46:18 +0200 Subject: [PATCH 213/246] can: mcp251xfd: mcp251xfd_stop(): add missing hrtimer_cancel() In commit 169d00a25658 ("can: mcp251xfd: add TX IRQ coalescing support") software based TX coalescing was added to the driver. The key idea is to keep the TX complete IRQ disabled for some time after processing it and re-enable later by a hrtimer. When bringing the interface down, this timer has to be stopped. Add the missing hrtimer_cancel() of the tx_irq_time hrtimer to mcp251xfd_stop(). Link: https://lore.kernel.org/all/20220620143942.891811-1-mkl@pengutronix.de Fixes: 169d00a25658 ("can: mcp251xfd: add TX IRQ coalescing support") Cc: stable@vger.kernel.org # v5.18 Reviewed-by: Manivannan Sadhasivam Signed-off-by: Marc Kleine-Budde --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index b21252390216..34b160024ce3 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1650,6 +1650,7 @@ static int mcp251xfd_stop(struct net_device *ndev) netif_stop_queue(ndev); set_bit(MCP251XFD_FLAGS_DOWN, priv->flags); hrtimer_cancel(&priv->rx_irq_timer); + hrtimer_cancel(&priv->tx_irq_timer); mcp251xfd_chip_interrupts_disable(priv); free_irq(ndev->irq, priv); can_rx_offload_disable(&priv->offload); From 0ff32bfa0e794ccc3601de7158b522bf736fa63c Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Thu, 16 Jun 2022 11:38:00 +0200 Subject: [PATCH 214/246] can: mcp251xfd: mcp251xfd_register_get_dev_id(): use correct length to read dev_id The device ID register is 32 bits wide. The driver uses incorrectly the size of a pointer to a u32 to calculate the length of the SPI transfer. This results in a read of 2 registers on 64 bit platforms. This is no problem on the Linux side, as the RX buffer of the SPI transfer is large enough. In the mpc251xfd chip this results in the read of an undocumented register. So far no problems were observed. Fix the length of the SPI transfer to read the device ID register only. Link: https://lore.kernel.org/all/20220616094914.244440-1-mkl@pengutronix.de Fixes: 55e5b97f003e ("can: mcp25xxfd: add driver for Microchip MCP25xxFD SPI CAN") Reported-by: Rasmus Villemoes Reviewed-by: Manivannan Sadhasivam Signed-off-by: Marc Kleine-Budde --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 34b160024ce3..3160881e89d9 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1778,7 +1778,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id, xfer[0].len = sizeof(buf_tx->cmd); xfer[0].speed_hz = priv->spi_max_speed_hz_slow; xfer[1].rx_buf = buf_rx->data; - xfer[1].len = sizeof(dev_id); + xfer[1].len = sizeof(*dev_id); xfer[1].speed_hz = priv->spi_max_speed_hz_fast; mcp251xfd_spi_cmd_read_nocrc(&buf_tx->cmd, MCP251XFD_REG_DEVID); From 1c0e78a287e3493e22bde8553d02f3b89177eaf7 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 20 Jun 2022 11:49:24 +0200 Subject: [PATCH 215/246] can: mcp251xfd: mcp251xfd_register_get_dev_id(): fix endianness conversion In mcp251xfd_register_get_dev_id() the device ID register is read with handcrafted SPI transfers. As all registers, this register is in little endian. Further it is not naturally aligned in struct mcp251xfd_map_buf_nocrc::data. However after the transfer the register content is converted from big endian to CPU endianness not taking care of being unaligned. Fix the conversion by converting from little endian to CPU endianness taking the unaligned source into account. Side note: So far the register content is 0x0 on all mcp251xfd compatible chips, and is only used for an informative printk. Link: https://lore.kernel.org/all/20220627092859.809042-1-mkl@pengutronix.de Fixes: 55e5b97f003e ("can: mcp25xxfd: add driver for Microchip MCP25xxFD SPI CAN") Reviewed-by: Rasmus Villemoes Reviewed-by: Manivannan Sadhasivam Signed-off-by: Marc Kleine-Budde --- drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 3160881e89d9..9b47b07162fe 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -12,6 +12,7 @@ // Copyright (c) 2019 Martin Sperl // +#include #include #include #include @@ -1787,7 +1788,7 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id, if (err) goto out_kfree_buf_tx; - *dev_id = be32_to_cpup((__be32 *)buf_rx->data); + *dev_id = get_unaligned_le32(buf_rx->data); *effective_speed_hz_slow = xfer[0].effective_speed_hz; *effective_speed_hz_fast = xfer[1].effective_speed_hz; From 6e2c9105e0b743c92a157389d40f00b81bdd09fe Mon Sep 17 00:00:00 2001 From: John Veness Date: Fri, 24 Jun 2022 15:07:57 +0100 Subject: [PATCH 216/246] ALSA: usb-audio: Add quirks for MacroSilicon MS2100/MS2106 devices Treat the claimed 96kHz 1ch in the descriptors as 48kHz 2ch, so that the audio stream doesn't sound mono. Also fix initial stream alignment, so that left and right channels are in the correct order. Signed-off-by: John Veness Link: https://lore.kernel.org/r/20220624140757.28758-1-john-linux@pelago.org.uk Signed-off-by: Takashi Iwai --- sound/usb/quirks-table.h | 48 ++++++++++++++++++++++++++++++++++++++++ sound/usb/quirks.c | 3 +++ 2 files changed, 51 insertions(+) diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 4f56e1784932..853da162fd18 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -3802,6 +3802,54 @@ YAMAHA_DEVICE(0x7010, "UB99"), } }, +/* + * MacroSilicon MS2100/MS2106 based AV capture cards + * + * These claim 96kHz 1ch in the descriptors, but are actually 48kHz 2ch. + * They also need QUIRK_FLAG_ALIGN_TRANSFER, which makes one wonder if + * they pretend to be 96kHz mono as a workaround for stereo being broken + * by that... + * + * They also have an issue with initial stream alignment that causes the + * channels to be swapped and out of phase, which is dealt with in quirks.c. + */ +{ + USB_AUDIO_DEVICE(0x534d, 0x0021), + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .vendor_name = "MacroSilicon", + .product_name = "MS210x", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = &(const struct snd_usb_audio_quirk[]) { + { + .ifnum = 2, + .type = QUIRK_AUDIO_STANDARD_MIXER, + }, + { + .ifnum = 3, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .channels = 2, + .iface = 3, + .altsetting = 1, + .altset_idx = 1, + .attributes = 0, + .endpoint = 0x82, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 48000, + .rate_max = 48000, + } + }, + { + .ifnum = -1 + } + } + } +}, + /* * MacroSilicon MS2109 based HDMI capture cards * diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 12ce69b04f63..a7bcae0a2c75 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1478,6 +1478,7 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs, case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */ set_format_emu_quirk(subs, fmt); break; + case USB_ID(0x534d, 0x0021): /* MacroSilicon MS2100/MS2106 */ case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */ subs->stream_offset_adj = 2; break; @@ -1908,6 +1909,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_IGNORE_CTL_ERROR), DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x534d, 0x0021, /* MacroSilicon MS2100/MS2106 */ + QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */ QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */ From 11bea26929a1a3a9dd1a287b60c2f471701bf706 Mon Sep 17 00:00:00 2001 From: Tim Crawford Date: Fri, 24 Jun 2022 08:41:09 -0600 Subject: [PATCH 217/246] ALSA: hda/realtek: Add quirk for Clevo L140PU Fixes headset detection on Clevo L140PU. Signed-off-by: Tim Crawford Cc: Link: https://lore.kernel.org/r/20220624144109.3957-1-tcrawford@system76.com Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cee69fa7e246..007dd8b5e1f2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9212,6 +9212,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1558, 0x70f4, "Clevo NH77EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x70f6, "Clevo NH77DPQ-Y", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x7716, "Clevo NS50PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), + SND_PCI_QUIRK(0x1558, 0x7718, "Clevo L140PU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x8228, "Clevo NR40BU", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x8520, "Clevo NH50D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1558, 0x8521, "Clevo NH77D[CD]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE), From 4fb7c24f69c48fdc02ea7858dbd5a60ff08bf7e5 Mon Sep 17 00:00:00 2001 From: Egor Vorontsov Date: Mon, 27 Jun 2022 13:00:34 +0300 Subject: [PATCH 218/246] ALSA: usb-audio: Add quirk for Fiero SC-01 Fiero SC-01 is a USB sound card with two mono inputs and a single stereo output. The inputs are composed into a single stereo stream. The device uses a vendor-provided driver on Windows and does not work at all without it. The driver mostly provides ASIO functionality, but also alters the way the sound card is queried for sample rates and clocks. ALSA queries those failing with an EPIPE (same as Windows 10 does). Presumably, the vendor-provided driver does not query it at all, simply matching by VID:PID. Thus, I consider this a buggy firmware and adhere to a set of fixed endpoint quirks instead. The soundcard has an internal clock. Implicit feedback mode is required for the playback. I have updated my device to v1.1.0 from a Windows 10 VM using a vendor- provided binary prior to the development, hoping for it to just begin working. The device provides no obvious way to downgrade the firmware, and regardless, there's no binary available for v1.0.0 anyway. Thus, I will be getting another unit to extend the patch with support for that. Expected to be a simple copy-paste of the existing one, though. There were no previous reports of that device in context of Linux anywhere. Other issues have been reported though, but that's out of the scope. Signed-off-by: Egor Vorontsov Link: https://lore.kernel.org/r/20220627100041.2861494-1-sdoregor@sdore.me Signed-off-by: Takashi Iwai --- sound/usb/quirks-table.h | 68 ++++++++++++++++++++++++++++++++++++++++ sound/usb/quirks.c | 2 ++ 2 files changed, 70 insertions(+) diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 853da162fd18..7067d314fecd 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -4167,6 +4167,74 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, +{ + /* + * Fiero SC-01 (firmware v1.1.0) + */ + USB_DEVICE(0x2b53, 0x0031), + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .vendor_name = "Fiero", + .product_name = "SC-01", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = &(const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + /* Playback */ + { + .ifnum = 1, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 2, + .fmt_bits = 24, + .iface = 1, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x01, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000, + .rate_min = 48000, + .rate_max = 96000, + .nr_rates = 2, + .rate_table = (unsigned int[]) { 48000, 96000 }, + .clock = 0x29 + } + }, + /* Capture */ + { + .ifnum = 2, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 2, + .fmt_bits = 24, + .iface = 2, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x82, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC | + USB_ENDPOINT_USAGE_IMPLICIT_FB, + .rates = SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000, + .rate_min = 48000, + .rate_max = 96000, + .nr_rates = 2, + .rate_table = (unsigned int[]) { 48000, 96000 }, + .clock = 0x29 + } + }, + { + .ifnum = -1 + } + } + } +}, #undef USB_DEVICE_VENDOR_SPEC #undef USB_AUDIO_DEVICE diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index a7bcae0a2c75..51138350f03c 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1915,6 +1915,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */ + QUIRK_FLAG_GENERIC_IMPLICIT_FB), /* Vendor matches */ VENDOR_FLG(0x045e, /* MS Lifecam */ From 2307a0e1ca0b5c1337b37ac6302f96e017ebac3c Mon Sep 17 00:00:00 2001 From: Egor Vorontsov Date: Mon, 27 Jun 2022 13:00:35 +0300 Subject: [PATCH 219/246] ALSA: usb-audio: Add quirk for Fiero SC-01 (fw v1.0.0) The patch applies the same quirks used for SC-01 at firmware v1.1.0 to the ones running v1.0.0, with respect to hard-coded sample rates. I got two more units and successfully tested the patch series with both firmwares. The support is now complete (not accounting ASIO). Signed-off-by: Egor Vorontsov Link: https://lore.kernel.org/r/20220627100041.2861494-2-sdoregor@sdore.me Signed-off-by: Takashi Iwai --- sound/usb/quirks-table.h | 132 +++++++++++++++++++++++++++++++++++++++ sound/usb/quirks.c | 4 ++ 2 files changed, 136 insertions(+) diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 7067d314fecd..f93201a830b5 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h @@ -4167,6 +4167,138 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, +{ + /* + * Fiero SC-01 (firmware v1.0.0 @ 48 kHz) + */ + USB_DEVICE(0x2b53, 0x0023), + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .vendor_name = "Fiero", + .product_name = "SC-01", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = &(const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + /* Playback */ + { + .ifnum = 1, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 2, + .fmt_bits = 24, + .iface = 1, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x01, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + .nr_rates = 1, + .rate_table = (unsigned int[]) { 48000 }, + .clock = 0x29 + } + }, + /* Capture */ + { + .ifnum = 2, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 2, + .fmt_bits = 24, + .iface = 2, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x82, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC | + USB_ENDPOINT_USAGE_IMPLICIT_FB, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + .nr_rates = 1, + .rate_table = (unsigned int[]) { 48000 }, + .clock = 0x29 + } + }, + { + .ifnum = -1 + } + } + } +}, +{ + /* + * Fiero SC-01 (firmware v1.0.0 @ 96 kHz) + */ + USB_DEVICE(0x2b53, 0x0024), + .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { + .vendor_name = "Fiero", + .product_name = "SC-01", + .ifnum = QUIRK_ANY_INTERFACE, + .type = QUIRK_COMPOSITE, + .data = &(const struct snd_usb_audio_quirk[]) { + { + .ifnum = 0, + .type = QUIRK_AUDIO_STANDARD_INTERFACE + }, + /* Playback */ + { + .ifnum = 1, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 2, + .fmt_bits = 24, + .iface = 1, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x01, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC, + .rates = SNDRV_PCM_RATE_96000, + .rate_min = 96000, + .rate_max = 96000, + .nr_rates = 1, + .rate_table = (unsigned int[]) { 96000 }, + .clock = 0x29 + } + }, + /* Capture */ + { + .ifnum = 2, + .type = QUIRK_AUDIO_FIXED_ENDPOINT, + .data = &(const struct audioformat) { + .formats = SNDRV_PCM_FMTBIT_S32_LE, + .channels = 2, + .fmt_bits = 24, + .iface = 2, + .altsetting = 1, + .altset_idx = 1, + .endpoint = 0x82, + .ep_attr = USB_ENDPOINT_XFER_ISOC | + USB_ENDPOINT_SYNC_ASYNC | + USB_ENDPOINT_USAGE_IMPLICIT_FB, + .rates = SNDRV_PCM_RATE_96000, + .rate_min = 96000, + .rate_max = 96000, + .nr_rates = 1, + .rate_table = (unsigned int[]) { 96000 }, + .clock = 0x29 + } + }, + { + .ifnum = -1 + } + } + } +}, { /* * Fiero SC-01 (firmware v1.1.0) diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 51138350f03c..968d90caeefa 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1915,6 +1915,10 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */ QUIRK_FLAG_GET_SAMPLE_RATE), + DEVICE_FLG(0x2b53, 0x0023, /* Fiero SC-01 (firmware v1.0.0 @ 48 kHz) */ + QUIRK_FLAG_GENERIC_IMPLICIT_FB), + DEVICE_FLG(0x2b53, 0x0024, /* Fiero SC-01 (firmware v1.0.0 @ 96 kHz) */ + QUIRK_FLAG_GENERIC_IMPLICIT_FB), DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */ QUIRK_FLAG_GENERIC_IMPLICIT_FB), From 0ec29ccf94eb4c32570555a882575eca9eec6467 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 21 Mar 2022 10:49:12 -0700 Subject: [PATCH 220/246] soc: qcom: smem: use correct format characters When compiling with -Wformat, clang emits the following warnings: drivers/soc/qcom/smem.c:847:41: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] dev_err(smem->dev, "bad host %hu\n", remote_host); ~~~ ^~~~~~~~~~~ %u ./include/linux/dev_printk.h:144:65: note: expanded from macro 'dev_err' dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) ~~~ ^~~~~~~~~~~ ./include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap' _p_func(dev, fmt, ##__VA_ARGS__); \ ~~~ ^~~~~~~~~~~ drivers/soc/qcom/smem.c:852:47: warning: format specifies type 'unsigned short' but the argument has type 'unsigned int' [-Wformat] dev_err(smem->dev, "duplicate host %hu\n", remote_host); ~~~ ^~~~~~~~~~~ %u ./include/linux/dev_printk.h:144:65: note: expanded from macro 'dev_err' dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) ~~~ ^~~~~~~~~~~ ./include/linux/dev_printk.h:110:23: note: expanded from macro 'dev_printk_index_wrap' _p_func(dev, fmt, ##__VA_ARGS__); \ ~~~ ^~~~~~~~~~~ The types of these arguments are unconditionally defined, so this patch updates the format character to the correct one and change type of remote_host to "u16" to match with other types. Signed-off-by: Bill Wendling Tested-by: Justin Stitt Reviewed-by: Justin Stitt Link: https://github.com/ClangBuiltLinux/linux/issues/378 Signed-off-by: Arnd Bergmann --- drivers/soc/qcom/smem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 3e95835653ea..4f163d62942c 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -926,7 +926,7 @@ qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host) struct smem_partition_header *header; struct smem_ptable_entry *entry; struct smem_ptable *ptable; - unsigned int remote_host; + u16 remote_host; u16 host0, host1; int i; @@ -951,12 +951,12 @@ qcom_smem_enumerate_partitions(struct qcom_smem *smem, u16 local_host) continue; if (remote_host >= SMEM_HOST_COUNT) { - dev_err(smem->dev, "bad host %hu\n", remote_host); + dev_err(smem->dev, "bad host %u\n", remote_host); return -EINVAL; } if (smem->partitions[remote_host].virt_base) { - dev_err(smem->dev, "duplicate host %hu\n", remote_host); + dev_err(smem->dev, "duplicate host %u\n", remote_host); return -EINVAL; } From b8e629b05f5d23f9649c901bef09fab8b0c2e4b9 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Sun, 3 Jul 2022 10:36:24 +0300 Subject: [PATCH 221/246] selftests: forwarding: fix flood_unicast_test when h2 supports IFF_UNICAST_FLT As mentioned in the blamed commit, flood_unicast_test() works by checking the match count on a tc filter placed on the receiving interface. But the second host interface (host2_if) has no interest in receiving a packet with MAC DA de:ad:be:ef:13:37, so its RX filter drops it even before the ingress tc filter gets to be executed. So we will incorrectly get the message "Packet was not flooded when should", when in fact, the packet was flooded as expected but dropped due to an unrelated reason, at some other layer on the receiving side. Force h2 to accept this packet by temporarily placing it in promiscuous mode. Alternatively we could either deliver to its MAC address or use tcpdump_start, but this has the fewest complications. This fixes the "flooding" test from bridge_vlan_aware.sh and bridge_vlan_unaware.sh, which calls flood_test from the lib. Fixes: 236dd50bf67a ("selftests: forwarding: Add a test for flooded traffic") Signed-off-by: Vladimir Oltean Reviewed-by: Ido Schimmel Tested-by: Ido Schimmel Signed-off-by: Paolo Abeni --- tools/testing/selftests/net/forwarding/lib.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh index 37ae49d47853..4e69497f021f 100755 --- a/tools/testing/selftests/net/forwarding/lib.sh +++ b/tools/testing/selftests/net/forwarding/lib.sh @@ -1306,6 +1306,7 @@ flood_test_do() # Add an ACL on `host2_if` which will tell us whether the packet # was flooded to it or not. + ip link set $host2_if promisc on tc qdisc add dev $host2_if ingress tc filter add dev $host2_if ingress protocol ip pref 1 handle 101 \ flower dst_mac $mac action drop @@ -1323,6 +1324,7 @@ flood_test_do() tc filter del dev $host2_if ingress protocol ip pref 1 handle 101 flower tc qdisc del dev $host2_if ingress + ip link set $host2_if promisc off return $err } From 1a635d3e1c80626237fdae47a5545b6655d8d81c Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Sun, 3 Jul 2022 10:36:25 +0300 Subject: [PATCH 222/246] selftests: forwarding: fix learning_test when h1 supports IFF_UNICAST_FLT The first host interface has by default no interest in receiving packets MAC DA de:ad:be:ef:13:37, so it might drop them before they hit the tc filter and this might confuse the selftest. Enable promiscuous mode such that the filter properly counts received packets. Fixes: d4deb01467ec ("selftests: forwarding: Add a test for FDB learning") Signed-off-by: Vladimir Oltean Reviewed-by: Ido Schimmel Tested-by: Ido Schimmel Signed-off-by: Paolo Abeni --- tools/testing/selftests/net/forwarding/lib.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh index 4e69497f021f..26ba8b5d264a 100755 --- a/tools/testing/selftests/net/forwarding/lib.sh +++ b/tools/testing/selftests/net/forwarding/lib.sh @@ -1240,6 +1240,7 @@ learning_test() # FDB entry was installed. bridge link set dev $br_port1 flood off + ip link set $host1_if promisc on tc qdisc add dev $host1_if ingress tc filter add dev $host1_if ingress protocol ip pref 1 handle 101 \ flower dst_mac $mac action drop @@ -1289,6 +1290,7 @@ learning_test() tc filter del dev $host1_if ingress protocol ip pref 1 handle 101 flower tc qdisc del dev $host1_if ingress + ip link set $host1_if promisc off bridge link set dev $br_port1 flood on From 83844aacab2015da1dba1df0cc61fc4b4c4e8076 Mon Sep 17 00:00:00 2001 From: Vladimir Oltean Date: Sun, 3 Jul 2022 10:36:26 +0300 Subject: [PATCH 223/246] selftests: forwarding: fix error message in learning_test When packets are not received, they aren't received on $host1_if, so the message talking about the second host not receiving them is incorrect. Fix it. Fixes: d4deb01467ec ("selftests: forwarding: Add a test for FDB learning") Signed-off-by: Vladimir Oltean Reviewed-by: Ido Schimmel Signed-off-by: Paolo Abeni --- tools/testing/selftests/net/forwarding/lib.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/forwarding/lib.sh b/tools/testing/selftests/net/forwarding/lib.sh index 26ba8b5d264a..3ffb9d6c0950 100755 --- a/tools/testing/selftests/net/forwarding/lib.sh +++ b/tools/testing/selftests/net/forwarding/lib.sh @@ -1251,7 +1251,7 @@ learning_test() tc -j -s filter show dev $host1_if ingress \ | jq -e ".[] | select(.options.handle == 101) \ | select(.options.actions[0].stats.packets == 1)" &> /dev/null - check_fail $? "Packet reached second host when should not" + check_fail $? "Packet reached first host when should not" $MZ $host1_if -c 1 -p 64 -a $mac -t ip -q sleep 1 From c5e58c4545a69677d078b4c813b5d10d3481be9c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 5 Jul 2022 17:23:36 +0200 Subject: [PATCH 224/246] ALSA: cs46xx: Fix missing snd_card_free() call at probe error The previous cleanup with devres may lead to the incorrect release orders at the probe error handling due to the devres's nature. Until we register the card, snd_card_free() has to be called at first for releasing the stuff properly when the driver tries to manage and release the stuff via card->private_free(). This patch fixes it by calling snd_card_free() manually on the error from the probe callback. Fixes: 5bff69b3645d ("ALSA: cs46xx: Allocate resources with device-managed APIs") Cc: Reported-and-tested-by: Jan Engelhardt Link: https://lore.kernel.org/r/p2p1s96o-746-74p4-s95-61qo1p7782pn@vanv.qr Link: https://lore.kernel.org/r/20220705152336.350-1-tiwai@suse.de Signed-off-by: Takashi Iwai --- sound/pci/cs46xx/cs46xx.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index bd60308769ff..8634004a606b 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c @@ -74,36 +74,36 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci, err = snd_cs46xx_create(card, pci, external_amp[dev], thinkpad[dev]); if (err < 0) - return err; + goto error; card->private_data = chip; chip->accept_valid = mmap_valid[dev]; err = snd_cs46xx_pcm(chip, 0); if (err < 0) - return err; + goto error; #ifdef CONFIG_SND_CS46XX_NEW_DSP err = snd_cs46xx_pcm_rear(chip, 1); if (err < 0) - return err; + goto error; err = snd_cs46xx_pcm_iec958(chip, 2); if (err < 0) - return err; + goto error; #endif err = snd_cs46xx_mixer(chip, 2); if (err < 0) - return err; + goto error; #ifdef CONFIG_SND_CS46XX_NEW_DSP if (chip->nr_ac97_codecs ==2) { err = snd_cs46xx_pcm_center_lfe(chip, 3); if (err < 0) - return err; + goto error; } #endif err = snd_cs46xx_midi(chip, 0); if (err < 0) - return err; + goto error; err = snd_cs46xx_start_dsp(chip); if (err < 0) - return err; + goto error; snd_cs46xx_gameport(chip); @@ -117,11 +117,15 @@ static int snd_card_cs46xx_probe(struct pci_dev *pci, err = snd_card_register(card); if (err < 0) - return err; + goto error; pci_set_drvdata(pci, card); dev++; return 0; + + error: + snd_card_free(card); + return err; } static struct pci_driver cs46xx_driver = { From e36bea6e78ab2b6c9c7396972fee231eae551cfc Mon Sep 17 00:00:00 2001 From: Vasyl Vavrychuk Date: Tue, 5 Jul 2022 15:59:31 +0300 Subject: [PATCH 225/246] Bluetooth: core: Fix deadlock on hci_power_on_sync. `cancel_work_sync(&hdev->power_on)` was moved to hci_dev_close_sync in commit [1] to ensure that power_on work is canceled after HCI interface down. But, in certain cases power_on work function may call hci_dev_close_sync itself: hci_power_on -> hci_dev_do_close -> hci_dev_close_sync -> cancel_work_sync(&hdev->power_on), causing deadlock. In particular, this happens when device is rfkilled on boot. To avoid deadlock, move power_on work canceling out of hci_dev_do_close/hci_dev_close_sync. Deadlock introduced by commit [1] was reported in [2,3] as broken suspend. Suspend did not work because `hdev->req_lock` held as result of `power_on` work deadlock. In fact, other BT features were not working. It was not observed when testing [1] since it was verified without rfkill in place. NOTE: It is not needed to cancel power_on work from other places where hci_dev_do_close/hci_dev_close_sync is called in case: * Requests were serialized due to `hdev->req_workqueue`. The power_on work is first in that workqueue. * hci_rfkill_set_block which won't close device anyway until HCI_SETUP is on. * hci_sock_release which runs after hci_sock_bind which ensures HCI_SETUP was cleared. As result, behaviour is the same as in pre-dd06ed7 commit, except power_on work cancel added to hci_dev_close. [1]: commit ff7f2926114d ("Bluetooth: core: Fix missing power_on work cancel on HCI close") [2]: https://lore.kernel.org/lkml/20220614181706.26513-1-max.oss.09@gmail.com/ [2]: https://lore.kernel.org/lkml/1236061d-95dd-c3ad-a38f-2dae7aae51ef@o2.pl/ Fixes: ff7f2926114d ("Bluetooth: core: Fix missing power_on work cancel on HCI close") Signed-off-by: Vasyl Vavrychuk Reported-by: Max Krummenacher Reported-by: Mateusz Jonczyk Tested-by: Max Krummenacher Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_core.c | 3 +++ net/bluetooth/hci_sync.c | 1 - 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 59a5c1341c26..a0f99baafd35 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -571,6 +571,7 @@ int hci_dev_close(__u16 dev) goto done; } + cancel_work_sync(&hdev->power_on); if (hci_dev_test_and_clear_flag(hdev, HCI_AUTO_OFF)) cancel_delayed_work(&hdev->power_off); @@ -2675,6 +2676,8 @@ void hci_unregister_dev(struct hci_dev *hdev) list_del(&hdev->list); write_unlock(&hci_dev_list_lock); + cancel_work_sync(&hdev->power_on); + hci_cmd_sync_clear(hdev); if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index 286d6767f017..1739e8cb3291 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -4088,7 +4088,6 @@ int hci_dev_close_sync(struct hci_dev *hdev) bt_dev_dbg(hdev, ""); - cancel_work_sync(&hdev->power_on); cancel_delayed_work(&hdev->power_off); cancel_delayed_work(&hdev->ncmd_timer); From e6fa930f73a15238f3cb0c204e2f786c919b815c Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Mon, 4 Jul 2022 17:36:54 +0200 Subject: [PATCH 226/246] net: lan966x: hardcode the number of external ports Instead of counting the child nodes in the device tree, hardcode the number of ports in the driver itself. The counting won't work at all if an ethernet port is marked as disabled, e.g. because it is not connected on the board at all. It turns out that the LAN9662 and LAN9668 use the same switching IP with the same synthesis parameters. The only difference is that the output ports are not connected. Thus, we can just hardcode the number of physical ports to 8. Fixes: db8bcaad5393 ("net: lan966x: add the basic lan966x driver") Signed-off-by: Michael Walle Reviewed-by: Horatiu Vultur Link: https://lore.kernel.org/r/20220704153654.1167886-1-michael@walle.cc Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/microchip/lan966x/lan966x_main.c | 8 ++------ drivers/net/ethernet/microchip/lan966x/lan966x_main.h | 1 + 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c index 5784c4161e5e..1d6e3b641b2e 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -994,7 +994,7 @@ static int lan966x_probe(struct platform_device *pdev) struct fwnode_handle *ports, *portnp; struct lan966x *lan966x; u8 mac_addr[ETH_ALEN]; - int err, i; + int err; lan966x = devm_kzalloc(&pdev->dev, sizeof(*lan966x), GFP_KERNEL); if (!lan966x) @@ -1025,11 +1025,7 @@ static int lan966x_probe(struct platform_device *pdev) if (err) return dev_err_probe(&pdev->dev, err, "Reset failed"); - i = 0; - fwnode_for_each_available_child_node(ports, portnp) - ++i; - - lan966x->num_phys_ports = i; + lan966x->num_phys_ports = NUM_PHYS_PORTS; lan966x->ports = devm_kcalloc(&pdev->dev, lan966x->num_phys_ports, sizeof(struct lan966x_port *), GFP_KERNEL); diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h index 3b86ddddc756..2787055c1847 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.h +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.h @@ -34,6 +34,7 @@ /* Reserved amount for (SRC, PRIO) at index 8*SRC + PRIO */ #define QSYS_Q_RSRV 95 +#define NUM_PHYS_PORTS 8 #define CPU_PORT 8 /* Reserved PGIDs */ From 052f744f44462cc49b88a125b0f7b93a9e47a9dd Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Mon, 4 Jul 2022 22:44:04 +0200 Subject: [PATCH 227/246] net/sched: act_police: allow 'continue' action offload Offloading police with action TC_ACT_UNSPEC was erroneously disabled even though it was supported by mlx5 matchall offload implementation, which didn't verify the action type but instead assumed that any single police action attached to matchall classifier is a 'continue' action. Lack of action type check made it non-obvious what mlx5 matchall implementation actually supports and caused implementers and reviewers of referenced commits to disallow it as a part of improved validation code. Fixes: b8cd5831c61c ("net: flow_offload: add tc police action parameters") Fixes: b50e462bc22d ("net/sched: act_police: Add extack messages for offload failure") Signed-off-by: Vlad Buslov Reviewed-by: Ido Schimmel Tested-by: Ido Schimmel Signed-off-by: David S. Miller --- include/net/flow_offload.h | 1 + net/sched/act_police.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h index 6484095a8c01..7ac313858037 100644 --- a/include/net/flow_offload.h +++ b/include/net/flow_offload.h @@ -152,6 +152,7 @@ enum flow_action_id { FLOW_ACTION_PIPE, FLOW_ACTION_VLAN_PUSH_ETH, FLOW_ACTION_VLAN_POP_ETH, + FLOW_ACTION_CONTINUE, NUM_FLOW_ACTIONS, }; diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 79c8901f66ab..b759628a47c2 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -442,7 +442,7 @@ static int tcf_police_act_to_flow_act(int tc_act, u32 *extval, act_id = FLOW_ACTION_JUMP; *extval = tc_act & TC_ACT_EXT_VAL_MASK; } else if (tc_act == TC_ACT_UNSPEC) { - NL_SET_ERR_MSG_MOD(extack, "Offload not supported when conform/exceed action is \"continue\""); + act_id = FLOW_ACTION_CONTINUE; } else { NL_SET_ERR_MSG_MOD(extack, "Unsupported conform/exceed action offload"); } From 4d1e07d83ccc87f210e5b852b0a5ea812a2f191c Mon Sep 17 00:00:00 2001 From: Vlad Buslov Date: Mon, 4 Jul 2022 22:44:05 +0200 Subject: [PATCH 228/246] net/mlx5e: Fix matchall police parameters validation Referenced commit prepared the code for upcoming extension that allows mlx5 to offload police action attached to flower classifier. However, with regard to existing matchall classifier offload validation should be reversed as FLOW_ACTION_CONTINUE is the only supported notexceed police action type. Fix the problem by allowing FLOW_ACTION_CONTINUE for police action and extend scan_tc_matchall_fdb_actions() to only allow such actions with matchall classifier. Fixes: d97b4b105ce7 ("flow_offload: reject offload for all drivers with invalid police parameters") Signed-off-by: Vlad Buslov Acked-by: Saeed Mahameed Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 34bf11cdf90f..3a39a50146dd 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -4529,13 +4529,6 @@ static int mlx5e_policer_validate(const struct flow_action *action, return -EOPNOTSUPP; } - if (act->police.notexceed.act_id != FLOW_ACTION_PIPE && - act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) { - NL_SET_ERR_MSG_MOD(extack, - "Offload not supported when conform action is not pipe or ok"); - return -EOPNOTSUPP; - } - if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT && !flow_action_is_last_entry(action, act)) { NL_SET_ERR_MSG_MOD(extack, @@ -4586,6 +4579,12 @@ static int scan_tc_matchall_fdb_actions(struct mlx5e_priv *priv, flow_action_for_each(i, act, flow_action) { switch (act->id) { case FLOW_ACTION_POLICE: + if (act->police.notexceed.act_id != FLOW_ACTION_CONTINUE) { + NL_SET_ERR_MSG_MOD(extack, + "Offload not supported when conform action is not continue"); + return -EOPNOTSUPP; + } + err = mlx5e_policer_validate(flow_action, act, extack); if (err) return err; From 5ccecaec5c1e85cabfda848c6f146da0d8d55bd6 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Tue, 5 Jul 2022 14:32:11 -0700 Subject: [PATCH 229/246] mptcp: fix locking in mptcp_nl_cmd_sf_destroy() The user-space PM subflow removal path uses a couple of helpers that must be called under the msk socket lock and the current code lacks such requirement. Change the existing lock scope so that the relevant code is under its protection. Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment") Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/287 Signed-off-by: Paolo Abeni Signed-off-by: Mat Martineau Signed-off-by: David S. Miller --- net/mptcp/pm_userspace.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index f56378e4f597..26212bebc5ed 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -306,15 +306,11 @@ static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk, const struct mptcp_addr_info *local, const struct mptcp_addr_info *remote) { - struct sock *sk = &msk->sk.icsk_inet.sk; struct mptcp_subflow_context *subflow; - struct sock *found = NULL; if (local->family != remote->family) return NULL; - lock_sock(sk); - mptcp_for_each_subflow(msk, subflow) { const struct inet_sock *issk; struct sock *ssk; @@ -347,16 +343,11 @@ static struct sock *mptcp_nl_find_ssk(struct mptcp_sock *msk, } if (issk->inet_sport == local->port && - issk->inet_dport == remote->port) { - found = ssk; - goto found; - } + issk->inet_dport == remote->port) + return ssk; } -found: - release_sock(sk); - - return found; + return NULL; } int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info) @@ -412,6 +403,7 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info) } sk = &msk->sk.icsk_inet.sk; + lock_sock(sk); ssk = mptcp_nl_find_ssk(msk, &addr_l, &addr_r); if (ssk) { struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk); @@ -422,8 +414,9 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info) } else { err = -ESRCH; } + release_sock(sk); - destroy_err: +destroy_err: sock_put((struct sock *)msk); return err; } From c21b50d5912b68c4414c60ef5b30416c103f9fd8 Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Tue, 5 Jul 2022 14:32:12 -0700 Subject: [PATCH 230/246] mptcp: Avoid acquiring PM lock for subflow priority changes The in-kernel path manager code for changing subflow flags acquired both the msk socket lock and the PM lock when possibly changing the "backup" and "fullmesh" flags. mptcp_pm_nl_mp_prio_send_ack() does not access anything protected by the PM lock, and it must release and reacquire the PM lock. By pushing the PM lock to where it is needed in mptcp_pm_nl_fullmesh(), the lock is only acquired when the fullmesh flag is changed and the backup flag code no longer has to release and reacquire the PM lock. The change in locking context requires the MIB update to be modified - move that to a better location instead. This change also makes it possible to call mptcp_pm_nl_mp_prio_send_ack() for the userspace PM commands without manipulating the in-kernel PM lock. Fixes: 0f9f696a502e ("mptcp: add set_flags command in PM netlink") Acked-by: Paolo Abeni Signed-off-by: Mat Martineau Signed-off-by: David S. Miller --- net/mptcp/options.c | 3 +++ net/mptcp/pm_netlink.c | 8 ++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/net/mptcp/options.c b/net/mptcp/options.c index aead331866a0..bd8f0f425be4 100644 --- a/net/mptcp/options.c +++ b/net/mptcp/options.c @@ -1584,6 +1584,9 @@ mp_rst: *ptr++ = mptcp_option(MPTCPOPT_MP_PRIO, TCPOLEN_MPTCP_PRIO, opts->backup, TCPOPT_NOP); + + MPTCP_INC_STATS(sock_net((const struct sock *)tp), + MPTCP_MIB_MPPRIOTX); } mp_capable_done: diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index e099f2a12504..5ff93b73f33d 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -727,7 +727,6 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - struct sock *sk = (struct sock *)msk; struct mptcp_addr_info local; local_address((struct sock_common *)ssk, &local); @@ -739,12 +738,9 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, subflow->backup = bkup; subflow->send_mp_prio = 1; subflow->request_bkup = bkup; - __MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_MPPRIOTX); - spin_unlock_bh(&msk->pm.lock); pr_debug("send ack for mp_prio"); mptcp_subflow_send_ack(ssk); - spin_lock_bh(&msk->pm.lock); return 0; } @@ -1816,8 +1812,10 @@ static void mptcp_pm_nl_fullmesh(struct mptcp_sock *msk, list.ids[list.nr++] = addr->id; + spin_lock_bh(&msk->pm.lock); mptcp_pm_nl_rm_subflow_received(msk, &list); mptcp_pm_create_subflow_or_signal_addr(msk); + spin_unlock_bh(&msk->pm.lock); } static int mptcp_nl_set_flags(struct net *net, @@ -1835,12 +1833,10 @@ static int mptcp_nl_set_flags(struct net *net, goto next; lock_sock(sk); - spin_lock_bh(&msk->pm.lock); if (changed & MPTCP_PM_ADDR_FLAG_BACKUP) ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, bkup); if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH) mptcp_pm_nl_fullmesh(msk, addr); - spin_unlock_bh(&msk->pm.lock); release_sock(sk); next: From a657430260e5437df16004c8c317821d946b5ead Mon Sep 17 00:00:00 2001 From: Mat Martineau Date: Tue, 5 Jul 2022 14:32:13 -0700 Subject: [PATCH 231/246] mptcp: Acquire the subflow socket lock before modifying MP_PRIO flags When setting up a subflow's flags for sending MP_PRIO MPTCP options, the subflow socket lock was not held while reading and modifying several struct members that are also read and modified in mptcp_write_options(). Acquire the subflow socket lock earlier and send the MP_PRIO ACK with that lock already acquired. Add a new variant of the mptcp_subflow_send_ack() helper to use with the subflow lock held. Fixes: 067065422fcd ("mptcp: add the outgoing MP_PRIO support") Acked-by: Paolo Abeni Signed-off-by: Mat Martineau Signed-off-by: David S. Miller --- net/mptcp/pm_netlink.c | 5 ++++- net/mptcp/protocol.c | 9 +++++++-- net/mptcp/protocol.h | 1 + 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index 5ff93b73f33d..ca86c88f89e0 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -728,11 +728,13 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); struct mptcp_addr_info local; + bool slow; local_address((struct sock_common *)ssk, &local); if (!mptcp_addresses_equal(&local, addr, addr->port)) continue; + slow = lock_sock_fast(ssk); if (subflow->backup != bkup) msk->last_snd = NULL; subflow->backup = bkup; @@ -740,7 +742,8 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, subflow->request_bkup = bkup; pr_debug("send ack for mp_prio"); - mptcp_subflow_send_ack(ssk); + __mptcp_subflow_send_ack(ssk); + unlock_sock_fast(ssk, slow); return 0; } diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index e475212f2618..cc21fafd9726 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -506,13 +506,18 @@ static inline bool tcp_can_send_ack(const struct sock *ssk) (TCPF_SYN_SENT | TCPF_SYN_RECV | TCPF_TIME_WAIT | TCPF_CLOSE | TCPF_LISTEN)); } +void __mptcp_subflow_send_ack(struct sock *ssk) +{ + if (tcp_can_send_ack(ssk)) + tcp_send_ack(ssk); +} + void mptcp_subflow_send_ack(struct sock *ssk) { bool slow; slow = lock_sock_fast(ssk); - if (tcp_can_send_ack(ssk)) - tcp_send_ack(ssk); + __mptcp_subflow_send_ack(ssk); unlock_sock_fast(ssk, slow); } diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index c14d70c036d0..033c995772dc 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -607,6 +607,7 @@ void __init mptcp_subflow_init(void); void mptcp_subflow_shutdown(struct sock *sk, struct sock *ssk, int how); void mptcp_close_ssk(struct sock *sk, struct sock *ssk, struct mptcp_subflow_context *subflow); +void __mptcp_subflow_send_ack(struct sock *ssk); void mptcp_subflow_send_ack(struct sock *ssk); void mptcp_subflow_reset(struct sock *ssk); void mptcp_subflow_queue_clean(struct sock *ssk); From 892f396c8e68faab7f76ff49cf39e9fbbeea4097 Mon Sep 17 00:00:00 2001 From: Kishen Maloor Date: Tue, 5 Jul 2022 14:32:14 -0700 Subject: [PATCH 232/246] mptcp: netlink: issue MP_PRIO signals from userspace PMs This change updates MPTCP_PM_CMD_SET_FLAGS to allow userspace PMs to issue MP_PRIO signals over a specific subflow selected by the connection token, local and remote address+port. Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/286 Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment") Acked-by: Paolo Abeni Signed-off-by: Kishen Maloor Signed-off-by: Mat Martineau Signed-off-by: David S. Miller --- net/mptcp/pm_netlink.c | 30 +++++++++++++++++++++++++----- net/mptcp/pm_userspace.c | 30 ++++++++++++++++++++++++++++++ net/mptcp/protocol.h | 8 +++++++- 3 files changed, 62 insertions(+), 6 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index ca86c88f89e0..2da251dd7c00 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -717,9 +717,10 @@ void mptcp_pm_nl_addr_send_ack(struct mptcp_sock *msk) } } -static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, - struct mptcp_addr_info *addr, - u8 bkup) +int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, + struct mptcp_addr_info *addr, + struct mptcp_addr_info *rem, + u8 bkup) { struct mptcp_subflow_context *subflow; @@ -727,13 +728,19 @@ static int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - struct mptcp_addr_info local; + struct mptcp_addr_info local, remote; bool slow; local_address((struct sock_common *)ssk, &local); if (!mptcp_addresses_equal(&local, addr, addr->port)) continue; + if (rem && rem->family != AF_UNSPEC) { + remote_address((struct sock_common *)ssk, &remote); + if (!mptcp_addresses_equal(&remote, rem, rem->port)) + continue; + } + slow = lock_sock_fast(ssk); if (subflow->backup != bkup) msk->last_snd = NULL; @@ -1837,7 +1844,7 @@ static int mptcp_nl_set_flags(struct net *net, lock_sock(sk); if (changed & MPTCP_PM_ADDR_FLAG_BACKUP) - ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, bkup); + ret = mptcp_pm_nl_mp_prio_send_ack(msk, addr, NULL, bkup); if (changed & MPTCP_PM_ADDR_FLAG_FULLMESH) mptcp_pm_nl_fullmesh(msk, addr); release_sock(sk); @@ -1853,6 +1860,9 @@ next: static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info) { struct mptcp_pm_addr_entry addr = { .addr = { .family = AF_UNSPEC }, }, *entry; + struct mptcp_pm_addr_entry remote = { .addr = { .family = AF_UNSPEC }, }; + struct nlattr *attr_rem = info->attrs[MPTCP_PM_ATTR_ADDR_REMOTE]; + struct nlattr *token = info->attrs[MPTCP_PM_ATTR_TOKEN]; struct nlattr *attr = info->attrs[MPTCP_PM_ATTR_ADDR]; struct pm_nl_pernet *pernet = genl_info_pm_nl(info); u8 changed, mask = MPTCP_PM_ADDR_FLAG_BACKUP | @@ -1865,6 +1875,12 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info) if (ret < 0) return ret; + if (attr_rem) { + ret = mptcp_pm_parse_entry(attr_rem, info, false, &remote); + if (ret < 0) + return ret; + } + if (addr.flags & MPTCP_PM_ADDR_FLAG_BACKUP) bkup = 1; if (addr.addr.family == AF_UNSPEC) { @@ -1873,6 +1889,10 @@ static int mptcp_nl_cmd_set_flags(struct sk_buff *skb, struct genl_info *info) return -EOPNOTSUPP; } + if (token) + return mptcp_userspace_pm_set_flags(sock_net(skb->sk), + token, &addr, &remote, bkup); + spin_lock_bh(&pernet->lock); entry = __lookup_addr(pernet, &addr.addr, lookup_by_id); if (!entry) { diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index 26212bebc5ed..51e2f066d54f 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -420,3 +420,33 @@ destroy_err: sock_put((struct sock *)msk); return err; } + +int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token, + struct mptcp_pm_addr_entry *loc, + struct mptcp_pm_addr_entry *rem, u8 bkup) +{ + struct mptcp_sock *msk; + int ret = -EINVAL; + u32 token_val; + + token_val = nla_get_u32(token); + + msk = mptcp_token_get_sock(net, token_val); + if (!msk) + return ret; + + if (!mptcp_pm_is_userspace(msk)) + goto set_flags_err; + + if (loc->addr.family == AF_UNSPEC || + rem->addr.family == AF_UNSPEC) + goto set_flags_err; + + lock_sock((struct sock *)msk); + ret = mptcp_pm_nl_mp_prio_send_ack(msk, &loc->addr, &rem->addr, bkup); + release_sock((struct sock *)msk); + +set_flags_err: + sock_put((struct sock *)msk); + return ret; +} diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h index 033c995772dc..480c5320b86e 100644 --- a/net/mptcp/protocol.h +++ b/net/mptcp/protocol.h @@ -772,6 +772,10 @@ void mptcp_pm_rm_addr_received(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_list); void mptcp_pm_mp_prio_received(struct sock *sk, u8 bkup); void mptcp_pm_mp_fail_received(struct sock *sk, u64 fail_seq); +int mptcp_pm_nl_mp_prio_send_ack(struct mptcp_sock *msk, + struct mptcp_addr_info *addr, + struct mptcp_addr_info *rem, + u8 bkup); bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk, const struct mptcp_pm_addr_entry *entry); void mptcp_pm_free_anno_list(struct mptcp_sock *msk); @@ -788,7 +792,9 @@ int mptcp_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, int mptcp_userspace_pm_get_flags_and_ifindex_by_id(struct mptcp_sock *msk, unsigned int id, u8 *flags, int *ifindex); - +int mptcp_userspace_pm_set_flags(struct net *net, struct nlattr *token, + struct mptcp_pm_addr_entry *loc, + struct mptcp_pm_addr_entry *rem, u8 bkup); int mptcp_pm_announce_addr(struct mptcp_sock *msk, const struct mptcp_addr_info *addr, bool echo); From ca188a25d43f85f9c6f1e0a303edad47c9d24989 Mon Sep 17 00:00:00 2001 From: Kishen Maloor Date: Tue, 5 Jul 2022 14:32:15 -0700 Subject: [PATCH 233/246] selftests: mptcp: userspace PM support for MP_PRIO signals This change updates the testing sample (pm_nl_ctl) to exercise the updated MPTCP_PM_CMD_SET_FLAGS command for userspace PMs to issue MP_PRIO signals over the selected subflow. E.g. ./pm_nl_ctl set 10.0.1.2 port 47234 flags backup token 823274047 rip 10.0.1.1 rport 50003 userspace_pm.sh has a new selftest that invokes this command. Fixes: 259a834fadda ("selftests: mptcp: functional tests for the userspace PM type") Acked-by: Paolo Abeni Signed-off-by: Kishen Maloor Signed-off-by: Mat Martineau Signed-off-by: David S. Miller --- tools/testing/selftests/net/mptcp/pm_nl_ctl.c | 73 ++++++++++++++++++- .../selftests/net/mptcp/userspace_pm.sh | 32 ++++++++ 2 files changed, 103 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c index 6a2f4b981e1d..cb79f0719e3b 100644 --- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c +++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c @@ -39,7 +39,7 @@ static void syntax(char *argv[]) fprintf(stderr, "\tdsf lip lport rip rport token \n"); fprintf(stderr, "\tdel []\n"); fprintf(stderr, "\tget \n"); - fprintf(stderr, "\tset [] [id ] flags [no]backup|[no]fullmesh [port ]\n"); + fprintf(stderr, "\tset [] [id ] flags [no]backup|[no]fullmesh [port ] [token ] [rip ] [rport ]\n"); fprintf(stderr, "\tflush\n"); fprintf(stderr, "\tdump\n"); fprintf(stderr, "\tlimits [ ]\n"); @@ -1279,7 +1279,10 @@ int set_flags(int fd, int pm_family, int argc, char *argv[]) struct rtattr *rta, *nest; struct nlmsghdr *nh; u_int32_t flags = 0; + u_int32_t token = 0; + u_int16_t rport = 0; u_int16_t family; + void *rip = NULL; int nest_start; int use_id = 0; u_int8_t id; @@ -1339,7 +1342,13 @@ int set_flags(int fd, int pm_family, int argc, char *argv[]) error(1, 0, " missing flags keyword"); for (; arg < argc; arg++) { - if (!strcmp(argv[arg], "flags")) { + if (!strcmp(argv[arg], "token")) { + if (++arg >= argc) + error(1, 0, " missing token value"); + + /* token */ + token = atoi(argv[arg]); + } else if (!strcmp(argv[arg], "flags")) { char *tok, *str; /* flags */ @@ -1378,12 +1387,72 @@ int set_flags(int fd, int pm_family, int argc, char *argv[]) rta->rta_len = RTA_LENGTH(2); memcpy(RTA_DATA(rta), &port, 2); off += NLMSG_ALIGN(rta->rta_len); + } else if (!strcmp(argv[arg], "rport")) { + if (++arg >= argc) + error(1, 0, " missing remote port"); + + rport = atoi(argv[arg]); + } else if (!strcmp(argv[arg], "rip")) { + if (++arg >= argc) + error(1, 0, " missing remote ip"); + + rip = argv[arg]; } else { error(1, 0, "unknown keyword %s", argv[arg]); } } nest->rta_len = off - nest_start; + /* token */ + if (token) { + rta = (void *)(data + off); + rta->rta_type = MPTCP_PM_ATTR_TOKEN; + rta->rta_len = RTA_LENGTH(4); + memcpy(RTA_DATA(rta), &token, 4); + off += NLMSG_ALIGN(rta->rta_len); + } + + /* remote addr/port */ + if (rip) { + nest_start = off; + nest = (void *)(data + off); + nest->rta_type = NLA_F_NESTED | MPTCP_PM_ATTR_ADDR_REMOTE; + nest->rta_len = RTA_LENGTH(0); + off += NLMSG_ALIGN(nest->rta_len); + + /* addr data */ + rta = (void *)(data + off); + if (inet_pton(AF_INET, rip, RTA_DATA(rta))) { + family = AF_INET; + rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR4; + rta->rta_len = RTA_LENGTH(4); + } else if (inet_pton(AF_INET6, rip, RTA_DATA(rta))) { + family = AF_INET6; + rta->rta_type = MPTCP_PM_ADDR_ATTR_ADDR6; + rta->rta_len = RTA_LENGTH(16); + } else { + error(1, errno, "can't parse ip %s", (char *)rip); + } + off += NLMSG_ALIGN(rta->rta_len); + + /* family */ + rta = (void *)(data + off); + rta->rta_type = MPTCP_PM_ADDR_ATTR_FAMILY; + rta->rta_len = RTA_LENGTH(2); + memcpy(RTA_DATA(rta), &family, 2); + off += NLMSG_ALIGN(rta->rta_len); + + if (rport) { + rta = (void *)(data + off); + rta->rta_type = MPTCP_PM_ADDR_ATTR_PORT; + rta->rta_len = RTA_LENGTH(2); + memcpy(RTA_DATA(rta), &rport, 2); + off += NLMSG_ALIGN(rta->rta_len); + } + + nest->rta_len = off - nest_start; + } + do_nl_req(fd, nh, off, 0); return 0; } diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh index 78d0bb640b11..abe3d4ebe554 100755 --- a/tools/testing/selftests/net/mptcp/userspace_pm.sh +++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh @@ -770,10 +770,42 @@ test_subflows() rm -f "$evts" } +test_prio() +{ + local count + + # Send MP_PRIO signal from client to server machine + ip netns exec "$ns2" ./pm_nl_ctl set 10.0.1.2 port "$client4_port" flags backup token "$client4_token" rip 10.0.1.1 rport "$server4_port" + sleep 0.5 + + # Check TX + stdbuf -o0 -e0 printf "MP_PRIO TX \t" + count=$(ip netns exec "$ns2" nstat -as | grep MPTcpExtMPPrioTx | awk '{print $2}') + [ -z "$count" ] && count=0 + if [ $count != 1 ]; then + stdbuf -o0 -e0 printf "[FAIL]\n" + exit 1 + else + stdbuf -o0 -e0 printf "[OK]\n" + fi + + # Check RX + stdbuf -o0 -e0 printf "MP_PRIO RX \t" + count=$(ip netns exec "$ns1" nstat -as | grep MPTcpExtMPPrioRx | awk '{print $2}') + [ -z "$count" ] && count=0 + if [ $count != 1 ]; then + stdbuf -o0 -e0 printf "[FAIL]\n" + exit 1 + else + stdbuf -o0 -e0 printf "[OK]\n" + fi +} + make_connection make_connection "v6" test_announce test_remove test_subflows +test_prio exit 0 From 843b5e75efff04db34fcf9856de53c9e415530a2 Mon Sep 17 00:00:00 2001 From: Paolo Abeni Date: Tue, 5 Jul 2022 14:32:16 -0700 Subject: [PATCH 234/246] mptcp: fix local endpoint accounting In mptcp_pm_nl_rm_addr_or_subflow() we always mark as available the id corresponding to the just removed address. The used bitmap actually tracks only the local IDs: we must restrict the operation when a (local) subflow is removed. Fixes: a88c9e496937 ("mptcp: do not block subflows creation on errors") Signed-off-by: Paolo Abeni Signed-off-by: Mat Martineau Signed-off-by: David S. Miller --- net/mptcp/pm_netlink.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index 2da251dd7c00..7c7395b58944 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -807,7 +807,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk, removed = true; __MPTCP_INC_STATS(sock_net(sk), rm_type); } - __set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap); + if (rm_type == MPTCP_MIB_RMSUBFLOW) + __set_bit(rm_list->ids[i], msk->pm.id_avail_bitmap); if (!removed) continue; From d2d21f175f1f9580eb5681f5b476c8d7a0a3c895 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Tue, 5 Jul 2022 14:32:17 -0700 Subject: [PATCH 235/246] mptcp: update MIB_RMSUBFLOW in cmd_sf_destroy This patch increases MPTCP_MIB_RMSUBFLOW mib counter in userspace pm destroy subflow function mptcp_nl_cmd_sf_destroy() when removing subflow. Fixes: 702c2f646d42 ("mptcp: netlink: allow userspace-driven subflow establishment") Signed-off-by: Geliang Tang Signed-off-by: Mat Martineau Signed-off-by: David S. Miller --- net/mptcp/pm_userspace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c index 51e2f066d54f..9e82250cbb70 100644 --- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -5,6 +5,7 @@ */ #include "protocol.h" +#include "mib.h" void mptcp_free_local_addr_list(struct mptcp_sock *msk) { @@ -410,6 +411,7 @@ int mptcp_nl_cmd_sf_destroy(struct sk_buff *skb, struct genl_info *info) mptcp_subflow_shutdown(sk, ssk, RCV_SHUTDOWN | SEND_SHUTDOWN); mptcp_close_ssk(sk, ssk, subflow); + MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_RMSUBFLOW); err = 0; } else { err = -ESRCH; From a069a90554168ac4cc81af65f000557d2a8a0745 Mon Sep 17 00:00:00 2001 From: Gal Pressman Date: Tue, 5 Jul 2022 14:08:37 +0300 Subject: [PATCH 236/246] Revert "tls: rx: move counting TlsDecryptErrors for sync" This reverts commit 284b4d93daee56dff3e10029ddf2e03227f50dbf. When using TLS device offload and coming from tls_device_reencrypt() flow, -EBADMSG error in tls_do_decryption() should not be counted towards the TLSTlsDecryptError counter. Move the counter increase back to the decrypt_internal() call site in decrypt_skb_update(). This also fixes an issue where: if (n_sgin < 1) return -EBADMSG; Errors in decrypt_internal() were not counted after the cited patch. Fixes: 284b4d93daee ("tls: rx: move counting TlsDecryptErrors for sync") Cc: Jakub Kicinski Reviewed-by: Maxim Mikityanskiy Reviewed-by: Tariq Toukan Signed-off-by: Gal Pressman Reviewed-by: Jakub Kicinski Signed-off-by: David S. Miller --- net/tls/tls_sw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 0513f82b8537..e30649f6dde5 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -267,9 +267,6 @@ static int tls_do_decryption(struct sock *sk, } darg->async = false; - if (ret == -EBADMSG) - TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSDECRYPTERROR); - return ret; } @@ -1579,8 +1576,11 @@ static int decrypt_skb_update(struct sock *sk, struct sk_buff *skb, } err = decrypt_internal(sk, skb, dest, NULL, darg); - if (err < 0) + if (err < 0) { + if (err == -EBADMSG) + TLS_INC_STATS(sock_net(sk), LINUX_MIB_TLSDECRYPTERROR); return err; + } if (darg->async) goto decrypt_next; From b55a21b764c1e182014630fa5486d717484ac58f Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 5 Jul 2022 14:53:51 +0200 Subject: [PATCH 237/246] usbnet: fix memory leak in error case usbnet_write_cmd_async() mixed up which buffers need to be freed in which error case. v2: add Fixes tag v3: fix uninitialized buf pointer Fixes: 877bd862f32b8 ("usbnet: introduce usbnet 3 command helpers") Signed-off-by: Oliver Neukum Link: https://lore.kernel.org/r/20220705125351.17309-1-oneukum@suse.com Signed-off-by: Jakub Kicinski --- drivers/net/usb/usbnet.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index e2135ab87a6e..78a92751ce4c 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -2137,7 +2137,7 @@ static void usbnet_async_cmd_cb(struct urb *urb) int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype, u16 value, u16 index, const void *data, u16 size) { - struct usb_ctrlrequest *req = NULL; + struct usb_ctrlrequest *req; struct urb *urb; int err = -ENOMEM; void *buf = NULL; @@ -2155,7 +2155,7 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype, if (!buf) { netdev_err(dev->net, "Error allocating buffer" " in %s!\n", __func__); - goto fail_free; + goto fail_free_urb; } } @@ -2179,14 +2179,21 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype, if (err < 0) { netdev_err(dev->net, "Error submitting the control" " message: status=%d\n", err); - goto fail_free; + goto fail_free_all; } return 0; +fail_free_all: + kfree(req); fail_free_buf: kfree(buf); -fail_free: - kfree(req); + /* + * avoid a double free + * needed because the flag can be set only + * after filling the URB + */ + urb->transfer_flags = 0; +fail_free_urb: usb_free_urb(urb); fail: return err; From 148ca04518070910739dfc4eeda765057856403d Mon Sep 17 00:00:00 2001 From: Duoming Zhou Date: Tue, 5 Jul 2022 20:56:10 +0800 Subject: [PATCH 238/246] net: rose: fix UAF bug caused by rose_t0timer_expiry There are UAF bugs caused by rose_t0timer_expiry(). The root cause is that del_timer() could not stop the timer handler that is running and there is no synchronization. One of the race conditions is shown below: (thread 1) | (thread 2) | rose_device_event | rose_rt_device_down | rose_remove_neigh rose_t0timer_expiry | rose_stop_t0timer(rose_neigh) ... | del_timer(&neigh->t0timer) | kfree(rose_neigh) //[1]FREE neigh->dce_mode //[2]USE | The rose_neigh is deallocated in position [1] and use in position [2]. The crash trace triggered by POC is like below: BUG: KASAN: use-after-free in expire_timers+0x144/0x320 Write of size 8 at addr ffff888009b19658 by task swapper/0/0 ... Call Trace: dump_stack_lvl+0xbf/0xee print_address_description+0x7b/0x440 print_report+0x101/0x230 ? expire_timers+0x144/0x320 kasan_report+0xed/0x120 ? expire_timers+0x144/0x320 expire_timers+0x144/0x320 __run_timers+0x3ff/0x4d0 run_timer_softirq+0x41/0x80 __do_softirq+0x233/0x544 ... This patch changes rose_stop_ftimer() and rose_stop_t0timer() in rose_remove_neigh() to del_timer_sync() in order that the timer handler could be finished before the resources such as rose_neigh and so on are deallocated. As a result, the UAF bugs could be mitigated. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Duoming Zhou Link: https://lore.kernel.org/r/20220705125610.77971-1-duoming@zju.edu.cn Signed-off-by: Jakub Kicinski --- net/rose/rose_route.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index fee6409c2bb3..eb0b8197ac82 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c @@ -227,8 +227,8 @@ static void rose_remove_neigh(struct rose_neigh *rose_neigh) { struct rose_neigh *s; - rose_stop_ftimer(rose_neigh); - rose_stop_t0timer(rose_neigh); + del_timer_sync(&rose_neigh->ftimer); + del_timer_sync(&rose_neigh->t0timer); skb_queue_purge(&rose_neigh->queue); From faa4e04e5e140a6d02260289a8fba8fd8d7a3003 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Tue, 5 Jul 2022 21:15:22 +0200 Subject: [PATCH 239/246] r8169: fix accessing unset transport header 66e4c8d95008 ("net: warn if transport header was not set") added a check that triggers a warning in r8169, see [0]. The commit referenced in the Fixes tag refers to the change from which the patch applies cleanly, there's nothing wrong with this commit. It seems the actual issue (not bug, because the warning is harmless here) was introduced with bdfa4ed68187 ("r8169: use Giant Send"). [0] https://bugzilla.kernel.org/show_bug.cgi?id=216157 Fixes: 8d520b4de3ed ("r8169: work around RTL8125 UDP hw bug") Reported-by: Erhard F. Tested-by: Erhard F. Signed-off-by: Heiner Kallweit Link: https://lore.kernel.org/r/1b2c2b29-3dc0-f7b6-5694-97ec526d51a0@gmail.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/realtek/r8169_main.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 3098d6672192..1b7fdb4f056b 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -4190,7 +4190,6 @@ static void rtl8169_tso_csum_v1(struct sk_buff *skb, u32 *opts) static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, struct sk_buff *skb, u32 *opts) { - u32 transport_offset = (u32)skb_transport_offset(skb); struct skb_shared_info *shinfo = skb_shinfo(skb); u32 mss = shinfo->gso_size; @@ -4207,7 +4206,7 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, WARN_ON_ONCE(1); } - opts[0] |= transport_offset << GTTCPHO_SHIFT; + opts[0] |= skb_transport_offset(skb) << GTTCPHO_SHIFT; opts[1] |= mss << TD1_MSS_SHIFT; } else if (skb->ip_summed == CHECKSUM_PARTIAL) { u8 ip_protocol; @@ -4235,7 +4234,7 @@ static bool rtl8169_tso_csum_v2(struct rtl8169_private *tp, else WARN_ON_ONCE(1); - opts[1] |= transport_offset << TCPHO_SHIFT; + opts[1] |= skb_transport_offset(skb) << TCPHO_SHIFT; } else { unsigned int padto = rtl_quirk_packet_padto(tp, skb); @@ -4402,14 +4401,13 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) { - int transport_offset = skb_transport_offset(skb); struct rtl8169_private *tp = netdev_priv(dev); if (skb_is_gso(skb)) { if (tp->mac_version == RTL_GIGA_MAC_VER_34) features = rtl8168evl_fix_tso(skb, features); - if (transport_offset > GTTCPHO_MAX && + if (skb_transport_offset(skb) > GTTCPHO_MAX && rtl_chip_supports_csum_v2(tp)) features &= ~NETIF_F_ALL_TSO; } else if (skb->ip_summed == CHECKSUM_PARTIAL) { @@ -4420,7 +4418,7 @@ static netdev_features_t rtl8169_features_check(struct sk_buff *skb, if (rtl_quirk_packet_padto(tp, skb)) features &= ~NETIF_F_CSUM_MASK; - if (transport_offset > TCPHO_MAX && + if (skb_transport_offset(skb) > TCPHO_MAX && rtl_chip_supports_csum_v2(tp)) features &= ~NETIF_F_CSUM_MASK; } From 829be057dbc1e71383b8d7de8edb31dcf07b4aa0 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 7 Jul 2022 02:31:52 +0200 Subject: [PATCH 240/246] wireguard: selftests: set fake real time in init Not all platforms have an RTC, and rather than trying to force one into each, it's much easier to just set a fixed time. This is necessary because WireGuard's latest handshakes parameter is returned in wallclock time, and if the system time isn't set, and the system is really fast, then this returns 0, which trips the test. Turning this on requires setting CONFIG_COMPAT_32BIT_TIME=y, as musl doesn't support settimeofday without it. Signed-off-by: Jason A. Donenfeld Signed-off-by: Jakub Kicinski --- .../testing/selftests/wireguard/qemu/arch/arm.config | 1 + .../selftests/wireguard/qemu/arch/armeb.config | 1 + .../testing/selftests/wireguard/qemu/arch/i686.config | 1 + .../testing/selftests/wireguard/qemu/arch/m68k.config | 1 + .../testing/selftests/wireguard/qemu/arch/mips.config | 1 + .../selftests/wireguard/qemu/arch/mipsel.config | 1 + .../selftests/wireguard/qemu/arch/powerpc.config | 1 + tools/testing/selftests/wireguard/qemu/init.c | 11 +++++++++++ 8 files changed, 18 insertions(+) diff --git a/tools/testing/selftests/wireguard/qemu/arch/arm.config b/tools/testing/selftests/wireguard/qemu/arch/arm.config index fc7959bef9c2..0579c66be83e 100644 --- a/tools/testing/selftests/wireguard/qemu/arch/arm.config +++ b/tools/testing/selftests/wireguard/qemu/arch/arm.config @@ -7,6 +7,7 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_VIRTIO_MENU=y CONFIG_VIRTIO_MMIO=y CONFIG_VIRTIO_CONSOLE=y +CONFIG_COMPAT_32BIT_TIME=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyAMA0 wg.success=vport0p1 panic_on_warn=1" CONFIG_FRAME_WARN=1024 diff --git a/tools/testing/selftests/wireguard/qemu/arch/armeb.config b/tools/testing/selftests/wireguard/qemu/arch/armeb.config index f3066be81c19..2a3307bbe534 100644 --- a/tools/testing/selftests/wireguard/qemu/arch/armeb.config +++ b/tools/testing/selftests/wireguard/qemu/arch/armeb.config @@ -7,6 +7,7 @@ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y CONFIG_VIRTIO_MENU=y CONFIG_VIRTIO_MMIO=y CONFIG_VIRTIO_CONSOLE=y +CONFIG_COMPAT_32BIT_TIME=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyAMA0 wg.success=vport0p1 panic_on_warn=1" CONFIG_CPU_BIG_ENDIAN=y diff --git a/tools/testing/selftests/wireguard/qemu/arch/i686.config b/tools/testing/selftests/wireguard/qemu/arch/i686.config index 6d90892a85a2..cd864b9be6fb 100644 --- a/tools/testing/selftests/wireguard/qemu/arch/i686.config +++ b/tools/testing/selftests/wireguard/qemu/arch/i686.config @@ -1,6 +1,7 @@ CONFIG_ACPI=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_COMPAT_32BIT_TIME=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0 wg.success=ttyS1 panic_on_warn=1" CONFIG_FRAME_WARN=1024 diff --git a/tools/testing/selftests/wireguard/qemu/arch/m68k.config b/tools/testing/selftests/wireguard/qemu/arch/m68k.config index 82c925e49beb..9639bfe06074 100644 --- a/tools/testing/selftests/wireguard/qemu/arch/m68k.config +++ b/tools/testing/selftests/wireguard/qemu/arch/m68k.config @@ -5,5 +5,6 @@ CONFIG_MAC=y CONFIG_SERIAL_PMACZILOG=y CONFIG_SERIAL_PMACZILOG_TTYS=y CONFIG_SERIAL_PMACZILOG_CONSOLE=y +CONFIG_COMPAT_32BIT_TIME=y CONFIG_CMDLINE="console=ttyS0 wg.success=ttyS1 panic_on_warn=1" CONFIG_FRAME_WARN=1024 diff --git a/tools/testing/selftests/wireguard/qemu/arch/mips.config b/tools/testing/selftests/wireguard/qemu/arch/mips.config index d7ec63c17b30..2a84402353ab 100644 --- a/tools/testing/selftests/wireguard/qemu/arch/mips.config +++ b/tools/testing/selftests/wireguard/qemu/arch/mips.config @@ -6,6 +6,7 @@ CONFIG_POWER_RESET=y CONFIG_POWER_RESET_SYSCON=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_COMPAT_32BIT_TIME=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0 wg.success=ttyS1 panic_on_warn=1" CONFIG_FRAME_WARN=1024 diff --git a/tools/testing/selftests/wireguard/qemu/arch/mipsel.config b/tools/testing/selftests/wireguard/qemu/arch/mipsel.config index 18a498293737..56146a101e7e 100644 --- a/tools/testing/selftests/wireguard/qemu/arch/mipsel.config +++ b/tools/testing/selftests/wireguard/qemu/arch/mipsel.config @@ -7,6 +7,7 @@ CONFIG_POWER_RESET=y CONFIG_POWER_RESET_SYSCON=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_COMPAT_32BIT_TIME=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0 wg.success=ttyS1 panic_on_warn=1" CONFIG_FRAME_WARN=1024 diff --git a/tools/testing/selftests/wireguard/qemu/arch/powerpc.config b/tools/testing/selftests/wireguard/qemu/arch/powerpc.config index 5e04882e8e35..174a9ffe2a36 100644 --- a/tools/testing/selftests/wireguard/qemu/arch/powerpc.config +++ b/tools/testing/selftests/wireguard/qemu/arch/powerpc.config @@ -4,6 +4,7 @@ CONFIG_PPC_85xx=y CONFIG_PHYS_64BIT=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_COMPAT_32BIT_TIME=y CONFIG_MATH_EMULATION=y CONFIG_CMDLINE_BOOL=y CONFIG_CMDLINE="console=ttyS0 wg.success=ttyS1 panic_on_warn=1" diff --git a/tools/testing/selftests/wireguard/qemu/init.c b/tools/testing/selftests/wireguard/qemu/init.c index c9e128436546..3e49924dd77e 100644 --- a/tools/testing/selftests/wireguard/qemu/init.c +++ b/tools/testing/selftests/wireguard/qemu/init.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +71,15 @@ static void seed_rng(void) close(fd); } +static void set_time(void) +{ + if (time(NULL)) + return; + pretty_message("[+] Setting fake time..."); + if (stime(&(time_t){1433512680}) < 0) + panic("settimeofday()"); +} + static void mount_filesystems(void) { pretty_message("[+] Mounting filesystems..."); @@ -259,6 +269,7 @@ int main(int argc, char *argv[]) print_banner(); mount_filesystems(); seed_rng(); + set_time(); kmod_selftests(); enable_logging(); clear_leaks(); From 1f2f341a62639c7066ee4c76b7d9ebe867e0a1d5 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 7 Jul 2022 02:31:53 +0200 Subject: [PATCH 241/246] wireguard: selftests: use virt machine on m68k This should be a bit more stable hopefully. Signed-off-by: Jason A. Donenfeld Signed-off-by: Jakub Kicinski --- tools/testing/selftests/wireguard/qemu/Makefile | 5 +++-- tools/testing/selftests/wireguard/qemu/arch/m68k.config | 9 +++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/wireguard/qemu/Makefile b/tools/testing/selftests/wireguard/qemu/Makefile index 7d1b80988d8a..ed07fdc4589c 100644 --- a/tools/testing/selftests/wireguard/qemu/Makefile +++ b/tools/testing/selftests/wireguard/qemu/Makefile @@ -208,10 +208,11 @@ QEMU_ARCH := m68k KERNEL_ARCH := m68k KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/vmlinux KERNEL_CMDLINE := $(shell sed -n 's/CONFIG_CMDLINE=\(.*\)/\1/p' arch/m68k.config) +QEMU_VPORT_RESULT := virtio-serial-device ifeq ($(HOST_ARCH),$(ARCH)) -QEMU_MACHINE := -cpu host,accel=kvm -machine q800 -append $(KERNEL_CMDLINE) +QEMU_MACHINE := -cpu host,accel=kvm -machine virt -append $(KERNEL_CMDLINE) else -QEMU_MACHINE := -machine q800 -smp 1 -append $(KERNEL_CMDLINE) +QEMU_MACHINE := -machine virt -smp 1 -append $(KERNEL_CMDLINE) endif else ifeq ($(ARCH),riscv64) CHOST := riscv64-linux-musl diff --git a/tools/testing/selftests/wireguard/qemu/arch/m68k.config b/tools/testing/selftests/wireguard/qemu/arch/m68k.config index 9639bfe06074..39c48cba56b7 100644 --- a/tools/testing/selftests/wireguard/qemu/arch/m68k.config +++ b/tools/testing/selftests/wireguard/qemu/arch/m68k.config @@ -1,10 +1,7 @@ CONFIG_MMU=y +CONFIG_VIRT=y CONFIG_M68KCLASSIC=y -CONFIG_M68040=y -CONFIG_MAC=y -CONFIG_SERIAL_PMACZILOG=y -CONFIG_SERIAL_PMACZILOG_TTYS=y -CONFIG_SERIAL_PMACZILOG_CONSOLE=y +CONFIG_VIRTIO_CONSOLE=y CONFIG_COMPAT_32BIT_TIME=y -CONFIG_CMDLINE="console=ttyS0 wg.success=ttyS1 panic_on_warn=1" +CONFIG_CMDLINE="console=ttyGF0 wg.success=vport0p1 panic_on_warn=1" CONFIG_FRAME_WARN=1024 From 1a087eec257154e26a81a7a0a15380d7a2431765 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 7 Jul 2022 02:31:54 +0200 Subject: [PATCH 242/246] wireguard: selftests: always call kernel makefile These selftests are used for much more extensive changes than just the wireguard source files. So always call the kernel's build file, which will do something or nothing after checking the whole tree, per usual. Signed-off-by: Jason A. Donenfeld Signed-off-by: Jakub Kicinski --- tools/testing/selftests/wireguard/qemu/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/testing/selftests/wireguard/qemu/Makefile b/tools/testing/selftests/wireguard/qemu/Makefile index ed07fdc4589c..ce6176928a7d 100644 --- a/tools/testing/selftests/wireguard/qemu/Makefile +++ b/tools/testing/selftests/wireguard/qemu/Makefile @@ -19,8 +19,6 @@ endif MIRROR := https://download.wireguard.com/qemu-test/distfiles/ KERNEL_BUILD_PATH := $(BUILD_PATH)/kernel$(if $(findstring yes,$(DEBUG_KERNEL)),-debug) -rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) -WIREGUARD_SOURCES := $(call rwildcard,$(KERNEL_PATH)/drivers/net/wireguard/,*) default: qemu @@ -323,8 +321,9 @@ $(KERNEL_BUILD_PATH)/.config: $(TOOLCHAIN_PATH)/.installed kernel.config arch/$( cd $(KERNEL_BUILD_PATH) && ARCH=$(KERNEL_ARCH) $(KERNEL_PATH)/scripts/kconfig/merge_config.sh -n $(KERNEL_BUILD_PATH)/.config $(KERNEL_BUILD_PATH)/minimal.config $(if $(findstring yes,$(DEBUG_KERNEL)),cp debug.config $(KERNEL_BUILD_PATH) && cd $(KERNEL_BUILD_PATH) && ARCH=$(KERNEL_ARCH) $(KERNEL_PATH)/scripts/kconfig/merge_config.sh -n $(KERNEL_BUILD_PATH)/.config debug.config,) -$(KERNEL_BZIMAGE): $(TOOLCHAIN_PATH)/.installed $(KERNEL_BUILD_PATH)/.config $(BUILD_PATH)/init-cpio-spec.txt $(IPERF_PATH)/src/iperf3 $(IPUTILS_PATH)/ping $(BASH_PATH)/bash $(IPROUTE2_PATH)/misc/ss $(IPROUTE2_PATH)/ip/ip $(IPTABLES_PATH)/iptables/xtables-legacy-multi $(NMAP_PATH)/ncat/ncat $(WIREGUARD_TOOLS_PATH)/src/wg $(BUILD_PATH)/init ../netns.sh $(WIREGUARD_SOURCES) +$(KERNEL_BZIMAGE): $(TOOLCHAIN_PATH)/.installed $(KERNEL_BUILD_PATH)/.config $(BUILD_PATH)/init-cpio-spec.txt $(IPERF_PATH)/src/iperf3 $(IPUTILS_PATH)/ping $(BASH_PATH)/bash $(IPROUTE2_PATH)/misc/ss $(IPROUTE2_PATH)/ip/ip $(IPTABLES_PATH)/iptables/xtables-legacy-multi $(NMAP_PATH)/ncat/ncat $(WIREGUARD_TOOLS_PATH)/src/wg $(BUILD_PATH)/init $(MAKE) -C $(KERNEL_PATH) O=$(KERNEL_BUILD_PATH) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(CROSS_COMPILE) +.PHONY: $(KERNEL_BZIMAGE) $(TOOLCHAIN_PATH)/$(CHOST)/include/linux/.installed: | $(KERNEL_BUILD_PATH)/.config $(TOOLCHAIN_PATH)/.installed rm -rf $(TOOLCHAIN_PATH)/$(CHOST)/include/linux From b83fdcd9fb8ad7e59f4188ba9ec221917f463a17 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 7 Jul 2022 02:31:55 +0200 Subject: [PATCH 243/246] wireguard: selftests: use microvm on x86 This makes for faster tests, faster compile time, and allows us to ditch ACPI finally. Signed-off-by: Jason A. Donenfeld Signed-off-by: Jakub Kicinski --- tools/testing/selftests/wireguard/qemu/Makefile | 10 ++++++---- .../testing/selftests/wireguard/qemu/arch/i686.config | 7 +++++-- .../selftests/wireguard/qemu/arch/x86_64.config | 7 +++++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/tools/testing/selftests/wireguard/qemu/Makefile b/tools/testing/selftests/wireguard/qemu/Makefile index ce6176928a7d..9700358e4337 100644 --- a/tools/testing/selftests/wireguard/qemu/Makefile +++ b/tools/testing/selftests/wireguard/qemu/Makefile @@ -107,20 +107,22 @@ CHOST := x86_64-linux-musl QEMU_ARCH := x86_64 KERNEL_ARCH := x86_64 KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/arch/x86/boot/bzImage +QEMU_VPORT_RESULT := virtio-serial-device ifeq ($(HOST_ARCH),$(ARCH)) -QEMU_MACHINE := -cpu host -machine q35,accel=kvm +QEMU_MACHINE := -cpu host -machine microvm,accel=kvm,pit=off,pic=off,rtc=off -no-acpi else -QEMU_MACHINE := -cpu max -machine q35 +QEMU_MACHINE := -cpu max -machine microvm -no-acpi endif else ifeq ($(ARCH),i686) CHOST := i686-linux-musl QEMU_ARCH := i386 KERNEL_ARCH := x86 KERNEL_BZIMAGE := $(KERNEL_BUILD_PATH)/arch/x86/boot/bzImage +QEMU_VPORT_RESULT := virtio-serial-device ifeq ($(subst x86_64,i686,$(HOST_ARCH)),$(ARCH)) -QEMU_MACHINE := -cpu host -machine q35,accel=kvm +QEMU_MACHINE := -cpu host -machine microvm,accel=kvm,pit=off,pic=off,rtc=off -no-acpi else -QEMU_MACHINE := -cpu max -machine q35 +QEMU_MACHINE := -cpu coreduo -machine microvm -no-acpi endif else ifeq ($(ARCH),mips64) CHOST := mips64-linux-musl diff --git a/tools/testing/selftests/wireguard/qemu/arch/i686.config b/tools/testing/selftests/wireguard/qemu/arch/i686.config index cd864b9be6fb..35b06502606f 100644 --- a/tools/testing/selftests/wireguard/qemu/arch/i686.config +++ b/tools/testing/selftests/wireguard/qemu/arch/i686.config @@ -1,7 +1,10 @@ -CONFIG_ACPI=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_VIRTIO_MENU=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y CONFIG_COMPAT_32BIT_TIME=y CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttyS0 wg.success=ttyS1 panic_on_warn=1" +CONFIG_CMDLINE="console=ttyS0 wg.success=vport0p1 panic_on_warn=1 reboot=t" CONFIG_FRAME_WARN=1024 diff --git a/tools/testing/selftests/wireguard/qemu/arch/x86_64.config b/tools/testing/selftests/wireguard/qemu/arch/x86_64.config index efa00693e08b..cf2d1376d121 100644 --- a/tools/testing/selftests/wireguard/qemu/arch/x86_64.config +++ b/tools/testing/selftests/wireguard/qemu/arch/x86_64.config @@ -1,6 +1,9 @@ -CONFIG_ACPI=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_VIRTIO_MENU=y +CONFIG_VIRTIO_MMIO=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttyS0 wg.success=ttyS1 panic_on_warn=1" +CONFIG_CMDLINE="console=ttyS0 wg.success=vport0p1 panic_on_warn=1 reboot=t" CONFIG_FRAME_WARN=1280 From b7133757da4c4c17d625970f6da3d76af12a8867 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Thu, 7 Jul 2022 02:31:56 +0200 Subject: [PATCH 244/246] crypto: s390 - do not depend on CRYPTO_HW for SIMD implementations Various accelerated software implementation Kconfig values for S390 were mistakenly placed into drivers/crypto/Kconfig, even though they're mainly just SIMD code and live in arch/s390/crypto/ like usual. This gives them the very unusual dependency on CRYPTO_HW, which leads to problems elsewhere. This patch fixes the issue by moving the Kconfig values for non-hardware drivers into the usual place in crypto/Kconfig. Acked-by: Herbert Xu Signed-off-by: Jason A. Donenfeld Signed-off-by: Jakub Kicinski --- crypto/Kconfig | 114 ++++++++++++++++++++++++++++++++++++++++ drivers/crypto/Kconfig | 115 ----------------------------------------- 2 files changed, 114 insertions(+), 115 deletions(-) diff --git a/crypto/Kconfig b/crypto/Kconfig index 1d44893a997b..7b81685b5655 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -666,6 +666,18 @@ config CRYPTO_CRC32_MIPS CRC32c and CRC32 CRC algorithms implemented using mips crypto instructions, when available. +config CRYPTO_CRC32_S390 + tristate "CRC-32 algorithms" + depends on S390 + select CRYPTO_HASH + select CRC32 + help + Select this option if you want to use hardware accelerated + implementations of CRC algorithms. With this option, you + can optimize the computation of CRC-32 (IEEE 802.3 Ethernet) + and CRC-32C (Castagnoli). + + It is available with IBM z13 or later. config CRYPTO_XXHASH tristate "xxHash hash algorithm" @@ -898,6 +910,16 @@ config CRYPTO_SHA512_SSSE3 Extensions version 1 (AVX1), or Advanced Vector Extensions version 2 (AVX2) instructions, when available. +config CRYPTO_SHA512_S390 + tristate "SHA384 and SHA512 digest algorithm" + depends on S390 + select CRYPTO_HASH + help + This is the s390 hardware accelerated implementation of the + SHA512 secure hash standard. + + It is available as of z10. + config CRYPTO_SHA1_OCTEON tristate "SHA1 digest algorithm (OCTEON)" depends on CPU_CAVIUM_OCTEON @@ -930,6 +952,16 @@ config CRYPTO_SHA1_PPC_SPE SHA-1 secure hash standard (DFIPS 180-4) implemented using powerpc SPE SIMD instruction set. +config CRYPTO_SHA1_S390 + tristate "SHA1 digest algorithm" + depends on S390 + select CRYPTO_HASH + help + This is the s390 hardware accelerated implementation of the + SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). + + It is available as of z990. + config CRYPTO_SHA256 tristate "SHA224 and SHA256 digest algorithm" select CRYPTO_HASH @@ -970,6 +1002,16 @@ config CRYPTO_SHA256_SPARC64 SHA-256 secure hash standard (DFIPS 180-2) implemented using sparc64 crypto instructions, when available. +config CRYPTO_SHA256_S390 + tristate "SHA256 digest algorithm" + depends on S390 + select CRYPTO_HASH + help + This is the s390 hardware accelerated implementation of the + SHA256 secure hash standard (DFIPS 180-2). + + It is available as of z9. + config CRYPTO_SHA512 tristate "SHA384 and SHA512 digest algorithms" select CRYPTO_HASH @@ -1010,6 +1052,26 @@ config CRYPTO_SHA3 References: http://keccak.noekeon.org/ +config CRYPTO_SHA3_256_S390 + tristate "SHA3_224 and SHA3_256 digest algorithm" + depends on S390 + select CRYPTO_HASH + help + This is the s390 hardware accelerated implementation of the + SHA3_256 secure hash standard. + + It is available as of z14. + +config CRYPTO_SHA3_512_S390 + tristate "SHA3_384 and SHA3_512 digest algorithm" + depends on S390 + select CRYPTO_HASH + help + This is the s390 hardware accelerated implementation of the + SHA3_512 secure hash standard. + + It is available as of z14. + config CRYPTO_SM3 tristate @@ -1070,6 +1132,16 @@ config CRYPTO_GHASH_CLMUL_NI_INTEL This is the x86_64 CLMUL-NI accelerated implementation of GHASH, the hash function used in GCM (Galois/Counter mode). +config CRYPTO_GHASH_S390 + tristate "GHASH hash function" + depends on S390 + select CRYPTO_HASH + help + This is the s390 hardware accelerated implementation of GHASH, + the hash function used in GCM (Galois/Counter mode). + + It is available as of z196. + comment "Ciphers" config CRYPTO_AES @@ -1185,6 +1257,23 @@ config CRYPTO_AES_PPC_SPE architecture specific assembler implementations that work on 1KB tables or 256 bytes S-boxes. +config CRYPTO_AES_S390 + tristate "AES cipher algorithms" + depends on S390 + select CRYPTO_ALGAPI + select CRYPTO_SKCIPHER + help + This is the s390 hardware accelerated implementation of the + AES cipher algorithms (FIPS-197). + + As of z9 the ECB and CBC modes are hardware accelerated + for 128 bit keys. + As of z10 the ECB and CBC modes are hardware accelerated + for all AES key sizes. + As of z196 the CTR mode is hardware accelerated for all AES + key sizes and XTS mode is hardware accelerated for 256 and + 512 bit keys. + config CRYPTO_ANUBIS tristate "Anubis cipher algorithm" depends on CRYPTO_USER_API_ENABLE_OBSOLETE @@ -1415,6 +1504,19 @@ config CRYPTO_DES3_EDE_X86_64 algorithm are provided; regular processing one input block and one that processes three blocks parallel. +config CRYPTO_DES_S390 + tristate "DES and Triple DES cipher algorithms" + depends on S390 + select CRYPTO_ALGAPI + select CRYPTO_SKCIPHER + select CRYPTO_LIB_DES + help + This is the s390 hardware accelerated implementation of the + DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). + + As of z990 the ECB and CBC mode are hardware accelerated. + As of z196 the CTR mode is hardware accelerated. + config CRYPTO_FCRYPT tristate "FCrypt cipher algorithm" select CRYPTO_ALGAPI @@ -1474,6 +1576,18 @@ config CRYPTO_CHACHA_MIPS select CRYPTO_SKCIPHER select CRYPTO_ARCH_HAVE_LIB_CHACHA +config CRYPTO_CHACHA_S390 + tristate "ChaCha20 stream cipher" + depends on S390 + select CRYPTO_SKCIPHER + select CRYPTO_LIB_CHACHA_GENERIC + select CRYPTO_ARCH_HAVE_LIB_CHACHA + help + This is the s390 SIMD implementation of the ChaCha20 stream + cipher (RFC 7539). + + It is available as of z13. + config CRYPTO_SEED tristate "SEED cipher algorithm" depends on CRYPTO_USER_API_ENABLE_OBSOLETE diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index ee99c02c84e8..3e6aa319920b 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -133,98 +133,6 @@ config CRYPTO_PAES_S390 Select this option if you want to use the paes cipher for example to use protected key encrypted devices. -config CRYPTO_SHA1_S390 - tristate "SHA1 digest algorithm" - depends on S390 - select CRYPTO_HASH - help - This is the s390 hardware accelerated implementation of the - SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). - - It is available as of z990. - -config CRYPTO_SHA256_S390 - tristate "SHA256 digest algorithm" - depends on S390 - select CRYPTO_HASH - help - This is the s390 hardware accelerated implementation of the - SHA256 secure hash standard (DFIPS 180-2). - - It is available as of z9. - -config CRYPTO_SHA512_S390 - tristate "SHA384 and SHA512 digest algorithm" - depends on S390 - select CRYPTO_HASH - help - This is the s390 hardware accelerated implementation of the - SHA512 secure hash standard. - - It is available as of z10. - -config CRYPTO_SHA3_256_S390 - tristate "SHA3_224 and SHA3_256 digest algorithm" - depends on S390 - select CRYPTO_HASH - help - This is the s390 hardware accelerated implementation of the - SHA3_256 secure hash standard. - - It is available as of z14. - -config CRYPTO_SHA3_512_S390 - tristate "SHA3_384 and SHA3_512 digest algorithm" - depends on S390 - select CRYPTO_HASH - help - This is the s390 hardware accelerated implementation of the - SHA3_512 secure hash standard. - - It is available as of z14. - -config CRYPTO_DES_S390 - tristate "DES and Triple DES cipher algorithms" - depends on S390 - select CRYPTO_ALGAPI - select CRYPTO_SKCIPHER - select CRYPTO_LIB_DES - help - This is the s390 hardware accelerated implementation of the - DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3). - - As of z990 the ECB and CBC mode are hardware accelerated. - As of z196 the CTR mode is hardware accelerated. - -config CRYPTO_AES_S390 - tristate "AES cipher algorithms" - depends on S390 - select CRYPTO_ALGAPI - select CRYPTO_SKCIPHER - help - This is the s390 hardware accelerated implementation of the - AES cipher algorithms (FIPS-197). - - As of z9 the ECB and CBC modes are hardware accelerated - for 128 bit keys. - As of z10 the ECB and CBC modes are hardware accelerated - for all AES key sizes. - As of z196 the CTR mode is hardware accelerated for all AES - key sizes and XTS mode is hardware accelerated for 256 and - 512 bit keys. - -config CRYPTO_CHACHA_S390 - tristate "ChaCha20 stream cipher" - depends on S390 - select CRYPTO_SKCIPHER - select CRYPTO_LIB_CHACHA_GENERIC - select CRYPTO_ARCH_HAVE_LIB_CHACHA - help - This is the s390 SIMD implementation of the ChaCha20 stream - cipher (RFC 7539). - - It is available as of z13. - config S390_PRNG tristate "Pseudo random number generator device driver" depends on S390 @@ -238,29 +146,6 @@ config S390_PRNG It is available as of z9. -config CRYPTO_GHASH_S390 - tristate "GHASH hash function" - depends on S390 - select CRYPTO_HASH - help - This is the s390 hardware accelerated implementation of GHASH, - the hash function used in GCM (Galois/Counter mode). - - It is available as of z196. - -config CRYPTO_CRC32_S390 - tristate "CRC-32 algorithms" - depends on S390 - select CRYPTO_HASH - select CRC32 - help - Select this option if you want to use hardware accelerated - implementations of CRC algorithms. With this option, you - can optimize the computation of CRC-32 (IEEE 802.3 Ethernet) - and CRC-32C (Castagnoli). - - It is available with IBM z13 or later. - config CRYPTO_DEV_NIAGARA2 tristate "Niagara2 Stream Processing Unit driver" select CRYPTO_LIB_DES From 0d1f700807d846b00e33cc87d90f404bbc904a97 Mon Sep 17 00:00:00 2001 From: Vladis Dronov Date: Thu, 7 Jul 2022 02:31:57 +0200 Subject: [PATCH 245/246] wireguard: Kconfig: select CRYPTO_CHACHA_S390 Select the new implementation of CHACHA20 for S390 when available. It is faster than the generic software implementation, but also prevents some linker errors in certain situations. Reported-by: kernel test robot Link: https://lore.kernel.org/linux-kernel/202207030630.6SZVkrWf-lkp@intel.com/ Signed-off-by: Vladis Dronov Signed-off-by: Jason A. Donenfeld Signed-off-by: Jakub Kicinski --- drivers/net/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index b2a4f998c180..8c1eeb5a8db8 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -94,6 +94,7 @@ config WIREGUARD select CRYPTO_CURVE25519_NEON if ARM && KERNEL_MODE_NEON select CRYPTO_CHACHA_MIPS if CPU_MIPS32_R2 select CRYPTO_POLY1305_MIPS if MIPS + select CRYPTO_CHACHA_S390 if S390 help WireGuard is a secure, fast, and easy to use replacement for IPSec that uses modern cryptography and clever networking tricks. It's From a382f8fee42ca10c9bfce0d2352d4153f931f5dc Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 6 Jul 2022 12:20:59 -0700 Subject: [PATCH 246/246] signal handling: don't use BUG_ON() for debugging These are indeed "should not happen" situations, but it turns out recent changes made the 'task_is_stopped_or_trace()' case trigger (fix for that exists, is pending more testing), and the BUG_ON() makes it unnecessarily hard to actually debug for no good reason. It's been that way for a long time, but let's make it clear: BUG_ON() is not good for debugging, and should never be used in situations where you could just say "this shouldn't happen, but we can continue". Use WARN_ON_ONCE() instead to make sure it gets logged, and then just continue running. Instead of making the system basically unusuable because you crashed the machine while potentially holding some very core locks (eg this function is commonly called while holding 'tasklist_lock' for writing). Signed-off-by: Linus Torvalds --- kernel/signal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index edb1dc9b00dc..6f86fda5e432 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2029,12 +2029,12 @@ bool do_notify_parent(struct task_struct *tsk, int sig) bool autoreap = false; u64 utime, stime; - BUG_ON(sig == -1); + WARN_ON_ONCE(sig == -1); - /* do_notify_parent_cldstop should have been called instead. */ - BUG_ON(task_is_stopped_or_traced(tsk)); + /* do_notify_parent_cldstop should have been called instead. */ + WARN_ON_ONCE(task_is_stopped_or_traced(tsk)); - BUG_ON(!tsk->ptrace && + WARN_ON_ONCE(!tsk->ptrace && (tsk->group_leader != tsk || !thread_group_empty(tsk))); /* Wake up all pidfd waiters */