From 55ad24857341c36616ecc1d9580af5626c226cf1 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Thu, 29 Jun 2023 09:26:20 +0200 Subject: irq-bcm6345-l1: Do not assume a fixed block to cpu mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The irq to block mapping is fixed, and interrupts from the first block will always be routed to the first parent IRQ. But the parent interrupts themselves can be routed to any available CPU. This is used by the bootloader to map the first parent interrupt to the boot CPU, regardless wether the boot CPU is the first one or the second one. When booting from the second CPU, the assumption that the first block's IRQ is mapped to the first CPU breaks, and the system hangs because interrupts do not get routed correctly. Fix this by passing the appropriate bcm6434_l1_cpu to the interrupt handler instead of the chip itself, so the handler always has the right block. Fixes: c7c42ec2baa1 ("irqchips/bmips: Add bcm6345-l1 interrupt controller") Signed-off-by: Jonas Gorski Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Florian Fainelli Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230629072620.62527-1-jonas.gorski@gmail.com --- drivers/irqchip/irq-bcm6345-l1.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-bcm6345-l1.c b/drivers/irqchip/irq-bcm6345-l1.c index fa113cb2529a..6341c0167c4a 100644 --- a/drivers/irqchip/irq-bcm6345-l1.c +++ b/drivers/irqchip/irq-bcm6345-l1.c @@ -82,6 +82,7 @@ struct bcm6345_l1_chip { }; struct bcm6345_l1_cpu { + struct bcm6345_l1_chip *intc; void __iomem *map_base; unsigned int parent_irq; u32 enable_cache[]; @@ -115,17 +116,11 @@ static inline unsigned int cpu_for_irq(struct bcm6345_l1_chip *intc, static void bcm6345_l1_irq_handle(struct irq_desc *desc) { - struct bcm6345_l1_chip *intc = irq_desc_get_handler_data(desc); - struct bcm6345_l1_cpu *cpu; + struct bcm6345_l1_cpu *cpu = irq_desc_get_handler_data(desc); + struct bcm6345_l1_chip *intc = cpu->intc; struct irq_chip *chip = irq_desc_get_chip(desc); unsigned int idx; -#ifdef CONFIG_SMP - cpu = intc->cpus[cpu_logical_map(smp_processor_id())]; -#else - cpu = intc->cpus[0]; -#endif - chained_irq_enter(chip, desc); for (idx = 0; idx < intc->n_words; idx++) { @@ -253,6 +248,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn, if (!cpu) return -ENOMEM; + cpu->intc = intc; cpu->map_base = ioremap(res.start, sz); if (!cpu->map_base) return -ENOMEM; @@ -271,7 +267,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn, return -EINVAL; } irq_set_chained_handler_and_data(cpu->parent_irq, - bcm6345_l1_irq_handle, intc); + bcm6345_l1_irq_handle, cpu); return 0; } -- cgit From 926846a703cbf5d0635cc06e67d34b228746554b Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sat, 17 Jun 2023 08:32:42 +0100 Subject: irqchip/gic-v4.1: Properly lock VPEs when doing a directLPI invalidation We normally rely on the irq_to_cpuid_[un]lock() primitives to make sure nothing will change col->idx while performing a LPI invalidation. However, these primitives do not cover VPE doorbells, and we have some open-coded locking for that. Unfortunately, this locking is pretty bogus. Instead, extend the above primitives to cover VPE doorbells and convert the whole thing to it. Fixes: f3a059219bc7 ("irqchip/gic-v4.1: Ensure mutual exclusion between vPE affinity change and RD access") Reported-by: Kunkun Jiang Signed-off-by: Marc Zyngier Cc: Zenghui Yu Cc: wanghaibin.wang@huawei.com Tested-by: Kunkun Jiang Reviewed-by: Zenghui Yu Link: https://lore.kernel.org/r/20230617073242.3199746-1-maz@kernel.org --- drivers/irqchip/irq-gic-v3-its.c | 75 ++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 1994541eaef8..5365bc3b1c49 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -273,13 +273,23 @@ static void vpe_to_cpuid_unlock(struct its_vpe *vpe, unsigned long flags) raw_spin_unlock_irqrestore(&vpe->vpe_lock, flags); } +static struct irq_chip its_vpe_irq_chip; + static int irq_to_cpuid_lock(struct irq_data *d, unsigned long *flags) { - struct its_vlpi_map *map = get_vlpi_map(d); + struct its_vpe *vpe = NULL; int cpu; - if (map) { - cpu = vpe_to_cpuid_lock(map->vpe, flags); + if (d->chip == &its_vpe_irq_chip) { + vpe = irq_data_get_irq_chip_data(d); + } else { + struct its_vlpi_map *map = get_vlpi_map(d); + if (map) + vpe = map->vpe; + } + + if (vpe) { + cpu = vpe_to_cpuid_lock(vpe, flags); } else { /* Physical LPIs are already locked via the irq_desc lock */ struct its_device *its_dev = irq_data_get_irq_chip_data(d); @@ -293,10 +303,18 @@ static int irq_to_cpuid_lock(struct irq_data *d, unsigned long *flags) static void irq_to_cpuid_unlock(struct irq_data *d, unsigned long flags) { - struct its_vlpi_map *map = get_vlpi_map(d); + struct its_vpe *vpe = NULL; + + if (d->chip == &its_vpe_irq_chip) { + vpe = irq_data_get_irq_chip_data(d); + } else { + struct its_vlpi_map *map = get_vlpi_map(d); + if (map) + vpe = map->vpe; + } - if (map) - vpe_to_cpuid_unlock(map->vpe, flags); + if (vpe) + vpe_to_cpuid_unlock(vpe, flags); } static struct its_collection *valid_col(struct its_collection *col) @@ -1433,14 +1451,29 @@ static void wait_for_syncr(void __iomem *rdbase) cpu_relax(); } -static void direct_lpi_inv(struct irq_data *d) +static void __direct_lpi_inv(struct irq_data *d, u64 val) { - struct its_vlpi_map *map = get_vlpi_map(d); void __iomem *rdbase; unsigned long flags; - u64 val; int cpu; + /* Target the redistributor this LPI is currently routed to */ + cpu = irq_to_cpuid_lock(d, &flags); + raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock); + + rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base; + gic_write_lpir(val, rdbase + GICR_INVLPIR); + wait_for_syncr(rdbase); + + raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock); + irq_to_cpuid_unlock(d, flags); +} + +static void direct_lpi_inv(struct irq_data *d) +{ + struct its_vlpi_map *map = get_vlpi_map(d); + u64 val; + if (map) { struct its_device *its_dev = irq_data_get_irq_chip_data(d); @@ -1453,15 +1486,7 @@ static void direct_lpi_inv(struct irq_data *d) val = d->hwirq; } - /* Target the redistributor this LPI is currently routed to */ - cpu = irq_to_cpuid_lock(d, &flags); - raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock); - rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base; - gic_write_lpir(val, rdbase + GICR_INVLPIR); - - wait_for_syncr(rdbase); - raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock); - irq_to_cpuid_unlock(d, flags); + __direct_lpi_inv(d, val); } static void lpi_update_config(struct irq_data *d, u8 clr, u8 set) @@ -3953,18 +3978,10 @@ static void its_vpe_send_inv(struct irq_data *d) { struct its_vpe *vpe = irq_data_get_irq_chip_data(d); - if (gic_rdists->has_direct_lpi) { - void __iomem *rdbase; - - /* Target the redistributor this VPE is currently known on */ - raw_spin_lock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock); - rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base; - gic_write_lpir(d->parent_data->hwirq, rdbase + GICR_INVLPIR); - wait_for_syncr(rdbase); - raw_spin_unlock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock); - } else { + if (gic_rdists->has_direct_lpi) + __direct_lpi_inv(d, d->parent_data->hwirq); + else its_vpe_send_cmd(vpe, its_send_inv); - } } static void its_vpe_mask_irq(struct irq_data *d) -- cgit From 567f67acac94e7bbc4cb4b71ff9773555d02609a Mon Sep 17 00:00:00 2001 From: Sebastian Reichel Date: Mon, 3 Jul 2023 18:41:29 +0200 Subject: irqchip/gic-v3: Enable Rockchip 3588001 erratum workaround for RK3588S Commit a8707f553884 ("irqchip/gic-v3: Add Rockchip 3588001 erratum workaround") mentioned RK3588S (the slimmed down variant of RK3588) being affected, but did not check for its compatible value. Thus the quirk is not applied on RK3588S. Since the GIC ITS node got added to the upstream DT, boards using RK3588S are no longer booting without this quirk being applied. Fixes: 06cdac8e8407 ("arm64: dts: rockchip: add GIC ITS support to rk3588") Signed-off-by: Sebastian Reichel Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230703164129.193991-1-sebastian.reichel@collabora.com --- drivers/irqchip/irq-gic-v3-its.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 5365bc3b1c49..e0c2b10d154d 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -4744,7 +4744,8 @@ static bool __maybe_unused its_enable_rk3588001(void *data) { struct its_node *its = data; - if (!of_machine_is_compatible("rockchip,rk3588")) + if (!of_machine_is_compatible("rockchip,rk3588") && + !of_machine_is_compatible("rockchip,rk3588s")) return false; its->flags |= ITS_FLAGS_FORCE_NON_SHAREABLE; -- cgit From 6fe5c68ee6a1aae0ef291a56001e7888de547fa2 Mon Sep 17 00:00:00 2001 From: Lorenzo Pieralisi Date: Tue, 4 Jul 2023 17:50:34 +0200 Subject: irqchip/gic-v3: Workaround for GIC-700 erratum 2941627 GIC700 erratum 2941627 may cause GIC-700 missing SPIs wake requests when SPIs are deactivated while targeting a sleeping CPU - ie a CPU for which the redistributor: GICR_WAKER.ProcessorSleep == 1 This runtime situation can happen if an SPI that has been activated on a core is retargeted to a different core, it becomes pending and the target core subsequently enters a power state quiescing the respective redistributor. When this situation is hit, the de-activation carried out on the core that activated the SPI (through either ICC_EOIR1_EL1 or ICC_DIR_EL1 register writes) does not trigger a wake requests for the sleeping GIC redistributor even if the SPI is pending. Work around the erratum by de-activating the SPI using the redistributor GICD_ICACTIVER register if the runtime conditions require it (ie the IRQ was retargeted between activation and de-activation). Signed-off-by: Lorenzo Pieralisi Signed-off-by: Marc Zyngier Link: https://lore.kernel.org/r/20230704155034.148262-1-lpieralisi@kernel.org --- drivers/irqchip/irq-gic-v3.c | 62 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 0c6c1af9a5b7..eedfa8e9f077 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -69,6 +69,8 @@ struct gic_chip_data { static void __iomem *t241_dist_base_alias[T241_CHIPS_MAX] __read_mostly; static DEFINE_STATIC_KEY_FALSE(gic_nvidia_t241_erratum); +static DEFINE_STATIC_KEY_FALSE(gic_arm64_2941627_erratum); + static struct gic_chip_data gic_data __read_mostly; static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key); @@ -592,10 +594,39 @@ static void gic_irq_nmi_teardown(struct irq_data *d) gic_irq_set_prio(d, GICD_INT_DEF_PRI); } +static bool gic_arm64_erratum_2941627_needed(struct irq_data *d) +{ + enum gic_intid_range range; + + if (!static_branch_unlikely(&gic_arm64_2941627_erratum)) + return false; + + range = get_intid_range(d); + + /* + * The workaround is needed if the IRQ is an SPI and + * the target cpu is different from the one we are + * executing on. + */ + return (range == SPI_RANGE || range == ESPI_RANGE) && + !cpumask_test_cpu(raw_smp_processor_id(), + irq_data_get_effective_affinity_mask(d)); +} + static void gic_eoi_irq(struct irq_data *d) { write_gicreg(gic_irq(d), ICC_EOIR1_EL1); isb(); + + if (gic_arm64_erratum_2941627_needed(d)) { + /* + * Make sure the GIC stream deactivate packet + * issued by ICC_EOIR1_EL1 has completed before + * deactivating through GICD_IACTIVER. + */ + dsb(sy); + gic_poke_irq(d, GICD_ICACTIVER); + } } static void gic_eoimode1_eoi_irq(struct irq_data *d) @@ -606,7 +637,11 @@ static void gic_eoimode1_eoi_irq(struct irq_data *d) */ if (gic_irq(d) >= 8192 || irqd_is_forwarded_to_vcpu(d)) return; - gic_write_dir(gic_irq(d)); + + if (!gic_arm64_erratum_2941627_needed(d)) + gic_write_dir(gic_irq(d)); + else + gic_poke_irq(d, GICD_ICACTIVER); } static int gic_set_type(struct irq_data *d, unsigned int type) @@ -1816,6 +1851,12 @@ static bool gic_enable_quirk_asr8601(void *data) return true; } +static bool gic_enable_quirk_arm64_2941627(void *data) +{ + static_branch_enable(&gic_arm64_2941627_erratum); + return true; +} + static const struct gic_quirk gic_quirks[] = { { .desc = "GICv3: Qualcomm MSM8996 broken firmware", @@ -1863,6 +1904,25 @@ static const struct gic_quirk gic_quirks[] = { .mask = 0xffffffff, .init = gic_enable_quirk_nvidia_t241, }, + { + /* + * GIC-700: 2941627 workaround - IP variant [0,1] + * + */ + .desc = "GICv3: ARM64 erratum 2941627", + .iidr = 0x0400043b, + .mask = 0xff0e0fff, + .init = gic_enable_quirk_arm64_2941627, + }, + { + /* + * GIC-700: 2941627 workaround - IP variant [2] + */ + .desc = "GICv3: ARM64 erratum 2941627", + .iidr = 0x0402043b, + .mask = 0xff0f0fff, + .init = gic_enable_quirk_arm64_2941627, + }, { } }; -- cgit From d64b1ee12a168030fbb3e0aebf7bce49e9a07589 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 29 Jun 2023 09:07:37 +0300 Subject: RDMA/mlx4: Make check for invalid flags stricter This code is trying to ensure that only the flags specified in the list are allowed. The problem is that ucmd->rx_hash_fields_mask is a u64 and the flags are an enum which is treated as a u32 in this context. That means the test doesn't check whether the highest 32 bits are zero. Fixes: 4d02ebd9bbbd ("IB/mlx4: Fix RSS hash fields restrictions") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/233ed975-982d-422a-b498-410f71d8a101@moroto.mountain Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/mlx4/qp.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index 456656617c33..9d08aa99f3cb 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -565,15 +565,15 @@ static int set_qp_rss(struct mlx4_ib_dev *dev, struct mlx4_ib_rss *rss_ctx, return (-EOPNOTSUPP); } - if (ucmd->rx_hash_fields_mask & ~(MLX4_IB_RX_HASH_SRC_IPV4 | - MLX4_IB_RX_HASH_DST_IPV4 | - MLX4_IB_RX_HASH_SRC_IPV6 | - MLX4_IB_RX_HASH_DST_IPV6 | - MLX4_IB_RX_HASH_SRC_PORT_TCP | - MLX4_IB_RX_HASH_DST_PORT_TCP | - MLX4_IB_RX_HASH_SRC_PORT_UDP | - MLX4_IB_RX_HASH_DST_PORT_UDP | - MLX4_IB_RX_HASH_INNER)) { + if (ucmd->rx_hash_fields_mask & ~(u64)(MLX4_IB_RX_HASH_SRC_IPV4 | + MLX4_IB_RX_HASH_DST_IPV4 | + MLX4_IB_RX_HASH_SRC_IPV6 | + MLX4_IB_RX_HASH_DST_IPV6 | + MLX4_IB_RX_HASH_SRC_PORT_TCP | + MLX4_IB_RX_HASH_DST_PORT_TCP | + MLX4_IB_RX_HASH_SRC_PORT_UDP | + MLX4_IB_RX_HASH_DST_PORT_UDP | + MLX4_IB_RX_HASH_INNER)) { pr_debug("RX Hash fields_mask has unsupported mask (0x%llx)\n", ucmd->rx_hash_fields_mask); return (-EOPNOTSUPP); -- cgit From 5782017cc4d0c8f3425d55b893675bb8a20c33e9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 11 Jul 2023 09:13:25 +0300 Subject: phy: phy-mtk-dp: Fix an error code in probe() Negative -EINVAL was intended instead of positive EINVAL. Fixes: 6a23afad443a ("phy: phy-mtk-dp: Add driver for DP phy") Signed-off-by: Dan Carpenter Reviewed-by: Chen-Yu Tsai Link: https://lore.kernel.org/r/3c699e00-2883-40d9-92c3-0da1dc38fdd4@moroto.mountain Signed-off-by: Vinod Koul --- drivers/phy/mediatek/phy-mtk-dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/phy/mediatek/phy-mtk-dp.c b/drivers/phy/mediatek/phy-mtk-dp.c index 232fd3f1ff1b..d7024a144335 100644 --- a/drivers/phy/mediatek/phy-mtk-dp.c +++ b/drivers/phy/mediatek/phy-mtk-dp.c @@ -169,7 +169,7 @@ static int mtk_dp_phy_probe(struct platform_device *pdev) regs = *(struct regmap **)dev->platform_data; if (!regs) - return dev_err_probe(dev, EINVAL, + return dev_err_probe(dev, -EINVAL, "No data passed, requires struct regmap**\n"); dp_phy = devm_kzalloc(dev, sizeof(*dp_phy), GFP_KERNEL); -- cgit From 95bd315f0a5ed7d7afe771776272c5b3cdb29bc8 Mon Sep 17 00:00:00 2001 From: Guillaume Ranquet Date: Tue, 30 May 2023 10:43:07 +0200 Subject: phy: mediatek: hdmi: mt8195: fix prediv bad upper limit test The pll prediv calculus searchs for the smallest prediv that gets the ns_hdmipll_ck in the range of 5 GHz to 12 GHz. A typo in the upper bound test was testing for 5Ghz to 1Ghz Fixes: 45810d486bb44 ("phy: mediatek: add support for phy-mtk-hdmi-mt8195") Signed-off-by: Guillaume Ranquet Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230529-hdmi_phy_fix-v1-1-bf65f53af533@baylibre.com Signed-off-by: Vinod Koul --- drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c index 8aa7251de4a9..bbfe11d6a69d 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c @@ -253,7 +253,7 @@ static int mtk_hdmi_pll_calc(struct mtk_hdmi_phy *hdmi_phy, struct clk_hw *hw, for (i = 0; i < ARRAY_SIZE(txpredivs); i++) { ns_hdmipll_ck = 5 * tmds_clk * txposdiv * txpredivs[i]; if (ns_hdmipll_ck >= 5 * GIGA && - ns_hdmipll_ck <= 1 * GIGA) + ns_hdmipll_ck <= 12 * GIGA) break; } if (i == (ARRAY_SIZE(txpredivs) - 1) && -- cgit From 45d89a344eb46db9dce851c28e14f5e3c635c251 Mon Sep 17 00:00:00 2001 From: Adrien Thierry Date: Thu, 29 Jun 2023 10:45:38 -0400 Subject: phy: qcom-snps-femto-v2: keep cfg_ahb_clk enabled during runtime suspend In the dwc3 core, both system and runtime suspend end up calling dwc3_suspend_common(). From there, what happens for the PHYs depends on the USB mode and whether the controller is entering system or runtime suspend. HOST mode: (1) system suspend on a non-wakeup-capable controller The [1] if branch is taken. dwc3_core_exit() is called, which ends up calling phy_power_off() and phy_exit(). Those two functions decrease the PM runtime count at some point, so they will trigger the PHY runtime sleep (assuming the count is right). (2) runtime suspend / system suspend on a wakeup-capable controller The [1] branch is not taken. dwc3_suspend_common() calls phy_pm_runtime_put_sync(). Assuming the ref count is right, the PHY runtime suspend op is called. DEVICE mode: dwc3_core_exit() is called on both runtime and system sleep unless the controller is already runtime suspended. OTG mode: (1) system suspend : dwc3_core_exit() is called (2) runtime suspend : do nothing In host mode, the code seems to make a distinction between 1) runtime sleep / system sleep for wakeup-capable controller, and 2) system sleep for non-wakeup-capable controller, where phy_power_off() and phy_exit() are only called for the latter. This suggests the PHY is not supposed to be in a fully powered-off state for runtime sleep and system sleep for wakeup-capable controller. Moreover, downstream, cfg_ahb_clk only gets disabled for system suspend. The clocks are disabled by phy->set_suspend() [2] which is only called in the system sleep path through dwc3_core_exit() [3]. With that in mind, don't disable the clocks during the femto PHY runtime suspend callback. The clocks will only be disabled during system suspend for non-wakeup-capable controllers, through dwc3_core_exit(). [1] https://elixir.bootlin.com/linux/v6.4/source/drivers/usb/dwc3/core.c#L1988 [2] https://git.codelinaro.org/clo/la/kernel/msm-5.4/-/blob/LV.AU.1.2.1.r2-05300-gen3meta.0/drivers/usb/phy/phy-msm-snps-hs.c#L524 [3] https://git.codelinaro.org/clo/la/kernel/msm-5.4/-/blob/LV.AU.1.2.1.r2-05300-gen3meta.0/drivers/usb/dwc3/core.c#L1915 Signed-off-by: Adrien Thierry Link: https://lore.kernel.org/r/20230629144542.14906-2-athierry@redhat.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c index 6c237f3cc66d..3335480fc395 100644 --- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c @@ -165,22 +165,13 @@ static int qcom_snps_hsphy_suspend(struct qcom_snps_hsphy *hsphy) 0, USB2_AUTO_RESUME); } - clk_disable_unprepare(hsphy->cfg_ahb_clk); return 0; } static int qcom_snps_hsphy_resume(struct qcom_snps_hsphy *hsphy) { - int ret; - dev_dbg(&hsphy->phy->dev, "Resume QCOM SNPS PHY, mode\n"); - ret = clk_prepare_enable(hsphy->cfg_ahb_clk); - if (ret) { - dev_err(&hsphy->phy->dev, "failed to enable cfg ahb clock\n"); - return ret; - } - return 0; } -- cgit From 8a0eb8f9b9a002291a3934acfd913660b905249e Mon Sep 17 00:00:00 2001 From: Adrien Thierry Date: Thu, 29 Jun 2023 10:45:39 -0400 Subject: phy: qcom-snps-femto-v2: properly enable ref clock The driver is not enabling the ref clock, which thus gets disabled by the clk_disable_unused() initcall. This leads to the dwc3 controller failing to initialize if probed after clk_disable_unused() is called, for instance when the driver is built as a module. To fix this, switch to the clk_bulk API to handle both cfg_ahb and ref clocks at the proper places. Note that the cfg_ahb clock is currently not used by any device tree instantiation of the PHY. Work needs to be done separately to fix this. Link: https://lore.kernel.org/linux-arm-msm/ZEqvy+khHeTkC2hf@fedora/ Fixes: 51e8114f80d0 ("phy: qcom-snps: Add SNPS USB PHY driver for QCOM based SOCs") Signed-off-by: Adrien Thierry Link: https://lore.kernel.org/r/20230629144542.14906-3-athierry@redhat.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 63 ++++++++++++++++++++------- 1 file changed, 48 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c index 3335480fc395..6170f8fd118e 100644 --- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c @@ -110,11 +110,13 @@ struct phy_override_seq { /** * struct qcom_snps_hsphy - snps hs phy attributes * + * @dev: device structure + * * @phy: generic phy * @base: iomapped memory space for snps hs phy * - * @cfg_ahb_clk: AHB2PHY interface clock - * @ref_clk: phy reference clock + * @num_clks: number of clocks + * @clks: array of clocks * @phy_reset: phy reset control * @vregs: regulator supplies bulk data * @phy_initialized: if PHY has been initialized correctly @@ -122,11 +124,13 @@ struct phy_override_seq { * @update_seq_cfg: tuning parameters for phy init */ struct qcom_snps_hsphy { + struct device *dev; + struct phy *phy; void __iomem *base; - struct clk *cfg_ahb_clk; - struct clk *ref_clk; + int num_clks; + struct clk_bulk_data *clks; struct reset_control *phy_reset; struct regulator_bulk_data vregs[SNPS_HS_NUM_VREGS]; @@ -135,6 +139,34 @@ struct qcom_snps_hsphy { struct phy_override_seq update_seq_cfg[NUM_HSPHY_TUNING_PARAMS]; }; +static int qcom_snps_hsphy_clk_init(struct qcom_snps_hsphy *hsphy) +{ + struct device *dev = hsphy->dev; + + hsphy->num_clks = 2; + hsphy->clks = devm_kcalloc(dev, hsphy->num_clks, sizeof(*hsphy->clks), GFP_KERNEL); + if (!hsphy->clks) + return -ENOMEM; + + /* + * TODO: Currently no device tree instantiation of the PHY is using the clock. + * This needs to be fixed in order for this code to be able to use devm_clk_bulk_get(). + */ + hsphy->clks[0].id = "cfg_ahb"; + hsphy->clks[0].clk = devm_clk_get_optional(dev, "cfg_ahb"); + if (IS_ERR(hsphy->clks[0].clk)) + return dev_err_probe(dev, PTR_ERR(hsphy->clks[0].clk), + "failed to get cfg_ahb clk\n"); + + hsphy->clks[1].id = "ref"; + hsphy->clks[1].clk = devm_clk_get(dev, "ref"); + if (IS_ERR(hsphy->clks[1].clk)) + return dev_err_probe(dev, PTR_ERR(hsphy->clks[1].clk), + "failed to get ref clk\n"); + + return 0; +} + static inline void qcom_snps_hsphy_write_mask(void __iomem *base, u32 offset, u32 mask, u32 val) { @@ -365,16 +397,16 @@ static int qcom_snps_hsphy_init(struct phy *phy) if (ret) return ret; - ret = clk_prepare_enable(hsphy->cfg_ahb_clk); + ret = clk_bulk_prepare_enable(hsphy->num_clks, hsphy->clks); if (ret) { - dev_err(&phy->dev, "failed to enable cfg ahb clock, %d\n", ret); + dev_err(&phy->dev, "failed to enable clocks, %d\n", ret); goto poweroff_phy; } ret = reset_control_assert(hsphy->phy_reset); if (ret) { dev_err(&phy->dev, "failed to assert phy_reset, %d\n", ret); - goto disable_ahb_clk; + goto disable_clks; } usleep_range(100, 150); @@ -382,7 +414,7 @@ static int qcom_snps_hsphy_init(struct phy *phy) ret = reset_control_deassert(hsphy->phy_reset); if (ret) { dev_err(&phy->dev, "failed to de-assert phy_reset, %d\n", ret); - goto disable_ahb_clk; + goto disable_clks; } qcom_snps_hsphy_write_mask(hsphy->base, USB2_PHY_USB_PHY_CFG0, @@ -439,8 +471,8 @@ static int qcom_snps_hsphy_init(struct phy *phy) return 0; -disable_ahb_clk: - clk_disable_unprepare(hsphy->cfg_ahb_clk); +disable_clks: + clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks); poweroff_phy: regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); @@ -452,7 +484,7 @@ static int qcom_snps_hsphy_exit(struct phy *phy) struct qcom_snps_hsphy *hsphy = phy_get_drvdata(phy); reset_control_assert(hsphy->phy_reset); - clk_disable_unprepare(hsphy->cfg_ahb_clk); + clk_bulk_disable_unprepare(hsphy->num_clks, hsphy->clks); regulator_bulk_disable(ARRAY_SIZE(hsphy->vregs), hsphy->vregs); hsphy->phy_initialized = false; @@ -545,14 +577,15 @@ static int qcom_snps_hsphy_probe(struct platform_device *pdev) if (!hsphy) return -ENOMEM; + hsphy->dev = dev; + hsphy->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(hsphy->base)) return PTR_ERR(hsphy->base); - hsphy->ref_clk = devm_clk_get(dev, "ref"); - if (IS_ERR(hsphy->ref_clk)) - return dev_err_probe(dev, PTR_ERR(hsphy->ref_clk), - "failed to get ref clk\n"); + ret = qcom_snps_hsphy_clk_init(hsphy); + if (ret) + return dev_err_probe(dev, ret, "failed to initialize clocks\n"); hsphy->phy_reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); if (IS_ERR(hsphy->phy_reset)) { -- cgit From 8932089b566c24ea19b57e37704c492678de1420 Mon Sep 17 00:00:00 2001 From: Adrien Thierry Date: Thu, 29 Jun 2023 10:45:40 -0400 Subject: phy: qcom-snps-femto-v2: use qcom_snps_hsphy_suspend/resume error code The return value from qcom_snps_hsphy_suspend/resume is not used. Make sure qcom_snps_hsphy_runtime_suspend/resume return this value as well. Signed-off-by: Adrien Thierry Link: https://lore.kernel.org/r/20230629144542.14906-4-athierry@redhat.com Signed-off-by: Vinod Koul --- drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c index 6170f8fd118e..d0319bee01c0 100644 --- a/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c +++ b/drivers/phy/qualcomm/phy-qcom-snps-femto-v2.c @@ -214,8 +214,7 @@ static int __maybe_unused qcom_snps_hsphy_runtime_suspend(struct device *dev) if (!hsphy->phy_initialized) return 0; - qcom_snps_hsphy_suspend(hsphy); - return 0; + return qcom_snps_hsphy_suspend(hsphy); } static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) @@ -225,8 +224,7 @@ static int __maybe_unused qcom_snps_hsphy_runtime_resume(struct device *dev) if (!hsphy->phy_initialized) return 0; - qcom_snps_hsphy_resume(hsphy); - return 0; + return qcom_snps_hsphy_resume(hsphy); } static int qcom_snps_hsphy_set_mode(struct phy *phy, enum phy_mode mode, -- cgit From c40d6b3249b11d60e09d81530588f56233d9aa44 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Wed, 5 Jul 2023 14:30:11 +0200 Subject: soundwire: fix enumeration completion The soundwire subsystem uses two completion structures that allow drivers to wait for soundwire device to become enumerated on the bus and initialised by their drivers, respectively. The code implementing the signalling is currently broken as it does not signal all current and future waiters and also uses the wrong reinitialisation function, which can potentially lead to memory corruption if there are still waiters on the queue. Not signalling future waiters specifically breaks sound card probe deferrals as codec drivers can not tell that the soundwire device is already attached when being reprobed. Some codec runtime PM implementations suffer from similar problems as waiting for enumeration during resume can also timeout despite the device already having been enumerated. Fixes: fb9469e54fa7 ("soundwire: bus: fix race condition with enumeration_complete signaling") Fixes: a90def068127 ("soundwire: bus: fix race condition with initialization_complete signaling") Cc: stable@vger.kernel.org # 5.7 Cc: Pierre-Louis Bossart Cc: Rander Wang Signed-off-by: Johan Hovold Reviewed-by: Pierre-Louis Bossart Link: https://lore.kernel.org/r/20230705123018.30903-2-johan+linaro@kernel.org Signed-off-by: Vinod Koul --- drivers/soundwire/bus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/soundwire/bus.c b/drivers/soundwire/bus.c index dba920ec88f6..cf78839b3f74 100644 --- a/drivers/soundwire/bus.c +++ b/drivers/soundwire/bus.c @@ -922,8 +922,8 @@ static void sdw_modify_slave_status(struct sdw_slave *slave, "initializing enumeration and init completion for Slave %d\n", slave->dev_num); - init_completion(&slave->enumeration_complete); - init_completion(&slave->initialization_complete); + reinit_completion(&slave->enumeration_complete); + reinit_completion(&slave->initialization_complete); } else if ((status == SDW_SLAVE_ATTACHED) && (slave->status == SDW_SLAVE_UNATTACHED)) { @@ -931,7 +931,7 @@ static void sdw_modify_slave_status(struct sdw_slave *slave, "signaling enumeration completion for Slave %d\n", slave->dev_num); - complete(&slave->enumeration_complete); + complete_all(&slave->enumeration_complete); } slave->status = status; mutex_unlock(&bus->bus_lock); @@ -1951,7 +1951,7 @@ int sdw_handle_slave_status(struct sdw_bus *bus, "signaling initialization completion for Slave %d\n", slave->dev_num); - complete(&slave->initialization_complete); + complete_all(&slave->initialization_complete); /* * If the manager became pm_runtime active, the peripherals will be -- cgit From f84d41b2a083b990cbdf70f3b24b6b108b9678ad Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Thu, 25 May 2023 14:38:09 +0100 Subject: soundwire: qcom: update status correctly with mask SoundWire device status can be incorrectly updated without proper mask, fix this by adding a mask before updating the status. Fixes: c7d49c76d1d5 ("soundwire: qcom: add support to new interrupts") Signed-off-by: Srinivas Kandagatla Link: https://lore.kernel.org/r/20230525133812.30841-2-srinivas.kandagatla@linaro.org Signed-off-by: Vinod Koul --- drivers/soundwire/qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index 7970fdb27ba0..c029e4d53573 100644 --- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -540,7 +540,7 @@ static int qcom_swrm_get_alert_slave_dev_num(struct qcom_swrm_ctrl *ctrl) status = (val >> (dev_num * SWRM_MCP_SLV_STATUS_SZ)); if ((status & SWRM_MCP_SLV_STATUS_MASK) == SDW_SLAVE_ALERT) { - ctrl->status[dev_num] = status; + ctrl->status[dev_num] = status & SWRM_MCP_SLV_STATUS_MASK; return dev_num; } } -- cgit From 7891d0a5ce6f627132d3068ba925cf86f29008b1 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 27 Jun 2023 08:42:10 +0300 Subject: soundwire: amd: Fix a check for errors in probe() This code has two problems: 1) The devm_ioremap() function returns NULL, not error pointers. 2) It's checking the wrong variable. ->mmio instead of ->acp_mmio. Fixes: d8f48fbdfd9a ("soundwire: amd: Add support for AMD Manager driver") Suggested-by: "Mukunda,Vijendar" Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/9863b2bf-0de2-4bf8-8f09-fe24dc5c63ff@moroto.mountain Signed-off-by: Vinod Koul --- drivers/soundwire/amd_manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c index 08aeb7ed00e1..3a99f6dcdfaf 100644 --- a/drivers/soundwire/amd_manager.c +++ b/drivers/soundwire/amd_manager.c @@ -910,9 +910,9 @@ static int amd_sdw_manager_probe(struct platform_device *pdev) return -ENOMEM; amd_manager->acp_mmio = devm_ioremap(dev, res->start, resource_size(res)); - if (IS_ERR(amd_manager->mmio)) { + if (!amd_manager->acp_mmio) { dev_err(dev, "mmio not found\n"); - return PTR_ERR(amd_manager->mmio); + return -ENOMEM; } amd_manager->instance = pdata->instance; amd_manager->mmio = amd_manager->acp_mmio + -- cgit From a85c238c5ccd64f8d4c4560702c65cb25dee791c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 12 Jul 2023 15:11:39 +0300 Subject: drm/msm/mdss: correct UBWC programming for SM8550 The SM8550 platform employs newer UBWC decoder, which requires slightly different programming. Fixes: a2f33995c19d ("drm/msm: mdss: add support for SM8550") Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/546934/ Link: https://lore.kernel.org/r/20230712121145.1994830-3-dmitry.baryshkov@linaro.org Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/msm_mdss.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_mdss.c b/drivers/gpu/drm/msm/msm_mdss.c index 05648c910c68..798bd4f3b662 100644 --- a/drivers/gpu/drm/msm/msm_mdss.c +++ b/drivers/gpu/drm/msm/msm_mdss.c @@ -189,6 +189,7 @@ static int _msm_mdss_irq_domain_add(struct msm_mdss *msm_mdss) #define UBWC_2_0 0x20000000 #define UBWC_3_0 0x30000000 #define UBWC_4_0 0x40000000 +#define UBWC_4_3 0x40030000 static void msm_mdss_setup_ubwc_dec_20(struct msm_mdss *msm_mdss) { @@ -227,7 +228,10 @@ static void msm_mdss_setup_ubwc_dec_40(struct msm_mdss *msm_mdss) writel_relaxed(1, msm_mdss->mmio + UBWC_CTRL_2); writel_relaxed(0, msm_mdss->mmio + UBWC_PREDICTION_MODE); } else { - writel_relaxed(2, msm_mdss->mmio + UBWC_CTRL_2); + if (data->ubwc_dec_version == UBWC_4_3) + writel_relaxed(3, msm_mdss->mmio + UBWC_CTRL_2); + else + writel_relaxed(2, msm_mdss->mmio + UBWC_CTRL_2); writel_relaxed(1, msm_mdss->mmio + UBWC_PREDICTION_MODE); } } @@ -271,6 +275,7 @@ static int msm_mdss_enable(struct msm_mdss *msm_mdss) msm_mdss_setup_ubwc_dec_30(msm_mdss); break; case UBWC_4_0: + case UBWC_4_3: msm_mdss_setup_ubwc_dec_40(msm_mdss); break; default: @@ -569,6 +574,16 @@ static const struct msm_mdss_data sm8250_data = { .macrotile_mode = 1, }; +static const struct msm_mdss_data sm8550_data = { + .ubwc_version = UBWC_4_0, + .ubwc_dec_version = UBWC_4_3, + .ubwc_swizzle = 6, + .ubwc_static = 1, + /* TODO: highest_bank_bit = 2 for LP_DDR4 */ + .highest_bank_bit = 3, + .macrotile_mode = 1, +}; + static const struct of_device_id mdss_dt_match[] = { { .compatible = "qcom,mdss" }, { .compatible = "qcom,msm8998-mdss" }, @@ -585,7 +600,7 @@ static const struct of_device_id mdss_dt_match[] = { { .compatible = "qcom,sm8250-mdss", .data = &sm8250_data }, { .compatible = "qcom,sm8350-mdss", .data = &sm8250_data }, { .compatible = "qcom,sm8450-mdss", .data = &sm8250_data }, - { .compatible = "qcom,sm8550-mdss", .data = &sm8250_data }, + { .compatible = "qcom,sm8550-mdss", .data = &sm8550_data }, {} }; MODULE_DEVICE_TABLE(of, mdss_dt_match); -- cgit From ba7a94ea73120e3f72c4a9b7ed6fd5598d29c069 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Tue, 4 Jul 2023 12:01:04 -0400 Subject: drm/msm/dpu: add missing flush and fetch bits for DMA4/DMA5 planes Note that with this, DMA4/DMA5 are still non-functional, but at least display *something* in modetest instead of nothing or underflow. Fixes: efcd0107727c ("drm/msm/dpu: add support for SM8550") Signed-off-by: Jonathan Marek Reviewed-by: Abhinav Kumar Tested-by: Neil Armstrong # on SM8550-QRD Patchwork: https://patchwork.freedesktop.org/patch/545548/ Link: https://lore.kernel.org/r/20230704160106.26055-1-jonathan@marek.ca Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index c278fb9d2b5b..86182c734606 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -51,7 +51,7 @@ static const u32 fetch_tbl[SSPP_MAX] = {CTL_INVALID_BIT, 16, 17, 18, 19, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, CTL_INVALID_BIT, 0, - 1, 2, 3, CTL_INVALID_BIT, CTL_INVALID_BIT}; + 1, 2, 3, 4, 5}; static int _mixer_stages(const struct dpu_lm_cfg *mixer, int count, enum dpu_lm lm) @@ -198,6 +198,12 @@ static void dpu_hw_ctl_update_pending_flush_sspp(struct dpu_hw_ctl *ctx, case SSPP_DMA3: ctx->pending_flush_mask |= BIT(25); break; + case SSPP_DMA4: + ctx->pending_flush_mask |= BIT(13); + break; + case SSPP_DMA5: + ctx->pending_flush_mask |= BIT(14); + break; case SSPP_CURSOR0: ctx->pending_flush_mask |= BIT(22); break; -- cgit From e8383f5cf1b3573ce140a80bfbfd809278ab16d6 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 7 Jul 2023 22:39:32 +0300 Subject: drm/msm/dpu: drop enum dpu_core_perf_data_bus_id Drop the leftover of bus-client -> interconnect conversion, the enum dpu_core_perf_data_bus_id. Fixes: cb88482e2570 ("drm/msm/dpu: clean up references of DPU custom bus scaling") Reviewed-by: Konrad Dybcio Reviewed-by: Abhinav Kumar Signed-off-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/546048/ Link: https://lore.kernel.org/r/20230707193942.3806526-2-dmitry.baryshkov@linaro.org Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h index e3795995e145..29bb8ee2bc26 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.h @@ -14,19 +14,6 @@ #define DPU_PERF_DEFAULT_MAX_CORE_CLK_RATE 412500000 -/** - * enum dpu_core_perf_data_bus_id - data bus identifier - * @DPU_CORE_PERF_DATA_BUS_ID_MNOC: DPU/MNOC data bus - * @DPU_CORE_PERF_DATA_BUS_ID_LLCC: MNOC/LLCC data bus - * @DPU_CORE_PERF_DATA_BUS_ID_EBI: LLCC/EBI data bus - */ -enum dpu_core_perf_data_bus_id { - DPU_CORE_PERF_DATA_BUS_ID_MNOC, - DPU_CORE_PERF_DATA_BUS_ID_LLCC, - DPU_CORE_PERF_DATA_BUS_ID_EBI, - DPU_CORE_PERF_DATA_BUS_ID_MAX, -}; - /** * struct dpu_core_perf_params - definition of performance parameters * @max_per_pipe_ib: maximum instantaneous bandwidth request -- cgit From 97368254a08e2ca4766e7f84a45840230fe77fa3 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Tue, 27 Jun 2023 22:14:16 +0200 Subject: drm/msm/dsi: Drop unused regulators from QCM2290 14nm DSI PHY config The regulator setup was likely copied from other SoCs by mistake. Just like SM6125 the DSI PHY on this platform is not getting power from a regulator but from the MX power domain. Fixes: 572e9fd6d14a ("drm/msm/dsi: Add phy configuration for QCM2290") Signed-off-by: Marijn Suijten Reviewed-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Patchwork: https://patchwork.freedesktop.org/patch/544536/ Link: https://lore.kernel.org/r/20230627-sm6125-dpu-v2-1-03e430a2078c@somainline.org Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 3ce45b023e63..31deda1c664a 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -1087,8 +1087,6 @@ const struct msm_dsi_phy_cfg dsi_phy_14nm_8953_cfgs = { const struct msm_dsi_phy_cfg dsi_phy_14nm_2290_cfgs = { .has_phy_lane = true, - .regulator_data = dsi_phy_14nm_17mA_regulators, - .num_regulators = ARRAY_SIZE(dsi_phy_14nm_17mA_regulators), .ops = { .enable = dsi_14nm_phy_enable, .disable = dsi_14nm_phy_disable, -- cgit From 9c2dcfc2cf0f2e4e0a0db33bc1a626e35928c475 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 30 May 2023 12:16:39 +0200 Subject: media: tc358746: Address compiler warnings Address these compiler warnings by initialising the m_best and p_best values to 0 and 1 respectively (as latter is used as a divisor): drivers/media/i2c/tc358746.c: In function 'tc358746_find_pll_settings': >> drivers/media/i2c/tc358746.c:817:13: warning: 'p_best' is used uninitialized [-Wuninitialized] 817 | u16 p_best, p; | ^~~~~~ >> drivers/media/i2c/tc358746.c:816:13: warning: 'm_best' is used uninitialized [-Wuninitialized] 816 | u16 m_best, mul; | ^~~~~~ The warnings may well be a false positive but it is difficult for a compiler to find out whether that truly is the case. Closes: https://lore.kernel.org/oe-kbuild-all/202305301627.fLT3Bkds-lkp@intel.com/ Reported-by: kernel test robot Fixes: 80a21da3605 ("media: tc358746: add Toshiba TC358746 Parallel to CSI-2 bridge driver") Signed-off-by: Sakari Ailus Reviewed-by: Marco Felsch Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/tc358746.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/i2c/tc358746.c b/drivers/media/i2c/tc358746.c index e9b2d906c177..3f7e147ef594 100644 --- a/drivers/media/i2c/tc358746.c +++ b/drivers/media/i2c/tc358746.c @@ -813,8 +813,8 @@ static unsigned long tc358746_find_pll_settings(struct tc358746 *tc358746, u32 min_delta = 0xffffffff; u16 prediv_max = 17; u16 prediv_min = 1; - u16 m_best, mul; - u16 p_best, p; + u16 m_best = 0, mul; + u16 p_best = 1, p; u8 postdiv; if (fout > 1000 * HZ_PER_MHZ) { -- cgit From bf4c985707d3168ebb7d87d15830de66949d979c Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Tue, 13 Jun 2023 18:47:53 +0200 Subject: media: staging: atomisp: select V4L2_FWNODE Select V4L2_FWNODE as the driver depends on it. Reported-by: Andy Shevchenko Fixes: aa31f6514047 ("media: atomisp: allow building the driver again") Signed-off-by: Sakari Ailus Tested-by: Andy Shevchenko Reviewed-by: Hans de Goede Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/media/atomisp/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/staging/media/atomisp/Kconfig b/drivers/staging/media/atomisp/Kconfig index c9bff98e5309..e9b168ba97bf 100644 --- a/drivers/staging/media/atomisp/Kconfig +++ b/drivers/staging/media/atomisp/Kconfig @@ -13,6 +13,7 @@ config VIDEO_ATOMISP tristate "Intel Atom Image Signal Processor Driver" depends on VIDEO_DEV && INTEL_ATOMISP depends on PMIC_OPREGION + select V4L2_FWNODE select IOSF_MBI select VIDEOBUF2_VMALLOC select VIDEO_V4L2_SUBDEV_API -- cgit From 517f088385e1b8015606143e6212cb30f8714070 Mon Sep 17 00:00:00 2001 From: Alexander Stein Date: Tue, 31 Jan 2023 11:32:44 +0100 Subject: media: amphion: use dev_err_probe This simplifies the code and silences -517 error messages. Also the reason is listed in /sys/kernel/debug/devices_deferred. Signed-off-by: Alexander Stein Reviewed-by: ming_qian Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/amphion/vpu_mbox.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/amphion/vpu_mbox.c b/drivers/media/platform/amphion/vpu_mbox.c index bf759eb2fd46..b6d5b4844f67 100644 --- a/drivers/media/platform/amphion/vpu_mbox.c +++ b/drivers/media/platform/amphion/vpu_mbox.c @@ -46,11 +46,10 @@ static int vpu_mbox_request_channel(struct device *dev, struct vpu_mbox *mbox) cl->rx_callback = vpu_mbox_rx_callback; ch = mbox_request_channel_byname(cl, mbox->name); - if (IS_ERR(ch)) { - dev_err(dev, "Failed to request mbox chan %s, ret : %ld\n", - mbox->name, PTR_ERR(ch)); - return PTR_ERR(ch); - } + if (IS_ERR(ch)) + return dev_err_probe(dev, PTR_ERR(ch), + "Failed to request mbox chan %s\n", + mbox->name); mbox->ch = ch; return 0; -- cgit From dcff0b56f661b6b42e828012b464d22cc2068c38 Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 25 May 2023 22:10:15 +0200 Subject: media: amphion: Fix firmware path to match linux-firmware The path did not match the one it was submitted into linux-firmware which prevented generic distribution from having working CODEC. Fixes: 9f599f351e86 ("media: amphion: add vpu core driver") Signed-off-by: Nicolas Dufresne Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/amphion/vpu_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/amphion/vpu_core.c b/drivers/media/platform/amphion/vpu_core.c index 43d85a54268b..7863b7b53494 100644 --- a/drivers/media/platform/amphion/vpu_core.c +++ b/drivers/media/platform/amphion/vpu_core.c @@ -826,7 +826,7 @@ static const struct dev_pm_ops vpu_core_pm_ops = { static struct vpu_core_resources imx8q_enc = { .type = VPU_CORE_TYPE_ENC, - .fwname = "vpu/vpu_fw_imx8_enc.bin", + .fwname = "amphion/vpu/vpu_fw_imx8_enc.bin", .stride = 16, .max_width = 1920, .max_height = 1920, @@ -841,7 +841,7 @@ static struct vpu_core_resources imx8q_enc = { static struct vpu_core_resources imx8q_dec = { .type = VPU_CORE_TYPE_DEC, - .fwname = "vpu/vpu_fw_imx8_dec.bin", + .fwname = "amphion/vpu/vpu_fw_imx8_dec.bin", .stride = 256, .max_width = 8188, .max_height = 8188, -- cgit From 53ebeea50599c1ed05277d7a57e331a34e6d6a82 Mon Sep 17 00:00:00 2001 From: Ming Qian Date: Tue, 30 May 2023 09:16:30 +0200 Subject: media: imx-jpeg: Support to assign slot for encoder/decoder imx jpeg encoder and decoder support 4 slots each, aim to support some virtualization scenarios. driver should only enable one slot one time. but due to some hardware issue, only slot 0 can be enabled in imx8q platform, and they may be fixed in imx9 platform. Signed-off-by: Ming Qian Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h | 1 - drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c | 135 +++++++++++----------- drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h | 5 +- 3 files changed, 68 insertions(+), 73 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h index ed15ea348f97..a2b4fb9e29e7 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg-hw.h @@ -58,7 +58,6 @@ #define CAST_OFBSIZE_LO CAST_STATUS18 #define CAST_OFBSIZE_HI CAST_STATUS19 -#define MXC_MAX_SLOTS 1 /* TODO use all 4 slots*/ /* JPEG-Decoder Wrapper Slot Registers 0..3 */ #define SLOT_BASE 0x10000 #define SLOT_STATUS 0x0 diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index c0e49be42450..9512c0a61966 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -745,87 +745,77 @@ static void notify_src_chg(struct mxc_jpeg_ctx *ctx) v4l2_event_queue_fh(&ctx->fh, &ev); } -static int mxc_get_free_slot(struct mxc_jpeg_slot_data slot_data[], int n) +static int mxc_get_free_slot(struct mxc_jpeg_slot_data *slot_data) { - int free_slot = 0; - - while (slot_data[free_slot].used && free_slot < n) - free_slot++; - - return free_slot; /* >=n when there are no more free slots */ + if (!slot_data->used) + return slot_data->slot; + return -1; } -static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg, - unsigned int slot) +static bool mxc_jpeg_alloc_slot_data(struct mxc_jpeg_dev *jpeg) { struct mxc_jpeg_desc *desc; struct mxc_jpeg_desc *cfg_desc; void *cfg_stm; - if (jpeg->slot_data[slot].desc) + if (jpeg->slot_data.desc) goto skip_alloc; /* already allocated, reuse it */ /* allocate descriptor for decoding/encoding phase */ desc = dma_alloc_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - &jpeg->slot_data[slot].desc_handle, + &jpeg->slot_data.desc_handle, GFP_ATOMIC); if (!desc) goto err; - jpeg->slot_data[slot].desc = desc; + jpeg->slot_data.desc = desc; /* allocate descriptor for configuration phase (encoder only) */ cfg_desc = dma_alloc_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - &jpeg->slot_data[slot].cfg_desc_handle, + &jpeg->slot_data.cfg_desc_handle, GFP_ATOMIC); if (!cfg_desc) goto err; - jpeg->slot_data[slot].cfg_desc = cfg_desc; + jpeg->slot_data.cfg_desc = cfg_desc; /* allocate configuration stream */ cfg_stm = dma_alloc_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, - &jpeg->slot_data[slot].cfg_stream_handle, + &jpeg->slot_data.cfg_stream_handle, GFP_ATOMIC); if (!cfg_stm) goto err; - jpeg->slot_data[slot].cfg_stream_vaddr = cfg_stm; + jpeg->slot_data.cfg_stream_vaddr = cfg_stm; skip_alloc: - jpeg->slot_data[slot].used = true; + jpeg->slot_data.used = true; return true; err: - dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", slot); + dev_err(jpeg->dev, "Could not allocate descriptors for slot %d", jpeg->slot_data.slot); return false; } -static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg, - unsigned int slot) +static void mxc_jpeg_free_slot_data(struct mxc_jpeg_dev *jpeg) { - if (slot >= MXC_MAX_SLOTS) { - dev_err(jpeg->dev, "Invalid slot %d, nothing to free.", slot); - return; - } - /* free descriptor for decoding/encoding phase */ dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - jpeg->slot_data[slot].desc, - jpeg->slot_data[slot].desc_handle); + jpeg->slot_data.desc, + jpeg->slot_data.desc_handle); /* free descriptor for encoder configuration phase / decoder DHT */ dma_free_coherent(jpeg->dev, sizeof(struct mxc_jpeg_desc), - jpeg->slot_data[slot].cfg_desc, - jpeg->slot_data[slot].cfg_desc_handle); + jpeg->slot_data.cfg_desc, + jpeg->slot_data.cfg_desc_handle); /* free configuration stream */ dma_free_coherent(jpeg->dev, MXC_JPEG_MAX_CFG_STREAM, - jpeg->slot_data[slot].cfg_stream_vaddr, - jpeg->slot_data[slot].cfg_stream_handle); + jpeg->slot_data.cfg_stream_vaddr, + jpeg->slot_data.cfg_stream_handle); - jpeg->slot_data[slot].used = false; + jpeg->slot_data.used = false; } static void mxc_jpeg_check_and_set_last_buffer(struct mxc_jpeg_ctx *ctx, @@ -855,7 +845,7 @@ static void mxc_jpeg_job_finish(struct mxc_jpeg_ctx *ctx, enum vb2_buffer_state v4l2_m2m_buf_done(dst_buf, state); mxc_jpeg_disable_irq(reg, ctx->slot); - ctx->mxc_jpeg->slot_data[ctx->slot].used = false; + jpeg->slot_data.used = false; if (reset) mxc_jpeg_sw_reset(reg); } @@ -919,7 +909,7 @@ static irqreturn_t mxc_jpeg_dec_irq(int irq, void *priv) goto job_unlock; } - if (!jpeg->slot_data[slot].used) + if (!jpeg->slot_data.used) goto job_unlock; dec_ret = readl(reg + MXC_SLOT_OFFSET(slot, SLOT_STATUS)); @@ -1179,13 +1169,13 @@ static void mxc_jpeg_config_dec_desc(struct vb2_buffer *out_buf, struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; void __iomem *reg = jpeg->base_reg; unsigned int slot = ctx->slot; - struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc; - struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc; - dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle; - dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle; - dma_addr_t cfg_stream_handle = jpeg->slot_data[slot].cfg_stream_handle; - unsigned int *cfg_size = &jpeg->slot_data[slot].cfg_stream_size; - void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr; + struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; + struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; + dma_addr_t desc_handle = jpeg->slot_data.desc_handle; + dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; + dma_addr_t cfg_stream_handle = jpeg->slot_data.cfg_stream_handle; + unsigned int *cfg_size = &jpeg->slot_data.cfg_stream_size; + void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; struct mxc_jpeg_src_buf *jpeg_src_buf; jpeg_src_buf = vb2_to_mxc_buf(src_buf); @@ -1245,18 +1235,18 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf, struct mxc_jpeg_dev *jpeg = ctx->mxc_jpeg; void __iomem *reg = jpeg->base_reg; unsigned int slot = ctx->slot; - struct mxc_jpeg_desc *desc = jpeg->slot_data[slot].desc; - struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data[slot].cfg_desc; - dma_addr_t desc_handle = jpeg->slot_data[slot].desc_handle; - dma_addr_t cfg_desc_handle = jpeg->slot_data[slot].cfg_desc_handle; - void *cfg_stream_vaddr = jpeg->slot_data[slot].cfg_stream_vaddr; + struct mxc_jpeg_desc *desc = jpeg->slot_data.desc; + struct mxc_jpeg_desc *cfg_desc = jpeg->slot_data.cfg_desc; + dma_addr_t desc_handle = jpeg->slot_data.desc_handle; + dma_addr_t cfg_desc_handle = jpeg->slot_data.cfg_desc_handle; + void *cfg_stream_vaddr = jpeg->slot_data.cfg_stream_vaddr; struct mxc_jpeg_q_data *q_data; enum mxc_jpeg_image_format img_fmt; int w, h; q_data = mxc_jpeg_get_q_data(ctx, src_buf->vb2_queue->type); - jpeg->slot_data[slot].cfg_stream_size = + jpeg->slot_data.cfg_stream_size = mxc_jpeg_setup_cfg_stream(cfg_stream_vaddr, q_data->fmt->fourcc, q_data->crop.width, @@ -1265,7 +1255,7 @@ static void mxc_jpeg_config_enc_desc(struct vb2_buffer *out_buf, /* chain the config descriptor with the encoding descriptor */ cfg_desc->next_descpt_ptr = desc_handle | MXC_NXT_DESCPT_EN; - cfg_desc->buf_base0 = jpeg->slot_data[slot].cfg_stream_handle; + cfg_desc->buf_base0 = jpeg->slot_data.cfg_stream_handle; cfg_desc->buf_base1 = 0; cfg_desc->line_pitch = 0; cfg_desc->stm_bufbase = 0; /* no output expected */ @@ -1408,7 +1398,7 @@ static void mxc_jpeg_device_run_timeout(struct work_struct *work) unsigned long flags; spin_lock_irqsave(&ctx->mxc_jpeg->hw_lock, flags); - if (ctx->slot < MXC_MAX_SLOTS && ctx->mxc_jpeg->slot_data[ctx->slot].used) { + if (ctx->mxc_jpeg->slot_data.used) { dev_warn(jpeg->dev, "%s timeout, cancel it\n", ctx->mxc_jpeg->mode == MXC_JPEG_DECODE ? "decode" : "encode"); mxc_jpeg_job_finish(ctx, VB2_BUF_STATE_ERROR, true); @@ -1476,12 +1466,12 @@ static void mxc_jpeg_device_run(void *priv) mxc_jpeg_enable(reg); mxc_jpeg_set_l_endian(reg, 1); - ctx->slot = mxc_get_free_slot(jpeg->slot_data, MXC_MAX_SLOTS); - if (ctx->slot >= MXC_MAX_SLOTS) { + ctx->slot = mxc_get_free_slot(&jpeg->slot_data); + if (ctx->slot < 0) { dev_err(dev, "No more free slots\n"); goto end; } - if (!mxc_jpeg_alloc_slot_data(jpeg, ctx->slot)) { + if (!mxc_jpeg_alloc_slot_data(jpeg)) { dev_err(dev, "Cannot allocate slot data\n"); goto end; } @@ -2101,7 +2091,7 @@ static int mxc_jpeg_open(struct file *file) } ctx->fh.ctrl_handler = &ctx->ctrl_handler; mxc_jpeg_set_default_params(ctx); - ctx->slot = MXC_MAX_SLOTS; /* slot not allocated yet */ + ctx->slot = -1; /* slot not allocated yet */ INIT_DELAYED_WORK(&ctx->task_timer, mxc_jpeg_device_run_timeout); if (mxc_jpeg->mode == MXC_JPEG_DECODE) @@ -2677,6 +2667,11 @@ static int mxc_jpeg_attach_pm_domains(struct mxc_jpeg_dev *jpeg) dev_err(dev, "No power domains defined for jpeg node\n"); return jpeg->num_domains; } + if (jpeg->num_domains == 1) { + /* genpd_dev_pm_attach() attach automatically if power domains count is 1 */ + jpeg->num_domains = 0; + return 0; + } jpeg->pd_dev = devm_kmalloc_array(dev, jpeg->num_domains, sizeof(*jpeg->pd_dev), GFP_KERNEL); @@ -2718,7 +2713,6 @@ static int mxc_jpeg_probe(struct platform_device *pdev) int ret; int mode; const struct of_device_id *of_id; - unsigned int slot; of_id = of_match_node(mxc_jpeg_match, dev->of_node); if (!of_id) @@ -2742,19 +2736,22 @@ static int mxc_jpeg_probe(struct platform_device *pdev) if (IS_ERR(jpeg->base_reg)) return PTR_ERR(jpeg->base_reg); - for (slot = 0; slot < MXC_MAX_SLOTS; slot++) { - dec_irq = platform_get_irq(pdev, slot); - if (dec_irq < 0) { - ret = dec_irq; - goto err_irq; - } - ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, - 0, pdev->name, jpeg); - if (ret) { - dev_err(&pdev->dev, "Failed to request irq %d (%d)\n", - dec_irq, ret); - goto err_irq; - } + ret = of_property_read_u32_index(pdev->dev.of_node, "slot", 0, &jpeg->slot_data.slot); + if (ret) + jpeg->slot_data.slot = 0; + dev_info(&pdev->dev, "choose slot %d\n", jpeg->slot_data.slot); + dec_irq = platform_get_irq(pdev, 0); + if (dec_irq < 0) { + dev_err(&pdev->dev, "Failed to get irq %d\n", dec_irq); + ret = dec_irq; + goto err_irq; + } + ret = devm_request_irq(&pdev->dev, dec_irq, mxc_jpeg_dec_irq, + 0, pdev->name, jpeg); + if (ret) { + dev_err(&pdev->dev, "Failed to request irq %d (%d)\n", + dec_irq, ret); + goto err_irq; } jpeg->pdev = pdev; @@ -2914,11 +2911,9 @@ static const struct dev_pm_ops mxc_jpeg_pm_ops = { static void mxc_jpeg_remove(struct platform_device *pdev) { - unsigned int slot; struct mxc_jpeg_dev *jpeg = platform_get_drvdata(pdev); - for (slot = 0; slot < MXC_MAX_SLOTS; slot++) - mxc_jpeg_free_slot_data(jpeg, slot); + mxc_jpeg_free_slot_data(jpeg); pm_runtime_disable(&pdev->dev); video_unregister_device(jpeg->dec_vdev); diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h index 87157db78082..d80e94cc9d99 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.h @@ -97,7 +97,7 @@ struct mxc_jpeg_ctx { struct mxc_jpeg_q_data cap_q; struct v4l2_fh fh; enum mxc_jpeg_enc_state enc_state; - unsigned int slot; + int slot; unsigned int source_change; bool header_parsed; struct v4l2_ctrl_handler ctrl_handler; @@ -106,6 +106,7 @@ struct mxc_jpeg_ctx { }; struct mxc_jpeg_slot_data { + int slot; bool used; struct mxc_jpeg_desc *desc; // enc/dec descriptor struct mxc_jpeg_desc *cfg_desc; // configuration descriptor @@ -128,7 +129,7 @@ struct mxc_jpeg_dev { struct v4l2_device v4l2_dev; struct v4l2_m2m_dev *m2m_dev; struct video_device *dec_vdev; - struct mxc_jpeg_slot_data slot_data[MXC_MAX_SLOTS]; + struct mxc_jpeg_slot_data slot_data; int num_domains; struct device **pd_dev; struct device_link **pd_link; -- cgit From 20de9fdaf4883deffb0138eef28e9cbbead32cfd Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 1 Jun 2023 23:37:22 +0200 Subject: media: mtk_jpeg_core: avoid unused-variable warning The mtk8195_jpegenc_drvdata object was added outside of an #ifdef causing a harmless build warning. drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c:1879:32: error: 'mtk8195_jpegenc_drvdata' defined but not used [-Werror=unused-variable] 1879 | static struct mtk_jpeg_variant mtk8195_jpegenc_drvdata = { | ^~~~~~~~~~~~~~~~~~~~~~~ A follow-up patch moved it inside of an #ifdef, which caused more warnings, and a third patch ended up adding even more #ifdefs. These were all bogus, since the actual problem here is the incorrect use of of_ptr(). Since the driver (like any other modern platform driver) only works in combination with CONFIG_OF, there is no point in hiding the reference, so just remove that along with all the pointless #ifdef checks in the driver. This improves build coverage and avoids running into the same problem again when another part of the driver gets changed that relies on the #ifdef blocks to be completely matched. Fixes: 934e8bccac95 ("mtk-jpegenc: support jpegenc multi-hardware") Fixes: 4ae47770d57b ("media: mtk-jpegenc: Fix a compilation issue") Fixes: da4ede4b7fd6 ("media: mtk-jpeg: move data/code inside CONFIG_OF blocks") Signed-off-by: Arnd Bergmann Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 6 +----- drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c | 4 +--- drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c | 4 +--- 3 files changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index 4768156181c9..40cb3cb87ba1 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -28,7 +28,6 @@ #include "mtk_jpeg_core.h" #include "mtk_jpeg_dec_parse.h" -#if defined(CONFIG_OF) static struct mtk_jpeg_fmt mtk_jpeg_enc_formats[] = { { .fourcc = V4L2_PIX_FMT_JPEG, @@ -102,7 +101,6 @@ static struct mtk_jpeg_fmt mtk_jpeg_dec_formats[] = { .flags = MTK_JPEG_FMT_FLAG_CAPTURE, }, }; -#endif #define MTK_JPEG_ENC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_enc_formats) #define MTK_JPEG_DEC_NUM_FORMATS ARRAY_SIZE(mtk_jpeg_dec_formats) @@ -1455,7 +1453,6 @@ static const struct dev_pm_ops mtk_jpeg_pm_ops = { SET_RUNTIME_PM_OPS(mtk_jpeg_pm_suspend, mtk_jpeg_pm_resume, NULL) }; -#if defined(CONFIG_OF) static int mtk_jpegenc_get_hw(struct mtk_jpeg_ctx *ctx) { struct mtk_jpegenc_comp_dev *comp_jpeg; @@ -1951,14 +1948,13 @@ static const struct of_device_id mtk_jpeg_match[] = { }; MODULE_DEVICE_TABLE(of, mtk_jpeg_match); -#endif static struct platform_driver mtk_jpeg_driver = { .probe = mtk_jpeg_probe, .remove_new = mtk_jpeg_remove, .driver = { .name = MTK_JPEG_NAME, - .of_match_table = of_match_ptr(mtk_jpeg_match), + .of_match_table = mtk_jpeg_match, .pm = &mtk_jpeg_pm_ops, }, }; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c index 869068fac5e2..baa7be58ce69 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_dec_hw.c @@ -39,7 +39,6 @@ enum mtk_jpeg_color { MTK_JPEG_COLOR_400 = 0x00110000 }; -#if defined(CONFIG_OF) static const struct of_device_id mtk_jpegdec_hw_ids[] = { { .compatible = "mediatek,mt8195-jpgdec-hw", @@ -47,7 +46,6 @@ static const struct of_device_id mtk_jpegdec_hw_ids[] = { {}, }; MODULE_DEVICE_TABLE(of, mtk_jpegdec_hw_ids); -#endif static inline int mtk_jpeg_verify_align(u32 val, int align, u32 reg) { @@ -653,7 +651,7 @@ static struct platform_driver mtk_jpegdec_hw_driver = { .probe = mtk_jpegdec_hw_probe, .driver = { .name = "mtk-jpegdec-hw", - .of_match_table = of_match_ptr(mtk_jpegdec_hw_ids), + .of_match_table = mtk_jpegdec_hw_ids, }, }; diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c index 71e85b4bbf12..244018365b6f 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_enc_hw.c @@ -46,7 +46,6 @@ static const struct mtk_jpeg_enc_qlt mtk_jpeg_enc_quality[] = { {.quality_param = 97, .hardware_value = JPEG_ENC_QUALITY_Q97}, }; -#if defined(CONFIG_OF) static const struct of_device_id mtk_jpegenc_drv_ids[] = { { .compatible = "mediatek,mt8195-jpgenc-hw", @@ -54,7 +53,6 @@ static const struct of_device_id mtk_jpegenc_drv_ids[] = { {}, }; MODULE_DEVICE_TABLE(of, mtk_jpegenc_drv_ids); -#endif void mtk_jpeg_enc_reset(void __iomem *base) { @@ -377,7 +375,7 @@ static struct platform_driver mtk_jpegenc_hw_driver = { .probe = mtk_jpegenc_hw_probe, .driver = { .name = "mtk-jpegenc-hw", - .of_match_table = of_match_ptr(mtk_jpegenc_drv_ids), + .of_match_table = mtk_jpegenc_drv_ids, }, }; -- cgit From 92cbf865ea2e0f2997ff97815c6db182eb23df1b Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Tue, 6 Jun 2023 06:38:15 +0200 Subject: media: pulse8-cec: handle possible ping error Handle (and warn about) possible error waiting for MSGCODE_PING result. Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Dmitry Antipov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/cec/usb/pulse8/pulse8-cec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/cec/usb/pulse8/pulse8-cec.c b/drivers/media/cec/usb/pulse8/pulse8-cec.c index 04b13cdc38d2..ba67587bd43e 100644 --- a/drivers/media/cec/usb/pulse8/pulse8-cec.c +++ b/drivers/media/cec/usb/pulse8/pulse8-cec.c @@ -809,8 +809,11 @@ static void pulse8_ping_eeprom_work_handler(struct work_struct *work) mutex_lock(&pulse8->lock); cmd = MSGCODE_PING; - pulse8_send_and_wait(pulse8, &cmd, 1, - MSGCODE_COMMAND_ACCEPTED, 0); + if (pulse8_send_and_wait(pulse8, &cmd, 1, + MSGCODE_COMMAND_ACCEPTED, 0)) { + dev_warn(pulse8->dev, "failed to ping EEPROM\n"); + goto unlock; + } if (pulse8->vers < 2) goto unlock; -- cgit From 4aaa96b59df5fac41ba891969df6b092061ea9d7 Mon Sep 17 00:00:00 2001 From: Nikolay Burykin Date: Tue, 10 Jan 2023 10:09:00 +0100 Subject: media: pci: cx23885: fix error handling for cx23885 ATSC boards After having been assigned to NULL value at cx23885-dvb.c:1202, pointer '0' is dereferenced at cx23885-dvb.c:2469. Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Nikolay Burykin Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-dvb.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index 8fd5b6ef2428..7551ca4a322a 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -2459,16 +2459,10 @@ static int dvb_register(struct cx23885_tsport *port) request_module("%s", info.type); client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); if (!i2c_client_has_driver(client_tuner)) { - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } if (!try_module_get(client_tuner->dev.driver->owner)) { i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } port->i2c_client_tuner = client_tuner; @@ -2505,16 +2499,10 @@ static int dvb_register(struct cx23885_tsport *port) request_module("%s", info.type); client_tuner = i2c_new_client_device(&dev->i2c_bus[1].i2c_adap, &info); if (!i2c_client_has_driver(client_tuner)) { - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } if (!try_module_get(client_tuner->dev.driver->owner)) { i2c_unregister_device(client_tuner); - module_put(client_demod->dev.driver->owner); - i2c_unregister_device(client_demod); - port->i2c_client_demod = NULL; goto frontend_detach; } port->i2c_client_tuner = client_tuner; -- cgit From d05dea76d4a813eb959ba0a150c45246d54e7148 Mon Sep 17 00:00:00 2001 From: Yunfei Dong Date: Mon, 12 Jun 2023 05:15:57 +0200 Subject: media: mediatek: vcodec: fix cancel_work_sync fail with fluster test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Will cause below warning then reboot when exercising the decoder with fluster on mt8192-asurada-spherion. This deinit function is called on the v4l2 release callback, even though the work might not have been initialized as that only happens if/when the codec specific 'decode' callback is called (as a result of device_run m2m callback). CPU: 5 PID: 2338 Comm: gst-launch-1.0 Tainted: G W 6.4.0-rc5-next-20230607+ #475 Hardware name: Google Spherion (rev0 - 3) (DT) pstate: 00400009 (nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __flush_work.isra.0+0x23c/0x258 lr : __cancel_work_timer+0x14c/0x1c8 sp : ffff8000896e3b00 x29: ffff8000896e3b00 x28: ffff57c3d4079f80 x27: 0000000000000000 x26: ffff57c3d4079f80 x25: ffffb76395b59dc8 x24: 0000000000000001 x23: ffffb763928daab8 x22: ffff57c3d4079f80 x21: 0000000000000000 x20: ffffb763955f6778 x19: ffff57c3cf06f4a0 x18: 0000000000000000 x17: 000000040044ffff x16: 005000f2b5503510 x15: 0000000000000000 x14: ffff57c3c03a1f80 x13: ffffa0616a2fc000 x12: 000000003464d91d x11: 0000000000000000 x10: 0000000000001b10 x9 : ffffb763928de61c x8 : ffff57c3d407baf0 x7 : 0000000000000000 x6 : ffff57c3d4079f80 x5 : ffff57c3d4079f80 x4 : 0000000000000000 x3 : 0000000000000000 x2 : ffff8000896e3bf0 x1 : 0000000000000011 x0 : 0000000000000000 Call trace: __flush_work.isra.0+0x23c/0x258 __cancel_work_timer+0x14c/0x1c8 cancel_work_sync+0x1c/0x30 vdec_msg_queue_deinit+0xac/0xc8 vdec_h264_slice_deinit+0x64/0xb8 vdec_if_deinit+0x3c/0x68 mtk_vcodec_dec_release+0x20/0x40 fops_vcodec_release+0x50/0xd8 v4l2_release+0x7c/0x100 __fput+0x80/0x270 ____fput+0x18/0x30 task_work_run+0x78/0xe0 do_notify_resume+0x29c/0x7f8 el0_svc+0xa4/0xb8 el0t_64_sync_handler+0xc0/0xc8 el0t_64_sync+0x1a8/0x1b0 ---[ end trace 0000000000000000 ]--- Fixes: 297160d411e3 ("media: mediatek: vcodec: move core context from device to each instance") Reported-by: Nícolas F. R. A. Prado Signed-off-by: Yunfei Dong Reviewed-by: AngeloGioacchino Del Regno Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c index f555341ae708..04e6dc6cfa1d 100644 --- a/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c +++ b/drivers/media/platform/mediatek/vcodec/vdec_msg_queue.c @@ -233,7 +233,8 @@ void vdec_msg_queue_deinit(struct vdec_msg_queue *msg_queue, kfree(lat_buf->private_data); } - cancel_work_sync(&msg_queue->core_work); + if (msg_queue->wdma_addr.size) + cancel_work_sync(&msg_queue->core_work); } static void vdec_msg_queue_core_work(struct work_struct *work) -- cgit From 7ee8acd1b803502878992acd6f99e61f1e8c7a25 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 16 Jun 2023 16:48:47 +0200 Subject: media: verisilicon: fix excessive stack usage In some configurations, gcc decides not to inline the register accessor functions, which in turn leads to lots of temporary hantro_reg structures on the stack that cannot be eliminated because they escape into an uninlined function: drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c:1022:1: warning: the frame size of 1112 bytes is larger than 1024 bytes [-Wframe-larger-than=] Mark all of these as __always_inline so the compiler is able to completely eliminate the temporary structures instead, which brings the stack usage back down to just the normal local variables. Closes: https://lore.kernel.org/oe-kbuild-all/202306151506.goHEegOd-lkp@intel.com/ [hverkuil: fix function prototype alignment, wrap commit log] Reported-by: kernel test robot Fixes: 727a400686a2 ("media: verisilicon: Add Rockchip AV1 decoder") Signed-off-by: Arnd Bergmann Reviewed-by: Nicolas Dufresne Tested-by: Nathan Chancellor Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/verisilicon/hantro.h | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h index 6523ffb74881..1afec3df8c73 100644 --- a/drivers/media/platform/verisilicon/hantro.h +++ b/drivers/media/platform/verisilicon/hantro.h @@ -370,26 +370,26 @@ extern int hantro_debug; pr_err("%s:%d: " fmt, __func__, __LINE__, ##args) /* Structure access helpers. */ -static inline struct hantro_ctx *fh_to_ctx(struct v4l2_fh *fh) +static __always_inline struct hantro_ctx *fh_to_ctx(struct v4l2_fh *fh) { return container_of(fh, struct hantro_ctx, fh); } /* Register accessors. */ -static inline void vepu_write_relaxed(struct hantro_dev *vpu, - u32 val, u32 reg) +static __always_inline void vepu_write_relaxed(struct hantro_dev *vpu, + u32 val, u32 reg) { vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); writel_relaxed(val, vpu->enc_base + reg); } -static inline void vepu_write(struct hantro_dev *vpu, u32 val, u32 reg) +static __always_inline void vepu_write(struct hantro_dev *vpu, u32 val, u32 reg) { vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); writel(val, vpu->enc_base + reg); } -static inline u32 vepu_read(struct hantro_dev *vpu, u32 reg) +static __always_inline u32 vepu_read(struct hantro_dev *vpu, u32 reg) { u32 val = readl(vpu->enc_base + reg); @@ -397,27 +397,27 @@ static inline u32 vepu_read(struct hantro_dev *vpu, u32 reg) return val; } -static inline void vdpu_write_relaxed(struct hantro_dev *vpu, - u32 val, u32 reg) +static __always_inline void vdpu_write_relaxed(struct hantro_dev *vpu, + u32 val, u32 reg) { vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); writel_relaxed(val, vpu->dec_base + reg); } -static inline void vdpu_write(struct hantro_dev *vpu, u32 val, u32 reg) +static __always_inline void vdpu_write(struct hantro_dev *vpu, u32 val, u32 reg) { vpu_debug(6, "0x%04x = 0x%08x\n", reg / 4, val); writel(val, vpu->dec_base + reg); } -static inline void hantro_write_addr(struct hantro_dev *vpu, - unsigned long offset, - dma_addr_t addr) +static __always_inline void hantro_write_addr(struct hantro_dev *vpu, + unsigned long offset, + dma_addr_t addr) { vdpu_write(vpu, addr & 0xffffffff, offset); } -static inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg) +static __always_inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg) { u32 val = readl(vpu->dec_base + reg); @@ -425,9 +425,9 @@ static inline u32 vdpu_read(struct hantro_dev *vpu, u32 reg) return val; } -static inline u32 vdpu_read_mask(struct hantro_dev *vpu, - const struct hantro_reg *reg, - u32 val) +static __always_inline u32 vdpu_read_mask(struct hantro_dev *vpu, + const struct hantro_reg *reg, + u32 val) { u32 v; @@ -437,16 +437,16 @@ static inline u32 vdpu_read_mask(struct hantro_dev *vpu, return v; } -static inline void hantro_reg_write(struct hantro_dev *vpu, - const struct hantro_reg *reg, - u32 val) +static __always_inline void hantro_reg_write(struct hantro_dev *vpu, + const struct hantro_reg *reg, + u32 val) { vdpu_write_relaxed(vpu, vdpu_read_mask(vpu, reg, val), reg->base); } -static inline void hantro_reg_write_s(struct hantro_dev *vpu, - const struct hantro_reg *reg, - u32 val) +static __always_inline void hantro_reg_write_s(struct hantro_dev *vpu, + const struct hantro_reg *reg, + u32 val) { vdpu_write(vpu, vdpu_read_mask(vpu, reg, val), reg->base); } -- cgit From 0cb1d9c845110ce638a43a1417c7df5968d1daa3 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 16 Jun 2023 16:48:48 +0200 Subject: media: verisilicon: change confusingly named relaxed register access The register abstraction has wrappers around both the normal writel() and its writel_relaxed() counterpart, but this has led to a lot of users ending up with the relaxed version. There is sometimes a need to intentionally pick the relaxed accessor for performance critical functions, but I noticed that each hantro_reg_write() call also contains a non-relaxed readl(), which is typically much more expensive than a writel, so there is little benefit here but an added risk of missing a serialization against DMA. To make this behave like other interfaces, use the normal accessor by default and only provide the relaxed version as an alternative for performance critical code. hantro_postproc.c is the only place that used both the relaxed and normal writel, but this does not seem cricital either, so change it all to the normal ones. [hverkuil: fix function prototype alignment] Signed-off-by: Arnd Bergmann Tested-by: Benjamin Gaignard Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/verisilicon/hantro.h | 10 +++++----- drivers/media/platform/verisilicon/hantro_postproc.c | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/platform/verisilicon/hantro.h b/drivers/media/platform/verisilicon/hantro.h index 1afec3df8c73..77aee9489516 100644 --- a/drivers/media/platform/verisilicon/hantro.h +++ b/drivers/media/platform/verisilicon/hantro.h @@ -441,14 +441,14 @@ static __always_inline void hantro_reg_write(struct hantro_dev *vpu, const struct hantro_reg *reg, u32 val) { - vdpu_write_relaxed(vpu, vdpu_read_mask(vpu, reg, val), reg->base); + vdpu_write(vpu, vdpu_read_mask(vpu, reg, val), reg->base); } -static __always_inline void hantro_reg_write_s(struct hantro_dev *vpu, - const struct hantro_reg *reg, - u32 val) +static __always_inline void hantro_reg_write_relaxed(struct hantro_dev *vpu, + const struct hantro_reg *reg, + u32 val) { - vdpu_write(vpu, vdpu_read_mask(vpu, reg, val), reg->base); + vdpu_write_relaxed(vpu, vdpu_read_mask(vpu, reg, val), reg->base); } void *hantro_get_ctrl(struct hantro_ctx *ctx, u32 id); diff --git a/drivers/media/platform/verisilicon/hantro_postproc.c b/drivers/media/platform/verisilicon/hantro_postproc.c index c977d64105b1..0224ff68ab3f 100644 --- a/drivers/media/platform/verisilicon/hantro_postproc.c +++ b/drivers/media/platform/verisilicon/hantro_postproc.c @@ -21,11 +21,11 @@ val); \ } -#define HANTRO_PP_REG_WRITE_S(vpu, reg_name, val) \ +#define HANTRO_PP_REG_WRITE_RELAXED(vpu, reg_name, val) \ { \ - hantro_reg_write_s(vpu, \ - &hantro_g1_postproc_regs.reg_name, \ - val); \ + hantro_reg_write_relaxed(vpu, \ + &hantro_g1_postproc_regs.reg_name, \ + val); \ } #define VPU_PP_IN_YUYV 0x0 @@ -72,7 +72,7 @@ static void hantro_postproc_g1_enable(struct hantro_ctx *ctx) dma_addr_t dst_dma; /* Turn on pipeline mode. Must be done first. */ - HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x1); + HANTRO_PP_REG_WRITE(vpu, pipeline_en, 0x1); src_pp_fmt = VPU_PP_IN_NV12; @@ -242,7 +242,7 @@ static void hantro_postproc_g1_disable(struct hantro_ctx *ctx) { struct hantro_dev *vpu = ctx->dev; - HANTRO_PP_REG_WRITE_S(vpu, pipeline_en, 0x0); + HANTRO_PP_REG_WRITE(vpu, pipeline_en, 0x0); } static void hantro_postproc_g2_disable(struct hantro_ctx *ctx) -- cgit From 8b58f757cd1c712b5f081e4c26b13611298dfb07 Mon Sep 17 00:00:00 2001 From: Thomas GENTY Date: Fri, 14 Jul 2023 12:51:17 +0200 Subject: platform/x86: touchscreen_dmi.c: small changes for Archos 101 Cesium Educ tablet Fix the axes and add home button support as suggested by Hans de Goede. Signed-off-by: Thomas GENTY Link: https://lore.kernel.org/r/20230714105117.192938-1-tomlohave@gmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/touchscreen_dmi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c index a5b687eed8f3..f9301a9382e7 100644 --- a/drivers/platform/x86/touchscreen_dmi.c +++ b/drivers/platform/x86/touchscreen_dmi.c @@ -27,11 +27,12 @@ struct ts_dmi_data { /* NOTE: Please keep all entries sorted alphabetically */ static const struct property_entry archos_101_cesium_educ_props[] = { - PROPERTY_ENTRY_U32("touchscreen-size-x", 1280), - PROPERTY_ENTRY_U32("touchscreen-size-y", 1850), - PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"), + PROPERTY_ENTRY_U32("touchscreen-size-x", 1850), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), + PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), PROPERTY_ENTRY_U32("silead,max-fingers", 10), + PROPERTY_ENTRY_BOOL("silead,home-button"), PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-archos-101-cesium-educ.fw"), { } }; -- cgit From f2ae72541d52a0bf50366840fe2238aaf111f7ae Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 11 Jul 2023 11:59:20 +0200 Subject: platform/x86/amd: pmc: Use release_mem_region() to undo request_mem_region_muxed() Muxed (mem) regions will wait in request_mem_region_muxed() if the region is busy (in use by another consumer) during the call. In order to wake-up possibly waiting other consumers of the region, it must be released by a release_mem_region() call, which will actually wake up any waiters. release_mem_region() also frees the resource created by request_mem_region_muxed(), avoiding the need for the unmatched kfree(). Signed-off-by: Hans de Goede Reviewed-by: Andy Shevchenko Reviewed-by: Mario Limonciello Link: https://lore.kernel.org/r/20230711095920.264308-1-hdegoede@redhat.com --- drivers/platform/x86/amd/pmc-quirks.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/amd/pmc-quirks.c b/drivers/platform/x86/amd/pmc-quirks.c index 362e7c0097d7..ad702463a65d 100644 --- a/drivers/platform/x86/amd/pmc-quirks.c +++ b/drivers/platform/x86/amd/pmc-quirks.c @@ -11,7 +11,6 @@ #include #include #include -#include #include "pmc.h" @@ -135,12 +134,10 @@ static const struct dmi_system_id fwbug_list[] = { */ static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio) { - struct resource *res; void __iomem *addr; u8 val; - res = request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80"); - if (!res) + if (!request_mem_region_muxed(s2idle_bug_mmio, 1, "amd_pmc_pm80")) return; addr = ioremap(s2idle_bug_mmio, 1); @@ -152,8 +149,7 @@ static void amd_pmc_skip_nvme_smi_handler(u32 s2idle_bug_mmio) iounmap(addr); cleanup_resource: - release_resource(res); - kfree(res); + release_mem_region(s2idle_bug_mmio, 1); } void amd_pmc_process_restore_quirks(struct amd_pmc_dev *dev) -- cgit From 676b7c5ecab36274442887ceadd6dee8248a244f Mon Sep 17 00:00:00 2001 From: David Xu Date: Thu, 13 Jul 2023 21:35:28 +0800 Subject: platform/x86: serial-multi-instantiate: Auto detect IRQ resource for CSC3551 The current code assumes that the CSC3551(multiple cs35l41) always have its interrupt pin connected to GPIO thus the IRQ can be acquired with acpi_dev_gpio_irq_get. However on some newer laptop models this is no longer the case as they have the CSC3551's interrupt pin connected to APIC. This causes smi_i2c_probe to fail on these machines. To support these machines, a new macro IRQ_RESOURCE_AUTO was introduced for cs35l41 smi_node, and smi_get_irq function was modified so it tries to get GPIO irq resource first and if failed, tries to get APIC irq resource for cs35l41. This patch affects only the cs35l41's probing and brings no negative influence on machines that indeed have the cs35l41's interrupt pin connected to GPIO. Signed-off-by: David Xu Link: https://lore.kernel.org/r/SY4P282MB18350CD8288687B87FFD2243E037A@SY4P282MB1835.AUSP282.PROD.OUTLOOK.COM Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/serial-multi-instantiate.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/serial-multi-instantiate.c b/drivers/platform/x86/serial-multi-instantiate.c index f3dcbdd72fec..2c2abf69f049 100644 --- a/drivers/platform/x86/serial-multi-instantiate.c +++ b/drivers/platform/x86/serial-multi-instantiate.c @@ -21,6 +21,7 @@ #define IRQ_RESOURCE_NONE 0 #define IRQ_RESOURCE_GPIO 1 #define IRQ_RESOURCE_APIC 2 +#define IRQ_RESOURCE_AUTO 3 enum smi_bus_type { SMI_I2C, @@ -52,6 +53,18 @@ static int smi_get_irq(struct platform_device *pdev, struct acpi_device *adev, int ret; switch (inst->flags & IRQ_RESOURCE_TYPE) { + case IRQ_RESOURCE_AUTO: + ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); + if (ret > 0) { + dev_dbg(&pdev->dev, "Using gpio irq\n"); + break; + } + ret = platform_get_irq(pdev, inst->irq_idx); + if (ret > 0) { + dev_dbg(&pdev->dev, "Using platform irq\n"); + break; + } + break; case IRQ_RESOURCE_GPIO: ret = acpi_dev_gpio_irq_get(adev, inst->irq_idx); break; @@ -307,10 +320,10 @@ static const struct smi_node int3515_data = { static const struct smi_node cs35l41_hda = { .instances = { - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, - { "cs35l41-hda", IRQ_RESOURCE_GPIO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, + { "cs35l41-hda", IRQ_RESOURCE_AUTO, 0 }, {} }, .bus_type = SMI_AUTO_DETECT, -- cgit From 9171dfcda4f26dc6ebfd8d50137c5f294c2060ee Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 3 Jul 2023 13:29:13 +0200 Subject: cxl: fix CONFIG_FW_LOADER dependency When FW_LOADER is disabled, cxl fails to link: arm-linux-gnueabi-ld: drivers/cxl/core/memdev.o: in function `cxl_memdev_setup_fw_upload': memdev.c:(.text+0x90e): undefined reference to `firmware_upload_register' memdev.c:(.text+0x93c): undefined reference to `firmware_upload_unregister' In order to use the firmware_upload_register() function, both FW_LOADER and FW_UPLOAD have to be enabled, which is a bit confusing. In addition, the dependency is on the wrong symbol, as the caller is part of the cxl_core.ko module, not the cxl_mem.ko module. Fixes: 9521875bbe005 ("cxl: add a firmware update mechanism using the sysfs firmware loader") Signed-off-by: Arnd Bergmann Link: https://lore.kernel.org/r/20230703112928.332321-1-arnd@kernel.org Reviewed-by: Xiao Yang Reviewed-by: Dave Jiang Signed-off-by: Vishal Verma --- drivers/cxl/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cxl/Kconfig b/drivers/cxl/Kconfig index fcbf8295fde3..8ea1d340e438 100644 --- a/drivers/cxl/Kconfig +++ b/drivers/cxl/Kconfig @@ -2,6 +2,8 @@ menuconfig CXL_BUS tristate "CXL (Compute Express Link) Devices Support" depends on PCI + select FW_LOADER + select FW_UPLOAD select PCI_DOE help CXL is a bus that is electrically compatible with PCI Express, but @@ -82,7 +84,6 @@ config CXL_PMEM config CXL_MEM tristate "CXL: Memory Expansion" depends on CXL_PCI - select FW_UPLOAD default CXL_BUS help The CXL.mem protocol allows a device to act as a provider of "System -- cgit From 95c6bff72b02ca084be60c08503d563e506b733f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 3 Jul 2023 17:17:45 +0300 Subject: cxl/mem: Fix a double shift bug The CXL_FW_CANCEL macro is used with set/test_bit() so it should be a bit number and not the shifted value. The original code is the equivalent of using BIT(BIT(0)) so it's 0x2 instead of 0x1. This has no effect on runtime because it's done consistently and nothing else was using the 0x2 bit. Fixes: 9521875bbe00 ("cxl: add a firmware update mechanism using the sysfs firmware loader") Signed-off-by: Dan Carpenter Link: https://lore.kernel.org/r/a11b0c78-4717-4f4e-90be-f47f300d607c@moroto.mountain Reviewed-by: Vishal Verma Reviewed-by: Davidlohr Bueso Reviewed-by: Dave Jiang Signed-off-by: Vishal Verma --- drivers/cxl/cxlmem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cxl/cxlmem.h b/drivers/cxl/cxlmem.h index 79e99c873ca2..499113328586 100644 --- a/drivers/cxl/cxlmem.h +++ b/drivers/cxl/cxlmem.h @@ -323,7 +323,7 @@ struct cxl_mbox_activate_fw { /* FW state bits */ #define CXL_FW_STATE_BITS 32 -#define CXL_FW_CANCEL BIT(0) +#define CXL_FW_CANCEL 0 /** * struct cxl_fw_state - Firmware upload / activation state -- cgit From 7164360030ea43c0a309fcff1cd728648501dfb7 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 4 Jul 2023 09:36:39 -0700 Subject: drm/msm/adreno: Fix warn splat for devices without revn Recently, a WARN_ON() was introduced to ensure that revn is filled before adreno_is_aXYZ is called. This however doesn't work very well when revn is 0 by design (such as for A635). Cc: Konrad Dybcio Fixes: cc943f43ece7 ("drm/msm/adreno: warn if chip revn is verified before being set") Signed-off-by: Rob Clark Reviewed-by: Dmitry Baryshkov Tested-by: Abhinav Kumar # sc7280 Patchwork: https://patchwork.freedesktop.org/patch/545554/ --- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index d8c9e8cc3753..afbf9e5bd4bc 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -149,7 +149,8 @@ bool adreno_cmp_rev(struct adreno_rev rev1, struct adreno_rev rev2); static inline bool adreno_is_revn(const struct adreno_gpu *gpu, uint32_t revn) { - WARN_ON_ONCE(!gpu->revn); + /* revn can be zero, but if not is set at same time as info */ + WARN_ON_ONCE(!gpu->info); return gpu->revn == revn; } @@ -161,14 +162,16 @@ static inline bool adreno_has_gmu_wrapper(const struct adreno_gpu *gpu) static inline bool adreno_is_a2xx(const struct adreno_gpu *gpu) { - WARN_ON_ONCE(!gpu->revn); + /* revn can be zero, but if not is set at same time as info */ + WARN_ON_ONCE(!gpu->info); return (gpu->revn < 300); } static inline bool adreno_is_a20x(const struct adreno_gpu *gpu) { - WARN_ON_ONCE(!gpu->revn); + /* revn can be zero, but if not is set at same time as info */ + WARN_ON_ONCE(!gpu->info); return (gpu->revn < 210); } -- cgit From 317ab1b90e593eba5b65165e959991837f5593bf Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 4 Jul 2023 09:36:40 -0700 Subject: drm/msm/a690: Remove revn and name These fields are deprecated. But any userspace new enough to support a690 also knows how to identify the GPU based on chip-id. Signed-off-by: Rob Clark Reviewed-by: Dmitry Baryshkov Patchwork: https://patchwork.freedesktop.org/patch/545552/ --- drivers/gpu/drm/msm/adreno/adreno_device.c | 2 -- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 3 ++- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index cb94cfd137a8..ce8d0b2475bf 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -369,8 +369,6 @@ static const struct adreno_info gpulist[] = { .hwcg = a640_hwcg, }, { .rev = ADRENO_REV(6, 9, 0, ANY_ID), - .revn = 690, - .name = "A690", .fw = { [ADRENO_FW_SQE] = "a660_sqe.fw", [ADRENO_FW_GMU] = "a690_gmu.bin", diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index afbf9e5bd4bc..845019891ad1 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -310,7 +310,8 @@ static inline int adreno_is_a680(const struct adreno_gpu *gpu) static inline int adreno_is_a690(const struct adreno_gpu *gpu) { - return adreno_is_revn(gpu, 690); + /* The order of args is important here to handle ANY_ID correctly */ + return adreno_cmp_rev(ADRENO_REV(6, 9, 0, ANY_ID), gpu->rev); }; /* check for a615, a616, a618, a619 or any derivatives */ -- cgit From bd846ceee9c478d0397428f02696602ba5eb264a Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 11 Jul 2023 10:54:07 -0700 Subject: drm/msm/adreno: Fix snapshot BINDLESS_DATA size The incorrect size was causing "CP | AHB bus error" when snapshotting the GPU state on a6xx gen4 (a660 family). Closes: https://gitlab.freedesktop.org/drm/msm/-/issues/26 Signed-off-by: Rob Clark Reviewed-by: Akhil P Oommen Fixes: 1707add81551 ("drm/msm/a6xx: Add a6xx gpu state") Patchwork: https://patchwork.freedesktop.org/patch/546763/ --- drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h index 790f55e24533..e788ed72eb0d 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.h @@ -206,7 +206,7 @@ static const struct a6xx_shader_block { SHADER(A6XX_SP_LB_3_DATA, 0x800), SHADER(A6XX_SP_LB_4_DATA, 0x800), SHADER(A6XX_SP_LB_5_DATA, 0x200), - SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x2000), + SHADER(A6XX_SP_CB_BINDLESS_DATA, 0x800), SHADER(A6XX_SP_CB_LEGACY_DATA, 0x280), SHADER(A6XX_SP_UAV_DATA, 0x80), SHADER(A6XX_SP_INST_TAG, 0x80), -- cgit From 368da76be8df60e9228a41b7d46e7836a67158fd Mon Sep 17 00:00:00 2001 From: Ahmad Khalifa Date: Sat, 15 Jul 2023 15:58:31 +0100 Subject: hwmon: (nct6775) Fix register for nct6799 Datasheet and variable name point to 0xe6 Fixes: aee395bb1905 ("hwmon: (nct6755) Add support for NCT6799D") Signed-off-by: Ahmad Khalifa Link: https://lore.kernel.org/r/20230715145831.1304633-1-ahmad@khalifa.ws Signed-off-by: Guenter Roeck --- drivers/hwmon/nct6775-platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/nct6775-platform.c b/drivers/hwmon/nct6775-platform.c index ada867d6b98a..a409d7a0b813 100644 --- a/drivers/hwmon/nct6775-platform.c +++ b/drivers/hwmon/nct6775-platform.c @@ -586,7 +586,7 @@ nct6775_check_fan_inputs(struct nct6775_data *data, struct nct6775_sio_data *sio int creb; int cred; - cre6 = sio_data->sio_inb(sio_data, 0xe0); + cre6 = sio_data->sio_inb(sio_data, 0xe6); sio_data->sio_select(sio_data, NCT6775_LD_12); cre0 = sio_data->sio_inb(sio_data, 0xe0); -- cgit From a746b3689546da27125da9ccaea62b1dbaaf927c Mon Sep 17 00:00:00 2001 From: Aleksa Savic Date: Fri, 14 Jul 2023 14:07:11 +0200 Subject: hwmon: (aquacomputer_d5next) Fix incorrect PWM value readout Commit 662d20b3a5af ("hwmon: (aquacomputer_d5next) Add support for temperature sensor offsets") changed aqc_get_ctrl_val() to return the value through a parameter instead of through the return value, but didn't fix up a case that relied on the old behavior. Fix it to use the proper received value and not the return code. Fixes: 662d20b3a5af ("hwmon: (aquacomputer_d5next) Add support for temperature sensor offsets") Cc: stable@vger.kernel.org Signed-off-by: Aleksa Savic Link: https://lore.kernel.org/r/20230714120712.16721-1-savicaleksa83@gmail.com Signed-off-by: Guenter Roeck --- drivers/hwmon/aquacomputer_d5next.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/aquacomputer_d5next.c b/drivers/hwmon/aquacomputer_d5next.c index a981f7086114..a997dbcb563f 100644 --- a/drivers/hwmon/aquacomputer_d5next.c +++ b/drivers/hwmon/aquacomputer_d5next.c @@ -1027,7 +1027,7 @@ static int aqc_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, if (ret < 0) return ret; - *val = aqc_percent_to_pwm(ret); + *val = aqc_percent_to_pwm(*val); break; } break; -- cgit From 4984eb51453ff7eddee9e5ce816145be39c0ec5c Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Tue, 11 Jul 2023 12:52:51 -0500 Subject: RDMA/irdma: Add missing read barriers On code inspection, there are many instances in the driver where CEQE and AEQE fields written to by HW are read without guaranteeing that the polarity bit has been read and checked first. Add a read barrier to avoid reordering of loads on the CEQE/AEQE fields prior to checking the polarity bit. Fixes: 3f49d6842569 ("RDMA/irdma: Implement HW Admin Queue OPs") Signed-off-by: Shiraz Saleem Link: https://lore.kernel.org/r/20230711175253.1289-2-shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/irdma/ctrl.c | 9 ++++++++- drivers/infiniband/hw/irdma/puda.c | 6 ++++++ drivers/infiniband/hw/irdma/uk.c | 3 +++ 3 files changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c index d88c9184007e..c91439f428c7 100644 --- a/drivers/infiniband/hw/irdma/ctrl.c +++ b/drivers/infiniband/hw/irdma/ctrl.c @@ -3363,6 +3363,9 @@ int irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq, if (polarity != ccq->cq_uk.polarity) return -ENOENT; + /* Ensure CEQE contents are read after valid bit is checked */ + dma_rmb(); + get_64bit_val(cqe, 8, &qp_ctx); cqp = (struct irdma_sc_cqp *)(unsigned long)qp_ctx; info->error = (bool)FIELD_GET(IRDMA_CQ_ERROR, temp); @@ -4009,13 +4012,17 @@ int irdma_sc_get_next_aeqe(struct irdma_sc_aeq *aeq, u8 polarity; aeqe = IRDMA_GET_CURRENT_AEQ_ELEM(aeq); - get_64bit_val(aeqe, 0, &compl_ctx); get_64bit_val(aeqe, 8, &temp); polarity = (u8)FIELD_GET(IRDMA_AEQE_VALID, temp); if (aeq->polarity != polarity) return -ENOENT; + /* Ensure AEQE contents are read after valid bit is checked */ + dma_rmb(); + + get_64bit_val(aeqe, 0, &compl_ctx); + print_hex_dump_debug("WQE: AEQ_ENTRY WQE", DUMP_PREFIX_OFFSET, 16, 8, aeqe, 16, false); diff --git a/drivers/infiniband/hw/irdma/puda.c b/drivers/infiniband/hw/irdma/puda.c index 4ec9639f1bdb..562531712ea4 100644 --- a/drivers/infiniband/hw/irdma/puda.c +++ b/drivers/infiniband/hw/irdma/puda.c @@ -230,6 +230,9 @@ static int irdma_puda_poll_info(struct irdma_sc_cq *cq, if (valid_bit != cq_uk->polarity) return -ENOENT; + /* Ensure CQE contents are read after valid bit is checked */ + dma_rmb(); + if (cq->dev->hw_attrs.uk_attrs.hw_rev >= IRDMA_GEN_2) ext_valid = (bool)FIELD_GET(IRDMA_CQ_EXTCQE, qword3); @@ -243,6 +246,9 @@ static int irdma_puda_poll_info(struct irdma_sc_cq *cq, if (polarity != cq_uk->polarity) return -ENOENT; + /* Ensure ext CQE contents are read after ext valid bit is checked */ + dma_rmb(); + IRDMA_RING_MOVE_HEAD_NOCHECK(cq_uk->cq_ring); if (!IRDMA_RING_CURRENT_HEAD(cq_uk->cq_ring)) cq_uk->polarity = !cq_uk->polarity; diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c index dd428d915c17..ea2c07751245 100644 --- a/drivers/infiniband/hw/irdma/uk.c +++ b/drivers/infiniband/hw/irdma/uk.c @@ -1527,6 +1527,9 @@ void irdma_uk_clean_cq(void *q, struct irdma_cq_uk *cq) if (polarity != temp) break; + /* Ensure CQE contents are read after valid bit is checked */ + dma_rmb(); + get_64bit_val(cqe, 8, &comp_ctx); if ((void *)(unsigned long)comp_ctx == q) set_64bit_val(cqe, 8, 0); -- cgit From f2c3037811381f9149243828c7eb9a1631df9f9c Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Tue, 11 Jul 2023 12:52:52 -0500 Subject: RDMA/irdma: Fix data race on CQP completion stats CQP completion statistics is read lockesly in irdma_wait_event and irdma_check_cqp_progress while it can be updated in the completion thread irdma_sc_ccq_get_cqe_info on another CPU as KCSAN reports. Make completion statistics an atomic variable to reflect coherent updates to it. This will also avoid load/store tearing logic bug potentially possible by compiler optimizations. [77346.170861] BUG: KCSAN: data-race in irdma_handle_cqp_op [irdma] / irdma_sc_ccq_get_cqe_info [irdma] [77346.171383] write to 0xffff8a3250b108e0 of 8 bytes by task 9544 on cpu 4: [77346.171483] irdma_sc_ccq_get_cqe_info+0x27a/0x370 [irdma] [77346.171658] irdma_cqp_ce_handler+0x164/0x270 [irdma] [77346.171835] cqp_compl_worker+0x1b/0x20 [irdma] [77346.172009] process_one_work+0x4d1/0xa40 [77346.172024] worker_thread+0x319/0x700 [77346.172037] kthread+0x180/0x1b0 [77346.172054] ret_from_fork+0x22/0x30 [77346.172136] read to 0xffff8a3250b108e0 of 8 bytes by task 9838 on cpu 2: [77346.172234] irdma_handle_cqp_op+0xf4/0x4b0 [irdma] [77346.172413] irdma_cqp_aeq_cmd+0x75/0xa0 [irdma] [77346.172592] irdma_create_aeq+0x390/0x45a [irdma] [77346.172769] irdma_rt_init_hw.cold+0x212/0x85d [irdma] [77346.172944] irdma_probe+0x54f/0x620 [irdma] [77346.173122] auxiliary_bus_probe+0x66/0xa0 [77346.173137] really_probe+0x140/0x540 [77346.173154] __driver_probe_device+0xc7/0x220 [77346.173173] driver_probe_device+0x5f/0x140 [77346.173190] __driver_attach+0xf0/0x2c0 [77346.173208] bus_for_each_dev+0xa8/0xf0 [77346.173225] driver_attach+0x29/0x30 [77346.173240] bus_add_driver+0x29c/0x2f0 [77346.173255] driver_register+0x10f/0x1a0 [77346.173272] __auxiliary_driver_register+0xbc/0x140 [77346.173287] irdma_init_module+0x55/0x1000 [irdma] [77346.173460] do_one_initcall+0x7d/0x410 [77346.173475] do_init_module+0x81/0x2c0 [77346.173491] load_module+0x1232/0x12c0 [77346.173506] __do_sys_finit_module+0x101/0x180 [77346.173522] __x64_sys_finit_module+0x3c/0x50 [77346.173538] do_syscall_64+0x39/0x90 [77346.173553] entry_SYSCALL_64_after_hwframe+0x63/0xcd [77346.173634] value changed: 0x0000000000000094 -> 0x0000000000000095 Fixes: 915cc7ac0f8e ("RDMA/irdma: Add miscellaneous utility definitions") Signed-off-by: Shiraz Saleem Link: https://lore.kernel.org/r/20230711175253.1289-3-shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/irdma/ctrl.c | 22 +++++++++--------- drivers/infiniband/hw/irdma/defs.h | 46 ++++++++++++++++++------------------- drivers/infiniband/hw/irdma/type.h | 2 ++ drivers/infiniband/hw/irdma/utils.c | 2 +- 4 files changed, 36 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c index c91439f428c7..45e3344daa04 100644 --- a/drivers/infiniband/hw/irdma/ctrl.c +++ b/drivers/infiniband/hw/irdma/ctrl.c @@ -2712,13 +2712,13 @@ static int irdma_sc_cq_modify(struct irdma_sc_cq *cq, */ void irdma_check_cqp_progress(struct irdma_cqp_timeout *timeout, struct irdma_sc_dev *dev) { - if (timeout->compl_cqp_cmds != dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]) { - timeout->compl_cqp_cmds = dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]; + u64 completed_ops = atomic64_read(&dev->cqp->completed_ops); + + if (timeout->compl_cqp_cmds != completed_ops) { + timeout->compl_cqp_cmds = completed_ops; timeout->count = 0; - } else { - if (dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS] != - timeout->compl_cqp_cmds) - timeout->count++; + } else if (timeout->compl_cqp_cmds != dev->cqp->requested_ops) { + timeout->count++; } } @@ -2761,7 +2761,7 @@ static int irdma_cqp_poll_registers(struct irdma_sc_cqp *cqp, u32 tail, if (newtail != tail) { /* SUCCESS */ IRDMA_RING_MOVE_TAIL(cqp->sq_ring); - cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]++; + atomic64_inc(&cqp->completed_ops); return 0; } udelay(cqp->dev->hw_attrs.max_sleep_count); @@ -3121,8 +3121,8 @@ int irdma_sc_cqp_init(struct irdma_sc_cqp *cqp, info->dev->cqp = cqp; IRDMA_RING_INIT(cqp->sq_ring, cqp->sq_size); - cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS] = 0; - cqp->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS] = 0; + cqp->requested_ops = 0; + atomic64_set(&cqp->completed_ops, 0); /* for the cqp commands backlog. */ INIT_LIST_HEAD(&cqp->dev->cqp_cmd_head); @@ -3274,7 +3274,7 @@ __le64 *irdma_sc_cqp_get_next_send_wqe_idx(struct irdma_sc_cqp *cqp, u64 scratch if (ret_code) return NULL; - cqp->dev->cqp_cmd_stats[IRDMA_OP_REQ_CMDS]++; + cqp->requested_ops++; if (!*wqe_idx) cqp->polarity = !cqp->polarity; wqe = cqp->sq_base[*wqe_idx].elem; @@ -3400,7 +3400,7 @@ int irdma_sc_ccq_get_cqe_info(struct irdma_sc_cq *ccq, dma_wmb(); /* make sure shadow area is updated before moving tail */ IRDMA_RING_MOVE_TAIL(cqp->sq_ring); - ccq->dev->cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]++; + atomic64_inc(&cqp->completed_ops); return ret_code; } diff --git a/drivers/infiniband/hw/irdma/defs.h b/drivers/infiniband/hw/irdma/defs.h index 6014b9d06a9b..d06e45d2c23f 100644 --- a/drivers/infiniband/hw/irdma/defs.h +++ b/drivers/infiniband/hw/irdma/defs.h @@ -191,32 +191,30 @@ enum irdma_cqp_op_type { IRDMA_OP_MANAGE_VF_PBLE_BP = 25, IRDMA_OP_QUERY_FPM_VAL = 26, IRDMA_OP_COMMIT_FPM_VAL = 27, - IRDMA_OP_REQ_CMDS = 28, - IRDMA_OP_CMPL_CMDS = 29, - IRDMA_OP_AH_CREATE = 30, - IRDMA_OP_AH_MODIFY = 31, - IRDMA_OP_AH_DESTROY = 32, - IRDMA_OP_MC_CREATE = 33, - IRDMA_OP_MC_DESTROY = 34, - IRDMA_OP_MC_MODIFY = 35, - IRDMA_OP_STATS_ALLOCATE = 36, - IRDMA_OP_STATS_FREE = 37, - IRDMA_OP_STATS_GATHER = 38, - IRDMA_OP_WS_ADD_NODE = 39, - IRDMA_OP_WS_MODIFY_NODE = 40, - IRDMA_OP_WS_DELETE_NODE = 41, - IRDMA_OP_WS_FAILOVER_START = 42, - IRDMA_OP_WS_FAILOVER_COMPLETE = 43, - IRDMA_OP_SET_UP_MAP = 44, - IRDMA_OP_GEN_AE = 45, - IRDMA_OP_QUERY_RDMA_FEATURES = 46, - IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY = 47, - IRDMA_OP_ADD_LOCAL_MAC_ENTRY = 48, - IRDMA_OP_DELETE_LOCAL_MAC_ENTRY = 49, - IRDMA_OP_CQ_MODIFY = 50, + IRDMA_OP_AH_CREATE = 28, + IRDMA_OP_AH_MODIFY = 29, + IRDMA_OP_AH_DESTROY = 30, + IRDMA_OP_MC_CREATE = 31, + IRDMA_OP_MC_DESTROY = 32, + IRDMA_OP_MC_MODIFY = 33, + IRDMA_OP_STATS_ALLOCATE = 34, + IRDMA_OP_STATS_FREE = 35, + IRDMA_OP_STATS_GATHER = 36, + IRDMA_OP_WS_ADD_NODE = 37, + IRDMA_OP_WS_MODIFY_NODE = 38, + IRDMA_OP_WS_DELETE_NODE = 39, + IRDMA_OP_WS_FAILOVER_START = 40, + IRDMA_OP_WS_FAILOVER_COMPLETE = 41, + IRDMA_OP_SET_UP_MAP = 42, + IRDMA_OP_GEN_AE = 43, + IRDMA_OP_QUERY_RDMA_FEATURES = 44, + IRDMA_OP_ALLOC_LOCAL_MAC_ENTRY = 45, + IRDMA_OP_ADD_LOCAL_MAC_ENTRY = 46, + IRDMA_OP_DELETE_LOCAL_MAC_ENTRY = 47, + IRDMA_OP_CQ_MODIFY = 48, /* Must be last entry*/ - IRDMA_MAX_CQP_OPS = 51, + IRDMA_MAX_CQP_OPS = 49, }; /* CQP SQ WQES */ diff --git a/drivers/infiniband/hw/irdma/type.h b/drivers/infiniband/hw/irdma/type.h index 5ee68604e59f..a20709577ab0 100644 --- a/drivers/infiniband/hw/irdma/type.h +++ b/drivers/infiniband/hw/irdma/type.h @@ -365,6 +365,8 @@ struct irdma_sc_cqp { struct irdma_dcqcn_cc_params dcqcn_params; __le64 *host_ctx; u64 *scratch_array; + u64 requested_ops; + atomic64_t completed_ops; u32 cqp_id; u32 sq_size; u32 hw_sq_size; diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c index 71e1c5d34709..775a79946f7d 100644 --- a/drivers/infiniband/hw/irdma/utils.c +++ b/drivers/infiniband/hw/irdma/utils.c @@ -567,7 +567,7 @@ static int irdma_wait_event(struct irdma_pci_f *rf, bool cqp_error = false; int err_code = 0; - cqp_timeout.compl_cqp_cmds = rf->sc_dev.cqp_cmd_stats[IRDMA_OP_CMPL_CMDS]; + cqp_timeout.compl_cqp_cmds = atomic64_read(&rf->sc_dev.cqp->completed_ops); do { irdma_cqp_ce_handler(rf, &rf->ccq.sc_cq); if (wait_event_timeout(cqp_request->waitq, -- cgit From f0842bb3d38863777e3454da5653d80b5fde6321 Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Tue, 11 Jul 2023 12:52:53 -0500 Subject: RDMA/irdma: Fix data race on CQP request done KCSAN detects a data race on cqp_request->request_done memory location which is accessed locklessly in irdma_handle_cqp_op while being updated in irdma_cqp_ce_handler. Annotate lockless intent with READ_ONCE/WRITE_ONCE to avoid any compiler optimizations like load fusing and/or KCSAN warning. [222808.417128] BUG: KCSAN: data-race in irdma_cqp_ce_handler [irdma] / irdma_wait_event [irdma] [222808.417532] write to 0xffff8e44107019dc of 1 bytes by task 29658 on cpu 5: [222808.417610] irdma_cqp_ce_handler+0x21e/0x270 [irdma] [222808.417725] cqp_compl_worker+0x1b/0x20 [irdma] [222808.417827] process_one_work+0x4d1/0xa40 [222808.417835] worker_thread+0x319/0x700 [222808.417842] kthread+0x180/0x1b0 [222808.417852] ret_from_fork+0x22/0x30 [222808.417918] read to 0xffff8e44107019dc of 1 bytes by task 29688 on cpu 1: [222808.417995] irdma_wait_event+0x1e2/0x2c0 [irdma] [222808.418099] irdma_handle_cqp_op+0xae/0x170 [irdma] [222808.418202] irdma_cqp_cq_destroy_cmd+0x70/0x90 [irdma] [222808.418308] irdma_puda_dele_rsrc+0x46d/0x4d0 [irdma] [222808.418411] irdma_rt_deinit_hw+0x179/0x1d0 [irdma] [222808.418514] irdma_ib_dealloc_device+0x11/0x40 [irdma] [222808.418618] ib_dealloc_device+0x2a/0x120 [ib_core] [222808.418823] __ib_unregister_device+0xde/0x100 [ib_core] [222808.418981] ib_unregister_device+0x22/0x40 [ib_core] [222808.419142] irdma_ib_unregister_device+0x70/0x90 [irdma] [222808.419248] i40iw_close+0x6f/0xc0 [irdma] [222808.419352] i40e_client_device_unregister+0x14a/0x180 [i40e] [222808.419450] i40iw_remove+0x21/0x30 [irdma] [222808.419554] auxiliary_bus_remove+0x31/0x50 [222808.419563] device_remove+0x69/0xb0 [222808.419572] device_release_driver_internal+0x293/0x360 [222808.419582] driver_detach+0x7c/0xf0 [222808.419592] bus_remove_driver+0x8c/0x150 [222808.419600] driver_unregister+0x45/0x70 [222808.419610] auxiliary_driver_unregister+0x16/0x30 [222808.419618] irdma_exit_module+0x18/0x1e [irdma] [222808.419733] __do_sys_delete_module.constprop.0+0x1e2/0x310 [222808.419745] __x64_sys_delete_module+0x1b/0x30 [222808.419755] do_syscall_64+0x39/0x90 [222808.419763] entry_SYSCALL_64_after_hwframe+0x63/0xcd [222808.419829] value changed: 0x01 -> 0x03 Fixes: 915cc7ac0f8e ("RDMA/irdma: Add miscellaneous utility definitions") Signed-off-by: Shiraz Saleem Link: https://lore.kernel.org/r/20230711175253.1289-4-shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/irdma/hw.c | 2 +- drivers/infiniband/hw/irdma/main.h | 2 +- drivers/infiniband/hw/irdma/utils.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c index 795f7fd4f257..1cfc03da89e7 100644 --- a/drivers/infiniband/hw/irdma/hw.c +++ b/drivers/infiniband/hw/irdma/hw.c @@ -2075,7 +2075,7 @@ void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq) cqp_request->compl_info.error = info.error; if (cqp_request->waiting) { - cqp_request->request_done = true; + WRITE_ONCE(cqp_request->request_done, true); wake_up(&cqp_request->waitq); irdma_put_cqp_request(&rf->cqp, cqp_request); } else { diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h index def6dd58dcd4..2323962cdeac 100644 --- a/drivers/infiniband/hw/irdma/main.h +++ b/drivers/infiniband/hw/irdma/main.h @@ -161,8 +161,8 @@ struct irdma_cqp_request { void (*callback_fcn)(struct irdma_cqp_request *cqp_request); void *param; struct irdma_cqp_compl_info compl_info; + bool request_done; /* READ/WRITE_ONCE macros operate on it */ bool waiting:1; - bool request_done:1; bool dynamic:1; }; diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c index 775a79946f7d..eb083f70b09f 100644 --- a/drivers/infiniband/hw/irdma/utils.c +++ b/drivers/infiniband/hw/irdma/utils.c @@ -481,7 +481,7 @@ void irdma_free_cqp_request(struct irdma_cqp *cqp, if (cqp_request->dynamic) { kfree(cqp_request); } else { - cqp_request->request_done = false; + WRITE_ONCE(cqp_request->request_done, false); cqp_request->callback_fcn = NULL; cqp_request->waiting = false; @@ -515,7 +515,7 @@ irdma_free_pending_cqp_request(struct irdma_cqp *cqp, { if (cqp_request->waiting) { cqp_request->compl_info.error = true; - cqp_request->request_done = true; + WRITE_ONCE(cqp_request->request_done, true); wake_up(&cqp_request->waitq); } wait_event_timeout(cqp->remove_wq, @@ -571,7 +571,7 @@ static int irdma_wait_event(struct irdma_pci_f *rf, do { irdma_cqp_ce_handler(rf, &rf->ccq.sc_cq); if (wait_event_timeout(cqp_request->waitq, - cqp_request->request_done, + READ_ONCE(cqp_request->request_done), msecs_to_jiffies(CQP_COMPL_WAIT_TIME_MS))) break; -- cgit From 0e15863015d97c1ee2cc29d599abcc7fa2dc3e95 Mon Sep 17 00:00:00 2001 From: Shiraz Saleem Date: Wed, 12 Jul 2023 18:41:33 -0500 Subject: RDMA/core: Update CMA destination address on rdma_resolve_addr 8d037973d48c ("RDMA/core: Refactor rdma_bind_addr") intoduces as regression on irdma devices on certain tests which uses rdma CM, such as cmtime. No connections can be established with the MAD QP experiences a fatal error on the active side. The cma destination address is not updated with the dst_addr when ULP on active side calls rdma_bind_addr followed by rdma_resolve_addr. The id_priv state is 'bound' in resolve_prepare_src and update is skipped. This leaves the dgid passed into irdma driver to create an Address Handle (AH) for the MAD QP at 0. The create AH descriptor as well as the ARP cache entry is invalid and HW throws an asynchronous events as result. [ 1207.656888] resolve_prepare_src caller: ucma_resolve_addr+0xff/0x170 [rdma_ucm] daddr=200.0.4.28 id_priv->state=7 [....] [ 1207.680362] ice 0000:07:00.1 rocep7s0f1: caller: irdma_create_ah+0x3e/0x70 [irdma] ah_id=0 arp_idx=0 dest_ip=0.0.0.0 destMAC=00:00:64:ca:b7:52 ipvalid=1 raw=0000:0000:0000:0000:0000:ffff:0000:0000 [ 1207.682077] ice 0000:07:00.1 rocep7s0f1: abnormal ae_id = 0x401 bool qp=1 qp_id = 1, ae_src=5 [ 1207.691657] infiniband rocep7s0f1: Fatal error (1) on MAD QP (1) Fix this by updating the CMA destination address when the ULP calls a resolve address with the CM state already bound. Fixes: 8d037973d48c ("RDMA/core: Refactor rdma_bind_addr") Signed-off-by: Shiraz Saleem Link: https://lore.kernel.org/r/20230712234133.1343-1-shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/core/cma.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 1ee87c3aaeab..9891c7dc2af5 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -4062,6 +4062,8 @@ static int resolve_prepare_src(struct rdma_id_private *id_priv, RDMA_CM_ADDR_QUERY))) return -EINVAL; + } else { + memcpy(cma_dst_addr(id_priv), dst_addr, rdma_addr_size(dst_addr)); } if (cma_family(id_priv) != dst_addr->sa_family) { -- cgit From dc52aadbc1849cbe3fcf6bc54d35f6baa396e0a1 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Thu, 13 Jul 2023 16:16:58 +0200 Subject: RDMA/mthca: Fix crash when polling CQ for shared QPs Commit 21c2fe94abb2 ("RDMA/mthca: Combine special QP struct with mthca QP") introduced a new struct mthca_sqp which doesn't contain struct mthca_qp any longer. Placing a pointer of this new struct into qptable leads to crashes, because mthca_poll_one() expects a qp pointer. Fix this by putting the correct pointer into qptable. Fixes: 21c2fe94abb2 ("RDMA/mthca: Combine special QP struct with mthca QP") Signed-off-by: Thomas Bogendoerfer Link: https://lore.kernel.org/r/20230713141658.9426-1-tbogendoerfer@suse.de Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/mthca/mthca_qp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 69bba0ef4a5d..53f43649f7d0 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c @@ -1393,7 +1393,7 @@ int mthca_alloc_sqp(struct mthca_dev *dev, if (mthca_array_get(&dev->qp_table.qp, mqpn)) err = -EBUSY; else - mthca_array_set(&dev->qp_table.qp, mqpn, qp->sqp); + mthca_array_set(&dev->qp_table.qp, mqpn, qp); spin_unlock_irq(&dev->qp_table.lock); if (err) -- cgit From b5bbc6551297447d3cca55cf907079e206e9cd82 Mon Sep 17 00:00:00 2001 From: Kashyap Desai Date: Fri, 14 Jul 2023 01:22:48 -0700 Subject: RDMA/bnxt_re: Prevent handling any completions after qp destroy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit HW may generate completions that indicates QP is destroyed. Driver should not be scheduling any more completion handlers for this QP, after the QP is destroyed. Since CQs are active during the QP destroy, driver may still schedule completion handlers. This can cause a race where the destroy_cq and poll_cq running simultaneously. Snippet of kernel panic while doing bnxt_re driver load unload in loop. This indicates a poll after the CQ is freed.  [77786.481636] Call Trace: [77786.481640]   [77786.481644]  bnxt_re_poll_cq+0x14a/0x620 [bnxt_re] [77786.481658]  ? kvm_clock_read+0x14/0x30 [77786.481693]  __ib_process_cq+0x57/0x190 [ib_core] [77786.481728]  ib_cq_poll_work+0x26/0x80 [ib_core] [77786.481761]  process_one_work+0x1e5/0x3f0 [77786.481768]  worker_thread+0x50/0x3a0 [77786.481785]  ? __pfx_worker_thread+0x10/0x10 [77786.481790]  kthread+0xe2/0x110 [77786.481794]  ? __pfx_kthread+0x10/0x10 [77786.481797]  ret_from_fork+0x2c/0x50 To avoid this, complete all completion handlers before returning the destroy QP. If free_cq is called soon after destroy_qp, IB stack will cancel the CQ work before invoking the destroy_cq verb and this will prevent any race mentioned. Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Signed-off-by: Kashyap Desai Signed-off-by: Selvin Xavier Link: https://lore.kernel.org/r/1689322969-25402-2-git-send-email-selvin.xavier@broadcom.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 12 ++++++++++++ drivers/infiniband/hw/bnxt_re/qplib_fp.c | 18 ++++++++++++++++++ drivers/infiniband/hw/bnxt_re/qplib_fp.h | 1 + 3 files changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index abef0b8baa7c..03cc45a5458d 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c @@ -869,7 +869,10 @@ fail: int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) { struct bnxt_re_qp *qp = container_of(ib_qp, struct bnxt_re_qp, ib_qp); + struct bnxt_qplib_qp *qplib_qp = &qp->qplib_qp; struct bnxt_re_dev *rdev = qp->rdev; + struct bnxt_qplib_nq *scq_nq = NULL; + struct bnxt_qplib_nq *rcq_nq = NULL; unsigned int flags; int rc; @@ -903,6 +906,15 @@ int bnxt_re_destroy_qp(struct ib_qp *ib_qp, struct ib_udata *udata) ib_umem_release(qp->rumem); ib_umem_release(qp->sumem); + /* Flush all the entries of notification queue associated with + * given qp. + */ + scq_nq = qplib_qp->scq->nq; + rcq_nq = qplib_qp->rcq->nq; + bnxt_re_synchronize_nq(scq_nq); + if (scq_nq != rcq_nq) + bnxt_re_synchronize_nq(rcq_nq); + return 0; } diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index 91aed77ce40d..a12c7ade101a 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -381,6 +381,24 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t) spin_unlock_bh(&hwq->lock); } +/* bnxt_re_synchronize_nq - self polling notification queue. + * @nq - notification queue pointer + * + * This function will start polling entries of a given notification queue + * for all pending entries. + * This function is useful to synchronize notification entries while resources + * are going away. + */ + +void bnxt_re_synchronize_nq(struct bnxt_qplib_nq *nq) +{ + int budget = nq->budget; + + nq->budget = nq->hwq.max_elements; + bnxt_qplib_service_nq(&nq->nq_tasklet); + nq->budget = budget; +} + static irqreturn_t bnxt_qplib_nq_irq(int irq, void *dev_instance) { struct bnxt_qplib_nq *nq = dev_instance; diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.h b/drivers/infiniband/hw/bnxt_re/qplib_fp.h index a42820821c47..404b851091ca 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.h +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.h @@ -553,6 +553,7 @@ int bnxt_qplib_process_flush_list(struct bnxt_qplib_cq *cq, struct bnxt_qplib_cqe *cqe, int num_cqes); void bnxt_qplib_flush_cqn_wq(struct bnxt_qplib_qp *qp); +void bnxt_re_synchronize_nq(struct bnxt_qplib_nq *nq); static inline void *bnxt_qplib_get_swqe(struct bnxt_qplib_q *que, u32 *swq_idx) { -- cgit From 29900bf351e1a7e4643da5c3c3cd9df75c577b88 Mon Sep 17 00:00:00 2001 From: Selvin Xavier Date: Fri, 14 Jul 2023 01:22:49 -0700 Subject: RDMA/bnxt_re: Fix hang during driver unload Driver unload hits a hang during stress testing of load/unload. stack trace snippet - tasklet_kill at ffffffff9aabb8b2 bnxt_qplib_nq_stop_irq at ffffffffc0a805fb [bnxt_re] bnxt_qplib_disable_nq at ffffffffc0a80c5b [bnxt_re] bnxt_re_dev_uninit at ffffffffc0a67d15 [bnxt_re] bnxt_re_remove_device at ffffffffc0a6af1d [bnxt_re] tasklet_kill can hang if the tasklet is scheduled after it is disabled. Modified the sequences to disable the interrupt first and synchronize irq before disabling the tasklet. Fixes: 1ac5a4047975 ("RDMA/bnxt_re: Add bnxt_re RoCE driver") Signed-off-by: Kashyap Desai Signed-off-by: Selvin Xavier Link: https://lore.kernel.org/r/1689322969-25402-3-git-send-email-selvin.xavier@broadcom.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 10 +++++----- drivers/infiniband/hw/bnxt_re/qplib_rcfw.c | 9 ++++----- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index a12c7ade101a..a42555623aed 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -420,19 +420,19 @@ void bnxt_qplib_nq_stop_irq(struct bnxt_qplib_nq *nq, bool kill) if (!nq->requested) return; - tasklet_disable(&nq->nq_tasklet); + nq->requested = false; /* Mask h/w interrupt */ bnxt_qplib_ring_nq_db(&nq->nq_db.dbinfo, nq->res->cctx, false); /* Sync with last running IRQ handler */ synchronize_irq(nq->msix_vec); - if (kill) - tasklet_kill(&nq->nq_tasklet); - irq_set_affinity_hint(nq->msix_vec, NULL); free_irq(nq->msix_vec, nq); kfree(nq->name); nq->name = NULL; - nq->requested = false; + + if (kill) + tasklet_kill(&nq->nq_tasklet); + tasklet_disable(&nq->nq_tasklet); } void bnxt_qplib_disable_nq(struct bnxt_qplib_nq *nq) diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index b30e66b64827..bc3aea4592b9 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -989,19 +989,18 @@ void bnxt_qplib_rcfw_stop_irq(struct bnxt_qplib_rcfw *rcfw, bool kill) if (!creq->requested) return; - tasklet_disable(&creq->creq_tasklet); + creq->requested = false; /* Mask h/w interrupts */ bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, rcfw->res->cctx, false); /* Sync with last running IRQ-handler */ synchronize_irq(creq->msix_vec); - if (kill) - tasklet_kill(&creq->creq_tasklet); - free_irq(creq->msix_vec, rcfw); kfree(creq->irq_name); creq->irq_name = NULL; - creq->requested = false; atomic_set(&rcfw->rcfw_intr_enabled, 0); + if (kill) + tasklet_kill(&creq->creq_tasklet); + tasklet_disable(&creq->creq_tasklet); } void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw) -- cgit From 6e8a996563ecbe68e49c49abd4aaeef69f11f2dc Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Mon, 17 Jul 2023 09:47:38 +0800 Subject: drm/msm: Fix IS_ERR_OR_NULL() vs NULL check in a5xx_submit_in_rb() The msm_gem_get_vaddr() returns an ERR_PTR() on failure, and a null is catastrophic here, so we should use IS_ERR_OR_NULL() to check the return value. Fixes: 6a8bd08d0465 ("drm/msm: add sudo flag to submit ioctl") Signed-off-by: Gaosheng Cui Reviewed-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar Reviewed-by: Akhil P Oommen Patchwork: https://patchwork.freedesktop.org/patch/547712/ Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index a99310b68793..bbb1bf33f98e 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -89,7 +89,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit * since we've already mapped it once in * submit_reloc() */ - if (WARN_ON(!ptr)) + if (WARN_ON(IS_ERR_OR_NULL(ptr))) return; for (i = 0; i < dwords; i++) { -- cgit From 1cd0787f082e1a179f2b6e749d08daff1a9f6b1b Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 12 Jul 2023 15:25:23 -0700 Subject: drm/msm: Fix hw_fence error path cleanup In an error path where the submit is free'd without the job being run, the hw_fence pointer is simply a kzalloc'd block of memory. In this case we should just kfree() it, rather than trying to decrement it's reference count. Fortunately we can tell that this is the case by checking for a zero refcount, since if the job was run, the submit would be holding a reference to the hw_fence. Fixes: f94e6a51e17c ("drm/msm: Pre-allocate hw_fence") Signed-off-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/547088/ --- drivers/gpu/drm/msm/msm_fence.c | 6 ++++++ drivers/gpu/drm/msm/msm_gem_submit.c | 14 +++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index 96599ec3eb78..1a5d4f1c8b42 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -191,6 +191,12 @@ msm_fence_init(struct dma_fence *fence, struct msm_fence_context *fctx) f->fctx = fctx; + /* + * Until this point, the fence was just some pre-allocated memory, + * no-one should have taken a reference to it yet. + */ + WARN_ON(kref_read(&fence->refcount)); + dma_fence_init(&f->base, &msm_fence_ops, &fctx->spinlock, fctx->context, ++fctx->last_fence); } diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 3f1aa4de3b87..9d66498cdc04 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -86,7 +86,19 @@ void __msm_gem_submit_destroy(struct kref *kref) } dma_fence_put(submit->user_fence); - dma_fence_put(submit->hw_fence); + + /* + * If the submit is freed before msm_job_run(), then hw_fence is + * just some pre-allocated memory, not a reference counted fence. + * Once the job runs and the hw_fence is initialized, it will + * have a refcount of at least one, since the submit holds a ref + * to the hw_fence. + */ + if (kref_read(&submit->hw_fence->refcount) == 0) { + kfree(submit->hw_fence); + } else { + dma_fence_put(submit->hw_fence); + } put_pid(submit->pid); msm_submitqueue_put(submit->queue); -- cgit From 5c719d7aef298e9b727f39b45e88528a96df3620 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 17 Jul 2023 21:55:56 +0200 Subject: RDMA/rxe: Fix an error handling path in rxe_bind_mw() All errors go to the error handling path, except this one. Be consistent and also branch to it. Fixes: 02ed253770fb ("RDMA/rxe: Introduce rxe access supported flags") Signed-off-by: Christophe JAILLET Link: https://lore.kernel.org/r/43698d8a3ed4e720899eadac887427f73d7ec2eb.1689623735.git.christophe.jaillet@wanadoo.fr Reviewed-by: Bob Pearson Acked-by: Zhu Yanjun Signed-off-by: Leon Romanovsky --- drivers/infiniband/sw/rxe/rxe_mw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/sw/rxe/rxe_mw.c b/drivers/infiniband/sw/rxe/rxe_mw.c index d8a43d87de93..d9312b5c9d20 100644 --- a/drivers/infiniband/sw/rxe/rxe_mw.c +++ b/drivers/infiniband/sw/rxe/rxe_mw.c @@ -199,7 +199,8 @@ int rxe_bind_mw(struct rxe_qp *qp, struct rxe_send_wqe *wqe) if (access & ~RXE_ACCESS_SUPPORTED_MW) { rxe_err_mw(mw, "access %#x not supported", access); - return -EOPNOTSUPP; + ret = -EOPNOTSUPP; + goto err_drop_mr; } spin_lock_bh(&mw->lock); -- cgit From 4cf67d3cc9994a59cf77bb9c0ccf9007fe916afe Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Fri, 14 Jul 2023 02:31:45 -0700 Subject: cxl/acpi: Fix a use-after-free in cxl_parse_cfmws() KASAN and KFENCE detected an user-after-free in the CXL driver. This happens in the cxl_decoder_add() fail path. KASAN prints the following error: BUG: KASAN: slab-use-after-free in cxl_parse_cfmws (drivers/cxl/acpi.c:299) This happens in cxl_parse_cfmws(), where put_device() is called, releasing cxld, which is accessed later. Use the local variables in the dev_err() instead of pointing to the released memory. Since the dev_err() is printing a resource, change the open coded print format to use the %pr format specifier. Fixes: e50fe01e1f2a ("cxl/core: Drop ->platform_res attribute for root decoders") Signed-off-by: Breno Leitao Link: https://lore.kernel.org/r/20230714093146.2253438-1-leitao@debian.org Reviewed-by: Alison Schofield Reviewed-by: Dave Jiang Reviewed-by: Jonathan Cameron Signed-off-by: Vishal Verma --- drivers/cxl/acpi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index 658e6b84a769..33c073f0d7fe 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -296,8 +296,7 @@ err_xormap: else rc = cxl_decoder_autoremove(dev, cxld); if (rc) { - dev_err(dev, "Failed to add decode range [%#llx - %#llx]\n", - cxld->hpa_range.start, cxld->hpa_range.end); + dev_err(dev, "Failed to add decode range: %pr", res); return 0; } dev_dbg(dev, "add: %s node: %d range [%#llx - %#llx]\n", -- cgit From 91019b5bc7c2c5e6f676cce80ee6d12b2753d018 Mon Sep 17 00:00:00 2001 From: Breno Leitao Date: Fri, 14 Jul 2023 02:31:46 -0700 Subject: cxl/acpi: Return 'rc' instead of '0' in cxl_parse_cfmws() Driver initialization returned success (return 0) even if the initialization (cxl_decoder_add() or acpi_table_parse_cedt()) failed. Return the error instead of swallowing it. Fixes: f4ce1f766f1e ("cxl/acpi: Convert CFMWS parsing to ACPI sub-table helpers") Signed-off-by: Breno Leitao Link: https://lore.kernel.org/r/20230714093146.2253438-2-leitao@debian.org Reviewed-by: Alison Schofield Signed-off-by: Vishal Verma --- drivers/cxl/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index 33c073f0d7fe..d1c559879dcc 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -297,7 +297,7 @@ err_xormap: rc = cxl_decoder_autoremove(dev, cxld); if (rc) { dev_err(dev, "Failed to add decode range: %pr", res); - return 0; + return rc; } dev_dbg(dev, "add: %s node: %d range [%#llx - %#llx]\n", dev_name(&cxld->dev), -- cgit From 957961b6dcc813e6222a4f7e8e3626fcd1f1e098 Mon Sep 17 00:00:00 2001 From: Joaquín Ignacio Aramendía Date: Mon, 17 Jul 2023 19:25:15 -0300 Subject: hwmon: (oxp-sensors) Move tt_toggle attribute to dev_groups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A driver should not be manually adding groups in its probe function (it will race with userspace), so replace the call to devm_device_add_groups() to use the platform dev_groups callback instead. This will allow for removal of the devm_device_add_groups() function. Signed-off-by: Joaquín Ignacio Aramendía Fixes: be144ee49127 ("hwmon: (oxp-sensors) Add tt_toggle attribute on supported boards") Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20230717222526.229984-2-samsagax@gmail.com Signed-off-by: Guenter Roeck --- drivers/hwmon/oxp-sensors.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/oxp-sensors.c b/drivers/hwmon/oxp-sensors.c index e1a907cae820..1e1cc67bcdea 100644 --- a/drivers/hwmon/oxp-sensors.c +++ b/drivers/hwmon/oxp-sensors.c @@ -220,6 +220,20 @@ static int tt_toggle_disable(void) } /* Callbacks for turbo toggle attribute */ +static umode_t tt_toggle_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + switch (board) { + case aok_zoe_a1: + case oxp_mini_amd_a07: + case oxp_mini_amd_pro: + return attr->mode; + default: + break; + } + return 0; +} + static ssize_t tt_toggle_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -396,7 +410,15 @@ static struct attribute *oxp_ec_attrs[] = { NULL }; -ATTRIBUTE_GROUPS(oxp_ec); +static struct attribute_group oxp_ec_attribute_group = { + .is_visible = tt_toggle_is_visible, + .attrs = oxp_ec_attrs, +}; + +static const struct attribute_group *oxp_ec_groups[] = { + &oxp_ec_attribute_group, + NULL +}; static const struct hwmon_ops oxp_ec_hwmon_ops = { .is_visible = oxp_ec_hwmon_is_visible, @@ -415,7 +437,6 @@ static int oxp_platform_probe(struct platform_device *pdev) const struct dmi_system_id *dmi_entry; struct device *dev = &pdev->dev; struct device *hwdev; - int ret; /* * Have to check for AMD processor here because DMI strings are the @@ -430,18 +451,6 @@ static int oxp_platform_probe(struct platform_device *pdev) board = (enum oxp_board)(unsigned long)dmi_entry->driver_data; - switch (board) { - case aok_zoe_a1: - case oxp_mini_amd_a07: - case oxp_mini_amd_pro: - ret = devm_device_add_groups(dev, oxp_ec_groups); - if (ret) - return ret; - break; - default: - break; - } - hwdev = devm_hwmon_device_register_with_info(dev, "oxpec", NULL, &oxp_ec_chip_info, NULL); @@ -451,6 +460,7 @@ static int oxp_platform_probe(struct platform_device *pdev) static struct platform_driver oxp_platform_driver = { .driver = { .name = "oxp-platform", + .dev_groups = oxp_ec_groups, }, .probe = oxp_platform_probe, }; -- cgit From 13558a2e6341d1ba6dff9f8e2febf97877067885 Mon Sep 17 00:00:00 2001 From: Ahmad Khalifa Date: Wed, 19 Jul 2023 20:28:48 +0100 Subject: hwmon: (nct6775) Fix IN scaling factors for 6798/6799 Scaling for VTT/VIN5/VIN6 registers were based on prior chips * Split scaling factors for 6798/6799 and assign at probe() * Pass them through driver data to sysfs functions Tested on nct6799 with old/new input/min/max Fixes: 0599682b826f ("hwmon: (nct6775) Add support for NCT6798D") Signed-off-by: Ahmad Khalifa Link: https://lore.kernel.org/r/20230719192848.337508-1-ahmad@khalifa.ws Signed-off-by: Guenter Roeck --- drivers/hwmon/nct6775-core.c | 28 ++++++++++++++++++++++------ drivers/hwmon/nct6775.h | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/nct6775-core.c b/drivers/hwmon/nct6775-core.c index 236dc97f4d22..08ce4984151d 100644 --- a/drivers/hwmon/nct6775-core.c +++ b/drivers/hwmon/nct6775-core.c @@ -955,14 +955,25 @@ static const u16 scale_in[15] = { 800, 800 }; -static inline long in_from_reg(u8 reg, u8 nr) +/* + * NCT6798 scaling: + * CPUVC, IN1, AVSB, 3VCC, IN0, IN8, IN4, 3VSB, VBAT, VTT, IN5, IN6, IN2, + * IN3, IN7 + * Additional scales to be added later: IN9 (800), VHIF (1600) + */ +static const u16 scale_in_6798[15] = { + 800, 800, 1600, 1600, 800, 800, 800, 1600, 1600, 1600, 1600, 1600, 800, + 800, 800 +}; + +static inline long in_from_reg(u8 reg, u8 nr, const u16 *scales) { - return DIV_ROUND_CLOSEST(reg * scale_in[nr], 100); + return DIV_ROUND_CLOSEST(reg * scales[nr], 100); } -static inline u8 in_to_reg(u32 val, u8 nr) +static inline u8 in_to_reg(u32 val, u8 nr, const u16 *scales) { - return clamp_val(DIV_ROUND_CLOSEST(val * 100, scale_in[nr]), 0, 255); + return clamp_val(DIV_ROUND_CLOSEST(val * 100, scales[nr]), 0, 255); } /* TSI temperatures are in 8.3 format */ @@ -1673,7 +1684,8 @@ show_in_reg(struct device *dev, struct device_attribute *attr, char *buf) if (IS_ERR(data)) return PTR_ERR(data); - return sprintf(buf, "%ld\n", in_from_reg(data->in[nr][index], nr)); + return sprintf(buf, "%ld\n", + in_from_reg(data->in[nr][index], nr, data->scale_in)); } static ssize_t @@ -1691,7 +1703,7 @@ store_in_reg(struct device *dev, struct device_attribute *attr, const char *buf, if (err < 0) return err; mutex_lock(&data->update_lock); - data->in[nr][index] = in_to_reg(val, nr); + data->in[nr][index] = in_to_reg(val, nr, data->scale_in); err = nct6775_write_value(data, data->REG_IN_MINMAX[index - 1][nr], data->in[nr][index]); mutex_unlock(&data->update_lock); return err ? : count; @@ -3462,6 +3474,7 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data, mutex_init(&data->update_lock); data->name = nct6775_device_names[data->kind]; data->bank = 0xff; /* Force initial bank selection */ + data->scale_in = scale_in; switch (data->kind) { case nct6106: @@ -3977,6 +3990,9 @@ int nct6775_probe(struct device *dev, struct nct6775_data *data, break; } + if (data->kind == nct6798 || data->kind == nct6799) + data->scale_in = scale_in_6798; + reg_temp = NCT6779_REG_TEMP; num_reg_temp = ARRAY_SIZE(NCT6779_REG_TEMP); if (data->kind == nct6791) { diff --git a/drivers/hwmon/nct6775.h b/drivers/hwmon/nct6775.h index 44f79c5726a9..a84c6ce7275d 100644 --- a/drivers/hwmon/nct6775.h +++ b/drivers/hwmon/nct6775.h @@ -98,6 +98,7 @@ struct nct6775_data { u8 bank; /* current register bank */ u8 in_num; /* number of in inputs we have */ u8 in[15][3]; /* [0]=in, [1]=in_max, [2]=in_min */ + const u16 *scale_in; /* internal scaling factors */ unsigned int rpm[NUM_FAN]; u16 fan_min[NUM_FAN]; u8 fan_pulses[NUM_FAN]; -- cgit From 80b6051085c5fedcb1dfd7b2562a63a83655c4d8 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Wed, 5 Jul 2023 10:40:01 +0800 Subject: scsi: sg: Fix checking return value of blk_get_queue() Commit fcaa174a9c99 ("scsi/sg: don't grab scsi host module reference") make a mess how blk_get_queue() is called, blk_get_queue() returns true on success while the caller expects it returns 0 on success. Fix this problem and also add a corresponding error message on failure. Fixes: fcaa174a9c99 ("scsi/sg: don't grab scsi host module reference") Reported-by: Marc Hartmayer Closes: https://lore.kernel.org/all/87lefv622n.fsf@linux.ibm.com/ Signed-off-by: Yu Kuai Link: https://lore.kernel.org/r/20230705024001.177585-1-yukuai1@huaweicloud.com Tested-by: Shin'ichiro Kawasaki Tested-by: Marc Hartmayer Reviewed-by: Christoph Hellwig Reviewed-by: Marc Hartmayer Signed-off-by: Martin K. Petersen --- drivers/scsi/sg.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 89fa046c7158..0d8afffd1683 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1497,9 +1497,10 @@ sg_add_device(struct device *cl_dev) int error; unsigned long iflags; - error = blk_get_queue(scsidp->request_queue); - if (error) - return error; + if (!blk_get_queue(scsidp->request_queue)) { + pr_warn("%s: get scsi_device queue failed\n", __func__); + return -ENODEV; + } error = -ENOMEM; cdev = cdev_alloc(); -- cgit From 4f7cab49cecee16120d27c1734cfdf3d6c0e5329 Mon Sep 17 00:00:00 2001 From: Jerry Meng Date: Thu, 29 Jun 2023 17:35:22 +0800 Subject: USB: serial: option: support Quectel EM060K_128 EM060K_128 is EM060K's sub-model, having the same name "Quectel EM060K-GL" MBIM + GNSS + DIAG + NMEA + AT + QDSS + DPL T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=0128 Rev= 5.04 S: Manufacturer=Quectel S: Product=Quectel EM060K-GL S: SerialNumber=f6fa08b6 C:* #Ifs= 8 Cfg#= 1 Atr=a0 MxPwr=500mA A: FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=0e Prot=00 I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 0 #EPs= 0 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim I:* If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=82(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=85(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=87(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 6 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=70 Driver=(none) E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 7 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=ff Prot=80 Driver=(none) E: Ad=8f(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Jerry Meng Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 288a96a74266..a1600ec82f56 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -251,6 +251,7 @@ static void option_instat_callback(struct urb *urb); #define QUECTEL_PRODUCT_EM061K_LTA 0x0123 #define QUECTEL_PRODUCT_EM061K_LMS 0x0124 #define QUECTEL_PRODUCT_EC25 0x0125 +#define QUECTEL_PRODUCT_EM060K_128 0x0128 #define QUECTEL_PRODUCT_EG91 0x0191 #define QUECTEL_PRODUCT_EG95 0x0195 #define QUECTEL_PRODUCT_BG96 0x0296 @@ -1197,6 +1198,9 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0x00, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K, 0xff, 0xff, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0x00, 0x40) }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM060K_128, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0x00, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM061K_LCN, 0xff, 0xff, 0x40) }, -- cgit From f8a2da6ec2417cca169fa85a8ab15817bccbb109 Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Tue, 18 Jul 2023 11:43:54 +0200 Subject: can: gs_usb: gs_can_close(): add missing set of CAN state to CAN_STATE_STOPPED After an initial link up the CAN device is in ERROR-ACTIVE mode. Due to a missing CAN_STATE_STOPPED in gs_can_close() it doesn't change to STOPPED after a link down: | ip link set dev can0 up | ip link set dev can0 down | ip --details link show can0 | 13: can0: mtu 16 qdisc pfifo_fast state DOWN mode DEFAULT group default qlen 10 | link/can promiscuity 0 allmulti 0 minmtu 0 maxmtu 0 | can state ERROR-ACTIVE restart-ms 1000 Add missing assignment of CAN_STATE_STOPPED in gs_can_close(). Cc: stable@vger.kernel.org Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") Link: https://lore.kernel.org/all/20230718-gs_usb-fix-can-state-v1-1-f19738ae2c23@pengutronix.de Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/gs_usb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index f418066569fc..bd9eb066ecf1 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -1030,6 +1030,8 @@ static int gs_can_close(struct net_device *netdev) usb_kill_anchored_urbs(&dev->tx_submitted); atomic_set(&dev->active_tx_urbs, 0); + dev->can.state = CAN_STATE_STOPPED; + /* reset the device */ rc = gs_cmd_reset(dev); if (rc < 0) -- cgit From 857ea9005806e2a458016880278f98715873e977 Mon Sep 17 00:00:00 2001 From: Mohsen Tahmasebi Date: Mon, 10 Jul 2023 11:22:18 +0330 Subject: USB: serial: option: add Quectel EC200A module support Add Quectel EC200A "DIAG, AT, MODEM": 0x6005: ECM / RNDIS + DIAG + AT + MODEM T: Bus=01 Lev=01 Prnt=02 Port=05 Cnt=01 Dev#= 8 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=2c7c ProdID=6005 Rev=03.18 S: Manufacturer=Android S: Product=Android S: SerialNumber=0000 C: #Ifs= 5 Cfg#= 1 Atr=e0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=06 Prot=00 Driver=cdc_ether E: Ad=87(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=cdc_ether E: Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=89(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=88(I) Atr=03(Int.) MxPS= 64 Ivl=4096ms Signed-off-by: Mohsen Tahmasebi Tested-by: Mostafa Ghofrani Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index a1600ec82f56..8ac98e60fff5 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -269,6 +269,7 @@ static void option_instat_callback(struct urb *urb); #define QUECTEL_PRODUCT_RM520N 0x0801 #define QUECTEL_PRODUCT_EC200U 0x0901 #define QUECTEL_PRODUCT_EC200S_CN 0x6002 +#define QUECTEL_PRODUCT_EC200A 0x6005 #define QUECTEL_PRODUCT_EM061K_LWW 0x6008 #define QUECTEL_PRODUCT_EM061K_LCN 0x6009 #define QUECTEL_PRODUCT_EC200T 0x6026 @@ -1229,6 +1230,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM520N, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0900, 0xff, 0, 0), /* RM500U-CN */ .driver_info = ZLP }, + { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200A, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200U, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200S_CN, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC200T, 0xff, 0, 0) }, -- cgit From dd92c8a1f99bcd166204ffc219ea5a23dd65d64f Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 12 Jul 2023 16:16:41 +0200 Subject: USB: serial: simple: add Kaufmann RKS+CAN VCP Add the device and product ID for this CAN bus interface / license dongle. The device is usable either directly from user space or can be attached to a kernel CAN interface with slcan_attach. Reported-by: Kaufmann Automotive GmbH Tested-by: Kaufmann Automotive GmbH Signed-off-by: Oliver Neukum [ johan: amend commit message and move entries in sort order ] Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold --- drivers/usb/serial/usb-serial-simple.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c index 4c6747889a19..3c552e4b87ce 100644 --- a/drivers/usb/serial/usb-serial-simple.c +++ b/drivers/usb/serial/usb-serial-simple.c @@ -63,6 +63,11 @@ DEVICE(flashloader, FLASHLOADER_IDS); 0x01) } DEVICE(google, GOOGLE_IDS); +/* KAUFMANN RKS+CAN VCP */ +#define KAUFMANN_IDS() \ + { USB_DEVICE(0x16d0, 0x0870) } +DEVICE(kaufmann, KAUFMANN_IDS); + /* Libtransistor USB console */ #define LIBTRANSISTOR_IDS() \ { USB_DEVICE(0x1209, 0x8b00) } @@ -124,6 +129,7 @@ static struct usb_serial_driver * const serial_drivers[] = { &funsoft_device, &flashloader_device, &google_device, + &kaufmann_device, &libtransistor_device, &vivopay_device, &moto_modem_device, @@ -142,6 +148,7 @@ static const struct usb_device_id id_table[] = { FUNSOFT_IDS(), FLASHLOADER_IDS(), GOOGLE_IDS(), + KAUFMANN_IDS(), LIBTRANSISTOR_IDS(), VIVOPAY_IDS(), MOTO_IDS(), -- cgit From d245aedc00775c4d7265a9f4522cc4e1fd34d102 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 20 Jul 2023 09:53:57 +0200 Subject: USB: serial: simple: sort driver entries Sort the driver symbols alphabetically in order to make it more obvious where new driver entries should be added. Cc: stable@vger.kernel.org Acked-by: Greg Kroah-Hartman Signed-off-by: Johan Hovold --- drivers/usb/serial/usb-serial-simple.c | 66 +++++++++++++++++----------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial-simple.c b/drivers/usb/serial/usb-serial-simple.c index 3c552e4b87ce..24b8772a345e 100644 --- a/drivers/usb/serial/usb-serial-simple.c +++ b/drivers/usb/serial/usb-serial-simple.c @@ -38,16 +38,6 @@ static struct usb_serial_driver vendor##_device = { \ { USB_DEVICE(0x0a21, 0x8001) } /* MMT-7305WW */ DEVICE(carelink, CARELINK_IDS); -/* ZIO Motherboard USB driver */ -#define ZIO_IDS() \ - { USB_DEVICE(0x1CBE, 0x0103) } -DEVICE(zio, ZIO_IDS); - -/* Funsoft Serial USB driver */ -#define FUNSOFT_IDS() \ - { USB_DEVICE(0x1404, 0xcddc) } -DEVICE(funsoft, FUNSOFT_IDS); - /* Infineon Flashloader driver */ #define FLASHLOADER_IDS() \ { USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \ @@ -55,6 +45,11 @@ DEVICE(funsoft, FUNSOFT_IDS); { USB_DEVICE(0x8087, 0x0801) } DEVICE(flashloader, FLASHLOADER_IDS); +/* Funsoft Serial USB driver */ +#define FUNSOFT_IDS() \ + { USB_DEVICE(0x1404, 0xcddc) } +DEVICE(funsoft, FUNSOFT_IDS); + /* Google Serial USB SubClass */ #define GOOGLE_IDS() \ { USB_VENDOR_AND_INTERFACE_INFO(0x18d1, \ @@ -63,6 +58,11 @@ DEVICE(flashloader, FLASHLOADER_IDS); 0x01) } DEVICE(google, GOOGLE_IDS); +/* HP4x (48/49) Generic Serial driver */ +#define HP4X_IDS() \ + { USB_DEVICE(0x03f0, 0x0121) } +DEVICE(hp4x, HP4X_IDS); + /* KAUFMANN RKS+CAN VCP */ #define KAUFMANN_IDS() \ { USB_DEVICE(0x16d0, 0x0870) } @@ -73,11 +73,6 @@ DEVICE(kaufmann, KAUFMANN_IDS); { USB_DEVICE(0x1209, 0x8b00) } DEVICE(libtransistor, LIBTRANSISTOR_IDS); -/* ViVOpay USB Serial Driver */ -#define VIVOPAY_IDS() \ - { USB_DEVICE(0x1d5f, 0x1004) } /* ViVOpay 8800 */ -DEVICE(vivopay, VIVOPAY_IDS); - /* Motorola USB Phone driver */ #define MOTO_IDS() \ { USB_DEVICE(0x05c6, 0x3197) }, /* unknown Motorola phone */ \ @@ -106,10 +101,10 @@ DEVICE(nokia, NOKIA_IDS); { USB_DEVICE(0x09d7, 0x0100) } /* NovAtel FlexPack GPS */ DEVICE_N(novatel_gps, NOVATEL_IDS, 3); -/* HP4x (48/49) Generic Serial driver */ -#define HP4X_IDS() \ - { USB_DEVICE(0x03f0, 0x0121) } -DEVICE(hp4x, HP4X_IDS); +/* Siemens USB/MPI adapter */ +#define SIEMENS_IDS() \ + { USB_DEVICE(0x908, 0x0004) } +DEVICE(siemens_mpi, SIEMENS_IDS); /* Suunto ANT+ USB Driver */ #define SUUNTO_IDS() \ @@ -117,47 +112,52 @@ DEVICE(hp4x, HP4X_IDS); { USB_DEVICE(0x0fcf, 0x1009) } /* Dynastream ANT USB-m Stick */ DEVICE(suunto, SUUNTO_IDS); -/* Siemens USB/MPI adapter */ -#define SIEMENS_IDS() \ - { USB_DEVICE(0x908, 0x0004) } -DEVICE(siemens_mpi, SIEMENS_IDS); +/* ViVOpay USB Serial Driver */ +#define VIVOPAY_IDS() \ + { USB_DEVICE(0x1d5f, 0x1004) } /* ViVOpay 8800 */ +DEVICE(vivopay, VIVOPAY_IDS); + +/* ZIO Motherboard USB driver */ +#define ZIO_IDS() \ + { USB_DEVICE(0x1CBE, 0x0103) } +DEVICE(zio, ZIO_IDS); /* All of the above structures mushed into two lists */ static struct usb_serial_driver * const serial_drivers[] = { &carelink_device, - &zio_device, - &funsoft_device, &flashloader_device, + &funsoft_device, &google_device, + &hp4x_device, &kaufmann_device, &libtransistor_device, - &vivopay_device, &moto_modem_device, &motorola_tetra_device, &nokia_device, &novatel_gps_device, - &hp4x_device, - &suunto_device, &siemens_mpi_device, + &suunto_device, + &vivopay_device, + &zio_device, NULL }; static const struct usb_device_id id_table[] = { CARELINK_IDS(), - ZIO_IDS(), - FUNSOFT_IDS(), FLASHLOADER_IDS(), + FUNSOFT_IDS(), GOOGLE_IDS(), + HP4X_IDS(), KAUFMANN_IDS(), LIBTRANSISTOR_IDS(), - VIVOPAY_IDS(), MOTO_IDS(), MOTOROLA_TETRA_IDS(), NOKIA_IDS(), NOVATEL_IDS(), - HP4X_IDS(), - SUUNTO_IDS(), SIEMENS_IDS(), + SUUNTO_IDS(), + VIVOPAY_IDS(), + ZIO_IDS(), { }, }; MODULE_DEVICE_TABLE(usb, id_table); -- cgit From 690c8b804ad2eafbd35da5d3c95ad325ca7d5061 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Mon, 10 Jul 2023 02:26:45 +0200 Subject: TIOCSTI: always enable for CAP_SYS_ADMIN 83efeeeb3d04 ("tty: Allow TIOCSTI to be disabled") broke BRLTTY's ability to simulate keypresses on the console, thus effectively breaking braille keyboards of blind users. This restores the TIOCSTI feature for CAP_SYS_ADMIN processes, which BRLTTY is, thus fixing braille keyboards without re-opening the security issue. Signed-off-by: Samuel Thibault Acked-by: Kees Cook Fixes: 83efeeeb3d04 ("tty: Allow TIOCSTI to be disabled") Cc: stable@vger.kernel.org Reported-by: Nicolas Pitre Link: https://lore.kernel.org/r/20230710002645.v565c7xq5iddruse@begin Acked-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3959efc717aa..63db04b9113a 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -2285,7 +2285,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p) char ch, mbz = 0; struct tty_ldisc *ld; - if (!tty_legacy_tiocsti) + if (!tty_legacy_tiocsti && !capable(CAP_SYS_ADMIN)) return -EIO; if ((current->signal->tty != tty) && !capable(CAP_SYS_ADMIN)) -- cgit From 043b1f185fb0f3939b7427f634787706f45411c4 Mon Sep 17 00:00:00 2001 From: Wang Ming Date: Thu, 13 Jul 2023 09:42:39 +0800 Subject: i40e: Fix an NULL vs IS_ERR() bug for debugfs_create_dir() The debugfs_create_dir() function returns error pointers. It never returns NULL. Most incorrect error checks were fixed, but the one in i40e_dbg_init() was forgotten. Fix the remaining error check. Fixes: 02e9c290814c ("i40e: debugfs interface") Signed-off-by: Wang Ming Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/i40e/i40e_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index 9954493cd448..62497f5565c5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c @@ -1839,7 +1839,7 @@ void i40e_dbg_pf_exit(struct i40e_pf *pf) void i40e_dbg_init(void) { i40e_dbg_root = debugfs_create_dir(i40e_driver_name, NULL); - if (!i40e_dbg_root) + if (IS_ERR(i40e_dbg_root)) pr_info("init of debugfs failed\n"); } -- cgit From a2f054c10bef0b54600ec9cb776508443e941343 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Mon, 10 Jul 2023 13:41:27 -0700 Subject: iavf: fix potential deadlock on allocation failure In iavf_adminq_task(), if kzalloc() fails to allocate the event.msg_buf, the function will exit without releasing the adapter->crit_lock. This is unlikely, but if it happens, the next access to that mutex will deadlock. Fix this by moving the unlock to the end of the function, and adding a new label to allow jumping to the unlock portion of the function exit flow. Fixes: fc2e6b3b132a ("iavf: Rework mutexes for better synchronisation") Signed-off-by: Jacob Keller Tested-by: Rafal Romanowski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/iavf/iavf_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 3a88d413ddee..939c8126eb43 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -3264,7 +3264,7 @@ static void iavf_adminq_task(struct work_struct *work) event.buf_len = IAVF_MAX_AQ_BUF_SIZE; event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL); if (!event.msg_buf) - goto out; + goto unlock; do { ret = iavf_clean_arq_element(hw, &event, &pending); @@ -3279,7 +3279,6 @@ static void iavf_adminq_task(struct work_struct *work) if (pending != 0) memset(event.msg_buf, 0, IAVF_MAX_AQ_BUF_SIZE); } while (pending); - mutex_unlock(&adapter->crit_lock); if (iavf_is_reset_in_progress(adapter)) goto freedom; @@ -3323,6 +3322,8 @@ static void iavf_adminq_task(struct work_struct *work) freedom: kfree(event.msg_buf); +unlock: + mutex_unlock(&adapter->crit_lock); out: /* re-enable Admin queue interrupt cause */ iavf_misc_irq_enable(adapter); -- cgit From 91896c8acce23d33ed078cffd46a9534b1f82be5 Mon Sep 17 00:00:00 2001 From: Jacob Keller Date: Mon, 10 Jul 2023 13:41:28 -0700 Subject: iavf: check for removal state before IAVF_FLAG_PF_COMMS_FAILED In iavf_adminq_task(), if the function can't acquire the adapter->crit_lock, it checks if the driver is removing. If so, it simply exits without re-enabling the interrupt. This is done to ensure that the task stops processing as soon as possible once the driver is being removed. However, if the IAVF_FLAG_PF_COMMS_FAILED is set, the function checks this before attempting to acquire the lock. In this case, the function exits early and re-enables the interrupt. This will happen even if the driver is already removing. Avoid this, by moving the check to after the adapter->crit_lock is acquired. This way, if the driver is removing, we will not re-enable the interrupt. Fixes: fc2e6b3b132a ("iavf: Rework mutexes for better synchronisation") Signed-off-by: Jacob Keller Tested-by: Rafal Romanowski Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/iavf/iavf_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 939c8126eb43..9610ca770349 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -3250,9 +3250,6 @@ static void iavf_adminq_task(struct work_struct *work) u32 val, oldval; u16 pending; - if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) - goto out; - if (!mutex_trylock(&adapter->crit_lock)) { if (adapter->state == __IAVF_REMOVE) return; @@ -3261,6 +3258,9 @@ static void iavf_adminq_task(struct work_struct *work) goto out; } + if (adapter->flags & IAVF_FLAG_PF_COMMS_FAILED) + goto unlock; + event.buf_len = IAVF_MAX_AQ_BUF_SIZE; event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL); if (!event.msg_buf) -- cgit From c7b75bea853daeb64fc831dbf39a6bbabcc402ac Mon Sep 17 00:00:00 2001 From: Jiawen Wu Date: Wed, 19 Jul 2023 17:22:33 +0800 Subject: net: phy: marvell10g: fix 88x3310 power up Clear MV_V2_PORT_CTRL_PWRDOWN bit to set power up for 88x3310 PHY, it sometimes does not take effect immediately. And a read of this register causes the bit not to clear. This will cause mv3310_reset() to time out, which will fail the config initialization. So add a delay before the next access. Fixes: c9cc1c815d36 ("net: phy: marvell10g: place in powersave mode at probe") Signed-off-by: Jiawen Wu Reviewed-by: Russell King (Oracle) Signed-off-by: David S. Miller --- drivers/net/phy/marvell10g.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c index 55d9d7acc32e..d4bb90d76881 100644 --- a/drivers/net/phy/marvell10g.c +++ b/drivers/net/phy/marvell10g.c @@ -328,6 +328,13 @@ static int mv3310_power_up(struct phy_device *phydev) ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL, MV_V2_PORT_CTRL_PWRDOWN); + /* Sometimes, the power down bit doesn't clear immediately, and + * a read of this register causes the bit not to clear. Delay + * 100us to allow the PHY to come out of power down mode before + * the next access. + */ + udelay(100); + if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310 || priv->firmware_ver < 0x00030000) return ret; -- cgit From 649fee5a17a7f96152fee2fb9111d9a4db535f35 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 21 Jul 2023 16:28:54 +0800 Subject: regulator: mt6358: Sync VCN33_* enable status after checking ID Syncing VCN33_* enable status should be done after checking the PMIC's ID, to avoid setting random bits on other PMICs. Suggested-by: AngeloGioacchino Del Regno Fixes: 65bae54e08c1 ("regulator: mt6358: Merge VCN33_* regulators") Signed-off-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230721082903.2038975-3-wenst@chromium.org Signed-off-by: Mark Brown --- drivers/regulator/mt6358-regulator.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c index 31a16fb28ecd..da6b40f947c4 100644 --- a/drivers/regulator/mt6358-regulator.c +++ b/drivers/regulator/mt6358-regulator.c @@ -676,10 +676,6 @@ static int mt6358_regulator_probe(struct platform_device *pdev) const struct mt6358_regulator_info *mt6358_info; int i, max_regulator, ret; - ret = mt6358_sync_vcn33_setting(&pdev->dev); - if (ret) - return ret; - if (mt6397->chip_id == MT6366_CHIP_ID) { max_regulator = MT6366_MAX_REGULATOR; mt6358_info = mt6366_regulators; @@ -688,6 +684,10 @@ static int mt6358_regulator_probe(struct platform_device *pdev) mt6358_info = mt6358_regulators; } + ret = mt6358_sync_vcn33_setting(&pdev->dev); + if (ret) + return ret; + for (i = 0; i < max_regulator; i++) { config.dev = &pdev->dev; config.regmap = mt6397->regmap; -- cgit From 67cb608838e0aac8efb48828b1165156f99c1af9 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Fri, 21 Jul 2023 16:28:55 +0800 Subject: regulator: mt6358: Fix incorrect VCN33 sync error message After syncing the enable status of VCN33_WIFI to VCN33_BT, the driver will disable VCN33_WIFI. If it fails it will error out with a message. However the error message incorrectly refers to VCN33_BT. Fix the error message so that it correctly refers to VCN33_WIFI. Suggested-by: Fei Shao Fixes: 65bae54e08c1 ("regulator: mt6358: Merge VCN33_* regulators") Signed-off-by: Chen-Yu Tsai Reviewed-by: AngeloGioacchino Del Regno Link: https://lore.kernel.org/r/20230721082903.2038975-4-wenst@chromium.org Signed-off-by: Mark Brown --- drivers/regulator/mt6358-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c index da6b40f947c4..b9cda2210c33 100644 --- a/drivers/regulator/mt6358-regulator.c +++ b/drivers/regulator/mt6358-regulator.c @@ -661,7 +661,7 @@ static int mt6358_sync_vcn33_setting(struct device *dev) /* Disable VCN33_WIFI */ ret = regmap_update_bits(mt6397->regmap, MT6358_LDO_VCN33_CON0_1, BIT(0), 0); if (ret) { - dev_err(dev, "Failed to disable VCN33_BT\n"); + dev_err(dev, "Failed to disable VCN33_WIFI\n"); return ret; } -- cgit From 80ddce5f2dbd0e83eadc9f9d373439180d599fe5 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Sat, 8 Jul 2023 13:27:19 +0200 Subject: thermal: core: constify params in thermal_zone_device_register Since commit 3d439b1a2ad3 ("thermal/core: Alloc-copy-free the thermal zone parameters structure"), thermal_zone_device_register() allocates a copy of the tzp argument and callers need not explicitly manage its lifetime. This means the function no longer cares about the parameter being mutable, so constify it. No functional change. Signed-off-by: Ahmad Fatoum Acked-by: Daniel Lezcano Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index 842f678c1c3e..cc2b5e81c620 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -1203,7 +1203,7 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_crit_temp); struct thermal_zone_device * thermal_zone_device_register_with_trips(const char *type, struct thermal_trip *trips, int num_trips, int mask, void *devdata, struct thermal_zone_device_ops *ops, - struct thermal_zone_params *tzp, int passive_delay, + const struct thermal_zone_params *tzp, int passive_delay, int polling_delay) { struct thermal_zone_device *tz; @@ -1371,7 +1371,7 @@ EXPORT_SYMBOL_GPL(thermal_zone_device_register_with_trips); struct thermal_zone_device *thermal_zone_device_register(const char *type, int ntrips, int mask, void *devdata, struct thermal_zone_device_ops *ops, - struct thermal_zone_params *tzp, int passive_delay, + const struct thermal_zone_params *tzp, int passive_delay, int polling_delay) { return thermal_zone_device_register_with_trips(type, NULL, ntrips, mask, -- cgit From ac4436a5b20e0ef1f608a9ef46c08d5d142f8da6 Mon Sep 17 00:00:00 2001 From: Ahmad Fatoum Date: Sat, 8 Jul 2023 13:27:20 +0200 Subject: thermal: of: fix double-free on unregistration Since commit 3d439b1a2ad3 ("thermal/core: Alloc-copy-free the thermal zone parameters structure"), thermal_zone_device_register() allocates a copy of the tzp argument and frees it when unregistering, so thermal_of_zone_register() now ends up leaking its original tzp and double-freeing the tzp copy. Fix this by locating tzp on stack instead. Fixes: 3d439b1a2ad3 ("thermal/core: Alloc-copy-free the thermal zone parameters structure") Signed-off-by: Ahmad Fatoum Acked-by: Daniel Lezcano Cc: 6.4+ # 6.4+: 8bcbb18c61d6: thermal: core: constify params in thermal_zone_device_register Signed-off-by: Rafael J. Wysocki --- drivers/thermal/thermal_of.c | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index 6fb14e521197..bc07ae1c284c 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -238,17 +238,13 @@ static int thermal_of_monitor_init(struct device_node *np, int *delay, int *pdel return 0; } -static struct thermal_zone_params *thermal_of_parameters_init(struct device_node *np) +static void thermal_of_parameters_init(struct device_node *np, + struct thermal_zone_params *tzp) { - struct thermal_zone_params *tzp; int coef[2]; int ncoef = ARRAY_SIZE(coef); int prop, ret; - tzp = kzalloc(sizeof(*tzp), GFP_KERNEL); - if (!tzp) - return ERR_PTR(-ENOMEM); - tzp->no_hwmon = true; if (!of_property_read_u32(np, "sustainable-power", &prop)) @@ -267,8 +263,6 @@ static struct thermal_zone_params *thermal_of_parameters_init(struct device_node tzp->slope = coef[0]; tzp->offset = coef[1]; - - return tzp; } static struct device_node *thermal_of_zone_get_by_name(struct thermal_zone_device *tz) @@ -442,13 +436,11 @@ static int thermal_of_unbind(struct thermal_zone_device *tz, static void thermal_of_zone_unregister(struct thermal_zone_device *tz) { struct thermal_trip *trips = tz->trips; - struct thermal_zone_params *tzp = tz->tzp; struct thermal_zone_device_ops *ops = tz->ops; thermal_zone_device_disable(tz); thermal_zone_device_unregister(tz); kfree(trips); - kfree(tzp); kfree(ops); } @@ -477,7 +469,7 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * { struct thermal_zone_device *tz; struct thermal_trip *trips; - struct thermal_zone_params *tzp; + struct thermal_zone_params tzp = {}; struct thermal_zone_device_ops *of_ops; struct device_node *np; int delay, pdelay; @@ -509,12 +501,7 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * goto out_kfree_trips; } - tzp = thermal_of_parameters_init(np); - if (IS_ERR(tzp)) { - ret = PTR_ERR(tzp); - pr_err("Failed to initialize parameter from %pOFn: %d\n", np, ret); - goto out_kfree_trips; - } + thermal_of_parameters_init(np, &tzp); of_ops->bind = thermal_of_bind; of_ops->unbind = thermal_of_unbind; @@ -522,12 +509,12 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * mask = GENMASK_ULL((ntrips) - 1, 0); tz = thermal_zone_device_register_with_trips(np->name, trips, ntrips, - mask, data, of_ops, tzp, + mask, data, of_ops, &tzp, pdelay, delay); if (IS_ERR(tz)) { ret = PTR_ERR(tz); pr_err("Failed to register thermal zone %pOFn: %d\n", np, ret); - goto out_kfree_tzp; + goto out_kfree_trips; } ret = thermal_zone_device_enable(tz); @@ -540,8 +527,6 @@ static struct thermal_zone_device *thermal_of_zone_register(struct device_node * return tz; -out_kfree_tzp: - kfree(tzp); out_kfree_trips: kfree(trips); out_kfree_of_ops: -- cgit From 8527beb12087238d4387607597b4020bc393c4b4 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 13 Jul 2023 16:57:39 +0200 Subject: PM: sleep: wakeirq: fix wake irq arming The decision whether to enable a wake irq during suspend can not be done based on the runtime PM state directly as a driver may use wake irqs without implementing runtime PM. Such drivers specifically leave the state set to the default 'suspended' and the wake irq is thus never enabled at suspend. Add a new wake irq flag to track whether a dedicated wake irq has been enabled at runtime suspend and therefore must not be enabled at system suspend. Note that pm_runtime_enabled() can not be used as runtime PM is always disabled during late suspend. Fixes: 69728051f5bf ("PM / wakeirq: Fix unbalanced IRQ enable for wakeirq") Cc: 4.16+ # 4.16+ Signed-off-by: Johan Hovold Reviewed-by: Tony Lindgren Tested-by: Tony Lindgren Signed-off-by: Rafael J. Wysocki --- drivers/base/power/power.h | 1 + drivers/base/power/wakeirq.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 0eb7f02b3ad5..922ed457db19 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -29,6 +29,7 @@ extern u64 pm_runtime_active_time(struct device *dev); #define WAKE_IRQ_DEDICATED_MASK (WAKE_IRQ_DEDICATED_ALLOCATED | \ WAKE_IRQ_DEDICATED_MANAGED | \ WAKE_IRQ_DEDICATED_REVERSE) +#define WAKE_IRQ_DEDICATED_ENABLED BIT(3) struct wake_irq { struct device *dev; diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c index d487a6bac630..afd094dec5ca 100644 --- a/drivers/base/power/wakeirq.c +++ b/drivers/base/power/wakeirq.c @@ -314,8 +314,10 @@ void dev_pm_enable_wake_irq_check(struct device *dev, return; enable: - if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) + if (!can_change_status || !(wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) { enable_irq(wirq->irq); + wirq->status |= WAKE_IRQ_DEDICATED_ENABLED; + } } /** @@ -336,8 +338,10 @@ void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) if (cond_disable && (wirq->status & WAKE_IRQ_DEDICATED_REVERSE)) return; - if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) + if (wirq->status & WAKE_IRQ_DEDICATED_MANAGED) { + wirq->status &= ~WAKE_IRQ_DEDICATED_ENABLED; disable_irq_nosync(wirq->irq); + } } /** @@ -376,7 +380,7 @@ void dev_pm_arm_wake_irq(struct wake_irq *wirq) if (device_may_wakeup(wirq->dev)) { if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && - !pm_runtime_status_suspended(wirq->dev)) + !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) enable_irq(wirq->irq); enable_irq_wake(wirq->irq); @@ -399,7 +403,7 @@ void dev_pm_disarm_wake_irq(struct wake_irq *wirq) disable_irq_wake(wirq->irq); if (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED && - !pm_runtime_status_suspended(wirq->dev)) + !(wirq->status & WAKE_IRQ_DEDICATED_ENABLED)) disable_irq_nosync(wirq->irq); } } -- cgit From e7b915219baa4b2bf30afe1dbaca7a24ff627ad2 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 13 Jul 2023 16:57:40 +0200 Subject: PM: sleep: wakeirq: drop unused enable helpers Drop the wake-irq enable and disable helpers which have not been used since commit bed570307ed7 ("PM / wakeirq: Fix dedicated wakeirq for drivers not using autosuspend"). Note that these functions are essentially just leftovers from the first iteration of the wake-irq implementation where device drivers were supposed to call these functions themselves instead of PM core (as is also indicated by the bogus kernel doc comments). Signed-off-by: Johan Hovold Reviewed-by: Tony Lindgren Signed-off-by: Rafael J. Wysocki --- drivers/base/power/wakeirq.c | 49 -------------------------------------------- 1 file changed, 49 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c index afd094dec5ca..42171f766dcb 100644 --- a/drivers/base/power/wakeirq.c +++ b/drivers/base/power/wakeirq.c @@ -194,7 +194,6 @@ err_free: return err; } - /** * dev_pm_set_dedicated_wake_irq - Request a dedicated wake-up interrupt * @dev: Device entry @@ -206,11 +205,6 @@ err_free: * Sets up a threaded interrupt handler for a device that has * a dedicated wake-up interrupt in addition to the device IO * interrupt. - * - * The interrupt starts disabled, and needs to be managed for - * the device by the bus code or the device driver using - * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() - * functions. */ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) { @@ -232,11 +226,6 @@ EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq); * the status of WAKE_IRQ_DEDICATED_REVERSE to tell rpm_suspend() * to enable dedicated wake-up interrupt after running the runtime suspend * callback for @dev. - * - * The interrupt starts disabled, and needs to be managed for - * the device by the bus code or the device driver using - * dev_pm_enable_wake_irq*() and dev_pm_disable_wake_irq*() - * functions. */ int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) { @@ -244,44 +233,6 @@ int dev_pm_set_dedicated_wake_irq_reverse(struct device *dev, int irq) } EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse); -/** - * dev_pm_enable_wake_irq - Enable device wake-up interrupt - * @dev: Device - * - * Optionally called from the bus code or the device driver for - * runtime_resume() to override the PM runtime core managed wake-up - * interrupt handling to enable the wake-up interrupt. - * - * Note that for runtime_suspend()) the wake-up interrupts - * should be unconditionally enabled unlike for suspend() - * that is conditional. - */ -void dev_pm_enable_wake_irq(struct device *dev) -{ - struct wake_irq *wirq = dev->power.wakeirq; - - if (wirq && (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED)) - enable_irq(wirq->irq); -} -EXPORT_SYMBOL_GPL(dev_pm_enable_wake_irq); - -/** - * dev_pm_disable_wake_irq - Disable device wake-up interrupt - * @dev: Device - * - * Optionally called from the bus code or the device driver for - * runtime_suspend() to override the PM runtime core managed wake-up - * interrupt handling to disable the wake-up interrupt. - */ -void dev_pm_disable_wake_irq(struct device *dev) -{ - struct wake_irq *wirq = dev->power.wakeirq; - - if (wirq && (wirq->status & WAKE_IRQ_DEDICATED_ALLOCATED)) - disable_irq_nosync(wirq->irq); -} -EXPORT_SYMBOL_GPL(dev_pm_disable_wake_irq); - /** * dev_pm_enable_wake_irq_check - Checks and enables wake-up interrupt * @dev: Device -- cgit From 4dd8752a14ca0303fbdf0a6c68ff65f0a50bd2fa Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 13 Jul 2023 16:57:41 +0200 Subject: serial: qcom-geni: drop bogus runtime pm state update The runtime PM state should not be changed by drivers that do not implement runtime PM even if it happens to work around a bug in PM core. With the wake irq arming now fixed, drop the bogus runtime PM state update which left the device in active state (and could potentially prevent a parent device from suspending). Fixes: f3974413cf02 ("tty: serial: qcom_geni_serial: Wakeup IRQ cleanup") Cc: 5.6+ # 5.6+ Signed-off-by: Johan Hovold Reviewed-by: Tony Lindgren Signed-off-by: Rafael J. Wysocki --- drivers/tty/serial/qcom_geni_serial.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c index 444c74eeab7d..daaf2a64e7f1 100644 --- a/drivers/tty/serial/qcom_geni_serial.c +++ b/drivers/tty/serial/qcom_geni_serial.c @@ -1681,13 +1681,6 @@ static int qcom_geni_serial_probe(struct platform_device *pdev) if (ret) return ret; - /* - * Set pm_runtime status as ACTIVE so that wakeup_irq gets - * enabled/disabled from dev_pm_arm_wake_irq during system - * suspend/resume respectively. - */ - pm_runtime_set_active(&pdev->dev); - if (port->wakeup_irq > 0) { device_init_wakeup(&pdev->dev, true); ret = dev_pm_set_dedicated_wake_irq(&pdev->dev, -- cgit From b27d0232e8897f7c896dc8ad80c9907dd57fd3f3 Mon Sep 17 00:00:00 2001 From: Hao Lan Date: Thu, 20 Jul 2023 10:05:07 +0800 Subject: net: hns3: fix the imp capability bit cannot exceed 32 bits issue Current only the first 32 bits of the capability flag bit are considered. When the matching capability flag bit is greater than 31 bits, it will get an error bit.This patch use bitmap to solve this issue. It can handle each capability bit whitout bit width limit. Fixes: da77aef9cc58 ("net: hns3: create common cmdq resource allocate/free/query APIs") Signed-off-by: Hao Lan Signed-off-by: Jijie Shao Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 3 ++- .../hisilicon/hns3/hns3_common/hclge_comm_cmd.c | 21 ++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index b99d75260d59..7de167329b1e 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -407,7 +408,7 @@ struct hnae3_ae_dev { unsigned long hw_err_reset_req; struct hnae3_dev_specs dev_specs; u32 dev_version; - unsigned long caps[BITS_TO_LONGS(HNAE3_DEV_CAPS_MAX_NUM)]; + DECLARE_BITMAP(caps, HNAE3_DEV_CAPS_MAX_NUM); void *priv; }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c index b85c412683dd..16ba98ff2c9b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c @@ -171,6 +171,20 @@ static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = { {HCLGE_COMM_CAP_GRO_B, HNAE3_DEV_SUPPORT_GRO_B}, }; +static void +hclge_comm_capability_to_bitmap(unsigned long *bitmap, __le32 *caps) +{ + const unsigned int words = HCLGE_COMM_QUERY_CAP_LENGTH; + u32 val[HCLGE_COMM_QUERY_CAP_LENGTH]; + unsigned int i; + + for (i = 0; i < words; i++) + val[i] = __le32_to_cpu(caps[i]); + + bitmap_from_arr32(bitmap, val, + HCLGE_COMM_QUERY_CAP_LENGTH * BITS_PER_TYPE(u32)); +} + static void hclge_comm_parse_capability(struct hnae3_ae_dev *ae_dev, bool is_pf, struct hclge_comm_query_version_cmd *cmd) @@ -179,11 +193,12 @@ hclge_comm_parse_capability(struct hnae3_ae_dev *ae_dev, bool is_pf, is_pf ? hclge_pf_cmd_caps : hclge_vf_cmd_caps; u32 size = is_pf ? ARRAY_SIZE(hclge_pf_cmd_caps) : ARRAY_SIZE(hclge_vf_cmd_caps); - u32 caps, i; + DECLARE_BITMAP(caps, HCLGE_COMM_QUERY_CAP_LENGTH * BITS_PER_TYPE(u32)); + u32 i; - caps = __le32_to_cpu(cmd->caps[0]); + hclge_comm_capability_to_bitmap(caps, cmd->caps); for (i = 0; i < size; i++) - if (hnae3_get_bit(caps, caps_map[i].imp_bit)) + if (test_bit(caps_map[i].imp_bit, caps)) set_bit(caps_map[i].local_bit, ae_dev->caps); } -- cgit From 6d2336120aa6e1a8a64fa5d6ee5c3f3d0809fe9b Mon Sep 17 00:00:00 2001 From: Hao Lan Date: Thu, 20 Jul 2023 10:05:08 +0800 Subject: net: hns3: add tm flush when setting tm When the tm module is configured with traffic, traffic may be abnormal. This patch fixes this problem. Before the tm module is configured, traffic processing should be stopped. After the tm module is configured, traffic processing is enabled. Signed-off-by: Hao Lan Signed-off-by: Jijie Shao Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 4 +++ .../hisilicon/hns3/hns3_common/hclge_comm_cmd.c | 1 + .../hisilicon/hns3/hns3_common/hclge_comm_cmd.h | 2 ++ drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 3 ++ .../net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 34 ++++++++++++++++++---- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 31 +++++++++++++++++++- .../net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h | 4 +++ 7 files changed, 73 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h index 7de167329b1e..514a20bce4f4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h +++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h @@ -102,6 +102,7 @@ enum HNAE3_DEV_CAP_BITS { HNAE3_DEV_SUPPORT_FEC_STATS_B, HNAE3_DEV_SUPPORT_LANE_NUM_B, HNAE3_DEV_SUPPORT_WOL_B, + HNAE3_DEV_SUPPORT_TM_FLUSH_B, }; #define hnae3_ae_dev_fd_supported(ae_dev) \ @@ -173,6 +174,9 @@ enum HNAE3_DEV_CAP_BITS { #define hnae3_ae_dev_wol_supported(ae_dev) \ test_bit(HNAE3_DEV_SUPPORT_WOL_B, (ae_dev)->caps) +#define hnae3_ae_dev_tm_flush_supported(hdev) \ + test_bit(HNAE3_DEV_SUPPORT_TM_FLUSH_B, (hdev)->ae_dev->caps) + enum HNAE3_PF_CAP_BITS { HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B = 0, }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c index 16ba98ff2c9b..dcecb23daac6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.c @@ -156,6 +156,7 @@ static const struct hclge_comm_caps_bit_map hclge_pf_cmd_caps[] = { {HCLGE_COMM_CAP_FEC_STATS_B, HNAE3_DEV_SUPPORT_FEC_STATS_B}, {HCLGE_COMM_CAP_LANE_NUM_B, HNAE3_DEV_SUPPORT_LANE_NUM_B}, {HCLGE_COMM_CAP_WOL_B, HNAE3_DEV_SUPPORT_WOL_B}, + {HCLGE_COMM_CAP_TM_FLUSH_B, HNAE3_DEV_SUPPORT_TM_FLUSH_B}, }; static const struct hclge_comm_caps_bit_map hclge_vf_cmd_caps[] = { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h index 18f1b4bf362d..2b7197ce0ae8 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_common/hclge_comm_cmd.h @@ -153,6 +153,7 @@ enum hclge_opcode_type { HCLGE_OPC_TM_INTERNAL_STS = 0x0850, HCLGE_OPC_TM_INTERNAL_CNT = 0x0851, HCLGE_OPC_TM_INTERNAL_STS_1 = 0x0852, + HCLGE_OPC_TM_FLUSH = 0x0872, /* Packet buffer allocate commands */ HCLGE_OPC_TX_BUFF_ALLOC = 0x0901, @@ -349,6 +350,7 @@ enum HCLGE_COMM_CAP_BITS { HCLGE_COMM_CAP_FEC_STATS_B = 25, HCLGE_COMM_CAP_LANE_NUM_B = 27, HCLGE_COMM_CAP_WOL_B = 28, + HCLGE_COMM_CAP_TM_FLUSH_B = 31, }; enum HCLGE_COMM_API_CAP_BITS { diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c index 6546cfe7f7cc..52546f625c8b 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c @@ -411,6 +411,9 @@ static struct hns3_dbg_cap_info hns3_dbg_cap[] = { }, { .name = "support wake on lan", .cap_bit = HNAE3_DEV_SUPPORT_WOL_B, + }, { + .name = "support tm flush", + .cap_bit = HNAE3_DEV_SUPPORT_TM_FLUSH_B, } }; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c index c4aded65e848..cda7e0d0ba56 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c @@ -216,6 +216,10 @@ static int hclge_notify_down_uinit(struct hclge_dev *hdev) if (ret) return ret; + ret = hclge_tm_flush_cfg(hdev, true); + if (ret) + return ret; + return hclge_notify_client(hdev, HNAE3_UNINIT_CLIENT); } @@ -227,6 +231,10 @@ static int hclge_notify_init_up(struct hclge_dev *hdev) if (ret) return ret; + ret = hclge_tm_flush_cfg(hdev, false); + if (ret) + return ret; + return hclge_notify_client(hdev, HNAE3_UP_CLIENT); } @@ -313,6 +321,7 @@ static int hclge_ieee_setpfc(struct hnae3_handle *h, struct ieee_pfc *pfc) struct net_device *netdev = h->kinfo.netdev; struct hclge_dev *hdev = vport->back; u8 i, j, pfc_map, *prio_tc; + int last_bad_ret = 0; int ret; if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) @@ -350,13 +359,28 @@ static int hclge_ieee_setpfc(struct hnae3_handle *h, struct ieee_pfc *pfc) if (ret) return ret; - ret = hclge_buffer_alloc(hdev); - if (ret) { - hclge_notify_client(hdev, HNAE3_UP_CLIENT); + ret = hclge_tm_flush_cfg(hdev, true); + if (ret) return ret; - } - return hclge_notify_client(hdev, HNAE3_UP_CLIENT); + /* No matter whether the following operations are performed + * successfully or not, disabling the tm flush and notify + * the network status to up are necessary. + * Do not return immediately. + */ + ret = hclge_buffer_alloc(hdev); + if (ret) + last_bad_ret = ret; + + ret = hclge_tm_flush_cfg(hdev, false); + if (ret) + last_bad_ret = ret; + + ret = hclge_notify_client(hdev, HNAE3_UP_CLIENT); + if (ret) + last_bad_ret = ret; + + return last_bad_ret; } static int hclge_ieee_setapp(struct hnae3_handle *h, struct dcb_app *app) diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c index 922c0da3660c..c40ea6b8c8ec 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -1484,7 +1484,11 @@ int hclge_tm_schd_setup_hw(struct hclge_dev *hdev) return ret; /* Cfg schd mode for each level schd */ - return hclge_tm_schd_mode_hw(hdev); + ret = hclge_tm_schd_mode_hw(hdev); + if (ret) + return ret; + + return hclge_tm_flush_cfg(hdev, false); } static int hclge_pause_param_setup_hw(struct hclge_dev *hdev) @@ -2113,3 +2117,28 @@ int hclge_tm_get_port_shaper(struct hclge_dev *hdev, return 0; } + +int hclge_tm_flush_cfg(struct hclge_dev *hdev, bool enable) +{ + struct hclge_desc desc; + int ret; + + if (!hnae3_ae_dev_tm_flush_supported(hdev)) + return 0; + + hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_FLUSH, false); + + desc.data[0] = cpu_to_le32(enable ? HCLGE_TM_FLUSH_EN_MSK : 0); + + ret = hclge_cmd_send(&hdev->hw, &desc, 1); + if (ret) { + dev_err(&hdev->pdev->dev, + "failed to config tm flush, ret = %d\n", ret); + return ret; + } + + if (enable) + msleep(HCLGE_TM_FLUSH_TIME_MS); + + return ret; +} diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h index dd6f1fd486cf..45dcfef3f90c 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.h @@ -33,6 +33,9 @@ enum hclge_opcode_type; #define HCLGE_DSCP_MAP_TC_BD_NUM 2 #define HCLGE_DSCP_TC_SHIFT(n) (((n) & 1) * 4) +#define HCLGE_TM_FLUSH_TIME_MS 10 +#define HCLGE_TM_FLUSH_EN_MSK BIT(0) + struct hclge_pg_to_pri_link_cmd { u8 pg_id; u8 rsvd1[3]; @@ -272,4 +275,5 @@ int hclge_tm_get_port_shaper(struct hclge_dev *hdev, struct hclge_tm_shaper_para *para); int hclge_up_to_tc_map(struct hclge_dev *hdev); int hclge_dscp_to_tc_map(struct hclge_dev *hdev); +int hclge_tm_flush_cfg(struct hclge_dev *hdev, bool enable); #endif -- cgit From 116d9f732eef634abbd871f2c6f613a5b4677742 Mon Sep 17 00:00:00 2001 From: Jijie Shao Date: Thu, 20 Jul 2023 10:05:09 +0800 Subject: net: hns3: fix wrong tc bandwidth weight data issue Currently, the weight saved by the driver is used as the query result, which may be different from the actual weight in the register. Therefore, the register value read from the firmware is used as the query result Fixes: 0e32038dc856 ("net: hns3: refactor dump tc of debugfs") Signed-off-by: Jijie Shao Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c index 233c132dc513..409db2e70965 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -693,8 +693,7 @@ static int hclge_dbg_dump_tc(struct hclge_dev *hdev, char *buf, int len) for (i = 0; i < HNAE3_MAX_TC; i++) { sch_mode_str = ets_weight->tc_weight[i] ? "dwrr" : "sp"; pos += scnprintf(buf + pos, len - pos, "%u %4s %3u\n", - i, sch_mode_str, - hdev->tm_info.pg_info[0].tc_dwrr[i]); + i, sch_mode_str, ets_weight->tc_weight[i]); } return 0; -- cgit From 882481b1c55fc44861d7e2d54b4e0936b1b39f2c Mon Sep 17 00:00:00 2001 From: Jijie Shao Date: Thu, 20 Jul 2023 10:05:10 +0800 Subject: net: hns3: fix wrong bw weight of disabled tc issue In dwrr mode, the default bandwidth weight of disabled tc is set to 0. If the bandwidth weight is 0, the mode will change to sp. Therefore, disabled tc default bandwidth weight need changed to 1, and 0 is returned when query the bandwidth weight of disabled tc. In addition, driver need stop configure bandwidth weight if tc is disabled. Fixes: 848440544b41 ("net: hns3: Add support of TX Scheduler & Shaper to HNS3 driver") Signed-off-by: Jie Wang Signed-off-by: Jijie Shao Signed-off-by: David S. Miller --- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c | 17 ++++++++++++++--- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c | 3 ++- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c index cda7e0d0ba56..fad5a5ff3cda 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c @@ -52,7 +52,10 @@ static void hclge_tm_info_to_ieee_ets(struct hclge_dev *hdev, for (i = 0; i < HNAE3_MAX_TC; i++) { ets->prio_tc[i] = hdev->tm_info.prio_tc[i]; - ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i]; + if (i < hdev->tm_info.num_tc) + ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i]; + else + ets->tc_tx_bw[i] = 0; if (hdev->tm_info.tc_info[i].tc_sch_mode == HCLGE_SCH_MODE_SP) @@ -123,7 +126,8 @@ static u8 hclge_ets_tc_changed(struct hclge_dev *hdev, struct ieee_ets *ets, } static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev, - struct ieee_ets *ets, bool *changed) + struct ieee_ets *ets, bool *changed, + u8 tc_num) { bool has_ets_tc = false; u32 total_ets_bw = 0; @@ -137,6 +141,13 @@ static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev, *changed = true; break; case IEEE_8021QAZ_TSA_ETS: + if (i >= tc_num) { + dev_err(&hdev->pdev->dev, + "tc%u is disabled, cannot set ets bw\n", + i); + return -EINVAL; + } + /* The hardware will switch to sp mode if bandwidth is * 0, so limit ets bandwidth must be greater than 0. */ @@ -176,7 +187,7 @@ static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets, if (ret) return ret; - ret = hclge_ets_sch_mode_validate(hdev, ets, changed); + ret = hclge_ets_sch_mode_validate(hdev, ets, changed, tc_num); if (ret) return ret; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c index c40ea6b8c8ec..de509e5751a7 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_tm.c @@ -785,6 +785,7 @@ static void hclge_tm_tc_info_init(struct hclge_dev *hdev) static void hclge_tm_pg_info_init(struct hclge_dev *hdev) { #define BW_PERCENT 100 +#define DEFAULT_BW_WEIGHT 1 u8 i; @@ -806,7 +807,7 @@ static void hclge_tm_pg_info_init(struct hclge_dev *hdev) for (k = 0; k < hdev->tm_info.num_tc; k++) hdev->tm_info.pg_info[i].tc_dwrr[k] = BW_PERCENT; for (; k < HNAE3_MAX_TC; k++) - hdev->tm_info.pg_info[i].tc_dwrr[k] = 0; + hdev->tm_info.pg_info[i].tc_dwrr[k] = DEFAULT_BW_WEIGHT; } } -- cgit From 94d166c5318c6edd1e079df8552233443e909c33 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Thu, 20 Jul 2023 11:05:56 +0200 Subject: vxlan: calculate correct header length for GPE VXLAN-GPE does not add an extra inner Ethernet header. Take that into account when calculating header length. This causes problems in skb_tunnel_check_pmtu, where incorrect PMTU is cached. In the collect_md mode (which is the only mode that VXLAN-GPE supports), there's no magic auto-setting of the tunnel interface MTU. It can't be, since the destination and thus the underlying interface may be different for each packet. So, the administrator is responsible for setting the correct tunnel interface MTU. Apparently, the administrators are capable enough to calculate that the maximum MTU for VXLAN-GPE is (their_lower_MTU - 36). They set the tunnel interface MTU to 1464. If you run a TCP stream over such interface, it's then segmented according to the MTU 1464, i.e. producing 1514 bytes frames. Which is okay, this still fits the lower MTU. However, skb_tunnel_check_pmtu (called from vxlan_xmit_one) uses 50 as the header size and thus incorrectly calculates the frame size to be 1528. This leads to ICMP too big message being generated (locally), PMTU of 1450 to be cached and the TCP stream to be resegmented. The fix is to use the correct actual header size, especially for skb_tunnel_check_pmtu calculation. Fixes: e1e5314de08ba ("vxlan: implement GPE") Signed-off-by: Jiri Benc Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- drivers/net/vxlan/vxlan_core.c | 23 ++++++++++------------- 2 files changed, 11 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 1726297f2e0d..8eb9839a3ca6 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -8479,7 +8479,7 @@ static void ixgbe_atr(struct ixgbe_ring *ring, struct ixgbe_adapter *adapter = q_vector->adapter; if (unlikely(skb_tail_pointer(skb) < hdr.network + - VXLAN_HEADROOM)) + vxlan_headroom(0))) return; /* verify the port is recognized as VXLAN */ diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index 78744549c1b3..42be8a26c171 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -2516,7 +2516,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, } ndst = &rt->dst; - err = skb_tunnel_check_pmtu(skb, ndst, VXLAN_HEADROOM, + err = skb_tunnel_check_pmtu(skb, ndst, vxlan_headroom(flags & VXLAN_F_GPE), netif_is_any_bridge_port(dev)); if (err < 0) { goto tx_error; @@ -2577,7 +2577,8 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, goto out_unlock; } - err = skb_tunnel_check_pmtu(skb, ndst, VXLAN6_HEADROOM, + err = skb_tunnel_check_pmtu(skb, ndst, + vxlan_headroom((flags & VXLAN_F_GPE) | VXLAN_F_IPV6), netif_is_any_bridge_port(dev)); if (err < 0) { goto tx_error; @@ -2989,14 +2990,12 @@ static int vxlan_change_mtu(struct net_device *dev, int new_mtu) struct vxlan_rdst *dst = &vxlan->default_dst; struct net_device *lowerdev = __dev_get_by_index(vxlan->net, dst->remote_ifindex); - bool use_ipv6 = !!(vxlan->cfg.flags & VXLAN_F_IPV6); /* This check is different than dev->max_mtu, because it looks at * the lowerdev->mtu, rather than the static dev->max_mtu */ if (lowerdev) { - int max_mtu = lowerdev->mtu - - (use_ipv6 ? VXLAN6_HEADROOM : VXLAN_HEADROOM); + int max_mtu = lowerdev->mtu - vxlan_headroom(vxlan->cfg.flags); if (new_mtu > max_mtu) return -EINVAL; } @@ -3644,11 +3643,11 @@ static void vxlan_config_apply(struct net_device *dev, struct vxlan_dev *vxlan = netdev_priv(dev); struct vxlan_rdst *dst = &vxlan->default_dst; unsigned short needed_headroom = ETH_HLEN; - bool use_ipv6 = !!(conf->flags & VXLAN_F_IPV6); int max_mtu = ETH_MAX_MTU; + u32 flags = conf->flags; if (!changelink) { - if (conf->flags & VXLAN_F_GPE) + if (flags & VXLAN_F_GPE) vxlan_raw_setup(dev); else vxlan_ether_setup(dev); @@ -3673,8 +3672,7 @@ static void vxlan_config_apply(struct net_device *dev, dev->needed_tailroom = lowerdev->needed_tailroom; - max_mtu = lowerdev->mtu - (use_ipv6 ? VXLAN6_HEADROOM : - VXLAN_HEADROOM); + max_mtu = lowerdev->mtu - vxlan_headroom(flags); if (max_mtu < ETH_MIN_MTU) max_mtu = ETH_MIN_MTU; @@ -3685,10 +3683,9 @@ static void vxlan_config_apply(struct net_device *dev, if (dev->mtu > max_mtu) dev->mtu = max_mtu; - if (use_ipv6 || conf->flags & VXLAN_F_COLLECT_METADATA) - needed_headroom += VXLAN6_HEADROOM; - else - needed_headroom += VXLAN_HEADROOM; + if (flags & VXLAN_F_COLLECT_METADATA) + flags |= VXLAN_F_IPV6; + needed_headroom += vxlan_headroom(flags); dev->needed_headroom = needed_headroom; memcpy(&vxlan->cfg, conf, sizeof(*conf)); -- cgit From 8d01da0a1db237c44c92859ce3612df7af8d3a53 Mon Sep 17 00:00:00 2001 From: Yuanjun Gong Date: Thu, 20 Jul 2023 22:42:08 +0800 Subject: ethernet: atheros: fix return value check in atl1c_tso_csum() in atl1c_tso_csum, it should check the return value of pskb_trim(), and return an error code if an unexpected value is returned by pskb_trim(). Signed-off-by: Yuanjun Gong Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 4a288799633f..940c5d1ff9cf 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -2094,8 +2094,11 @@ static int atl1c_tso_csum(struct atl1c_adapter *adapter, real_len = (((unsigned char *)ip_hdr(skb) - skb->data) + ntohs(ip_hdr(skb)->tot_len)); - if (real_len < skb->len) - pskb_trim(skb, real_len); + if (real_len < skb->len) { + err = pskb_trim(skb, real_len); + if (err) + return err; + } hdr_len = skb_tcp_all_headers(skb); if (unlikely(skb->len == hdr_len)) { -- cgit From 17a0a64448b568442a101de09575f81ffdc45d15 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Fri, 21 Jul 2023 16:30:46 +0200 Subject: vxlan: generalize vxlan_parse_gpe_hdr and remove unused args The vxlan_parse_gpe_hdr function extracts the next protocol value from the GPE header and marks GPE bits as parsed. In order to be used in the next patch, split the function into protocol extraction and bit marking. The bit marking is meaningful only in vxlan_rcv; move it directly there. Rename the function to vxlan_parse_gpe_proto to reflect what it now does. Remove unused arguments skb and vxflags. Move the function earlier in the file to allow it to be called from more places in the next patch. Signed-off-by: Jiri Benc Signed-off-by: David S. Miller --- drivers/net/vxlan/vxlan_core.c | 58 ++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index 42be8a26c171..6d82adf1f8b3 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -623,6 +623,32 @@ static int vxlan_fdb_append(struct vxlan_fdb *f, return 1; } +static bool vxlan_parse_gpe_proto(struct vxlanhdr *hdr, __be16 *protocol) +{ + struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)hdr; + + /* Need to have Next Protocol set for interfaces in GPE mode. */ + if (!gpe->np_applied) + return false; + /* "The initial version is 0. If a receiver does not support the + * version indicated it MUST drop the packet. + */ + if (gpe->version != 0) + return false; + /* "When the O bit is set to 1, the packet is an OAM packet and OAM + * processing MUST occur." However, we don't implement OAM + * processing, thus drop the packet. + */ + if (gpe->oam_flag) + return false; + + *protocol = tun_p_to_eth_p(gpe->next_protocol); + if (!*protocol) + return false; + + return true; +} + static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, unsigned int off, struct vxlanhdr *vh, size_t hdrlen, @@ -1525,35 +1551,6 @@ out: unparsed->vx_flags &= ~VXLAN_GBP_USED_BITS; } -static bool vxlan_parse_gpe_hdr(struct vxlanhdr *unparsed, - __be16 *protocol, - struct sk_buff *skb, u32 vxflags) -{ - struct vxlanhdr_gpe *gpe = (struct vxlanhdr_gpe *)unparsed; - - /* Need to have Next Protocol set for interfaces in GPE mode. */ - if (!gpe->np_applied) - return false; - /* "The initial version is 0. If a receiver does not support the - * version indicated it MUST drop the packet. - */ - if (gpe->version != 0) - return false; - /* "When the O bit is set to 1, the packet is an OAM packet and OAM - * processing MUST occur." However, we don't implement OAM - * processing, thus drop the packet. - */ - if (gpe->oam_flag) - return false; - - *protocol = tun_p_to_eth_p(gpe->next_protocol); - if (!*protocol) - return false; - - unparsed->vx_flags &= ~VXLAN_GPE_USED_BITS; - return true; -} - static bool vxlan_set_mac(struct vxlan_dev *vxlan, struct vxlan_sock *vs, struct sk_buff *skb, __be32 vni) @@ -1655,8 +1652,9 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb) * used by VXLAN extensions if explicitly requested. */ if (vs->flags & VXLAN_F_GPE) { - if (!vxlan_parse_gpe_hdr(&unparsed, &protocol, skb, vs->flags)) + if (!vxlan_parse_gpe_proto(&unparsed, &protocol)) goto drop; + unparsed.vx_flags &= ~VXLAN_GPE_USED_BITS; raw_proto = true; } -- cgit From b0b672c4d0957e5897685667fc848132b8bd2d71 Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Fri, 21 Jul 2023 16:30:47 +0200 Subject: vxlan: fix GRO with VXLAN-GPE In VXLAN-GPE, there may not be an Ethernet header following the VXLAN header. But in GRO, the vxlan driver calls eth_gro_receive unconditionally, which means the following header is incorrectly parsed as Ethernet. Introduce GPE specific GRO handling. For better performance, do not check for GPE during GRO but rather install a different set of functions at setup time. Fixes: e1e5314de08ba ("vxlan: implement GPE") Reported-by: Paolo Abeni Signed-off-by: Jiri Benc Signed-off-by: David S. Miller --- drivers/net/vxlan/vxlan_core.c | 84 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index 6d82adf1f8b3..c9a9373733c0 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -675,26 +675,24 @@ static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, return vh; } -static struct sk_buff *vxlan_gro_receive(struct sock *sk, - struct list_head *head, - struct sk_buff *skb) +static struct vxlanhdr *vxlan_gro_prepare_receive(struct sock *sk, + struct list_head *head, + struct sk_buff *skb, + struct gro_remcsum *grc) { - struct sk_buff *pp = NULL; struct sk_buff *p; struct vxlanhdr *vh, *vh2; unsigned int hlen, off_vx; - int flush = 1; struct vxlan_sock *vs = rcu_dereference_sk_user_data(sk); __be32 flags; - struct gro_remcsum grc; - skb_gro_remcsum_init(&grc); + skb_gro_remcsum_init(grc); off_vx = skb_gro_offset(skb); hlen = off_vx + sizeof(*vh); vh = skb_gro_header(skb, hlen, off_vx); if (unlikely(!vh)) - goto out; + return NULL; skb_gro_postpull_rcsum(skb, vh, sizeof(struct vxlanhdr)); @@ -702,12 +700,12 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk, if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) { vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr), - vh->vx_vni, &grc, + vh->vx_vni, grc, !!(vs->flags & VXLAN_F_REMCSUM_NOPARTIAL)); if (!vh) - goto out; + return NULL; } skb_gro_pull(skb, sizeof(struct vxlanhdr)); /* pull vxlan header */ @@ -724,12 +722,48 @@ static struct sk_buff *vxlan_gro_receive(struct sock *sk, } } - pp = call_gro_receive(eth_gro_receive, head, skb); - flush = 0; + return vh; +} + +static struct sk_buff *vxlan_gro_receive(struct sock *sk, + struct list_head *head, + struct sk_buff *skb) +{ + struct sk_buff *pp = NULL; + struct gro_remcsum grc; + int flush = 1; -out: + if (vxlan_gro_prepare_receive(sk, head, skb, &grc)) { + pp = call_gro_receive(eth_gro_receive, head, skb); + flush = 0; + } skb_gro_flush_final_remcsum(skb, pp, flush, &grc); + return pp; +} +static struct sk_buff *vxlan_gpe_gro_receive(struct sock *sk, + struct list_head *head, + struct sk_buff *skb) +{ + const struct packet_offload *ptype; + struct sk_buff *pp = NULL; + struct gro_remcsum grc; + struct vxlanhdr *vh; + __be16 protocol; + int flush = 1; + + vh = vxlan_gro_prepare_receive(sk, head, skb, &grc); + if (vh) { + if (!vxlan_parse_gpe_proto(vh, &protocol)) + goto out; + ptype = gro_find_receive_by_type(protocol); + if (!ptype) + goto out; + pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb); + flush = 0; + } +out: + skb_gro_flush_final_remcsum(skb, pp, flush, &grc); return pp; } @@ -741,6 +775,21 @@ static int vxlan_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff) return eth_gro_complete(skb, nhoff + sizeof(struct vxlanhdr)); } +static int vxlan_gpe_gro_complete(struct sock *sk, struct sk_buff *skb, int nhoff) +{ + struct vxlanhdr *vh = (struct vxlanhdr *)(skb->data + nhoff); + const struct packet_offload *ptype; + int err = -ENOSYS; + __be16 protocol; + + if (!vxlan_parse_gpe_proto(vh, &protocol)) + return err; + ptype = gro_find_complete_by_type(protocol); + if (ptype) + err = ptype->callbacks.gro_complete(skb, nhoff + sizeof(struct vxlanhdr)); + return err; +} + static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan, const u8 *mac, __u16 state, __be32 src_vni, __u16 ndm_flags) @@ -3376,8 +3425,13 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6, tunnel_cfg.encap_rcv = vxlan_rcv; tunnel_cfg.encap_err_lookup = vxlan_err_lookup; tunnel_cfg.encap_destroy = NULL; - tunnel_cfg.gro_receive = vxlan_gro_receive; - tunnel_cfg.gro_complete = vxlan_gro_complete; + if (vs->flags & VXLAN_F_GPE) { + tunnel_cfg.gro_receive = vxlan_gpe_gro_receive; + tunnel_cfg.gro_complete = vxlan_gpe_gro_complete; + } else { + tunnel_cfg.gro_receive = vxlan_gro_receive; + tunnel_cfg.gro_complete = vxlan_gro_complete; + } setup_udp_tunnel_sock(net, sock, &tunnel_cfg); -- cgit From 13c088cf3657d70893d75cf116be937f1509cc0f Mon Sep 17 00:00:00 2001 From: Harshit Mogalapalli Date: Fri, 21 Jul 2023 02:05:55 -0700 Subject: phy: hisilicon: Fix an out of bounds check in hisi_inno_phy_probe() The size of array 'priv->ports[]' is INNO_PHY_PORT_NUM. In the for loop, 'i' is used as the index for array 'priv->ports[]' with a check (i > INNO_PHY_PORT_NUM) which indicates that INNO_PHY_PORT_NUM is allowed value for 'i' in the same loop. This > comparison needs to be changed to >=, otherwise it potentially leads to an out of bounds write on the next iteration through the loop Fixes: ba8b0ee81fbb ("phy: add inno-usb2-phy driver for hi3798cv200 SoC") Reported-by: Dan Carpenter Signed-off-by: Harshit Mogalapalli Link: https://lore.kernel.org/r/20230721090558.3588613-1-harshit.m.mogalapalli@oracle.com Signed-off-by: Vinod Koul --- drivers/phy/hisilicon/phy-hisi-inno-usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/phy/hisilicon/phy-hisi-inno-usb2.c b/drivers/phy/hisilicon/phy-hisi-inno-usb2.c index 15dafe359552..6ae6d509dfdd 100644 --- a/drivers/phy/hisilicon/phy-hisi-inno-usb2.c +++ b/drivers/phy/hisilicon/phy-hisi-inno-usb2.c @@ -184,7 +184,7 @@ static int hisi_inno_phy_probe(struct platform_device *pdev) phy_set_drvdata(phy, &priv->ports[i]); i++; - if (i > INNO_PHY_PORT_NUM) { + if (i >= INNO_PHY_PORT_NUM) { dev_warn(dev, "Support %d ports in maximum\n", i); of_node_put(child); break; -- cgit From 54685abe660a59402344d5045ce08c43c6a5ac42 Mon Sep 17 00:00:00 2001 From: Gilles Buloz Date: Mon, 24 Jul 2023 08:04:44 +0000 Subject: hwmon: (nct7802) Fix for temp6 (PECI1) processed even if PECI1 disabled Because of hex value 0x46 used instead of decimal 46, the temp6 (PECI1) temperature is always declared visible and then displayed even if disabled in the chip Signed-off-by: Gilles Buloz Link: https://lore.kernel.org/r/DU0PR10MB62526435ADBC6A85243B90E08002A@DU0PR10MB6252.EURPRD10.PROD.OUTLOOK.COM Fixes: fcdc5739dce03 ("hwmon: (nct7802) add temperature sensor type attribute") Cc: stable@vger.kernel.org Signed-off-by: Guenter Roeck --- drivers/hwmon/nct7802.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/nct7802.c b/drivers/hwmon/nct7802.c index 9339bfc02a3e..024cff151c36 100644 --- a/drivers/hwmon/nct7802.c +++ b/drivers/hwmon/nct7802.c @@ -725,7 +725,7 @@ static umode_t nct7802_temp_is_visible(struct kobject *kobj, if (index >= 38 && index < 46 && !(reg & 0x01)) /* PECI 0 */ return 0; - if (index >= 0x46 && (!(reg & 0x02))) /* PECI 1 */ + if (index >= 46 && !(reg & 0x02)) /* PECI 1 */ return 0; return attr->mode; -- cgit From 05f1d8ed03f547054efbc4d29bb7991c958ede95 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Fri, 21 Jul 2023 21:36:44 +0200 Subject: s390/dasd: fix hanging device after quiesce/resume Quiesce and resume are functions that tell the DASD driver to stop/resume issuing I/Os to a specific DASD. On resume dasd_schedule_block_bh() is called to kick handling of IO requests again. This does unfortunately not cover internal requests which are used for path verification for example. This could lead to a hanging device when a path event or anything else that triggers internal requests occurs on a quiesced device. Fix by also calling dasd_schedule_device_bh() which triggers handling of internal requests on resume. Fixes: 8e09f21574ea ("[S390] dasd: add hyper PAV support to DASD device driver, part 1") Cc: stable@vger.kernel.org Signed-off-by: Stefan Haberland Reviewed-by: Jan Hoeppner Link: https://lore.kernel.org/r/20230721193647.3889634-2-sth@linux.ibm.com Signed-off-by: Jens Axboe --- drivers/s390/block/dasd_ioctl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 513a7e6eee63..d55862605b82 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -131,6 +131,7 @@ static int dasd_ioctl_resume(struct dasd_block *block) spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); dasd_schedule_block_bh(block); + dasd_schedule_device_bh(base); return 0; } -- cgit From acea28a6b74f458defda7417d2217b051ba7d444 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Fri, 21 Jul 2023 21:36:45 +0200 Subject: s390/dasd: use correct number of retries for ERP requests If a DASD request fails an error recovery procedure (ERP) request might be built as a copy of the original request to do error recovery. The ERP request gets a number of retries assigned. This number is always 256 no matter what other value might have been set for the original request. This is not what is expected when a user specifies a certain amount of retries for the device via sysfs. Correctly use the number of retries of the original request for ERP requests. Signed-off-by: Stefan Haberland Reviewed-by: Jan Hoeppner Link: https://lore.kernel.org/r/20230721193647.3889634-3-sth@linux.ibm.com Signed-off-by: Jens Axboe --- drivers/s390/block/dasd_3990_erp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 9fd36c468706..91e9a17b848e 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -2441,7 +2441,7 @@ static struct dasd_ccw_req *dasd_3990_erp_add_erp(struct dasd_ccw_req *cqr) erp->block = cqr->block; erp->magic = cqr->magic; erp->expires = cqr->expires; - erp->retries = 256; + erp->retries = device->default_retries; erp->buildclk = get_tod_clock(); erp->status = DASD_CQR_FILLED; -- cgit From 8a2278ce9c25048d999fe1a3561def75d963f471 Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Fri, 21 Jul 2023 21:36:46 +0200 Subject: s390/dasd: fix hanging device after request requeue The DASD device driver has a function to requeue requests to the blocklayer. This function is used in various cases when basic settings for the device have to be changed like High Performance Ficon related parameters or copy pair settings. The functions iterates over the device->ccw_queue and also removes the requests from the block->ccw_queue. In case the device is started on an alias device instead of the base device it might be removed from the block->ccw_queue without having it canceled properly before. This might lead to a hanging device since the request is no longer on a queue and can not be handled properly. Fix by iterating over the block->ccw_queue instead of the device->ccw_queue. This will take care of all blocklayer related requests and handle them on all associated DASD devices. Signed-off-by: Stefan Haberland Reviewed-by: Jan Hoeppner Link: https://lore.kernel.org/r/20230721193647.3889634-4-sth@linux.ibm.com Signed-off-by: Jens Axboe --- drivers/s390/block/dasd.c | 125 ++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 77 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index edcbf77852c3..50a5ff70814a 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -2943,41 +2943,32 @@ static void _dasd_wake_block_flush_cb(struct dasd_ccw_req *cqr, void *data) * Requeue a request back to the block request queue * only works for block requests */ -static int _dasd_requeue_request(struct dasd_ccw_req *cqr) +static void _dasd_requeue_request(struct dasd_ccw_req *cqr) { - struct dasd_block *block = cqr->block; struct request *req; - if (!block) - return -EINVAL; /* * If the request is an ERP request there is nothing to requeue. * This will be done with the remaining original request. */ if (cqr->refers) - return 0; + return; spin_lock_irq(&cqr->dq->lock); req = (struct request *) cqr->callback_data; blk_mq_requeue_request(req, true); spin_unlock_irq(&cqr->dq->lock); - return 0; + return; } -/* - * Go through all request on the dasd_block request queue, cancel them - * on the respective dasd_device, and return them to the generic - * block layer. - */ -static int dasd_flush_block_queue(struct dasd_block *block) +static int _dasd_requests_to_flushqueue(struct dasd_block *block, + struct list_head *flush_queue) { struct dasd_ccw_req *cqr, *n; - int rc, i; - struct list_head flush_queue; unsigned long flags; + int rc, i; - INIT_LIST_HEAD(&flush_queue); - spin_lock_bh(&block->queue_lock); + spin_lock_irqsave(&block->queue_lock, flags); rc = 0; restart: list_for_each_entry_safe(cqr, n, &block->ccw_queue, blocklist) { @@ -2992,13 +2983,32 @@ restart: * is returned from the dasd_device layer. */ cqr->callback = _dasd_wake_block_flush_cb; - for (i = 0; cqr != NULL; cqr = cqr->refers, i++) - list_move_tail(&cqr->blocklist, &flush_queue); + for (i = 0; cqr; cqr = cqr->refers, i++) + list_move_tail(&cqr->blocklist, flush_queue); if (i > 1) /* moved more than one request - need to restart */ goto restart; } - spin_unlock_bh(&block->queue_lock); + spin_unlock_irqrestore(&block->queue_lock, flags); + + return rc; +} + +/* + * Go through all request on the dasd_block request queue, cancel them + * on the respective dasd_device, and return them to the generic + * block layer. + */ +static int dasd_flush_block_queue(struct dasd_block *block) +{ + struct dasd_ccw_req *cqr, *n; + struct list_head flush_queue; + unsigned long flags; + int rc; + + INIT_LIST_HEAD(&flush_queue); + rc = _dasd_requests_to_flushqueue(block, &flush_queue); + /* Now call the callback function of flushed requests */ restart_cb: list_for_each_entry_safe(cqr, n, &flush_queue, blocklist) { @@ -3881,75 +3891,36 @@ EXPORT_SYMBOL_GPL(dasd_generic_space_avail); */ int dasd_generic_requeue_all_requests(struct dasd_device *device) { + struct dasd_block *block = device->block; struct list_head requeue_queue; struct dasd_ccw_req *cqr, *n; - struct dasd_ccw_req *refers; int rc; - INIT_LIST_HEAD(&requeue_queue); - spin_lock_irq(get_ccwdev_lock(device->cdev)); - rc = 0; - list_for_each_entry_safe(cqr, n, &device->ccw_queue, devlist) { - /* Check status and move request to flush_queue */ - if (cqr->status == DASD_CQR_IN_IO) { - rc = device->discipline->term_IO(cqr); - if (rc) { - /* unable to terminate requeust */ - dev_err(&device->cdev->dev, - "Unable to terminate request %p " - "on suspend\n", cqr); - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - dasd_put_device(device); - return rc; - } - } - list_move_tail(&cqr->devlist, &requeue_queue); - } - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - - list_for_each_entry_safe(cqr, n, &requeue_queue, devlist) { - wait_event(dasd_flush_wq, - (cqr->status != DASD_CQR_CLEAR_PENDING)); + if (!block) + return 0; - /* - * requeue requests to blocklayer will only work - * for block device requests - */ - if (_dasd_requeue_request(cqr)) - continue; + INIT_LIST_HEAD(&requeue_queue); + rc = _dasd_requests_to_flushqueue(block, &requeue_queue); - /* remove requests from device and block queue */ - list_del_init(&cqr->devlist); - while (cqr->refers != NULL) { - refers = cqr->refers; - /* remove the request from the block queue */ - list_del(&cqr->blocklist); - /* free the finished erp request */ - dasd_free_erp_request(cqr, cqr->memdev); - cqr = refers; + /* Now call the callback function of flushed requests */ +restart_cb: + list_for_each_entry_safe(cqr, n, &requeue_queue, blocklist) { + wait_event(dasd_flush_wq, (cqr->status < DASD_CQR_QUEUED)); + /* Process finished ERP request. */ + if (cqr->refers) { + spin_lock_bh(&block->queue_lock); + __dasd_process_erp(block->base, cqr); + spin_unlock_bh(&block->queue_lock); + /* restart list_for_xx loop since dasd_process_erp + * might remove multiple elements + */ + goto restart_cb; } - - /* - * _dasd_requeue_request already checked for a valid - * blockdevice, no need to check again - * all erp requests (cqr->refers) have a cqr->block - * pointer copy from the original cqr - */ + _dasd_requeue_request(cqr); list_del_init(&cqr->blocklist); cqr->block->base->discipline->free_cp( cqr, (struct request *) cqr->callback_data); } - - /* - * if requests remain then they are internal request - * and go back to the device queue - */ - if (!list_empty(&requeue_queue)) { - /* move freeze_queue to start of the ccw_queue */ - spin_lock_irq(get_ccwdev_lock(device->cdev)); - list_splice_tail(&requeue_queue, &device->ccw_queue); - spin_unlock_irq(get_ccwdev_lock(device->cdev)); - } dasd_schedule_device_bh(device); return rc; } -- cgit From 856d8e3c633b183df23549ce760ae84478a7098d Mon Sep 17 00:00:00 2001 From: Stefan Haberland Date: Fri, 21 Jul 2023 21:36:47 +0200 Subject: s390/dasd: print copy pair message only for the correct error The DASD driver has certain types of requests that might be rejected by the storage server or z/VM because they are not supported. Since the missing support of the command is not a real issue there is no user visible kernel error message for this. For copy pair setups there is a specific error that IO is not allowed on secondary devices. This error case is explicitly handled and an error message is printed. The code checking for the error did use a bitwise 'and' that is used to check for specific bits. But in this case the whole sense byte has to match. This leads to the problem that the copy pair related error message is erroneously printed for other error cases that are usually not reported. This might heavily confuse users and lead to follow on actions that might disrupt application processing. Fix by checking the sense byte for the exact value and not single bits. Cc: stable@vger.kernel.org # 6.1+ Fixes: 1fca631a1185 ("s390/dasd: suppress generic error messages for PPRC secondary devices") Signed-off-by: Stefan Haberland Reviewed-by: Jan Hoeppner Link: https://lore.kernel.org/r/20230721193647.3889634-5-sth@linux.ibm.com Signed-off-by: Jens Axboe --- drivers/s390/block/dasd_3990_erp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 91e9a17b848e..89957bb7244d 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c @@ -1050,7 +1050,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) dev_err(&device->cdev->dev, "An I/O request was rejected" " because writing is inhibited\n"); erp = dasd_3990_erp_cleanup(erp, DASD_CQR_FAILED); - } else if (sense[7] & SNS7_INVALID_ON_SEC) { + } else if (sense[7] == SNS7_INVALID_ON_SEC) { dev_err(&device->cdev->dev, "An I/O request was rejected on a copy pair secondary device\n"); /* suppress dump of sense data for this error */ set_bit(DASD_CQR_SUPPRESS_CR, &erp->refers->flags); -- cgit From ed96824b71ed67664390890441b229423a25317f Mon Sep 17 00:00:00 2001 From: Yuanjun Gong Date: Sat, 22 Jul 2023 22:25:11 +0800 Subject: atheros: fix return value check in atl1_tso() in atl1_tso(), it should check the return value of pskb_trim(), and return an error code if an unexpected value is returned by pskb_trim(). Fixes: 401c0aabec4b ("atl1: simplify tx packet descriptor") Signed-off-by: Yuanjun Gong Link: https://lore.kernel.org/r/20230722142511.12448-1-ruc_gongyuanjun@163.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/atheros/atlx/atl1.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c index c8444bcdf527..02aa6fd8ebc2 100644 --- a/drivers/net/ethernet/atheros/atlx/atl1.c +++ b/drivers/net/ethernet/atheros/atlx/atl1.c @@ -2113,8 +2113,11 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb, real_len = (((unsigned char *)iph - skb->data) + ntohs(iph->tot_len)); - if (real_len < skb->len) - pskb_trim(skb, real_len); + if (real_len < skb->len) { + err = pskb_trim(skb, real_len); + if (err) + return err; + } hdr_len = skb_tcp_all_headers(skb); if (skb->len == hdr_len) { iph->check = 0; -- cgit From 69a184f7a372aac588babfb0bd681aaed9779f5b Mon Sep 17 00:00:00 2001 From: Yuanjun Gong Date: Thu, 20 Jul 2023 22:42:19 +0800 Subject: ethernet: atheros: fix return value check in atl1e_tso_csum() in atl1e_tso_csum, it should check the return value of pskb_trim(), and return an error code if an unexpected value is returned by pskb_trim(). Fixes: a6a5325239c2 ("atl1e: Atheros L1E Gigabit Ethernet driver") Signed-off-by: Yuanjun Gong Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230720144219.39285-1-ruc_gongyuanjun@163.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 5db0f3495a32..5935be190b9e 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -1641,8 +1641,11 @@ static int atl1e_tso_csum(struct atl1e_adapter *adapter, real_len = (((unsigned char *)ip_hdr(skb) - skb->data) + ntohs(ip_hdr(skb)->tot_len)); - if (real_len < skb->len) - pskb_trim(skb, real_len); + if (real_len < skb->len) { + err = pskb_trim(skb, real_len); + if (err) + return err; + } hdr_len = skb_tcp_all_headers(skb); if (unlikely(skb->len == hdr_len)) { -- cgit From bb7a0156365dffe2fcd63e2051145fbe4f8908b4 Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Fri, 21 Jul 2023 16:35:59 +0800 Subject: net: fec: avoid tx queue timeout when XDP is enabled According to the implementation of XDP of FEC driver, the XDP path shares the transmit queues with the kernel network stack, so it is possible to lead to a tx timeout event when XDP uses the tx queue pretty much exclusively. And this event will cause the reset of the FEC hardware. To avoid timeout in this case, we use the txq_trans_cond_update() interface to update txq->trans_start to jiffies so that watchdog won't generate a transmit timeout warning. Fixes: 6d6b39f180b8 ("net: fec: add initial XDP support") Signed-off-by: Wei Fang Link: https://lore.kernel.org/r/20230721083559.2857312-1-wei.fang@nxp.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/freescale/fec_main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index ec9e4bdb0c06..073d61619336 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3916,6 +3916,8 @@ static int fec_enet_xdp_xmit(struct net_device *dev, __netif_tx_lock(nq, cpu); + /* Avoid tx timeout as XDP shares the queue with kernel stack */ + txq_trans_cond_update(nq); for (i = 0; i < num_frames; i++) { if (fec_enet_txq_xmit_frame(fep, txq, frames[i]) < 0) break; -- cgit From a3336056504d780590ac6d6ac94fbba829994594 Mon Sep 17 00:00:00 2001 From: Jedrzej Jagielski Date: Fri, 21 Jul 2023 08:58:54 -0700 Subject: ice: Fix memory management in ice_ethtool_fdir.c Fix ethtool FDIR logic to not use memory after its release. In the ice_ethtool_fdir.c file there are 2 spots where code can refer to pointers which may be missing. In the ice_cfg_fdir_xtrct_seq() function seg may be freed but even then may be still used by memcpy(&tun_seg[1], seg, sizeof(*seg)). In the ice_add_fdir_ethtool() function struct ice_fdir_fltr *input may first fail to be added via ice_fdir_update_list_entry() but then may be deleted by ice_fdir_update_list_entry. Terminate in both cases when the returned value of the previous operation is other than 0, free memory and don't use it anymore. Reported-by: Michal Schmidt Link: https://bugzilla.redhat.com/show_bug.cgi?id=2208423 Fixes: cac2a27cd9ab ("ice: Support IPv4 Flow Director filters") Reviewed-by: Przemek Kitszel Signed-off-by: Jedrzej Jagielski Reviewed-by: Leon Romanovsky Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) Signed-off-by: Tony Nguyen Link: https://lore.kernel.org/r/20230721155854.1292805-1-anthony.l.nguyen@intel.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c | 26 ++++++++++++----------- 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c index ead6d50fc0ad..8c6e13f87b7d 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool_fdir.c @@ -1281,16 +1281,21 @@ ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp, ICE_FLOW_FLD_OFF_INVAL); } - /* add filter for outer headers */ fltr_idx = ice_ethtool_flow_to_fltr(fsp->flow_type & ~FLOW_EXT); + + assign_bit(fltr_idx, hw->fdir_perfect_fltr, perfect_filter); + + /* add filter for outer headers */ ret = ice_fdir_set_hw_fltr_rule(pf, seg, fltr_idx, ICE_FD_HW_SEG_NON_TUN); - if (ret == -EEXIST) - /* Rule already exists, free memory and continue */ - devm_kfree(dev, seg); - else if (ret) + if (ret == -EEXIST) { + /* Rule already exists, free memory and count as success */ + ret = 0; + goto err_exit; + } else if (ret) { /* could not write filter, free memory */ goto err_exit; + } /* make tunneled filter HW entries if possible */ memcpy(&tun_seg[1], seg, sizeof(*seg)); @@ -1305,18 +1310,13 @@ ice_cfg_fdir_xtrct_seq(struct ice_pf *pf, struct ethtool_rx_flow_spec *fsp, devm_kfree(dev, tun_seg); } - if (perfect_filter) - set_bit(fltr_idx, hw->fdir_perfect_fltr); - else - clear_bit(fltr_idx, hw->fdir_perfect_fltr); - return ret; err_exit: devm_kfree(dev, tun_seg); devm_kfree(dev, seg); - return -EOPNOTSUPP; + return ret; } /** @@ -1914,7 +1914,9 @@ int ice_add_fdir_ethtool(struct ice_vsi *vsi, struct ethtool_rxnfc *cmd) input->comp_report = ICE_FXD_FLTR_QW0_COMP_REPORT_SW_FAIL; /* input struct is added to the HW filter list */ - ice_fdir_update_list_entry(pf, input, fsp->location); + ret = ice_fdir_update_list_entry(pf, input, fsp->location); + if (ret) + goto release_lock; ret = ice_fdir_write_all_fltr(pf, input, true); if (ret) -- cgit From da19a2b967cf1e2c426f50d28550d1915214a81d Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Fri, 21 Jul 2023 12:03:55 +0800 Subject: bonding: reset bond's flags when down link is P2P device When adding a point to point downlink to the bond, we neglected to reset the bond's flags, which were still using flags like BROADCAST and MULTICAST. Consequently, this would initiate ARP/DAD for P2P downlink interfaces, such as when adding a GRE device to the bonding. To address this issue, let's reset the bond's flags for P2P interfaces. Before fix: 7: gre0@NONE: mtu 1500 qdisc noqueue master bond0 state UNKNOWN group default qlen 1000 link/gre6 2006:70:10::1 peer 2006:70:10::2 permaddr 167f:18:f188:: 8: bond0: mtu 1500 qdisc noqueue state UP group default qlen 1000 link/gre6 2006:70:10::1 brd 2006:70:10::2 inet6 fe80::200:ff:fe00:0/64 scope link valid_lft forever preferred_lft forever After fix: 7: gre0@NONE: mtu 1500 qdisc noqueue master bond2 state UNKNOWN group default qlen 1000 link/gre6 2006:70:10::1 peer 2006:70:10::2 permaddr c29e:557a:e9d9:: 8: bond0: mtu 1500 qdisc noqueue state UP group default qlen 1000 link/gre6 2006:70:10::1 peer 2006:70:10::2 inet6 fe80::1/64 scope link valid_lft forever preferred_lft forever Reported-by: Liang Li Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2221438 Fixes: 872254dd6b1f ("net/bonding: Enable bonding to enslave non ARPHRD_ETHER") Signed-off-by: Hangbin Liu Signed-off-by: Paolo Abeni --- drivers/net/bonding/bond_main.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 7a0f25301f7e..484c9e3e5e82 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1508,6 +1508,11 @@ static void bond_setup_by_slave(struct net_device *bond_dev, memcpy(bond_dev->broadcast, slave_dev->broadcast, slave_dev->addr_len); + + if (slave_dev->flags & IFF_POINTOPOINT) { + bond_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); + bond_dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); + } } /* On bonding slaves other than the currently active slave, suppress -- cgit From fa532bee17d15acf8bba4bc8e2062b7a093ba801 Mon Sep 17 00:00:00 2001 From: Hangbin Liu Date: Fri, 21 Jul 2023 12:03:56 +0800 Subject: team: reset team's flags when down link is P2P device When adding a point to point downlink to team device, we neglected to reset the team's flags, which were still using flags like BROADCAST and MULTICAST. Consequently, this would initiate ARP/DAD for P2P downlink interfaces, such as when adding a GRE device to team device. Fix this by remove multicast/broadcast flags and add p2p and noarp flags. After removing the none ethernet interface and adding an ethernet interface to team, we need to reset team interface flags. Unlike bonding interface, team do not need restore IFF_MASTER, IFF_SLAVE flags. Reported-by: Liang Li Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2221438 Fixes: 1d76efe1577b ("team: add support for non-ethernet devices") Signed-off-by: Hangbin Liu Signed-off-by: Paolo Abeni --- drivers/net/team/team.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 555b0b1e9a78..d3dc22509ea5 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -2135,6 +2135,15 @@ static void team_setup_by_port(struct net_device *dev, dev->mtu = port_dev->mtu; memcpy(dev->broadcast, port_dev->broadcast, port_dev->addr_len); eth_hw_addr_inherit(dev, port_dev); + + if (port_dev->flags & IFF_POINTOPOINT) { + dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); + dev->flags |= (IFF_POINTOPOINT | IFF_NOARP); + } else if ((port_dev->flags & (IFF_BROADCAST | IFF_MULTICAST)) == + (IFF_BROADCAST | IFF_MULTICAST)) { + dev->flags |= (IFF_BROADCAST | IFF_MULTICAST); + dev->flags &= ~(IFF_POINTOPOINT | IFF_NOARP); + } } static int team_dev_type_check_change(struct net_device *dev, -- cgit From 3844ed5e78823eebb5f0f1edefc403310693d402 Mon Sep 17 00:00:00 2001 From: Radhakrishna Sripada Date: Tue, 18 Jul 2023 15:51:18 -0700 Subject: drm/i915/dpt: Use shmem for dpt objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dpt objects that are created from internal get evicted when there is memory pressure and do not get restored when pinned during scanout. The pinned page table entries look corrupted and programming the display engine with the incorrect pte's result in DE throwing pipe faults. Create DPT objects from shmem and mark the object as dirty when pinning so that the object is restored when shrinker evicts an unpinned buffer object. v2: Unconditionally mark the dpt objects dirty during pinning(Chris). Fixes: 0dc987b699ce ("drm/i915/display: Add smem fallback allocation for dpt") Cc: # v6.0+ Cc: Ville Syrjälä Cc: Tvrtko Ursulin Suggested-by: Chris Wilson Signed-off-by: Fei Yang Signed-off-by: Radhakrishna Sripada Reviewed-by: Tvrtko Ursulin Link: https://patchwork.freedesktop.org/patch/msgid/20230718225118.2562132-1-radhakrishna.sripada@intel.com (cherry picked from commit e91a777a6e602ba0e3366e053e4e094a334a1244) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/display/intel_dpt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index 7c5fddb203ba..fbfd8f959f17 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -166,6 +166,8 @@ struct i915_vma *intel_dpt_pin(struct i915_address_space *vm) i915_vma_get(vma); } + dpt->obj->mm.dirty = true; + atomic_dec(&i915->gpu_error.pending_fb_pin); intel_runtime_pm_put(&i915->runtime_pm, wakeref); @@ -261,7 +263,7 @@ intel_dpt_create(struct intel_framebuffer *fb) dpt_obj = i915_gem_object_create_stolen(i915, size); if (IS_ERR(dpt_obj) && !HAS_LMEM(i915)) { drm_dbg_kms(&i915->drm, "Allocating dpt from smem\n"); - dpt_obj = i915_gem_object_create_internal(i915, size); + dpt_obj = i915_gem_object_create_shmem(i915, size); } if (IS_ERR(dpt_obj)) return ERR_CAST(dpt_obj); -- cgit From e354f67733115b4453268f61e6e072e9b1ea7a2f Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Mon, 17 Jul 2023 20:49:31 +0200 Subject: drm/i915: Fix an error handling path in igt_write_huge() All error handling paths go to 'out', except this one. Be consistent and also branch to 'out' here. Fixes: c10a652e239e ("drm/i915/selftests: Rework context handling in hugepages selftests") Signed-off-by: Christophe JAILLET Reviewed-by: Andrzej Hajda Reviewed-by: Andi Shyti Signed-off-by: Andi Shyti Link: https://patchwork.freedesktop.org/patch/msgid/7a036b88671312ee9adc01c74ef5b3376f690b76.1689619758.git.christophe.jaillet@wanadoo.fr (cherry picked from commit 361ecaadb1ce3c5312c7c4c419271326d43899eb) Signed-off-by: Tvrtko Ursulin --- drivers/gpu/drm/i915/gem/selftests/huge_pages.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index df6c9a84252c..6b9f6cf50bf6 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -1246,8 +1246,10 @@ static int igt_write_huge(struct drm_i915_private *i915, * times in succession a possibility by enlarging the permutation array. */ order = i915_random_order(count * count, &prng); - if (!order) - return -ENOMEM; + if (!order) { + err = -ENOMEM; + goto out; + } max_page_size = rounddown_pow_of_two(obj->mm.page_sizes.sg); max = div_u64(max - size, max_page_size); -- cgit From 4e62c99d71e56817c934caa2a709a775c8cee078 Mon Sep 17 00:00:00 2001 From: Suman Ghosh Date: Fri, 21 Jul 2023 11:42:22 +0530 Subject: octeontx2-af: Fix hash extraction enable configuration As of today, hash extraction support is enabled for all the silicons. Because of which we are facing initialization issues when the silicon does not support hash extraction. During creation of the hardware parsing table for IPv6 address, we need to consider if hash extraction is enabled then extract only 32 bit, otherwise 128 bit needs to be extracted. This patch fixes the issue and configures the hardware parser based on the availability of the feature. Fixes: a95ab93550d3 ("octeontx2-af: Use hashed field in MCAM key") Signed-off-by: Suman Ghosh Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230721061222.2632521-1-sumang@marvell.com Signed-off-by: Paolo Abeni --- .../ethernet/marvell/octeontx2/af/rvu_npc_hash.c | 43 +++++++++++++++++++++- .../ethernet/marvell/octeontx2/af/rvu_npc_hash.h | 8 ++-- 2 files changed, 46 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c index 6fe67f3a7f6f..7e20282c12d0 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c @@ -218,13 +218,54 @@ void npc_config_secret_key(struct rvu *rvu, int blkaddr) void npc_program_mkex_hash(struct rvu *rvu, int blkaddr) { + struct npc_mcam_kex_hash *mh = rvu->kpu.mkex_hash; struct hw_cap *hwcap = &rvu->hw->cap; + u8 intf, ld, hdr_offset, byte_len; struct rvu_hwinfo *hw = rvu->hw; - u8 intf; + u64 cfg; + /* Check if hardware supports hash extraction */ if (!hwcap->npc_hash_extract) return; + /* Check if IPv6 source/destination address + * should be hash enabled. + * Hashing reduces 128bit SIP/DIP fields to 32bit + * so that 224 bit X2 key can be used for IPv6 based filters as well, + * which in turn results in more number of MCAM entries available for + * use. + * + * Hashing of IPV6 SIP/DIP is enabled in below scenarios + * 1. If the silicon variant supports hashing feature + * 2. If the number of bytes of IP addr being extracted is 4 bytes ie + * 32bit. The assumption here is that if user wants 8bytes of LSB of + * IP addr or full 16 bytes then his intention is not to use 32bit + * hash. + */ + for (intf = 0; intf < hw->npc_intfs; intf++) { + for (ld = 0; ld < NPC_MAX_LD; ld++) { + cfg = rvu_read64(rvu, blkaddr, + NPC_AF_INTFX_LIDX_LTX_LDX_CFG(intf, + NPC_LID_LC, + NPC_LT_LC_IP6, + ld)); + hdr_offset = FIELD_GET(NPC_HDR_OFFSET, cfg); + byte_len = FIELD_GET(NPC_BYTESM, cfg); + /* Hashing of IPv6 source/destination address should be + * enabled if, + * hdr_offset == 8 (offset of source IPv6 address) or + * hdr_offset == 24 (offset of destination IPv6) + * address) and the number of byte to be + * extracted is 4. As per hardware configuration + * byte_len should be == actual byte_len - 1. + * Hence byte_len is checked against 3 but nor 4. + */ + if ((hdr_offset == 8 || hdr_offset == 24) && byte_len == 3) + mh->lid_lt_ld_hash_en[intf][NPC_LID_LC][NPC_LT_LC_IP6][ld] = true; + } + } + + /* Update hash configuration if the field is hash enabled */ for (intf = 0; intf < hw->npc_intfs; intf++) { npc_program_mkex_hash_rx(rvu, blkaddr, intf); npc_program_mkex_hash_tx(rvu, blkaddr, intf); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h index a1c3d987b804..57a09328d46b 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.h @@ -70,8 +70,8 @@ static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = { [NIX_INTF_RX] = { [NPC_LID_LC] = { [NPC_LT_LC_IP6] = { - true, - true, + false, + false, }, }, }, @@ -79,8 +79,8 @@ static struct npc_mcam_kex_hash npc_mkex_hash_default __maybe_unused = { [NIX_INTF_TX] = { [NPC_LID_LC] = { [NPC_LT_LC_IP6] = { - true, - true, + false, + false, }, }, }, -- cgit From 284779dbf4e98753458708783af8c35630674a21 Mon Sep 17 00:00:00 2001 From: Vincent Whitchurch Date: Fri, 21 Jul 2023 15:39:20 +0200 Subject: net: stmmac: Apply redundant write work around on 4.xx too commit a3a57bf07de23fe1ff779e0fdf710aa581c3ff73 ("net: stmmac: work around sporadic tx issue on link-up") worked around a problem with TX sometimes not working after a link-up by avoiding a redundant write to MAC_CTRL_REG (aka GMAC_CONFIG), since the IP appeared to have problems with handling multiple writes to that register in some cases. That commit however only added the work around to dwmac_lib.c (apart from the common code in stmmac_main.c), but my systems with version 4.21a of the IP exhibit the same problem, so add the work around to dwmac4_lib.c too. Fixes: a3a57bf07de2 ("net: stmmac: work around sporadic tx issue on link-up") Signed-off-by: Vincent Whitchurch Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230721-stmmac-tx-workaround-v1-1-9411cbd5ee07@axis.com Signed-off-by: Paolo Abeni --- drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c index df41eac54058..03ceb6a94073 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c @@ -240,13 +240,15 @@ void stmmac_dwmac4_set_mac_addr(void __iomem *ioaddr, const u8 addr[6], void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable) { u32 value = readl(ioaddr + GMAC_CONFIG); + u32 old_val = value; if (enable) value |= GMAC_CONFIG_RE | GMAC_CONFIG_TE; else value &= ~(GMAC_CONFIG_TE | GMAC_CONFIG_RE); - writel(value, ioaddr + GMAC_CONFIG); + if (value != old_val) + writel(value, ioaddr + GMAC_CONFIG); } void stmmac_dwmac4_get_mac_addr(void __iomem *ioaddr, unsigned char *addr, -- cgit From 839e90e75e695b3d9ee17f5a2811e7ee5aea8d4a Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Fri, 14 Jul 2023 20:14:34 +0530 Subject: platform/x86/amd/pmf: reduce verbosity of apmf_get_system_params apmf_get_system_params() failure is not a critical event, reduce its verbosity from dev_err to dev_dbg. Signed-off-by: Mario Limonciello Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20230714144435.1239776-1-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/platform/x86/amd/pmf/acpi.c b/drivers/platform/x86/amd/pmf/acpi.c index 081e84e116e7..732b15b392ab 100644 --- a/drivers/platform/x86/amd/pmf/acpi.c +++ b/drivers/platform/x86/amd/pmf/acpi.c @@ -289,7 +289,7 @@ int apmf_acpi_init(struct amd_pmf_dev *pmf_dev) ret = apmf_get_system_params(pmf_dev); if (ret) { - dev_err(pmf_dev->dev, "APMF apmf_get_system_params failed :%d\n", ret); + dev_dbg(pmf_dev->dev, "APMF apmf_get_system_params failed :%d\n", ret); goto out; } -- cgit From 33c9ab5b493a0e922b06c12fed4fdcb862212cda Mon Sep 17 00:00:00 2001 From: Shyam Sundar S K Date: Fri, 14 Jul 2023 20:14:35 +0530 Subject: platform/x86/amd/pmf: Notify OS power slider update APMF fn8 can notify EC about the OS slider position change. Add this capability to the PMF driver so that it can call the APMF fn8 based on the changes in the Platform profile events. Co-developed-by: Mario Limonciello Signed-off-by: Mario Limonciello Signed-off-by: Patil Rajesh Reddy Signed-off-by: Shyam Sundar S K Link: https://lore.kernel.org/r/20230714144435.1239776-2-Shyam-sundar.S-k@amd.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/amd/pmf/acpi.c | 21 +++++++++++ drivers/platform/x86/amd/pmf/core.c | 9 ++++- drivers/platform/x86/amd/pmf/pmf.h | 16 ++++++++ drivers/platform/x86/amd/pmf/sps.c | 74 +++++++++++++++++++++++++++++++++++-- 4 files changed, 114 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/amd/pmf/acpi.c b/drivers/platform/x86/amd/pmf/acpi.c index 732b15b392ab..3fc5e4547d9f 100644 --- a/drivers/platform/x86/amd/pmf/acpi.c +++ b/drivers/platform/x86/amd/pmf/acpi.c @@ -106,6 +106,27 @@ int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev, data, sizeof(*data)); } +int apmf_os_power_slider_update(struct amd_pmf_dev *pdev, u8 event) +{ + struct os_power_slider args; + struct acpi_buffer params; + union acpi_object *info; + int err = 0; + + args.size = sizeof(args); + args.slider_event = event; + + params.length = sizeof(args); + params.pointer = (void *)&args; + + info = apmf_if_call(pdev, APMF_FUNC_OS_POWER_SLIDER_UPDATE, ¶ms); + if (!info) + err = -EIO; + + kfree(info); + return err; +} + static void apmf_sbios_heartbeat_notify(struct work_struct *work) { struct amd_pmf_dev *dev = container_of(work, struct amd_pmf_dev, heart_beat.work); diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c index d8732557f9db..57bf1a9f0e76 100644 --- a/drivers/platform/x86/amd/pmf/core.c +++ b/drivers/platform/x86/amd/pmf/core.c @@ -72,7 +72,11 @@ static int amd_pmf_pwr_src_notify_call(struct notifier_block *nb, unsigned long return NOTIFY_DONE; } - amd_pmf_set_sps_power_limits(pmf); + if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR)) + amd_pmf_set_sps_power_limits(pmf); + + if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) + amd_pmf_power_slider_update_event(pmf); return NOTIFY_OK; } @@ -297,7 +301,8 @@ static void amd_pmf_init_features(struct amd_pmf_dev *dev) int ret; /* Enable Static Slider */ - if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { + if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR) || + is_apmf_func_supported(dev, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) { amd_pmf_init_sps(dev); dev->pwr_src_notifier.notifier_call = amd_pmf_pwr_src_notify_call; power_supply_reg_notifier(&dev->pwr_src_notifier); diff --git a/drivers/platform/x86/amd/pmf/pmf.h b/drivers/platform/x86/amd/pmf/pmf.h index 06c30cdc0573..deba88e6e4c8 100644 --- a/drivers/platform/x86/amd/pmf/pmf.h +++ b/drivers/platform/x86/amd/pmf/pmf.h @@ -21,6 +21,7 @@ #define APMF_FUNC_SBIOS_HEARTBEAT 4 #define APMF_FUNC_AUTO_MODE 5 #define APMF_FUNC_SET_FAN_IDX 7 +#define APMF_FUNC_OS_POWER_SLIDER_UPDATE 8 #define APMF_FUNC_STATIC_SLIDER_GRANULAR 9 #define APMF_FUNC_DYN_SLIDER_AC 11 #define APMF_FUNC_DYN_SLIDER_DC 12 @@ -44,6 +45,14 @@ #define GET_STT_LIMIT_APU 0x20 #define GET_STT_LIMIT_HS2 0x21 +/* OS slider update notification */ +#define DC_BEST_PERF 0 +#define DC_BETTER_PERF 1 +#define DC_BATTERY_SAVER 3 +#define AC_BEST_PERF 4 +#define AC_BETTER_PERF 5 +#define AC_BETTER_BATTERY 6 + /* Fan Index for Auto Mode */ #define FAN_INDEX_AUTO 0xFFFFFFFF @@ -193,6 +202,11 @@ struct amd_pmf_static_slider_granular { struct apmf_sps_prop_granular prop[POWER_SOURCE_MAX][POWER_MODE_MAX]; }; +struct os_power_slider { + u16 size; + u8 slider_event; +} __packed; + struct fan_table_control { bool manual; unsigned long fan_id; @@ -383,6 +397,7 @@ int amd_pmf_send_cmd(struct amd_pmf_dev *dev, u8 message, bool get, u32 arg, u32 int amd_pmf_init_metrics_table(struct amd_pmf_dev *dev); int amd_pmf_get_power_source(void); int apmf_install_handler(struct amd_pmf_dev *pmf_dev); +int apmf_os_power_slider_update(struct amd_pmf_dev *dev, u8 flag); /* SPS Layer */ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf); @@ -393,6 +408,7 @@ void amd_pmf_deinit_sps(struct amd_pmf_dev *dev); int apmf_get_static_slider_granular(struct amd_pmf_dev *pdev, struct apmf_static_slider_granular_output *output); bool is_pprof_balanced(struct amd_pmf_dev *pmf); +int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev); int apmf_update_fan_idx(struct amd_pmf_dev *pdev, bool manual, u32 idx); diff --git a/drivers/platform/x86/amd/pmf/sps.c b/drivers/platform/x86/amd/pmf/sps.c index 445ff053b4df..ab69d517a36a 100644 --- a/drivers/platform/x86/amd/pmf/sps.c +++ b/drivers/platform/x86/amd/pmf/sps.c @@ -174,14 +174,77 @@ int amd_pmf_get_pprof_modes(struct amd_pmf_dev *pmf) return mode; } +int amd_pmf_power_slider_update_event(struct amd_pmf_dev *dev) +{ + u8 mode, flag = 0; + int src; + + mode = amd_pmf_get_pprof_modes(dev); + if (mode < 0) + return mode; + + src = amd_pmf_get_power_source(); + + if (src == POWER_SOURCE_AC) { + switch (mode) { + case POWER_MODE_PERFORMANCE: + flag |= BIT(AC_BEST_PERF); + break; + case POWER_MODE_BALANCED_POWER: + flag |= BIT(AC_BETTER_PERF); + break; + case POWER_MODE_POWER_SAVER: + flag |= BIT(AC_BETTER_BATTERY); + break; + default: + dev_err(dev->dev, "unsupported platform profile\n"); + return -EOPNOTSUPP; + } + + } else if (src == POWER_SOURCE_DC) { + switch (mode) { + case POWER_MODE_PERFORMANCE: + flag |= BIT(DC_BEST_PERF); + break; + case POWER_MODE_BALANCED_POWER: + flag |= BIT(DC_BETTER_PERF); + break; + case POWER_MODE_POWER_SAVER: + flag |= BIT(DC_BATTERY_SAVER); + break; + default: + dev_err(dev->dev, "unsupported platform profile\n"); + return -EOPNOTSUPP; + } + } + + apmf_os_power_slider_update(dev, flag); + + return 0; +} + static int amd_pmf_profile_set(struct platform_profile_handler *pprof, enum platform_profile_option profile) { struct amd_pmf_dev *pmf = container_of(pprof, struct amd_pmf_dev, pprof); + int ret = 0; pmf->current_profile = profile; - return amd_pmf_set_sps_power_limits(pmf); + /* Notify EC about the slider position change */ + if (is_apmf_func_supported(pmf, APMF_FUNC_OS_POWER_SLIDER_UPDATE)) { + ret = amd_pmf_power_slider_update_event(pmf); + if (ret) + return ret; + } + + if (is_apmf_func_supported(pmf, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { + ret = amd_pmf_set_sps_power_limits(pmf); + if (ret) + return ret; + } + + return 0; } int amd_pmf_init_sps(struct amd_pmf_dev *dev) @@ -189,10 +252,13 @@ int amd_pmf_init_sps(struct amd_pmf_dev *dev) int err; dev->current_profile = PLATFORM_PROFILE_BALANCED; - amd_pmf_load_defaults_sps(dev); - /* update SPS balanced power mode thermals */ - amd_pmf_set_sps_power_limits(dev); + if (is_apmf_func_supported(dev, APMF_FUNC_STATIC_SLIDER_GRANULAR)) { + amd_pmf_load_defaults_sps(dev); + + /* update SPS balanced power mode thermals */ + amd_pmf_set_sps_power_limits(dev); + } dev->pprof.profile_get = amd_pmf_profile_get; dev->pprof.profile_set = amd_pmf_profile_set; -- cgit From e3ab18de2b09361d6f0e4aafb9cfd6d002ce43a1 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Jul 2023 20:15:16 +0200 Subject: platform/x86: intel: hid: Always call BTNL ACPI method On a HP Elite Dragonfly G2 the 0xcc and 0xcd events for SW_TABLET_MODE are only send after the BTNL ACPI method has been called. Likely more devices need this, so make the BTNL ACPI method unconditional instead of only doing it on devices with a 5 button array. Note this also makes the intel_button_array_enable() call in probe() unconditional, that function does its own priv->array check. This makes the intel_button_array_enable() call in probe() consistent with the calls done on suspend/resume which also rely on the priv->array check inside the function. Reported-by: Maxim Mikityanskiy Closes: https://lore.kernel.org/platform-driver-x86/20230712175023.31651-1-maxtram95@gmail.com/ Signed-off-by: Hans de Goede Link: https://lore.kernel.org/r/20230715181516.5173-1-hdegoede@redhat.com --- drivers/platform/x86/intel/hid.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c index 5632bd3c534a..641f2797406e 100644 --- a/drivers/platform/x86/intel/hid.c +++ b/drivers/platform/x86/intel/hid.c @@ -620,7 +620,7 @@ static bool button_array_present(struct platform_device *device) static int intel_hid_probe(struct platform_device *device) { acpi_handle handle = ACPI_HANDLE(&device->dev); - unsigned long long mode; + unsigned long long mode, dummy; struct intel_hid_priv *priv; acpi_status status; int err; @@ -692,18 +692,15 @@ static int intel_hid_probe(struct platform_device *device) if (err) goto err_remove_notify; - if (priv->array) { - unsigned long long dummy; + intel_button_array_enable(&device->dev, true); - intel_button_array_enable(&device->dev, true); - - /* Call button load method to enable HID power button */ - if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, - &dummy)) { - dev_warn(&device->dev, - "failed to enable HID power button\n"); - } - } + /* + * Call button load method to enable HID power button + * Always do this since it activates events on some devices without + * a button array too. + */ + if (!intel_hid_evaluate_method(handle, INTEL_HID_DSM_BTNL_FN, &dummy)) + dev_warn(&device->dev, "failed to enable HID power button\n"); device_init_wakeup(&device->dev, true); /* -- cgit From 7783e97f8558ad7a4d1748922461bc88483fbcdf Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Sun, 16 Jul 2023 21:32:13 +0300 Subject: platform/x86/intel/hid: Add HP Dragonfly G2 to VGBS DMI quirks HP Elite Dragonfly G2 (a convertible laptop/tablet) has a reliable VGBS method. If VGBS is not called on boot, the firmware sends an initial 0xcd event shortly after calling the BTNL method, but only if the device is booted in the laptop mode. However, if the device is booted in the tablet mode and VGBS is not called, there is no initial 0xcc event, and the input device for SW_TABLET_MODE is not registered up until the user turns the device into the laptop mode. Call VGBS on boot on this device to get the initial state of SW_TABLET_MODE in a reliable way. Tested with BIOS 1.13.1. Signed-off-by: Maxim Mikityanskiy Link: https://lore.kernel.org/r/20230716183213.64173-1-maxtram95@gmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/intel/hid.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c index 641f2797406e..7457ca2b27a6 100644 --- a/drivers/platform/x86/intel/hid.c +++ b/drivers/platform/x86/intel/hid.c @@ -150,6 +150,12 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Surface Go"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Elite Dragonfly G2 Notebook PC"), + }, + }, { } }; -- cgit From 1da0893aed2e48e2bdf37c29b029f2e060d25927 Mon Sep 17 00:00:00 2001 From: Wang Ming Date: Mon, 17 Jul 2023 18:11:02 +0800 Subject: platform/x86: think-lmi: Use kfree_sensitive instead of kfree key might contain private part of the key, so better use kfree_sensitive to free it. Signed-off-by: Wang Ming Link: https://lore.kernel.org/r/20230717101114.18966-1-machel@vivo.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/think-lmi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c index 52d1ce8dfe44..79346881cadb 100644 --- a/drivers/platform/x86/think-lmi.c +++ b/drivers/platform/x86/think-lmi.c @@ -719,12 +719,12 @@ static ssize_t cert_to_password_store(struct kobject *kobj, /* Format: 'Password,Signature' */ auth_str = kasprintf(GFP_KERNEL, "%s,%s", passwd, setting->signature); if (!auth_str) { - kfree(passwd); + kfree_sensitive(passwd); return -ENOMEM; } ret = tlmi_simple_call(LENOVO_CERT_TO_PASSWORD_GUID, auth_str); kfree(auth_str); - kfree(passwd); + kfree_sensitive(passwd); return ret ?: count; } -- cgit From 6a758a3e831ce1a84c9c209ac6dc755f4c8ce77a Mon Sep 17 00:00:00 2001 From: Kristian Angelov Date: Thu, 20 Jul 2023 18:29:50 +0300 Subject: platform/x86: asus-wmi: Fix setting RGB mode on some TUF laptops This patch fixes setting the cmd values to 0xb3 and 0xb4. This is necessary on some TUF laptops in order to set the RGB mode. Closes: https://lore.kernel.org/platform-driver-x86/443078148.491022.1677576298133@nm83.abv.bg Signed-off-by: Kristian Angelov Reviewed-by: Luke D. Jones Link: https://lore.kernel.org/r/ZLlS7o6UdTUBkyqa@wyvern.localdomain Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/asus-wmi.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 1038dfdcdd32..8bef66a2f0ce 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -738,13 +738,23 @@ static ssize_t kbd_rgb_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - u32 cmd, mode, r, g, b, speed; + u32 cmd, mode, r, g, b, speed; int err; if (sscanf(buf, "%d %d %d %d %d %d", &cmd, &mode, &r, &g, &b, &speed) != 6) return -EINVAL; - cmd = !!cmd; + /* B3 is set and B4 is save to BIOS */ + switch (cmd) { + case 0: + cmd = 0xb3; + break; + case 1: + cmd = 0xb4; + break; + default: + return -EINVAL; + } /* These are the known usable modes across all TUF/ROG */ if (mode >= 12 || mode == 9) -- cgit From ad084a6d99bc182bf109c190c808e2ea073ec57b Mon Sep 17 00:00:00 2001 From: Maxim Mikityanskiy Date: Fri, 21 Jul 2023 17:54:23 +0300 Subject: platform/x86: msi-laptop: Fix rfkill out-of-sync on MSI Wind U100 Only the HW rfkill state is toggled on laptops with quirks->ec_read_only (so far only MSI Wind U90/U100). There are, however, a few issues with the implementation: 1. The initial HW state is always unblocked, regardless of the actual state on boot, because msi_init_rfkill only sets the SW state, regardless of ec_read_only. 2. The initial SW state corresponds to the actual state on boot, but it can't be changed afterwards, because set_device_state returns -EOPNOTSUPP. It confuses the userspace, making Wi-Fi and/or Bluetooth unusable if it was blocked on boot, and breaking the airplane mode if the rfkill was unblocked on boot. Address the above issues by properly initializing the HW state on ec_read_only laptops and by allowing the userspace to toggle the SW state. Don't set the SW state ourselves and let the userspace fully control it. Toggling the SW state is a no-op, however, it allows the userspace to properly toggle the airplane mode. The actual SW radio disablement is handled by the corresponding rtl818x_pci and btusb drivers that have their own rfkills. Tested on MSI Wind U100 Plus, BIOS ver 1.0G, EC ver 130. Fixes: 0816392b97d4 ("msi-laptop: merge quirk tables to one") Fixes: 0de6575ad0a8 ("msi-laptop: Add MSI Wind U90/U100 support") Signed-off-by: Maxim Mikityanskiy Link: https://lore.kernel.org/r/20230721145423.161057-1-maxtram95@gmail.com Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/msi-laptop.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index 6b18ec543ac3..f4c6c36e05a5 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c @@ -208,7 +208,7 @@ static ssize_t set_device_state(const char *buf, size_t count, u8 mask) return -EINVAL; if (quirks->ec_read_only) - return -EOPNOTSUPP; + return 0; /* read current device state */ result = ec_read(MSI_STANDARD_EC_COMMAND_ADDRESS, &rdata); @@ -838,15 +838,15 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str, static void msi_init_rfkill(struct work_struct *ignored) { if (rfk_wlan) { - rfkill_set_sw_state(rfk_wlan, !wlan_s); + msi_rfkill_set_state(rfk_wlan, !wlan_s); rfkill_wlan_set(NULL, !wlan_s); } if (rfk_bluetooth) { - rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s); + msi_rfkill_set_state(rfk_bluetooth, !bluetooth_s); rfkill_bluetooth_set(NULL, !bluetooth_s); } if (rfk_threeg) { - rfkill_set_sw_state(rfk_threeg, !threeg_s); + msi_rfkill_set_state(rfk_threeg, !threeg_s); rfkill_threeg_set(NULL, !threeg_s); } } -- cgit From c21733754cd6ecbca346f2adf9b17d4cfa50504f Mon Sep 17 00:00:00 2001 From: Konstantin Shelekhin Date: Sat, 22 Jul 2023 18:59:20 +0300 Subject: platform/x86: huawei-wmi: Silence ambient light sensor Currently huawei-wmi causes a lot of spam in dmesg on my Huawei MateBook X Pro 2022: ... [36409.328463] input input9: Unknown key pressed, code: 0x02c1 [36411.335104] input input9: Unknown key pressed, code: 0x02c1 [36412.338674] input input9: Unknown key pressed, code: 0x02c1 [36414.848564] input input9: Unknown key pressed, code: 0x02c1 [36416.858706] input input9: Unknown key pressed, code: 0x02c1 ... Fix that by ignoring events generated by ambient light sensor. This issue was reported on GitHub and resolved with the following merge request: https://github.com/aymanbagabas/Huawei-WMI/pull/70 I've contacted the mainter of this repo and he gave me the "go ahead" to send this patch to the maling list. Signed-off-by: Konstantin Shelekhin Link: https://lore.kernel.org/r/20230722155922.173856-1-k.shelekhin@ftml.net Reviewed-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/platform/x86/huawei-wmi.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index 70e5c4c0574d..0ef1c46b617b 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -85,6 +85,8 @@ static const struct key_entry huawei_wmi_keymap[] = { { KE_IGNORE, 0x293, { KEY_KBDILLUMTOGGLE } }, { KE_IGNORE, 0x294, { KEY_KBDILLUMUP } }, { KE_IGNORE, 0x295, { KEY_KBDILLUMUP } }, + // Ignore Ambient Light Sensoring + { KE_KEY, 0x2c1, { KEY_RESERVED } }, { KE_END, 0 } }; -- cgit From 55aab08f1856894d7d47d0ee23abbb4bc4854345 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Tue, 25 Jul 2023 14:54:25 +0200 Subject: hwmon: (pmbus_core) Fix pmbus_is_enabled() Refactor pmbus_is_enabled() to return the status without any additional processing as it is already done in _pmbus_is_enabled(). Fixes: df5f6b6af01c ("hwmon: (pmbus/core) Generalise pmbus get status") Cc: stable@vger.kernel.org # v6.4 Signed-off-by: Patrick Rudolph Signed-off-by: Naresh Solanki Link: https://lore.kernel.org/r/20230725125428.3966803-1-Naresh.Solanki@9elements.com [groeck: Rephrased commit message] Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/pmbus_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index fa06325f5a7c..42fb7286805b 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -2768,7 +2768,7 @@ static int __maybe_unused pmbus_is_enabled(struct device *dev, u8 page) ret = _pmbus_is_enabled(dev, page); mutex_unlock(&data->update_lock); - return !!(ret & PB_OPERATION_CONTROL_ON); + return ret; } #define to_dev_attr(_dev_attr) \ -- cgit From 0bd66784274a287beada2933c2c0fa3a0ddae0d7 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Tue, 25 Jul 2023 14:54:26 +0200 Subject: hwmon: (pmbus_core) Fix NULL pointer dereference Pass i2c_client to _pmbus_is_enabled to drop the assumption that a regulator device is passed in. This will fix the issue of a NULL pointer dereference when called from _pmbus_get_flags. Fixes: df5f6b6af01c ("hwmon: (pmbus/core) Generalise pmbus get status") Cc: stable@vger.kernel.org # v6.4 Signed-off-by: Patrick Rudolph Signed-off-by: Naresh Solanki Link: https://lore.kernel.org/r/20230725125428.3966803-2-Naresh.Solanki@9elements.com Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/pmbus_core.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 42fb7286805b..30aeb59062a5 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -2745,9 +2745,8 @@ static const struct pmbus_status_category __maybe_unused pmbus_status_flag_map[] }, }; -static int _pmbus_is_enabled(struct device *dev, u8 page) +static int _pmbus_is_enabled(struct i2c_client *client, u8 page) { - struct i2c_client *client = to_i2c_client(dev->parent); int ret; ret = _pmbus_read_byte_data(client, page, PMBUS_OPERATION); @@ -2758,14 +2757,13 @@ static int _pmbus_is_enabled(struct device *dev, u8 page) return !!(ret & PB_OPERATION_CONTROL_ON); } -static int __maybe_unused pmbus_is_enabled(struct device *dev, u8 page) +static int __maybe_unused pmbus_is_enabled(struct i2c_client *client, u8 page) { - struct i2c_client *client = to_i2c_client(dev->parent); struct pmbus_data *data = i2c_get_clientdata(client); int ret; mutex_lock(&data->update_lock); - ret = _pmbus_is_enabled(dev, page); + ret = _pmbus_is_enabled(client, page); mutex_unlock(&data->update_lock); return ret; @@ -2844,7 +2842,7 @@ static int _pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flag if (status < 0) return status; - if (_pmbus_is_enabled(dev, page)) { + if (_pmbus_is_enabled(client, page)) { if (status & PB_STATUS_OFF) { *flags |= REGULATOR_ERROR_FAIL; *event |= REGULATOR_EVENT_FAIL; @@ -2898,7 +2896,10 @@ static int __maybe_unused pmbus_get_flags(struct pmbus_data *data, u8 page, unsi #if IS_ENABLED(CONFIG_REGULATOR) static int pmbus_regulator_is_enabled(struct regulator_dev *rdev) { - return pmbus_is_enabled(rdev_get_dev(rdev), rdev_get_id(rdev)); + struct device *dev = rdev_get_dev(rdev); + struct i2c_client *client = to_i2c_client(dev->parent); + + return pmbus_is_enabled(client, rdev_get_id(rdev)); } static int _pmbus_regulator_on_off(struct regulator_dev *rdev, bool enable) -- cgit From 0d8f7cc8057890db08c54fe610d8a94af59da082 Mon Sep 17 00:00:00 2001 From: Stefano Stabellini Date: Fri, 21 Jul 2023 16:13:03 -0700 Subject: xenbus: check xen_domain in xenbus_probe_initcall The same way we already do in xenbus_init. Fixes the following warning: [ 352.175563] Trying to free already-free IRQ 0 [ 352.177355] WARNING: CPU: 1 PID: 88 at kernel/irq/manage.c:1893 free_irq+0xbf/0x350 [...] [ 352.213951] Call Trace: [ 352.214390] [ 352.214717] ? __warn+0x81/0x170 [ 352.215436] ? free_irq+0xbf/0x350 [ 352.215906] ? report_bug+0x10b/0x200 [ 352.216408] ? prb_read_valid+0x17/0x20 [ 352.216926] ? handle_bug+0x44/0x80 [ 352.217409] ? exc_invalid_op+0x13/0x60 [ 352.217932] ? asm_exc_invalid_op+0x16/0x20 [ 352.218497] ? free_irq+0xbf/0x350 [ 352.218979] ? __pfx_xenbus_probe_thread+0x10/0x10 [ 352.219600] xenbus_probe+0x7a/0x80 [ 352.221030] xenbus_probe_thread+0x76/0xc0 Fixes: 5b3353949e89 ("xen: add support for initializing xenstore later as HVM domain") Signed-off-by: Stefano Stabellini Tested-by: Petr Mladek Reviewed-by: Oleksandr Tyshchenko Link: https://lore.kernel.org/r/alpine.DEB.2.22.394.2307211609140.3118466@ubuntu-linux-20-04-desktop Signed-off-by: Juergen Gross --- drivers/xen/xenbus/xenbus_probe.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 58b732dcbfb8..639bf628389b 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -811,6 +811,9 @@ static int xenbus_probe_thread(void *unused) static int __init xenbus_probe_initcall(void) { + if (!xen_domain()) + return -ENODEV; + /* * Probe XenBus here in the XS_PV case, and also XS_HVM unless we * need to wait for the platform PCI device to come up or -- cgit From c55afcbeaa7a6f4fffdbc999a9bf3f0b29a5186f Mon Sep 17 00:00:00 2001 From: Guiting Shen Date: Mon, 26 Jun 2023 23:27:13 +0800 Subject: usb: ohci-at91: Fix the unhandle interrupt when resume The ohci_hcd_at91_drv_suspend() sets ohci->rh_state to OHCI_RH_HALTED when suspend which will let the ohci_irq() skip the interrupt after resume. And nobody to handle this interrupt. According to the comment in ohci_hcd_at91_drv_suspend(), it need to reset when resume from suspend(MEM) to fix by setting "hibernated" argument of ohci_resume(). Signed-off-by: Guiting Shen Cc: stable Reviewed-by: Alan Stern Link: https://lore.kernel.org/r/20230626152713.18950-1-aarongt.shen@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-at91.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index b9ce8d80f20b..b805c4b52ac3 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c @@ -672,7 +672,13 @@ ohci_hcd_at91_drv_resume(struct device *dev) else at91_start_clock(ohci_at91); - ohci_resume(hcd, false); + /* + * According to the comment in ohci_hcd_at91_drv_suspend() + * we need to do a reset if the 48Mhz clock was stopped, + * that is, if ohci_at91->wakeup is clear. Tell ohci_resume() + * to reset in this case by setting its "hibernated" flag. + */ + ohci_resume(hcd, !ohci_at91->wakeup); return 0; } -- cgit From 71c47ad8920ef19d6545202191252a50c03aca30 Mon Sep 17 00:00:00 2001 From: Neil Armstrong Date: Mon, 26 Jun 2023 18:52:00 +0200 Subject: usb: typec: ucsi: move typec_set_mode(TYPEC_STATE_SAFE) to ucsi_unregister_partner() It's better to set TYPEC_STATE_SAFE mode from ucsi_unregister_partner() instead of ucsi_partner_change(), ucsi_unregister_partner() is always when the partner disconnects. Fixes: 25a2bc21c863 ("usb: typec: ucsi: call typec_set_mode on non-altmode partner change") Suggested-by: Heikki Krogerus Signed-off-by: Neil Armstrong Reviewed-by: Heikki Krogerus Link: https://lore.kernel.org/r/20230626-topic-sm8550-usb-c-audio-fixup-v1-1-bc72fddf3f42@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/ucsi/ucsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 9b6d6b14431f..f6901319639d 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -785,6 +785,8 @@ static void ucsi_unregister_partner(struct ucsi_connector *con) if (!con->partner) return; + typec_set_mode(con->port, TYPEC_STATE_SAFE); + ucsi_unregister_partner_pdos(con); ucsi_unregister_altmodes(con, UCSI_RECIPIENT_SOP); typec_unregister_partner(con->partner); @@ -825,8 +827,6 @@ static void ucsi_partner_change(struct ucsi_connector *con) UCSI_CONSTAT_PARTNER_FLAG_USB) typec_set_mode(con->port, TYPEC_STATE_USB); } - } else { - typec_set_mode(con->port, TYPEC_STATE_SAFE); } /* Only notify USB controller if partner supports USB data */ -- cgit From e835c0a4e23c38531dcee5ef77e8d1cf462658c7 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Wed, 28 Jun 2023 00:20:18 +0800 Subject: usb: dwc3: don't reset device side if dwc3 was configured as host-only Commit c4a5153e87fd ("usb: dwc3: core: Power-off core/PHYs on system_suspend in host mode") replaces check for HOST only dr_mode with current_dr_role. But during booting, the current_dr_role isn't initialized, thus the device side reset is always issued even if dwc3 was configured as host-only. What's more, on some platforms with host only dwc3, aways issuing device side reset by accessing device register block can cause kernel panic. Fixes: c4a5153e87fd ("usb: dwc3: core: Power-off core/PHYs on system_suspend in host mode") Cc: stable Signed-off-by: Jisheng Zhang Acked-by: Thinh Nguyen Link: https://lore.kernel.org/r/20230627162018.739-1-jszhang@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index f6689b731718..e719e772f926 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -277,9 +277,9 @@ int dwc3_core_soft_reset(struct dwc3 *dwc) /* * We're resetting only the device side because, if we're in host mode, * XHCI driver will reset the host block. If dwc3 was configured for - * host-only mode, then we can return early. + * host-only mode or current role is host, then we can return early. */ - if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) + if (dwc->dr_mode == USB_DR_MODE_HOST || dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) return 0; reg = dwc3_readl(dwc->regs, DWC3_DCTL); -- cgit From 9fd10829a9eb482e192a845675ecc5480e0bfa10 Mon Sep 17 00:00:00 2001 From: Ricardo Ribalda Date: Wed, 19 Jul 2023 13:01:04 +0000 Subject: usb: xhci-mtk: set the dma max_seg_size Allow devices to have dma operations beyond 64K, and avoid warnings such as: DMA-API: xhci-mtk 11200000.usb: mapping sg segment longer than device claims to support [len=98304] [max=65536] Fixes: 0cbd4b34cda9 ("xhci: mediatek: support MTK xHCI host controller") Cc: stable Tested-by: Zubin Mithra Reported-by: Zubin Mithra Signed-off-by: Ricardo Ribalda Link: https://lore.kernel.org/r/20230628-mtk-usb-v2-1-c8c34eb9f229@chromium.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-mtk.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-mtk.c b/drivers/usb/host/xhci-mtk.c index 51d9d4d4f6a5..bbdf1b0b7be1 100644 --- a/drivers/usb/host/xhci-mtk.c +++ b/drivers/usb/host/xhci-mtk.c @@ -586,6 +586,7 @@ static int xhci_mtk_probe(struct platform_device *pdev) } device_init_wakeup(dev, true); + dma_set_max_seg_size(dev, UINT_MAX); xhci = hcd_to_xhci(hcd); xhci->main_hcd = hcd; -- cgit From 9dc162e22387080e2d06de708b89920c0e158c9a Mon Sep 17 00:00:00 2001 From: Łukasz Bartosik Date: Mon, 24 Jul 2023 13:29:11 +0200 Subject: USB: quirks: add quirk for Focusrite Scarlett MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Focusrite Scarlett audio device does not behave correctly during resumes. Below is what happens during every resume (captured with Beagle 5000): // The Scarlett disconnects and is enumerated again. However from time to time it drops completely off the USB bus during resume. Below is captured occurrence of such an event: // // To fix the condition a user has to unplug and plug the device again. With USB_QUIRK_RESET_RESUME applied ("usbcore.quirks=1235:8211:b") for the Scarlett audio device the issue still reproduces. Applying USB_QUIRK_DISCONNECT_SUSPEND ("usbcore.quirks=1235:8211:m") fixed the issue and the Scarlett audio device didn't drop off the USB bus for ~5000 suspend/resume cycles where originally issue reproduced in ~100 or less suspend/resume cycles. Signed-off-by: Łukasz Bartosik Cc: stable Link: https://lore.kernel.org/r/20230724112911.1802577-1-lb@semihalf.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 934b3d997702..15e9bd180a1d 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -436,6 +436,10 @@ static const struct usb_device_id usb_quirk_list[] = { /* novation SoundControl XL */ { USB_DEVICE(0x1235, 0x0061), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Focusrite Scarlett Solo USB */ + { USB_DEVICE(0x1235, 0x8211), .driver_info = + USB_QUIRK_DISCONNECT_SUSPEND }, + /* Huawei 4G LTE module */ { USB_DEVICE(0x12d1, 0x15bb), .driver_info = USB_QUIRK_DISCONNECT_SUSPEND }, -- cgit From 5bef4b3cb95a5b883dfec8b3ffc0d671323d55bb Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 13 Jul 2023 13:28:10 +0200 Subject: Revert "xhci: add quirk for host controllers that don't update endpoint DCS" This reverts commit 5255660b208aebfdb71d574f3952cf48392f4306. This quirk breaks at least the following hardware: 0b:00.0 0c03: 1106:3483 (rev 01) (prog-if 30 [XHCI]) Subsystem: 1106:3483 Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+ Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- SERR- Fixes: 5255660b208a ("xhci: add quirk for host controllers that don't update endpoint DCS") Cc: stable Link: https://lore.kernel.org/r/20230713112830.21773-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-pci.c | 4 +--- drivers/usb/host/xhci-ring.c | 25 +------------------------ 2 files changed, 2 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index c6742bae41c0..b9ae5c2a2527 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -479,10 +479,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) pdev->device == 0x3432) xhci->quirks |= XHCI_BROKEN_STREAMS; - if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) { + if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483) xhci->quirks |= XHCI_LPM_SUPPORT; - xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS; - } if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) { diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 646ff125def5..1dde53f6eb31 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -626,11 +626,8 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci, struct xhci_ring *ep_ring; struct xhci_command *cmd; struct xhci_segment *new_seg; - struct xhci_segment *halted_seg = NULL; union xhci_trb *new_deq; int new_cycle; - union xhci_trb *halted_trb; - int index = 0; dma_addr_t addr; u64 hw_dequeue; bool cycle_found = false; @@ -668,27 +665,7 @@ static int xhci_move_dequeue_past_td(struct xhci_hcd *xhci, hw_dequeue = xhci_get_hw_deq(xhci, dev, ep_index, stream_id); new_seg = ep_ring->deq_seg; new_deq = ep_ring->dequeue; - - /* - * Quirk: xHC write-back of the DCS field in the hardware dequeue - * pointer is wrong - use the cycle state of the TRB pointed to by - * the dequeue pointer. - */ - if (xhci->quirks & XHCI_EP_CTX_BROKEN_DCS && - !(ep->ep_state & EP_HAS_STREAMS)) - halted_seg = trb_in_td(xhci, td->start_seg, - td->first_trb, td->last_trb, - hw_dequeue & ~0xf, false); - if (halted_seg) { - index = ((dma_addr_t)(hw_dequeue & ~0xf) - halted_seg->dma) / - sizeof(*halted_trb); - halted_trb = &halted_seg->trbs[index]; - new_cycle = halted_trb->generic.field[3] & 0x1; - xhci_dbg(xhci, "Endpoint DCS = %d TRB index = %d cycle = %d\n", - (u8)(hw_dequeue & 0x1), index, new_cycle); - } else { - new_cycle = hw_dequeue & 0x1; - } + new_cycle = hw_dequeue & 0x1; /* * We want to find the pointer, segment and cycle state of the new trb -- cgit From 734ae15ab95a18d3d425fc9cb38b7a627d786f08 Mon Sep 17 00:00:00 2001 From: Jakub Vanek Date: Fri, 14 Jul 2023 14:24:19 +0200 Subject: Revert "usb: dwc3: core: Enable AutoRetry feature in the controller" This reverts commit b138e23d3dff90c0494925b4c1874227b81bddf7. AutoRetry has been found to sometimes cause controller freezes when communicating with buggy USB devices. This controller feature allows the controller in host mode to send non-terminating/burst retry ACKs instead of terminating retry ACKs to devices when a transaction error (CRC error or overflow) occurs. Unfortunately, if the USB device continues to respond with a CRC error, the controller will not complete endpoint-related commands while it keeps trying to auto-retry. [3] The xHCI driver will notice this once it tries to abort the transfer using a Stop Endpoint command and does not receive a completion in time. [1] This situation is reported to dmesg: [sda] tag#29 uas_eh_abort_handler 0 uas-tag 1 inflight: CMD IN [sda] tag#29 CDB: opcode=0x28 28 00 00 69 42 80 00 00 48 00 xhci-hcd: xHCI host not responding to stop endpoint command xhci-hcd: xHCI host controller not responding, assume dead xhci-hcd: HC died; cleaning up Some users observed this problem on an Odroid HC2 with the JMS578 USB3-to-SATA bridge. The issue can be triggered by starting a read-heavy workload on an attached SSD. After a while, the host controller would die and the SSD would disappear from the system. [1] Further analysis by Synopsys determined that controller revisions other than the one in Odroid HC2 are also affected by this. The recommended solution was to disable AutoRetry altogether. This change does not have a noticeable performance impact. [2] Revert the enablement commit. This will keep the AutoRetry bit in the default state configured during SoC design [2]. Fixes: b138e23d3dff ("usb: dwc3: core: Enable AutoRetry feature in the controller") Link: https://lore.kernel.org/r/a21f34c04632d250cd0a78c7c6f4a1c9c7a43142.camel@gmail.com/ [1] Link: https://lore.kernel.org/r/20230711214834.kyr6ulync32d4ktk@synopsys.com/ [2] Link: https://lore.kernel.org/r/20230712225518.2smu7wse6djc7l5o@synopsys.com/ [3] Cc: stable@vger.kernel.org Cc: Mauro Ribeiro Cc: Krzysztof Kozlowski Suggested-by: Thinh Nguyen Signed-off-by: Jakub Vanek Acked-by: Thinh Nguyen Link: https://lore.kernel.org/r/20230714122419.27741-1-linuxtardis@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/core.c | 16 ---------------- drivers/usb/dwc3/core.h | 3 --- 2 files changed, 19 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index e719e772f926..9c6bf054f15d 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -1209,22 +1209,6 @@ static int dwc3_core_init(struct dwc3 *dwc) dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); } - if (dwc->dr_mode == USB_DR_MODE_HOST || - dwc->dr_mode == USB_DR_MODE_OTG) { - reg = dwc3_readl(dwc->regs, DWC3_GUCTL); - - /* - * Enable Auto retry Feature to make the controller operating in - * Host mode on seeing transaction errors(CRC errors or internal - * overrun scenerios) on IN transfers to reply to the device - * with a non-terminating retry ACK (i.e, an ACK transcation - * packet with Retry=1 & Nump != 0) - */ - reg |= DWC3_GUCTL_HSTINAUTORETRY; - - dwc3_writel(dwc->regs, DWC3_GUCTL, reg); - } - /* * Must config both number of packets and max burst settings to enable * RX and/or TX threshold. diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 8b1295e4dcdd..a69ac67d89fe 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -256,9 +256,6 @@ #define DWC3_GCTL_GBLHIBERNATIONEN BIT(1) #define DWC3_GCTL_DSBLCLKGTNG BIT(0) -/* Global User Control Register */ -#define DWC3_GUCTL_HSTINAUTORETRY BIT(14) - /* Global User Control 1 Register */ #define DWC3_GUCTL1_DEV_DECOUPLE_L1L2_EVT BIT(31) #define DWC3_GUCTL1_TX_IPGAP_LINECHECK_DIS BIT(28) -- cgit From 6237390644fb92b81f5262877fe545d0d2c7b5d7 Mon Sep 17 00:00:00 2001 From: Michael Grzeschik Date: Sat, 22 Jul 2023 00:22:56 +0200 Subject: usb: gadget: core: remove unbalanced mutex_unlock in usb_gadget_activate Commit 286d9975a838 ("usb: gadget: udc: core: Prevent soft_connect_store() race") introduced one extra mutex_unlock of connect_lock in the usb_gadget_active function. Fixes: 286d9975a838 ("usb: gadget: udc: core: Prevent soft_connect_store() race") Cc: stable Signed-off-by: Michael Grzeschik Reviewed-by: Alan Stern Link: https://lore.kernel.org/r/20230721222256.1743645-1-m.grzeschik@pengutronix.de Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/core.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 59188ea065e0..cd58f2a4e7f3 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -878,7 +878,6 @@ int usb_gadget_activate(struct usb_gadget *gadget) */ if (gadget->connected) ret = usb_gadget_connect_locked(gadget); - mutex_unlock(&gadget->udc->connect_lock); unlock: mutex_unlock(&gadget->udc->connect_lock); -- cgit From 83e30f2bf86ef7c38fbd476ed81a88522b620628 Mon Sep 17 00:00:00 2001 From: Zqiang Date: Fri, 14 Jul 2023 15:40:11 +0800 Subject: USB: gadget: Fix the memory leak in raw_gadget driver Currently, increasing raw_dev->count happens before invoke the raw_queue_event(), if the raw_queue_event() return error, invoke raw_release() will not trigger the dev_free() to be called. [ 268.905865][ T5067] raw-gadget.0 gadget.0: failed to queue event [ 268.912053][ T5067] udc dummy_udc.0: failed to start USB Raw Gadget: -12 [ 268.918885][ T5067] raw-gadget.0: probe of gadget.0 failed with error -12 [ 268.925956][ T5067] UDC core: USB Raw Gadget: couldn't find an available UDC or it's busy [ 268.934657][ T5067] misc raw-gadget: fail, usb_gadget_register_driver returned -16 BUG: memory leak [] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076 [] kmalloc include/linux/slab.h:582 [inline] [] kzalloc include/linux/slab.h:703 [inline] [] dev_new drivers/usb/gadget/legacy/raw_gadget.c:191 [inline] [] raw_open+0x45/0x110 drivers/usb/gadget/legacy/raw_gadget.c:385 [] misc_open+0x1a9/0x1f0 drivers/char/misc.c:165 [] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076 [] kmalloc include/linux/slab.h:582 [inline] [] raw_ioctl_init+0xdf/0x410 drivers/usb/gadget/legacy/raw_gadget.c:460 [] raw_ioctl+0x5f9/0x1120 drivers/usb/gadget/legacy/raw_gadget.c:1250 [] vfs_ioctl fs/ioctl.c:51 [inline] [] kmalloc_trace+0x24/0x90 mm/slab_common.c:1076 [] kmalloc include/linux/slab.h:582 [inline] [] kzalloc include/linux/slab.h:703 [inline] [] dummy_alloc_request+0x5a/0xe0 drivers/usb/gadget/udc/dummy_hcd.c:665 [] usb_ep_alloc_request+0x22/0xd0 drivers/usb/gadget/udc/core.c:196 [] gadget_bind+0x6d/0x370 drivers/usb/gadget/legacy/raw_gadget.c:292 This commit therefore invoke kref_get() under the condition that raw_queue_event() return success. Reported-by: syzbot+feb045d335c1fdde5bf7@syzkaller.appspotmail.com Cc: stable Closes: https://syzkaller.appspot.com/bug?extid=feb045d335c1fdde5bf7 Signed-off-by: Zqiang Reviewed-by: Andrey Konovalov Tested-by: Andrey Konovalov Link: https://lore.kernel.org/r/20230714074011.20989-1-qiang.zhang1211@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/legacy/raw_gadget.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c index 2acece16b890..e549022642e5 100644 --- a/drivers/usb/gadget/legacy/raw_gadget.c +++ b/drivers/usb/gadget/legacy/raw_gadget.c @@ -310,13 +310,15 @@ static int gadget_bind(struct usb_gadget *gadget, dev->eps_num = i; spin_unlock_irqrestore(&dev->lock, flags); - /* Matches kref_put() in gadget_unbind(). */ - kref_get(&dev->count); - ret = raw_queue_event(dev, USB_RAW_EVENT_CONNECT, 0, NULL); - if (ret < 0) + if (ret < 0) { dev_err(&gadget->dev, "failed to queue event\n"); + set_gadget_data(gadget, NULL); + return ret; + } + /* Matches kref_put() in gadget_unbind(). */ + kref_get(&dev->count); return ret; } -- cgit From 288b4fa1798e3637a9304c6e90a93d900e02369c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 4 Jul 2023 17:08:27 +0300 Subject: Revert "usb: xhci: tegra: Fix error check" This reverts commit 18fc7c435be3f17ea26a21b2e2312fcb9088e01f. The reverted commit was based on static analysis and a misunderstanding of how PTR_ERR() and NULLs are supposed to work. When a function returns both pointer errors and NULL then normally the NULL means "continue operating without a feature because it was deliberately turned off". The NULL should not be treated as a failure. If a driver cannot work when that feature is disabled then the KConfig should enforce that the function cannot return NULL. We should not need to test for it. In this code, the patch means that certain tegra_xusb_probe() will fail if the firmware supports power-domains but CONFIG_PM is disabled. Signed-off-by: Dan Carpenter Fixes: 18fc7c435be3 ("usb: xhci: tegra: Fix error check") Cc: stable Link: https://lore.kernel.org/r/8baace8d-fb4b-41a4-ad5f-848ae643a23b@moroto.mountain Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-tegra.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 6ca8a37e53e1..4693d83351c6 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -1145,15 +1145,15 @@ static int tegra_xusb_powerdomain_init(struct device *dev, int err; tegra->genpd_dev_host = dev_pm_domain_attach_by_name(dev, "xusb_host"); - if (IS_ERR_OR_NULL(tegra->genpd_dev_host)) { - err = PTR_ERR(tegra->genpd_dev_host) ? : -ENODATA; + if (IS_ERR(tegra->genpd_dev_host)) { + err = PTR_ERR(tegra->genpd_dev_host); dev_err(dev, "failed to get host pm-domain: %d\n", err); return err; } tegra->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "xusb_ss"); - if (IS_ERR_OR_NULL(tegra->genpd_dev_ss)) { - err = PTR_ERR(tegra->genpd_dev_ss) ? : -ENODATA; + if (IS_ERR(tegra->genpd_dev_ss)) { + err = PTR_ERR(tegra->genpd_dev_ss); dev_err(dev, "failed to get superspeed pm-domain: %d\n", err); return err; } -- cgit From a8291be6b5dd465c22af229483dbac543a91e24e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 4 Jul 2023 17:09:09 +0300 Subject: Revert "usb: gadget: tegra-xudc: Fix error check in tegra_xudc_powerdomain_init()" This reverts commit f08aa7c80dac27ee00fa6827f447597d2fba5465. The reverted commit was based on static analysis and a misunderstanding of how PTR_ERR() and NULLs are supposed to work. When a function returns both pointer errors and NULL then normally the NULL means "continue operating without a feature because it was deliberately turned off". The NULL should not be treated as a failure. If a driver cannot work when that feature is disabled then the KConfig should enforce that the function cannot return NULL. We should not need to test for it. In this driver, the bug means that probe cannot succeed when CONFIG_PM is disabled. Signed-off-by: Dan Carpenter Fixes: f08aa7c80dac ("usb: gadget: tegra-xudc: Fix error check in tegra_xudc_powerdomain_init()") Cc: stable Link: https://lore.kernel.org/r/ZKQoBa84U/ykEh3C@moroto Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/udc/tegra-xudc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c index 83eaa65ddde3..df6028f7b273 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -3718,15 +3718,15 @@ static int tegra_xudc_powerdomain_init(struct tegra_xudc *xudc) int err; xudc->genpd_dev_device = dev_pm_domain_attach_by_name(dev, "dev"); - if (IS_ERR_OR_NULL(xudc->genpd_dev_device)) { - err = PTR_ERR(xudc->genpd_dev_device) ? : -ENODATA; + if (IS_ERR(xudc->genpd_dev_device)) { + err = PTR_ERR(xudc->genpd_dev_device); dev_err(dev, "failed to get device power domain: %d\n", err); return err; } xudc->genpd_dev_ss = dev_pm_domain_attach_by_name(dev, "ss"); - if (IS_ERR_OR_NULL(xudc->genpd_dev_ss)) { - err = PTR_ERR(xudc->genpd_dev_ss) ? : -ENODATA; + if (IS_ERR(xudc->genpd_dev_ss)) { + err = PTR_ERR(xudc->genpd_dev_ss); dev_err(dev, "failed to get SuperSpeed power domain: %d\n", err); return err; } -- cgit From da6d91ed77062960107e2eddacd932abecfd0592 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 25 Jul 2023 20:53:19 +0800 Subject: usb: typec: qcom: fix return value check in qcom_pmic_typec_probe() device_get_named_child_node() returns NULL, if it fails, replace IS_ERR() with NULL pointer check. Fixes: a4422ff22142 ("usb: typec: qcom: Add Qualcomm PMIC Type-C driver") Signed-off-by: Yang Yingliang Acked-by: Konrad Dybcio Acked-by: Bryan O'Donoghue Reviewed-by: Guenter Roeck Link: https://lore.kernel.org/r/20230725125319.565733-1-yangyingliang@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c index a905160dd860..9b467a346114 100644 --- a/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c +++ b/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec.c @@ -209,8 +209,8 @@ static int qcom_pmic_typec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, tcpm); tcpm->tcpc.fwnode = device_get_named_child_node(tcpm->dev, "connector"); - if (IS_ERR(tcpm->tcpc.fwnode)) - return PTR_ERR(tcpm->tcpc.fwnode); + if (!tcpm->tcpc.fwnode) + return -EINVAL; tcpm->tcpm_port = tcpm_register_port(tcpm->dev, &tcpm->tcpc); if (IS_ERR(tcpm->tcpm_port)) { -- cgit From b33ebb2415e7e0a55ee3d049c2890d3a3e3805b6 Mon Sep 17 00:00:00 2001 From: Kyle Tso Date: Fri, 23 Jun 2023 23:10:34 +0800 Subject: usb: typec: Set port->pd before adding device for typec_port When calling device_add in the registration of typec_port, it will do the NULL check on usb_power_delivery handle in typec_port for the visibility of the device attributes. It is always NULL because port->pd is set in typec_port_set_usb_power_delivery which is later than the device_add call. Set port->pd before device_add and only link the device after that. Fixes: a7cff92f0635 ("usb: typec: USB Power Delivery helpers for ports and partners") Cc: stable@vger.kernel.org Signed-off-by: Kyle Tso Acked-by: Heikki Krogerus Link: https://lore.kernel.org/r/20230623151036.3955013-2-kyletso@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/class.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index faa184ae3dac..3b30948bf4b0 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -2288,6 +2288,8 @@ struct typec_port *typec_register_port(struct device *parent, return ERR_PTR(ret); } + port->pd = cap->pd; + ret = device_add(&port->dev); if (ret) { dev_err(parent, "failed to register port (%d)\n", ret); @@ -2295,7 +2297,7 @@ struct typec_port *typec_register_port(struct device *parent, return ERR_PTR(ret); } - ret = typec_port_set_usb_power_delivery(port, cap->pd); + ret = usb_power_delivery_link_device(port->pd, &port->dev); if (ret) { dev_err(&port->dev, "failed to link pd\n"); device_unregister(&port->dev); -- cgit From 4b642dc9829507e4afabc03d32a18abbdb192c5e Mon Sep 17 00:00:00 2001 From: Kyle Tso Date: Fri, 23 Jun 2023 23:10:35 +0800 Subject: usb: typec: Iterate pds array when showing the pd list The pointers of each usb_power_delivery handles are stored in "pds" array returned from the pd_get ops but not in the adjacent memory calculated from "pd". Get the handles from "pds" array directly instead of deriving them from "pd". Fixes: a7cff92f0635 ("usb: typec: USB Power Delivery helpers for ports and partners") Cc: stable@vger.kernel.org Signed-off-by: Kyle Tso Acked-by: Heikki Krogerus Link: https://lore.kernel.org/r/20230623151036.3955013-3-kyletso@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/class.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 3b30948bf4b0..e7312295f8c9 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1277,8 +1277,7 @@ static ssize_t select_usb_power_delivery_show(struct device *dev, { struct typec_port *port = to_typec_port(dev); struct usb_power_delivery **pds; - struct usb_power_delivery *pd; - int ret = 0; + int i, ret = 0; if (!port->ops || !port->ops->pd_get) return -EOPNOTSUPP; @@ -1287,11 +1286,11 @@ static ssize_t select_usb_power_delivery_show(struct device *dev, if (!pds) return 0; - for (pd = pds[0]; pd; pd++) { - if (pd == port->pd) - ret += sysfs_emit(buf + ret, "[%s] ", dev_name(&pd->dev)); + for (i = 0; pds[i]; i++) { + if (pds[i] == port->pd) + ret += sysfs_emit(buf + ret, "[%s] ", dev_name(&pds[i]->dev)); else - ret += sysfs_emit(buf + ret, "%s ", dev_name(&pd->dev)); + ret += sysfs_emit(buf + ret, "%s ", dev_name(&pds[i]->dev)); } buf[ret - 1] = '\n'; -- cgit From 609fded3f91972ada551c141c5d04a71704f8967 Mon Sep 17 00:00:00 2001 From: Kyle Tso Date: Fri, 23 Jun 2023 23:10:36 +0800 Subject: usb: typec: Use sysfs_emit_at when concatenating the string The buffer address used in sysfs_emit should be aligned to PAGE_SIZE. Use sysfs_emit_at instead to offset the buffer. Fixes: a7cff92f0635 ("usb: typec: USB Power Delivery helpers for ports and partners") Cc: stable@vger.kernel.org Signed-off-by: Kyle Tso Acked-by: Heikki Krogerus Link: https://lore.kernel.org/r/20230623151036.3955013-4-kyletso@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/typec/class.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index e7312295f8c9..9c1dbf3c00e0 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1288,9 +1288,9 @@ static ssize_t select_usb_power_delivery_show(struct device *dev, for (i = 0; pds[i]; i++) { if (pds[i] == port->pd) - ret += sysfs_emit(buf + ret, "[%s] ", dev_name(&pds[i]->dev)); + ret += sysfs_emit_at(buf, ret, "[%s] ", dev_name(&pds[i]->dev)); else - ret += sysfs_emit(buf + ret, "%s ", dev_name(&pds[i]->dev)); + ret += sysfs_emit_at(buf, ret, "%s ", dev_name(&pds[i]->dev)); } buf[ret - 1] = '\n'; -- cgit From f4fc01af5b640bc39bd9403b5fd855345a2ad5f8 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Fri, 7 Jul 2023 19:00:14 -0400 Subject: usb: gadget: call usb_gadget_check_config() to verify UDC capability The legacy gadget driver omitted calling usb_gadget_check_config() to ensure that the USB device controller (UDC) has adequate resources, including sufficient endpoint numbers and types, to support the given configuration. Previously, usb_add_config() was solely invoked by the legacy gadget driver. Adds the necessary usb_gadget_check_config() after the bind() operation to fix the issue. Fixes: dce49449e04f ("usb: cdns3: allocate TX FIFO size according to composite EP number") Cc: stable Reported-by: Ravi Gunasekaran Signed-off-by: Frank Li Link: https://lore.kernel.org/r/20230707230015.494999-1-Frank.Li@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/composite.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 1b3489149e5e..dd9b90481b4c 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1125,6 +1125,10 @@ int usb_add_config(struct usb_composite_dev *cdev, goto done; status = bind(config); + + if (status == 0) + status = usb_gadget_check_config(cdev->gadget); + if (status < 0) { while (!list_empty(&config->functions)) { struct usb_function *f; -- cgit From 2627335a1329a0d39d8d277994678571c4f21800 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Fri, 7 Jul 2023 19:00:15 -0400 Subject: usb: cdns3: fix incorrect calculation of ep_buf_size when more than one config Previously, the cdns3_gadget_check_config() function in the cdns3 driver mistakenly calculated the ep_buf_size by considering only one configuration's endpoint information because "claimed" will be clear after call usb_gadget_check_config(). The fix involves checking the private flags EP_CLAIMED instead of relying on the "claimed" flag. Fixes: dce49449e04f ("usb: cdns3: allocate TX FIFO size according to composite EP number") Cc: stable Reported-by: Ravi Gunasekaran Signed-off-by: Frank Li Acked-by: Peter Chen Tested-by: Ravi Gunasekaran Link: https://lore.kernel.org/r/20230707230015.494999-2-Frank.Li@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/cdns3/cdns3-gadget.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c index ea19253fd2d0..aa0111b365bb 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -3015,12 +3015,14 @@ static int cdns3_gadget_udc_stop(struct usb_gadget *gadget) static int cdns3_gadget_check_config(struct usb_gadget *gadget) { struct cdns3_device *priv_dev = gadget_to_cdns3_device(gadget); + struct cdns3_endpoint *priv_ep; struct usb_ep *ep; int n_in = 0; int total; list_for_each_entry(ep, &gadget->ep_list, ep_list) { - if (ep->claimed && (ep->address & USB_DIR_IN)) + priv_ep = ep_to_cdns3_ep(ep); + if ((priv_ep->flags & EP_CLAIMED) && (ep->address & USB_DIR_IN)) n_in++; } -- cgit From d4a3806bea61c8ef6e0103d0f39786e00586522e Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 3 Jul 2023 17:12:39 +0200 Subject: dm integrity: fix double free on memory allocation failure If the statement "recalc_tags = kvmalloc(recalc_tags_size, GFP_NOIO);" fails, we call "vfree(recalc_buffer)" and we jump to the label "oom". If the condition "recalc_sectors >= 1U << ic->sb->log2_sectors_per_block" is false, we jump to the label "free_ret" and call "vfree(recalc_buffer)" again, on an already released memory block. Fix the bug by setting "recalc_buffer = NULL" after freeing it. Fixes: da8b4fc1f63a ("dm integrity: only allocate recalculate buffer when needed") Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer --- drivers/md/dm-integrity.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 3d5c56e0a062..97a8d5fc9ebb 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -2676,6 +2676,7 @@ oom: recalc_tags = kvmalloc(recalc_tags_size, GFP_NOIO); if (!recalc_tags) { vfree(recalc_buffer); + recalc_buffer = NULL; goto oom; } -- cgit From bae3028799dc4f1109acc4df37c8ff06f2d8f1a0 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Sat, 8 Jul 2023 17:21:51 +0800 Subject: dm raid: fix missing reconfig_mutex unlock in raid_ctr() error paths In the error paths 'bad_stripe_cache' and 'bad_check_reshape', 'reconfig_mutex' is still held after raid_ctr() returns. Fixes: 9dbd1aa3a81c ("dm raid: add reshaping support to the target") Signed-off-by: Yu Kuai Signed-off-by: Mike Snitzer --- drivers/md/dm-raid.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 8846bf510a35..3d7366b912bf 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -3271,15 +3271,19 @@ size_check: /* Try to adjust the raid4/5/6 stripe cache size to the stripe size */ if (rs_is_raid456(rs)) { r = rs_set_raid456_stripe_cache(rs); - if (r) + if (r) { + mddev_unlock(&rs->md); goto bad_stripe_cache; + } } /* Now do an early reshape check */ if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) { r = rs_check_reshape(rs); - if (r) + if (r) { + mddev_unlock(&rs->md); goto bad_check_reshape; + } /* Restore new, ctr requested layout to perform check */ rs_config_restore(rs, &rs_layout); @@ -3288,6 +3292,7 @@ size_check: r = rs->md.pers->check_reshape(&rs->md); if (r) { ti->error = "Reshape check failed"; + mddev_unlock(&rs->md); goto bad_check_reshape; } } -- cgit From e74c874eabe2e9173a8fbdad616cd89c70eb8ffd Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Sat, 8 Jul 2023 17:21:52 +0800 Subject: dm raid: clean up four equivalent goto tags in raid_ctr() There are four equivalent goto tags in raid_ctr(), clean them up to use just one. There is no functional change and this is preparation to fix raid_ctr()'s unprotected md_stop(). Signed-off-by: Yu Kuai Signed-off-by: Mike Snitzer --- drivers/md/dm-raid.c | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 3d7366b912bf..845b68c3fd5f 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -3251,8 +3251,7 @@ size_check: r = md_start(&rs->md); if (r) { ti->error = "Failed to start raid array"; - mddev_unlock(&rs->md); - goto bad_md_start; + goto bad_unlock; } /* If raid4/5/6 journal mode explicitly requested (only possible with journal dev) -> set it */ @@ -3260,8 +3259,7 @@ size_check: r = r5c_journal_mode_set(&rs->md, rs->journal_dev.mode); if (r) { ti->error = "Failed to set raid4/5/6 journal mode"; - mddev_unlock(&rs->md); - goto bad_journal_mode_set; + goto bad_unlock; } } @@ -3271,19 +3269,15 @@ size_check: /* Try to adjust the raid4/5/6 stripe cache size to the stripe size */ if (rs_is_raid456(rs)) { r = rs_set_raid456_stripe_cache(rs); - if (r) { - mddev_unlock(&rs->md); - goto bad_stripe_cache; - } + if (r) + goto bad_unlock; } /* Now do an early reshape check */ if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) { r = rs_check_reshape(rs); - if (r) { - mddev_unlock(&rs->md); - goto bad_check_reshape; - } + if (r) + goto bad_unlock; /* Restore new, ctr requested layout to perform check */ rs_config_restore(rs, &rs_layout); @@ -3292,8 +3286,7 @@ size_check: r = rs->md.pers->check_reshape(&rs->md); if (r) { ti->error = "Reshape check failed"; - mddev_unlock(&rs->md); - goto bad_check_reshape; + goto bad_unlock; } } } @@ -3304,10 +3297,8 @@ size_check: mddev_unlock(&rs->md); return 0; -bad_md_start: -bad_journal_mode_set: -bad_stripe_cache: -bad_check_reshape: +bad_unlock: + mddev_unlock(&rs->md); md_stop(&rs->md); bad: raid_set_free(rs); -- cgit From 7d5fff8982a2199d49ec067818af7d84d4f95ca0 Mon Sep 17 00:00:00 2001 From: Yu Kuai Date: Sat, 8 Jul 2023 17:21:53 +0800 Subject: dm raid: protect md_stop() with 'reconfig_mutex' __md_stop_writes() and __md_stop() will modify many fields that are protected by 'reconfig_mutex', and all the callers will grab 'reconfig_mutex' except for md_stop(). Also, update md_stop() to make certain 'reconfig_mutex' is held using lockdep_assert_held(). Fixes: 9d09e663d550 ("dm: raid456 basic support") Signed-off-by: Yu Kuai Signed-off-by: Mike Snitzer --- drivers/md/dm-raid.c | 4 +++- drivers/md/md.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 845b68c3fd5f..becdb689190e 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -3298,8 +3298,8 @@ size_check: return 0; bad_unlock: - mddev_unlock(&rs->md); md_stop(&rs->md); + mddev_unlock(&rs->md); bad: raid_set_free(rs); @@ -3310,7 +3310,9 @@ static void raid_dtr(struct dm_target *ti) { struct raid_set *rs = ti->private; + mddev_lock_nointr(&rs->md); md_stop(&rs->md); + mddev_unlock(&rs->md); raid_set_free(rs); } diff --git a/drivers/md/md.c b/drivers/md/md.c index 2e38ef421d69..78be7811a89f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6247,6 +6247,8 @@ static void __md_stop(struct mddev *mddev) void md_stop(struct mddev *mddev) { + lockdep_assert_held(&mddev->reconfig_mutex); + /* stop the array and free an attached data structures. * This is called from dm-raid */ -- cgit From 1e4ab7b4c881cf26c1c72b3f56519e03475486fb Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Tue, 25 Jul 2023 11:44:41 -0400 Subject: dm cache policy smq: ensure IO doesn't prevent cleaner policy progress When using the cleaner policy to decommission the cache, there is never any writeback started from the cache as it is constantly delayed due to normal I/O keeping the device busy. Meaning @idle=false was always being passed to clean_target_met() Fix this by adding a specific 'cleaner' flag that is set when the cleaner policy is configured. This flag serves to always allow the cleaner's writeback work to be queued until the cache is decommissioned (even if the cache isn't idle). Reported-by: David Jeffery Fixes: b29d4986d0da ("dm cache: significant rework to leverage dm-bio-prison-v2") Cc: stable@vger.kernel.org Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer --- drivers/md/dm-cache-policy-smq.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-cache-policy-smq.c b/drivers/md/dm-cache-policy-smq.c index 493a8715dc8f..8bd2ad743d9a 100644 --- a/drivers/md/dm-cache-policy-smq.c +++ b/drivers/md/dm-cache-policy-smq.c @@ -857,7 +857,13 @@ struct smq_policy { struct background_tracker *bg_work; - bool migrations_allowed; + bool migrations_allowed:1; + + /* + * If this is set the policy will try and clean the whole cache + * even if the device is not idle. + */ + bool cleaner:1; }; /*----------------------------------------------------------------*/ @@ -1138,7 +1144,7 @@ static bool clean_target_met(struct smq_policy *mq, bool idle) * Cache entries may not be populated. So we cannot rely on the * size of the clean queue. */ - if (idle) { + if (idle || mq->cleaner) { /* * We'd like to clean everything. */ @@ -1722,11 +1728,9 @@ static void calc_hotspot_params(sector_t origin_size, *hotspot_block_size /= 2u; } -static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size, - sector_t origin_size, - sector_t cache_block_size, - bool mimic_mq, - bool migrations_allowed) +static struct dm_cache_policy * +__smq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size, + bool mimic_mq, bool migrations_allowed, bool cleaner) { unsigned int i; unsigned int nr_sentinels_per_queue = 2u * NR_CACHE_LEVELS; @@ -1813,6 +1817,7 @@ static struct dm_cache_policy *__smq_create(dm_cblock_t cache_size, goto bad_btracker; mq->migrations_allowed = migrations_allowed; + mq->cleaner = cleaner; return &mq->policy; @@ -1836,21 +1841,24 @@ static struct dm_cache_policy *smq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size) { - return __smq_create(cache_size, origin_size, cache_block_size, false, true); + return __smq_create(cache_size, origin_size, cache_block_size, + false, true, false); } static struct dm_cache_policy *mq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size) { - return __smq_create(cache_size, origin_size, cache_block_size, true, true); + return __smq_create(cache_size, origin_size, cache_block_size, + true, true, false); } static struct dm_cache_policy *cleaner_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_size) { - return __smq_create(cache_size, origin_size, cache_block_size, false, false); + return __smq_create(cache_size, origin_size, cache_block_size, + false, false, true); } /*----------------------------------------------------------------*/ -- cgit From 9b9c8195f3f0d74a826077fc1c01b9ee74907239 Mon Sep 17 00:00:00 2001 From: Chaoyuan Peng Date: Tue, 18 Jul 2023 04:39:43 +0000 Subject: tty: n_gsm: fix UAF in gsm_cleanup_mux In gsm_cleanup_mux() the 'gsm->dlci' pointer was not cleaned properly, leaving it a dangling pointer after gsm_dlci_release. This leads to use-after-free where 'gsm->dlci[0]' are freed and accessed by the subsequent gsm_cleanup_mux(). Such is the case in the following call trace: __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x1e3/0x2cb lib/dump_stack.c:106 print_address_description+0x63/0x3b0 mm/kasan/report.c:248 __kasan_report mm/kasan/report.c:434 [inline] kasan_report+0x16b/0x1c0 mm/kasan/report.c:451 gsm_cleanup_mux+0x76a/0x850 drivers/tty/n_gsm.c:2397 gsm_config drivers/tty/n_gsm.c:2653 [inline] gsmld_ioctl+0xaae/0x15b0 drivers/tty/n_gsm.c:2986 tty_ioctl+0x8ff/0xc50 drivers/tty/tty_io.c:2816 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:874 [inline] __se_sys_ioctl+0xf1/0x160 fs/ioctl.c:860 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x61/0xcb Allocated by task 3501: kasan_save_stack mm/kasan/common.c:38 [inline] kasan_set_track mm/kasan/common.c:46 [inline] set_alloc_info mm/kasan/common.c:434 [inline] ____kasan_kmalloc+0xba/0xf0 mm/kasan/common.c:513 kasan_kmalloc include/linux/kasan.h:264 [inline] kmem_cache_alloc_trace+0x143/0x290 mm/slub.c:3247 kmalloc include/linux/slab.h:591 [inline] kzalloc include/linux/slab.h:721 [inline] gsm_dlci_alloc+0x53/0x3a0 drivers/tty/n_gsm.c:1932 gsm_activate_mux+0x1c/0x330 drivers/tty/n_gsm.c:2438 gsm_config drivers/tty/n_gsm.c:2677 [inline] gsmld_ioctl+0xd46/0x15b0 drivers/tty/n_gsm.c:2986 tty_ioctl+0x8ff/0xc50 drivers/tty/tty_io.c:2816 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:874 [inline] __se_sys_ioctl+0xf1/0x160 fs/ioctl.c:860 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x61/0xcb Freed by task 3501: kasan_save_stack mm/kasan/common.c:38 [inline] kasan_set_track+0x4b/0x80 mm/kasan/common.c:46 kasan_set_free_info+0x1f/0x40 mm/kasan/generic.c:360 ____kasan_slab_free+0xd8/0x120 mm/kasan/common.c:366 kasan_slab_free include/linux/kasan.h:230 [inline] slab_free_hook mm/slub.c:1705 [inline] slab_free_freelist_hook+0xdd/0x160 mm/slub.c:1731 slab_free mm/slub.c:3499 [inline] kfree+0xf1/0x270 mm/slub.c:4559 dlci_put drivers/tty/n_gsm.c:1988 [inline] gsm_dlci_release drivers/tty/n_gsm.c:2021 [inline] gsm_cleanup_mux+0x574/0x850 drivers/tty/n_gsm.c:2415 gsm_config drivers/tty/n_gsm.c:2653 [inline] gsmld_ioctl+0xaae/0x15b0 drivers/tty/n_gsm.c:2986 tty_ioctl+0x8ff/0xc50 drivers/tty/tty_io.c:2816 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:874 [inline] __se_sys_ioctl+0xf1/0x160 fs/ioctl.c:860 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x61/0xcb Fixes: aa371e96f05d ("tty: n_gsm: fix restart handling via CLD command") Signed-off-by: Chaoyuan Peng Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/n_gsm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index b411a26cc092..1cdefac4dd1b 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -3070,8 +3070,10 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) gsm->has_devices = false; } for (i = NUM_DLCI - 1; i >= 0; i--) - if (gsm->dlci[i]) + if (gsm->dlci[i]) { gsm_dlci_release(gsm->dlci[i]); + gsm->dlci[i] = NULL; + } mutex_unlock(&gsm->mutex); /* Now wipe the queues */ tty_ldisc_flush(gsm->tty); -- cgit From e29c3f81eb8904edb762ea450aa78f52e5044b31 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sun, 23 Jul 2023 23:33:41 -0700 Subject: Documentation: devices.txt: reconcile serial/ucc_uart minor numers Reconcile devices.txt with serial/ucc_uart.c regarding device number assignments. ucc_uart.c supports 4 ports and uses minor devnums 46-49, so update devices.txt with that info. Then update ucc_uart.c's reference to the location of the devices.txt list in the kernel source tree. Fixes: d7584ed2b994 ("[POWERPC] qe-uart: add support for Freescale QUICCEngine UART") Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Randy Dunlap Cc: Timur Tabi Cc: Kumar Gala Cc: linuxppc-dev@lists.ozlabs.org Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: linux-serial@vger.kernel.org Cc: Jonathan Corbet Cc: linux-doc@vger.kernel.org Link: https://lore.kernel.org/r/20230724063341.28198-1-rdunlap@infradead.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/ucc_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 404230c1ebb2..0a370b9ea70b 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -59,7 +59,7 @@ static int firmware_loaded; /* #define LOOPBACK */ /* The major and minor device numbers are defined in - * http://www.lanana.org/docs/device-list/devices-2.6+.txt. For the QE + * Documentation/admin-guide/devices.txt. For the QE * UART, we have major number 204 and minor numbers 46 - 49, which are the * same as for the CPM2. This decision was made because no Freescale part * has both a CPM and a QE. -- cgit From 17aaf9ea07b656016316dc37716e987742b3e296 Mon Sep 17 00:00:00 2001 From: Vijaya Krishna Nivarthi Date: Tue, 25 Jul 2023 17:18:06 +0530 Subject: spi: spi-qcom-qspi: Ignore disabled interrupts' status in isr During FIFO/DMA modes dynamic switching, only corresponding interrupts are enabled. However its possible that FIFO related interrupt status registers get set during DMA mode. For example WR_FIFO_EMPTY bit is set during DMA TX. Ignore such status bits so that they don't trip unwanted operations. Suggested-by: Douglas Anderson Signed-off-by: Vijaya Krishna Nivarthi Fixes: b5762d95607e ("spi: spi-qcom-qspi: Add DMA mode support") Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson Link: https://lore.kernel.org/r/1690285689-30233-2-git-send-email-quic_vnivarth@quicinc.com Signed-off-by: Mark Brown --- drivers/spi/spi-qcom-qspi.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c index a8a683d6145c..21a13605d3b0 100644 --- a/drivers/spi/spi-qcom-qspi.c +++ b/drivers/spi/spi-qcom-qspi.c @@ -603,6 +603,9 @@ static irqreturn_t qcom_qspi_irq(int irq, void *dev_id) int_status = readl(ctrl->base + MSTR_INT_STATUS); writel(int_status, ctrl->base + MSTR_INT_STATUS); + /* Ignore disabled interrupts */ + int_status &= readl(ctrl->base + MSTR_INT_EN); + /* PIO mode handling */ if (ctrl->xfer.dir == QSPI_WRITE) { if (int_status & WR_FIFO_EMPTY) -- cgit From f7ba36d399c4558f36886adff9400be591b245f6 Mon Sep 17 00:00:00 2001 From: Vijaya Krishna Nivarthi Date: Tue, 25 Jul 2023 17:18:07 +0530 Subject: spi: spi-qcom-qspi: Use GFP_ATOMIC flag while allocating for descriptor While allocating for DMA descriptor, GFP_KERNEL flag is being used and this allocation happens within critical section with spinlock acquired. This generates a static checker warning. Use GFP_ATOMIC to prevent sleeping; and since this increases chances of allocation failure, add handling accordingly. Reported-by: Dan Carpenter Closes: https://lore.kernel.org/all/abc223e8-44af-40bb-a0bd-9865b393f435@moroto.mountain/ Signed-off-by: Vijaya Krishna Nivarthi Fixes: b5762d95607e ("spi: spi-qcom-qspi: Add DMA mode support") Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/1690285689-30233-3-git-send-email-quic_vnivarth@quicinc.com Signed-off-by: Mark Brown --- drivers/spi/spi-qcom-qspi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c index 21a13605d3b0..67c101792a74 100644 --- a/drivers/spi/spi-qcom-qspi.c +++ b/drivers/spi/spi-qcom-qspi.c @@ -308,9 +308,11 @@ static int qcom_qspi_alloc_desc(struct qcom_qspi *ctrl, dma_addr_t dma_ptr, dma_addr_t dma_cmd_desc; /* allocate for dma cmd descriptor */ - virt_cmd_desc = dma_pool_alloc(ctrl->dma_cmd_pool, GFP_KERNEL | __GFP_ZERO, &dma_cmd_desc); - if (!virt_cmd_desc) - return -ENOMEM; + virt_cmd_desc = dma_pool_alloc(ctrl->dma_cmd_pool, GFP_ATOMIC | __GFP_ZERO, &dma_cmd_desc); + if (!virt_cmd_desc) { + dev_warn_once(ctrl->dev, "Couldn't find memory for descriptor\n"); + return -EAGAIN; + } ctrl->virt_cmd_desc[ctrl->n_cmd_desc] = virt_cmd_desc; ctrl->dma_cmd_desc[ctrl->n_cmd_desc] = dma_cmd_desc; -- cgit From cfb81f2243b25a0d79accc6510ad66c5c5ad99ba Mon Sep 17 00:00:00 2001 From: Vijaya Krishna Nivarthi Date: Tue, 25 Jul 2023 17:18:08 +0530 Subject: spi: spi-qcom-qspi: Call dma_wmb() after setting up descriptors After setting up dma descriptors and before initiaiting dma transfer, call dma_wmb() to ensure all writes go through. This doesn't fix any reported problem but is added for safety. Signed-off-by: Vijaya Krishna Nivarthi Fixes: b5762d95607e ("spi: spi-qcom-qspi: Add DMA mode support") Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/1690285689-30233-4-git-send-email-quic_vnivarth@quicinc.com Signed-off-by: Mark Brown --- drivers/spi/spi-qcom-qspi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c index 67c101792a74..75fcb9145d91 100644 --- a/drivers/spi/spi-qcom-qspi.c +++ b/drivers/spi/spi-qcom-qspi.c @@ -443,8 +443,10 @@ static int qcom_qspi_transfer_one(struct spi_master *master, ret = qcom_qspi_setup_dma_desc(ctrl, xfer); if (ret != -EAGAIN) { - if (!ret) + if (!ret) { + dma_wmb(); qcom_qspi_dma_xfer(ctrl); + } goto exit; } dev_warn_once(ctrl->dev, "DMA failure, falling back to PIO\n"); -- cgit From 916a4edf3daed845b1e5d6cf0578a7e43c6f520e Mon Sep 17 00:00:00 2001 From: Vijaya Krishna Nivarthi Date: Tue, 25 Jul 2023 17:18:09 +0530 Subject: spi: spi-qcom-qspi: Add DMA_CHAIN_DONE to ALL_IRQS Add latest added DMA_CHAIN_DONE irq to QSPI_ALL_IRQS that encompasses all of the qspi IRQs. Signed-off-by: Vijaya Krishna Nivarthi Reviewed-by: Douglas Anderson Link: https://lore.kernel.org/r/1690285689-30233-5-git-send-email-quic_vnivarth@quicinc.com Signed-off-by: Mark Brown --- drivers/spi/spi-qcom-qspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c index 75fcb9145d91..9b3092e22942 100644 --- a/drivers/spi/spi-qcom-qspi.c +++ b/drivers/spi/spi-qcom-qspi.c @@ -69,7 +69,7 @@ WR_FIFO_OVERRUN) #define QSPI_ALL_IRQS (QSPI_ERR_IRQS | RESP_FIFO_RDY | \ WR_FIFO_EMPTY | WR_FIFO_FULL | \ - TRANSACTION_DONE) + TRANSACTION_DONE | DMA_CHAIN_DONE) #define PIO_XFER_CTRL 0x0014 #define REQUEST_COUNT_MSK 0xffff -- cgit From 9b8fef6345d5487137d4193bb0a0eae2203c284e Mon Sep 17 00:00:00 2001 From: Samuel Holland Date: Fri, 23 Jun 2023 23:01:59 -0700 Subject: serial: sifive: Fix sifive_serial_console_setup() section This function is called indirectly from the platform driver probe function. Even if the driver is built in, it may be probed after free_initmem() due to deferral or unbinding/binding via sysfs. Thus the function cannot be marked as __init. Fixes: 45c054d0815b ("tty: serial: add driver for the SiFive UART") Cc: stable Signed-off-by: Samuel Holland Link: https://lore.kernel.org/r/20230624060159.3401369-1-samuel.holland@sifive.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sifive.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sifive.c b/drivers/tty/serial/sifive.c index 1f565a216e74..a19db49327e2 100644 --- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -811,7 +811,7 @@ static void sifive_serial_console_write(struct console *co, const char *s, local_irq_restore(flags); } -static int __init sifive_serial_console_setup(struct console *co, char *options) +static int sifive_serial_console_setup(struct console *co, char *options) { struct sifive_serial_port *ssp; int baud = SIFIVE_DEFAULT_BAUD_RATE; -- cgit From 57c984f6fe20ebb9306d6e8c09b4f67fe63298c6 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Tue, 4 Jul 2023 16:48:18 +0100 Subject: tty: serial: sh-sci: Fix sleeping in atomic context Fix sleeping in atomic context warning as reported by the Smatch static checker tool by replacing disable_irq->disable_irq_nosync. Reported by: Dan Carpenter Fixes: 8749061be196 ("tty: serial: sh-sci: Add RZ/G2L SCIFA DMA tx support") Cc: stable@kernel.org Signed-off-by: Biju Das Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230704154818.406913-1-biju.das.jz@bp.renesas.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sh-sci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 7c9457962a3d..8b7a42e05d6d 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -590,7 +590,7 @@ static void sci_start_tx(struct uart_port *port) dma_submit_error(s->cookie_tx)) { if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) /* Switch irq from SCIF to DMA */ - disable_irq(s->irqs[SCIx_TXI_IRQ]); + disable_irq_nosync(s->irqs[SCIx_TXI_IRQ]); s->cookie_tx = 0; schedule_work(&s->work_tx); -- cgit From 748c5ea8b8796ae8ee80b8d3a3d940570b588d59 Mon Sep 17 00:00:00 2001 From: Ruihong Luo Date: Thu, 13 Jul 2023 08:42:36 +0800 Subject: serial: 8250_dw: Preserve original value of DLF register MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Preserve the original value of the Divisor Latch Fraction (DLF) register. When the DLF register is modified without preservation, it can disrupt the baudrate settings established by firmware or bootloader, leading to data corruption and the generation of unreadable or distorted characters. Fixes: 701c5e73b296 ("serial: 8250_dw: add fractional divisor support") Cc: stable Signed-off-by: Ruihong Luo Link: https://lore.kernel.org/stable/20230713004235.35904-1-colorsu1922%40gmail.com Reviewed-by: Ilpo Järvinen Reviewed-by: Andy Shevchenko Link: https://lore.kernel.org/r/20230713004235.35904-1-colorsu1922@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_dwlib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/8250/8250_dwlib.c b/drivers/tty/serial/8250/8250_dwlib.c index 75f32f054ebb..84843e204a5e 100644 --- a/drivers/tty/serial/8250/8250_dwlib.c +++ b/drivers/tty/serial/8250/8250_dwlib.c @@ -244,7 +244,7 @@ void dw8250_setup_port(struct uart_port *p) struct dw8250_port_data *pd = p->private_data; struct dw8250_data *data = to_dw8250_data(pd); struct uart_8250_port *up = up_to_u8250p(p); - u32 reg; + u32 reg, old_dlf; pd->hw_rs485_support = dw8250_detect_rs485_hw(p); if (pd->hw_rs485_support) { @@ -270,9 +270,11 @@ void dw8250_setup_port(struct uart_port *p) dev_dbg(p->dev, "Designware UART version %c.%c%c\n", (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); + /* Preserve value written by firmware or bootloader */ + old_dlf = dw8250_readl_ext(p, DW_UART_DLF); dw8250_writel_ext(p, DW_UART_DLF, ~0U); reg = dw8250_readl_ext(p, DW_UART_DLF); - dw8250_writel_ext(p, DW_UART_DLF, 0); + dw8250_writel_ext(p, DW_UART_DLF, old_dlf); if (reg) { pd->dlf_size = fls(reg); -- cgit From 602816c3ee3fdbf4a72cb4d2e5b8b756a5104b0f Mon Sep 17 00:00:00 2001 From: Jonathan Kim Date: Wed, 12 Jul 2023 16:32:29 -0400 Subject: drm/amdkfd: fix trap handling work around for debugging Update the list of devices that require the cwsr trap handling workaround for debugging use cases. Signed-off-by: Jonathan Kim Acked-by: Ruili Ji Reviewed-by: Felix Kuehling Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdkfd/kfd_debug.c | 5 ++--- drivers/gpu/drm/amd/amdkfd/kfd_debug.h | 6 ++++++ drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 6 ++---- 3 files changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c index fff3ccc04fa9..9766076e9ec4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c @@ -302,8 +302,7 @@ static int kfd_dbg_set_queue_workaround(struct queue *q, bool enable) if (!q) return 0; - if (KFD_GC_VERSION(q->device) < IP_VERSION(11, 0, 0) || - KFD_GC_VERSION(q->device) >= IP_VERSION(12, 0, 0)) + if (!kfd_dbg_has_cwsr_workaround(q->device)) return 0; if (enable && q->properties.is_user_cu_masked) @@ -349,7 +348,7 @@ int kfd_dbg_set_mes_debug_mode(struct kfd_process_device *pdd) { uint32_t spi_dbg_cntl = pdd->spi_dbg_override | pdd->spi_dbg_launch_mode; uint32_t flags = pdd->process->dbg_flags; - bool sq_trap_en = !!spi_dbg_cntl; + bool sq_trap_en = !!spi_dbg_cntl || !kfd_dbg_has_cwsr_workaround(pdd->dev); if (!kfd_dbg_is_per_vmid_supported(pdd->dev)) return 0; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.h b/drivers/gpu/drm/amd/amdkfd/kfd_debug.h index a289e59ceb79..662a13a0d582 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.h @@ -100,6 +100,12 @@ static inline bool kfd_dbg_is_rlc_restore_supported(struct kfd_node *dev) KFD_GC_VERSION(dev) == IP_VERSION(10, 1, 1)); } +static inline bool kfd_dbg_has_cwsr_workaround(struct kfd_node *dev) +{ + return KFD_GC_VERSION(dev) >= IP_VERSION(11, 0, 0) && + KFD_GC_VERSION(dev) <= IP_VERSION(11, 0, 3); +} + static inline bool kfd_dbg_has_gws_support(struct kfd_node *dev) { if ((KFD_GC_VERSION(dev) == IP_VERSION(9, 0, 1) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index f515cb8f30ca..2df153828ff4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -226,8 +226,7 @@ static int add_queue_mes(struct device_queue_manager *dqm, struct queue *q, queue_input.paging = false; queue_input.tba_addr = qpd->tba_addr; queue_input.tma_addr = qpd->tma_addr; - queue_input.trap_en = KFD_GC_VERSION(q->device) < IP_VERSION(11, 0, 0) || - KFD_GC_VERSION(q->device) > IP_VERSION(11, 0, 3); + queue_input.trap_en = !kfd_dbg_has_cwsr_workaround(q->device); queue_input.skip_process_ctx_clear = qpd->pqm->process->debug_trap_enabled; queue_type = convert_to_mes_queue_type(q->properties.type); @@ -1806,8 +1805,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q, */ q->properties.is_evicted = !!qpd->evicted; q->properties.is_dbg_wa = qpd->pqm->process->debug_trap_enabled && - KFD_GC_VERSION(q->device) >= IP_VERSION(11, 0, 0) && - KFD_GC_VERSION(q->device) <= IP_VERSION(11, 0, 3); + kfd_dbg_has_cwsr_workaround(q->device); if (qd) mqd_mgr->restore_mqd(mqd_mgr, &q->mqd, q->mqd_mem_obj, &q->gart_mqd_addr, -- cgit From 9beb223f2a3d1bb2cc4dff71b9750d2b82f01ae5 Mon Sep 17 00:00:00 2001 From: Victor Lu Date: Tue, 18 Jul 2023 14:31:58 -0400 Subject: drm/amdgpu: Fix infinite loop in gfxhub_v1_2_xcc_gart_enable (v2) An instance of for_each_inst() was not changed to match its new behaviour and is causing a loop. v2: remove tmp_mask variable Fixes: b579ea632fca ("drm/amdgpu: Modify for_each_inst macro") Signed-off-by: Victor Lu Acked-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c index 4dabf910334b..d9f14dc55998 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c +++ b/drivers/gpu/drm/amd/amdgpu/gfxhub_v1_2.c @@ -402,18 +402,15 @@ static void gfxhub_v1_2_xcc_program_invalidation(struct amdgpu_device *adev, static int gfxhub_v1_2_xcc_gart_enable(struct amdgpu_device *adev, uint32_t xcc_mask) { - uint32_t tmp_mask; int i; - tmp_mask = xcc_mask; /* * MC_VM_FB_LOCATION_BASE/TOP is NULL for VF, because they are * VF copy registers so vbios post doesn't program them, for * SRIOV driver need to program them */ if (amdgpu_sriov_vf(adev)) { - for_each_inst(i, tmp_mask) { - i = ffs(tmp_mask) - 1; + for_each_inst(i, xcc_mask) { WREG32_SOC15_RLC(GC, GET_INST(GC, i), regMC_VM_FB_LOCATION_BASE, adev->gmc.vram_start >> 24); WREG32_SOC15_RLC(GC, GET_INST(GC, i), regMC_VM_FB_LOCATION_TOP, -- cgit From c01aebeef3ce45f696ffa0a1303cea9b34babb45 Mon Sep 17 00:00:00 2001 From: Mario Limonciello Date: Thu, 13 Jul 2023 00:14:59 -0500 Subject: drm/amd: Fix an error handling mistake in psp_sw_init() If the second call to amdgpu_bo_create_kernel() fails, the memory allocated from the first call should be cleared. If the third call fails, the memory from the second call should be cleared. Fixes: b95b5391684b ("drm/amdgpu/psp: move PSP memory alloc from hw_init to sw_init") Signed-off-by: Mario Limonciello Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index 6d676bdd1505..78d1ee71f3f4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -498,11 +498,11 @@ static int psp_sw_init(void *handle) return 0; failed2: - amdgpu_bo_free_kernel(&psp->fw_pri_bo, - &psp->fw_pri_mc_addr, &psp->fw_pri_buf); -failed1: amdgpu_bo_free_kernel(&psp->fence_buf_bo, &psp->fence_buf_mc_addr, &psp->fence_buf); +failed1: + amdgpu_bo_free_kernel(&psp->fw_pri_bo, + &psp->fw_pri_mc_addr, &psp->fw_pri_buf); return ret; } -- cgit From 4a37c55b859a69f429bfa7fab4fc43ee470b60ed Mon Sep 17 00:00:00 2001 From: Jane Jian Date: Thu, 20 Jul 2023 18:08:07 +0800 Subject: drm/amd/smu: use AverageGfxclkFrequency* to replace previous GFX Curr Clock Report current GFX clock also from average clock value as the original CurrClock data is not valid/accurate any more as per FW team Signed-off-by: Jane Jian Reviewed-by: Lijo Lazar Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index b9bde5fa8f8f..3d188616ba24 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -1734,7 +1734,7 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, gpu_metrics->average_vclk1_frequency = metrics->AverageVclk1Frequency; gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency; - gpu_metrics->current_gfxclk = metrics->CurrClock[PPCLK_GFXCLK]; + gpu_metrics->current_gfxclk = gpu_metrics->average_gfxclk_frequency; gpu_metrics->current_socclk = metrics->CurrClock[PPCLK_SOCCLK]; gpu_metrics->current_uclk = metrics->CurrClock[PPCLK_UCLK]; gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0]; -- cgit From 25b054c3c89cb6a7106a7982f0f70e83d0797dab Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 11 Jul 2023 13:22:36 -0400 Subject: drm/amd/display: Guard DCN31 PHYD32CLK logic against chip family [Why] Current yellow carp B0 PHYD32CLK logic is incorrectly applied to other ASICs. [How] Add guard to check chip family is yellow carp before applying logic. Reviewed-by: Hansen Dsouza Acked-by: Alex Hung Signed-off-by: George Shen Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c index 65c1d754e2d6..01cc679ae418 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_dccg.c @@ -84,7 +84,8 @@ static enum phyd32clk_clock_source get_phy_mux_symclk( struct dcn_dccg *dccg_dcn, enum phyd32clk_clock_source src) { - if (dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { + if (dccg_dcn->base.ctx->asic_id.chip_family == FAMILY_YELLOW_CARP && + dccg_dcn->base.ctx->asic_id.hw_internal_rev == YELLOW_CARP_B0) { if (src == PHYD32CLKC) src = PHYD32CLKF; if (src == PHYD32CLKD) -- cgit From 4509e69a07761d08df7c46d4a08c8222522b1933 Mon Sep 17 00:00:00 2001 From: Alvin Lee Date: Wed, 12 Jul 2023 17:22:25 -0400 Subject: drm/amd/display: Don't apply FIFO resync W/A if rdivider = 0 [Description] It is not valid to set the WDIVIDER value to 0, so do not re-write to DISPCLK_WDIVIDER if the current value is 0 (i.e., it is at it's initial value and we have not made any requests to change DISPCLK yet). Reviewed-by: Saaem Rizvi Acked-by: Alex Hung Signed-off-by: Alvin Lee Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c index 11e28e056cf7..61ceff6bc0b1 100644 --- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dccg.c @@ -49,7 +49,10 @@ static void dccg32_trigger_dio_fifo_resync( uint32_t dispclk_rdivider_value = 0; REG_GET(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_RDIVIDER, &dispclk_rdivider_value); - REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value); + + /* Not valid for the WDIVIDER to be set to 0 */ + if (dispclk_rdivider_value != 0) + REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value); } static void dccg32_get_pixel_rate_div( -- cgit From de612738e9771bd66aeb20044486c457c512f684 Mon Sep 17 00:00:00 2001 From: Leo Chen Date: Wed, 12 Jul 2023 16:50:15 -0400 Subject: drm/amd/display: Exit idle optimizations before attempt to access PHY [Why & How] DMUB may hang when powering down pixel clocks due to no dprefclk. It is fixed by exiting idle optimization before the attempt to access PHY. Reviewed-by: Nicholas Kazlauskas Acked-by: Alex Hung Signed-off-by: Leo Chen Tested-by: Daniel Wheeler Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c index 6c9ca43d1040..20d4d08a6a2f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c @@ -1792,10 +1792,13 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) hws->funcs.edp_backlight_control(edp_link_with_sink, false); } /*resume from S3, no vbios posting, no need to power down again*/ + clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr); + power_down_all_hw_blocks(dc); disable_vga_and_power_gate_all_controllers(dc); if (edp_link_with_sink && !keep_edp_vdd_on) dc->hwss.edp_power_control(edp_link_with_sink, false); + clk_mgr_optimize_pwr_state(dc, dc->clk_mgr); } bios_set_scratch_acc_mode_change(dc->ctx->dc_bios, 1); } -- cgit From 38ac4e8385ffb275b1837986ca6c16f26ea028c5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 21 Jul 2023 17:55:49 +0300 Subject: drm/amd/display: Unlock on error path in dm_handle_mst_sideband_msg_ready_event() This error path needs to unlock the "aconnector->handle_mst_msg_ready" mutex before returning. Fixes: 4f6d9e38c4d2 ("drm/amd/display: Add polling method to handle MST reply packet") Signed-off-by: Dan Carpenter Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 888e80f498e9..9bc86deac9e8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -706,7 +706,7 @@ void dm_handle_mst_sideband_msg_ready_event( if (retry == 3) { DRM_ERROR("Failed to ack MST event.\n"); - return; + break; } drm_dp_mst_hpd_irq_send_new_request(&aconnector->mst_mgr); -- cgit From bc1688fce2ec7726112276650762275392d1bab1 Mon Sep 17 00:00:00 2001 From: Lijo Lazar Date: Tue, 25 Jul 2023 11:00:08 +0530 Subject: drm/amdgpu: Restore HQD persistent state register On GFX v9.4.3, compute queue MQD is populated using the values in HQD persistent state register. Hence don't clear the values on module unload, instead restore it to the default reset value so that MQD is initialized correctly during next module load. In particular, preload flag needs to be set on compute queue MQD, otherwise it could cause uninitialized values being used at device reset state resulting in EDC. Signed-off-by: Lijo Lazar Reviewed-by: Hawking Zhang Reviewed-by: Asad Kamal Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c index 9e3b835bdbb2..4f883b94f98e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_3.c @@ -46,6 +46,7 @@ MODULE_FIRMWARE("amdgpu/gc_9_4_3_rlc.bin"); #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L #define GOLDEN_GB_ADDR_CONFIG 0x2a114042 +#define CP_HQD_PERSISTENT_STATE_DEFAULT 0xbe05301 struct amdgpu_gfx_ras gfx_v9_4_3_ras; @@ -1736,7 +1737,7 @@ static int gfx_v9_4_3_xcc_q_fini_register(struct amdgpu_ring *ring, WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_IQ_TIMER, 0); WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_IB_CONTROL, 0); - WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_PERSISTENT_STATE, 0); + WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_PERSISTENT_STATE, CP_HQD_PERSISTENT_STATE_DEFAULT); WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_PQ_DOORBELL_CONTROL, 0x40000000); WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_PQ_DOORBELL_CONTROL, 0); WREG32_SOC15_RLC(GC, GET_INST(GC, xcc_id), regCP_HQD_PQ_RPTR, 0); -- cgit From 4139f992c49356391fb086c0c8ce51f66c26d623 Mon Sep 17 00:00:00 2001 From: Minjie Du Date: Tue, 25 Jul 2023 11:06:25 +0800 Subject: ata: pata_arasan_cf: Use dev_err_probe() instead dev_err() in data_xfer() It is possible for dma_request_chan() to return EPROBE_DEFER, which means acdev->host->dev is not ready yet. At this point dev_err() will have no output. Use dev_err_probe() instead. Signed-off-by: Minjie Du Acked-by: Viresh Kumar Reviewed-by: Sergey Shtylyov Signed-off-by: Damien Le Moal --- drivers/ata/pata_arasan_cf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_arasan_cf.c b/drivers/ata/pata_arasan_cf.c index 6ab294322e79..314eaa167954 100644 --- a/drivers/ata/pata_arasan_cf.c +++ b/drivers/ata/pata_arasan_cf.c @@ -529,7 +529,8 @@ static void data_xfer(struct work_struct *work) /* dma_request_channel may sleep, so calling from process context */ acdev->dma_chan = dma_request_chan(acdev->host->dev, "data"); if (IS_ERR(acdev->dma_chan)) { - dev_err(acdev->host->dev, "Unable to get dma_chan\n"); + dev_err_probe(acdev->host->dev, PTR_ERR(acdev->dma_chan), + "Unable to get dma_chan\n"); acdev->dma_chan = NULL; goto chan_request_fail; } -- cgit From 1cfe2d28e4d50a4e3e49344ade3b28f8dc26f891 Mon Sep 17 00:00:00 2001 From: Yang Yingliang Date: Tue, 25 Jul 2023 20:28:09 +0800 Subject: ata: pata_octeon_cf: fix error return code in octeon_cf_probe() The variable 'rv' is set to 0 after calling of_property_read_reg(), so it cannot be used as an error code. Change to using correct error codes in the error path. Fixes: d0b2461678b1 ("ata: Use of_property_read_reg() to parse "reg"") Signed-off-by: Yang Yingliang Reviewed-by: Sergey Shtylyov Reviewed-by: Rob Herring Signed-off-by: Damien Le Moal --- drivers/ata/pata_octeon_cf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_octeon_cf.c b/drivers/ata/pata_octeon_cf.c index ff538b858928..2884acfc4863 100644 --- a/drivers/ata/pata_octeon_cf.c +++ b/drivers/ata/pata_octeon_cf.c @@ -815,8 +815,8 @@ static int octeon_cf_probe(struct platform_device *pdev) irq_handler_t irq_handler = NULL; void __iomem *base; struct octeon_cf_port *cf_port; - int rv = -ENOMEM; u32 bus_width; + int rv; node = pdev->dev.of_node; if (node == NULL) @@ -893,12 +893,12 @@ static int octeon_cf_probe(struct platform_device *pdev) cs0 = devm_ioremap(&pdev->dev, res_cs0->start, resource_size(res_cs0)); if (!cs0) - return rv; + return -ENOMEM; /* allocate host */ host = ata_host_alloc(&pdev->dev, 1); if (!host) - return rv; + return -ENOMEM; ap = host->ports[0]; ap->private_data = cf_port; -- cgit From 55cef78c244d0d076f5a75a35530ca63c92f4426 Mon Sep 17 00:00:00 2001 From: Lin Ma Date: Sun, 23 Jul 2023 16:02:05 +0800 Subject: macvlan: add forgotten nla_policy for IFLA_MACVLAN_BC_CUTOFF The previous commit 954d1fa1ac93 ("macvlan: Add netlink attribute for broadcast cutoff") added one additional attribute named IFLA_MACVLAN_BC_CUTOFF to allow broadcast cutfoff. However, it forgot to describe the nla_policy at macvlan_policy (drivers/net/macvlan.c). Hence, this suppose NLA_S32 (4 bytes) integer can be faked as empty (0 bytes) by a malicious user, which could leads to OOB in heap just like CVE-2023-3773. To fix it, this commit just completes the nla_policy description for IFLA_MACVLAN_BC_CUTOFF. This enforces the length check and avoids the potential OOB read. Fixes: 954d1fa1ac93 ("macvlan: Add netlink attribute for broadcast cutoff") Signed-off-by: Lin Ma Reviewed-by: Simon Horman Link: https://lore.kernel.org/r/20230723080205.3715164-1-linma@zju.edu.cn Signed-off-by: Jakub Kicinski --- drivers/net/macvlan.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 4a53debf9d7c..ed908165a8b4 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -1746,6 +1746,7 @@ static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = { [IFLA_MACVLAN_MACADDR_COUNT] = { .type = NLA_U32 }, [IFLA_MACVLAN_BC_QUEUE_LEN] = { .type = NLA_U32 }, [IFLA_MACVLAN_BC_QUEUE_LEN_USED] = { .type = NLA_REJECT }, + [IFLA_MACVLAN_BC_CUTOFF] = { .type = NLA_S32 }, }; int macvlan_link_register(struct rtnl_link_ops *ops) -- cgit From e11ec2b868af2b351c6c1e2e50eb711cc5423a10 Mon Sep 17 00:00:00 2001 From: Alex Elder Date: Mon, 24 Jul 2023 17:40:55 -0500 Subject: net: ipa: only reset hashed tables when supported Last year, the code that manages GSI channel transactions switched from using spinlock-protected linked lists to using indexes into the ring buffer used for a channel. Recently, Google reported seeing transaction reference count underflows occasionally during shutdown. Doug Anderson found a way to reproduce the issue reliably, and bisected the issue to the commit that eliminated the linked lists and the lock. The root cause was ultimately determined to be related to unused transactions being committed as part of the modem shutdown cleanup activity. Unused transactions are not normally expected (except in error cases). The modem uses some ranges of IPA-resident memory, and whenever it shuts down we zero those ranges. In ipa_filter_reset_table() a transaction is allocated to zero modem filter table entries. If hashing is not supported, hashed table memory should not be zeroed. But currently nothing prevents that, and the result is an unused transaction. Something similar occurs when we zero routing table entries for the modem. By preventing any attempt to clear hashed tables when hashing is not supported, the reference count underflow is avoided in this case. Note that there likely remains an issue with properly freeing unused transactions (if they occur due to errors). This patch addresses only the underflows that Google originally reported. Cc: # 6.1.x Fixes: d338ae28d8a8 ("net: ipa: kill all other transaction lists") Tested-by: Douglas Anderson Signed-off-by: Alex Elder Link: https://lore.kernel.org/r/20230724224055.1688854-1-elder@linaro.org Signed-off-by: Jakub Kicinski --- drivers/net/ipa/ipa_table.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ipa/ipa_table.c b/drivers/net/ipa/ipa_table.c index f0529c31d0b6..7b637bb8b41c 100644 --- a/drivers/net/ipa/ipa_table.c +++ b/drivers/net/ipa/ipa_table.c @@ -273,16 +273,15 @@ static int ipa_filter_reset(struct ipa *ipa, bool modem) if (ret) return ret; - ret = ipa_filter_reset_table(ipa, true, false, modem); - if (ret) + ret = ipa_filter_reset_table(ipa, false, true, modem); + if (ret || !ipa_table_hash_support(ipa)) return ret; - ret = ipa_filter_reset_table(ipa, false, true, modem); + ret = ipa_filter_reset_table(ipa, true, false, modem); if (ret) return ret; - ret = ipa_filter_reset_table(ipa, true, true, modem); - return ret; + return ipa_filter_reset_table(ipa, true, true, modem); } /* The AP routes and modem routes are each contiguous within the @@ -291,12 +290,13 @@ static int ipa_filter_reset(struct ipa *ipa, bool modem) * */ static int ipa_route_reset(struct ipa *ipa, bool modem) { + bool hash_support = ipa_table_hash_support(ipa); u32 modem_route_count = ipa->modem_route_count; struct gsi_trans *trans; u16 first; u16 count; - trans = ipa_cmd_trans_alloc(ipa, 4); + trans = ipa_cmd_trans_alloc(ipa, hash_support ? 4 : 2); if (!trans) { dev_err(&ipa->pdev->dev, "no transaction for %s route reset\n", @@ -313,10 +313,12 @@ static int ipa_route_reset(struct ipa *ipa, bool modem) } ipa_table_reset_add(trans, false, false, false, first, count); - ipa_table_reset_add(trans, false, true, false, first, count); - ipa_table_reset_add(trans, false, false, true, first, count); - ipa_table_reset_add(trans, false, true, true, first, count); + + if (hash_support) { + ipa_table_reset_add(trans, false, true, false, first, count); + ipa_table_reset_add(trans, false, true, true, first, count); + } gsi_trans_commit_wait(trans); -- cgit From 58f6259b7a08f8d47d4629609703d358b042f0fd Mon Sep 17 00:00:00 2001 From: Rahul Singh Date: Tue, 18 Jul 2023 12:31:07 +0100 Subject: xen/evtchn: Introduce new IOCTL to bind static evtchn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Xen 4.17 supports the creation of static evtchns. To allow user space application to bind static evtchns introduce new ioctl "IOCTL_EVTCHN_BIND_STATIC". Existing IOCTL doing more than binding that’s why we need to introduce the new IOCTL to only bind the static event channels. Static evtchns to be available for use during the lifetime of the guest. When the application exits, __unbind_from_irq() ends up being called from release() file operations because of that static evtchns are getting closed. To avoid closing the static event channel, add the new bool variable "is_static" in "struct irq_info" to mark the event channel static when creating the event channel to avoid closing the static evtchn. Also, take this opportunity to remove the open-coded version of the evtchn close in drivers/xen/evtchn.c file and use xen_evtchn_close(). Signed-off-by: Rahul Singh Reviewed-by: Oleksandr Tyshchenko Acked-by: Stefano Stabellini Link: https://lore.kernel.org/r/ae7329bf1713f83e4aad4f3fa0f316258c40a3e9.1689677042.git.rahul.singh@arm.com Signed-off-by: Juergen Gross --- drivers/xen/events/events_base.c | 16 +++++----------- drivers/xen/evtchn.c | 35 ++++++++++++++++++++++++++--------- 2 files changed, 31 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index c7715f8bd452..3bdd5b59661d 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -112,6 +112,7 @@ struct irq_info { unsigned int irq_epoch; /* If eoi_cpu valid: irq_epoch of event */ u64 eoi_time; /* Time in jiffies when to EOI. */ raw_spinlock_t lock; + bool is_static; /* Is event channel static */ union { unsigned short virq; @@ -815,15 +816,6 @@ static void xen_free_irq(unsigned irq) irq_free_desc(irq); } -static void xen_evtchn_close(evtchn_port_t port) -{ - struct evtchn_close close; - - close.port = port; - if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0) - BUG(); -} - /* Not called for lateeoi events. */ static void event_handler_exit(struct irq_info *info) { @@ -982,7 +974,8 @@ static void __unbind_from_irq(unsigned int irq) unsigned int cpu = cpu_from_irq(irq); struct xenbus_device *dev; - xen_evtchn_close(evtchn); + if (!info->is_static) + xen_evtchn_close(evtchn); switch (type_from_irq(irq)) { case IRQT_VIRQ: @@ -1574,7 +1567,7 @@ int xen_set_irq_priority(unsigned irq, unsigned priority) } EXPORT_SYMBOL_GPL(xen_set_irq_priority); -int evtchn_make_refcounted(evtchn_port_t evtchn) +int evtchn_make_refcounted(evtchn_port_t evtchn, bool is_static) { int irq = get_evtchn_to_irq(evtchn); struct irq_info *info; @@ -1590,6 +1583,7 @@ int evtchn_make_refcounted(evtchn_port_t evtchn) WARN_ON(info->refcnt != -1); info->refcnt = 1; + info->is_static = is_static; return 0; } diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index c99415a70051..9139a7364df5 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -366,10 +366,10 @@ static int evtchn_resize_ring(struct per_user_data *u) return 0; } -static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port) +static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port, + bool is_static) { struct user_evtchn *evtchn; - struct evtchn_close close; int rc = 0; /* @@ -402,14 +402,14 @@ static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port) if (rc < 0) goto err; - rc = evtchn_make_refcounted(port); + rc = evtchn_make_refcounted(port, is_static); return rc; err: /* bind failed, should close the port now */ - close.port = port; - if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0) - BUG(); + if (!is_static) + xen_evtchn_close(port); + del_evtchn(u, evtchn); return rc; } @@ -456,7 +456,7 @@ static long evtchn_ioctl(struct file *file, if (rc != 0) break; - rc = evtchn_bind_to_user(u, bind_virq.port); + rc = evtchn_bind_to_user(u, bind_virq.port, false); if (rc == 0) rc = bind_virq.port; break; @@ -482,7 +482,7 @@ static long evtchn_ioctl(struct file *file, if (rc != 0) break; - rc = evtchn_bind_to_user(u, bind_interdomain.local_port); + rc = evtchn_bind_to_user(u, bind_interdomain.local_port, false); if (rc == 0) rc = bind_interdomain.local_port; break; @@ -507,7 +507,7 @@ static long evtchn_ioctl(struct file *file, if (rc != 0) break; - rc = evtchn_bind_to_user(u, alloc_unbound.port); + rc = evtchn_bind_to_user(u, alloc_unbound.port, false); if (rc == 0) rc = alloc_unbound.port; break; @@ -536,6 +536,23 @@ static long evtchn_ioctl(struct file *file, break; } + case IOCTL_EVTCHN_BIND_STATIC: { + struct ioctl_evtchn_bind bind; + struct user_evtchn *evtchn; + + rc = -EFAULT; + if (copy_from_user(&bind, uarg, sizeof(bind))) + break; + + rc = -EISCONN; + evtchn = find_evtchn(u, bind.port); + if (evtchn) + break; + + rc = evtchn_bind_to_user(u, bind.port, true); + break; + } + case IOCTL_EVTCHN_NOTIFY: { struct ioctl_evtchn_notify notify; struct user_evtchn *evtchn; -- cgit From f8ea95021022826a010f56cf19451c21f4c9c155 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 22 Jun 2023 09:45:20 +0200 Subject: misc/genalloc: Name subpools by of_node_full_name() A previous commit tried to come up with more generic subpool names, but this isn't quite working: the node name was used elsewhere to match pools to consumers which regressed the nVidia Tegra 2/3 video decoder. Revert back to an earlier approach using of_node_full_name() instead of just the name to make sure the pool name is more unique, and change both sites using this in the kernel. It is not perfect since two SRAM nodes could have the same subpool name but it makes the situation better than before. Reported-by: Dmitry Osipenko Fixes: 21e5a2d10c8f ("misc: sram: Generate unique names for subpools") Signed-off-by: Linus Walleij Tested-by: Dmitry Osipenko Link: https://lore.kernel.org/r/20230622074520.3058027-1-linus.walleij@linaro.org Signed-off-by: Greg Kroah-Hartman --- drivers/misc/sram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 5757adf418b1..61209739dc43 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -236,7 +236,7 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res) } if (!label) block->label = devm_kasprintf(sram->dev, GFP_KERNEL, - "%s", dev_name(sram->dev)); + "%s", of_node_full_name(child)); else block->label = devm_kstrdup(sram->dev, label, GFP_KERNEL); -- cgit From 2c39dd025da489cf87d26469d9f5ff19715324a0 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 24 Jul 2023 05:25:28 +0200 Subject: net: dsa: qca8k: enable use_single_write for qca8xxx The qca8xxx switch supports 2 way to write reg values, a slow way using mdio and a fast way by sending specially crafted mgmt packet to read/write reg. The fast way can support up to 32 bytes of data as eth packet are used to send/receive. This correctly works for almost the entire regmap of the switch but with the use of some kernel selftests for dsa drivers it was found a funny and interesting hw defect/limitation. For some specific reg, bulk write won't work and will result in writing only part of the requested regs resulting in half data written. This was especially hard to track and discover due to the total strangeness of the problem and also by the specific regs where this occurs. This occurs in the specific regs of the ATU table, where multiple entry needs to be written to compose the entire entry. It was discovered that with a bulk write of 12 bytes on QCA8K_REG_ATU_DATA0 only QCA8K_REG_ATU_DATA0 and QCA8K_REG_ATU_DATA2 were written, but QCA8K_REG_ATU_DATA1 was always zero. Tcpdump was used to make sure the specially crafted packet was correct and this was confirmed. The problem was hard to track as the lack of QCA8K_REG_ATU_DATA1 resulted in an entry somehow possible as the first bytes of the mac address are set in QCA8K_REG_ATU_DATA0 and the entry type is set in QCA8K_REG_ATU_DATA2. Funlly enough writing QCA8K_REG_ATU_DATA1 results in the same problem with QCA8K_REG_ATU_DATA2 empty and QCA8K_REG_ATU_DATA1 and QCA8K_REG_ATU_FUNC correctly written. A speculation on the problem might be that there are some kind of indirection internally when accessing these regs and they can't be accessed all together, due to the fact that it's really a table mapped somewhere in the switch SRAM. Even more funny is the fact that every other reg was tested with all kind of combination and they are not affected by this problem. Read operation was also tested and always worked so it's not affected by this problem. The problem is not present if we limit writing a single reg at times. To handle this hardware defect, enable use_single_write so that bulk api can correctly split the write in multiple different operation effectively reverting to a non-bulk write. Cc: Mark Brown Fixes: c766e077d927 ("net: dsa: qca8k: convert to regmap read/write API") Signed-off-by: Christian Marangi Cc: stable@vger.kernel.org Signed-off-by: David S. Miller --- drivers/net/dsa/qca/qca8k-8xxx.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c index 09b80644c11b..efe9380d4a15 100644 --- a/drivers/net/dsa/qca/qca8k-8xxx.c +++ b/drivers/net/dsa/qca/qca8k-8xxx.c @@ -576,8 +576,11 @@ static struct regmap_config qca8k_regmap_config = { .rd_table = &qca8k_readable_table, .disable_locking = true, /* Locking is handled by qca8k read/write */ .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ - .max_raw_read = 32, /* mgmt eth can read/write up to 8 registers at time */ - .max_raw_write = 32, + .max_raw_read = 32, /* mgmt eth can read up to 8 registers at time */ + /* ATU regs suffer from a bug where some data are not correctly + * written. Disable bulk write to correctly write ATU entry. + */ + .use_single_write = true, }; static int -- cgit From 80248d4160894d7e40b04111bdbaa4ff93fc4bd7 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 24 Jul 2023 05:25:29 +0200 Subject: net: dsa: qca8k: fix search_and_insert wrong handling of new rule On inserting a mdb entry, fdb_search_and_insert is used to add a port to the qca8k target entry in the FDB db. A FDB entry can't be modified so it needs to be removed and insert again with the new values. To detect if an entry already exist, the SEARCH operation is used and we check the aging of the entry. If the entry is not 0, the entry exist and we proceed to delete it. Current code have 2 main problem: - The condition to check if the FDB entry exist is wrong and should be the opposite. - When a FDB entry doesn't exist, aging was never actually set to the STATIC value resulting in allocating an invalid entry. Fix both problem by adding aging support to the function, calling the function with STATIC as aging by default and finally by correct the condition to check if the entry actually exist. Fixes: ba8f870dfa63 ("net: dsa: qca8k: add support for mdb_add/del") Signed-off-by: Christian Marangi Cc: stable@vger.kernel.org Signed-off-by: David S. Miller --- drivers/net/dsa/qca/qca8k-common.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c index 8c2dc0e48ff4..4909603d07c8 100644 --- a/drivers/net/dsa/qca/qca8k-common.c +++ b/drivers/net/dsa/qca/qca8k-common.c @@ -244,7 +244,7 @@ void qca8k_fdb_flush(struct qca8k_priv *priv) } static int qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, - const u8 *mac, u16 vid) + const u8 *mac, u16 vid, u8 aging) { struct qca8k_fdb fdb = { 0 }; int ret; @@ -261,10 +261,12 @@ static int qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask, goto exit; /* Rule exist. Delete first */ - if (!fdb.aging) { + if (fdb.aging) { ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); if (ret) goto exit; + } else { + fdb.aging = aging; } /* Add port to fdb portmask */ @@ -810,7 +812,8 @@ int qca8k_port_mdb_add(struct dsa_switch *ds, int port, const u8 *addr = mdb->addr; u16 vid = mdb->vid; - return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid); + return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid, + QCA8K_ATU_STATUS_STATIC); } int qca8k_port_mdb_del(struct dsa_switch *ds, int port, -- cgit From ae70dcb9d9ecaf7d9836d3e1b5bef654d7ef5680 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 24 Jul 2023 05:25:30 +0200 Subject: net: dsa: qca8k: fix broken search_and_del On deleting an MDB entry for a port, fdb_search_and_del is used. An FDB entry can't be modified so it needs to be deleted and readded again with the new portmap (and the port deleted as requested) We use the SEARCH operator to search the entry to edit by vid and mac address and then we check the aging if we actually found an entry. Currently the code suffer from a bug where the searched fdb entry is never read again with the found values (if found) resulting in the code always returning -EINVAL as aging was always 0. Fix this by correctly read the fdb entry after it was searched. Fixes: ba8f870dfa63 ("net: dsa: qca8k: add support for mdb_add/del") Signed-off-by: Christian Marangi Cc: stable@vger.kernel.org Signed-off-by: David S. Miller --- drivers/net/dsa/qca/qca8k-common.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c index 4909603d07c8..b644c05337c5 100644 --- a/drivers/net/dsa/qca/qca8k-common.c +++ b/drivers/net/dsa/qca/qca8k-common.c @@ -293,6 +293,10 @@ static int qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask, if (ret < 0) goto exit; + ret = qca8k_fdb_read(priv, &fdb); + if (ret < 0) + goto exit; + /* Rule doesn't exist. Why delete? */ if (!fdb.aging) { ret = -EINVAL; -- cgit From dfd739f182b00b02bd7470ed94d112684cc04fa2 Mon Sep 17 00:00:00 2001 From: Christian Marangi Date: Mon, 24 Jul 2023 05:25:31 +0200 Subject: net: dsa: qca8k: fix mdb add/del case with 0 VID The qca8k switch doesn't support using 0 as VID and require a default VID to be always set. MDB add/del function doesn't currently handle this and are currently setting the default VID. Fix this by correctly handling this corner case and internally use the default VID for VID 0 case. Fixes: ba8f870dfa63 ("net: dsa: qca8k: add support for mdb_add/del") Signed-off-by: Christian Marangi Cc: stable@vger.kernel.org Signed-off-by: David S. Miller --- drivers/net/dsa/qca/qca8k-common.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c index b644c05337c5..13b8452ce5b2 100644 --- a/drivers/net/dsa/qca/qca8k-common.c +++ b/drivers/net/dsa/qca/qca8k-common.c @@ -816,6 +816,9 @@ int qca8k_port_mdb_add(struct dsa_switch *ds, int port, const u8 *addr = mdb->addr; u16 vid = mdb->vid; + if (!vid) + vid = QCA8K_PORT_VID_DEF; + return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid, QCA8K_ATU_STATUS_STATIC); } @@ -828,6 +831,9 @@ int qca8k_port_mdb_del(struct dsa_switch *ds, int port, const u8 *addr = mdb->addr; u16 vid = mdb->vid; + if (!vid) + vid = QCA8K_PORT_VID_DEF; + return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid); } -- cgit From d4a7ce642100765119a872d4aba1bf63e3a22c8a Mon Sep 17 00:00:00 2001 From: Muhammad Husaini Zulkifli Date: Mon, 24 Jul 2023 09:12:50 -0700 Subject: igc: Fix Kernel Panic during ndo_tx_timeout callback The Xeon validation group has been carrying out some loaded tests with various HW configurations, and they have seen some transmit queue time out happening during the test. This will cause the reset adapter function to be called by igc_tx_timeout(). Similar race conditions may arise when the interface is being brought down and up in igc_reinit_locked(), an interrupt being generated, and igc_clean_tx_irq() being called to complete the TX. When the igc_tx_timeout() function is invoked, this patch will turn off all TX ring HW queues during igc_down() process. TX ring HW queues will be activated again during the igc_configure_tx_ring() process when performing the igc_up() procedure later. This patch also moved existing igc_disable_tx_ring_hw() to avoid using forward declaration. Kernel trace: [ 7678.747813] ------------[ cut here ]------------ [ 7678.757914] NETDEV WATCHDOG: enp1s0 (igc): transmit queue 2 timed out [ 7678.770117] WARNING: CPU: 0 PID: 13 at net/sched/sch_generic.c:525 dev_watchdog+0x1ae/0x1f0 [ 7678.784459] Modules linked in: xt_conntrack nft_chain_nat xt_MASQUERADE xt_addrtype nft_compat nf_tables nfnetlink br_netfilter bridge stp llc overlay dm_mod emrcha(PO) emriio(PO) rktpm(PO) cegbuf_mod(PO) patch_update(PO) se(PO) sgx_tgts(PO) mktme(PO) keylocker(PO) svtdx(PO) svfs_pci_hotplug(PO) vtd_mod(PO) davemem(PO) svmabort(PO) svindexio(PO) usbx2(PO) ehci_sched(PO) svheartbeat(PO) ioapic(PO) sv8259(PO) svintr(PO) lt(PO) pcierootport(PO) enginefw_mod(PO) ata(PO) smbus(PO) spiflash_cdf(PO) arden(PO) dsa_iax(PO) oobmsm_punit(PO) cpm(PO) svkdb(PO) ebg_pch(PO) pch(PO) sviotargets(PO) svbdf(PO) svmem(PO) svbios(PO) dram(PO) svtsc(PO) targets(PO) superio(PO) svkernel(PO) cswitch(PO) mcf(PO) pentiumIII_mod(PO) fs_svfs(PO) mdevdefdb(PO) svfs_os_services(O) ixgbe mdio mdio_devres libphy emeraldrapids_svdefs(PO) regsupport(O) libnvdimm nls_cp437 snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_intel_dspcfg snd_hda_codec snd_hwdep x86_pkg_temp_thermal snd_hda_core snd_pcm snd_timer isst_if_mbox_pci [ 7678.784496] input_leds isst_if_mmio sg snd isst_if_common soundcore wmi button sad9(O) drm fuse backlight configfs efivarfs ip_tables x_tables vmd sdhci led_class rtl8150 r8152 hid_generic pegasus mmc_block usbhid mmc_core hid megaraid_sas ixgb igb i2c_algo_bit ice i40e hpsa scsi_transport_sas e1000e e1000 e100 ax88179_178a usbnet xhci_pci sd_mod xhci_hcd t10_pi crc32c_intel crc64_rocksoft igc crc64 crc_t10dif usbcore crct10dif_generic ptp crct10dif_common usb_common pps_core [ 7679.200403] RIP: 0010:dev_watchdog+0x1ae/0x1f0 [ 7679.210201] Code: 28 e9 53 ff ff ff 4c 89 e7 c6 05 06 42 b9 00 01 e8 17 d1 fb ff 44 89 e9 4c 89 e6 48 c7 c7 40 ad fb 81 48 89 c2 e8 52 62 82 ff <0f> 0b e9 72 ff ff ff 65 8b 05 80 7d 7c 7e 89 c0 48 0f a3 05 0a c1 [ 7679.245438] RSP: 0018:ffa00000001f7d90 EFLAGS: 00010282 [ 7679.256021] RAX: 0000000000000000 RBX: ff11000109938440 RCX: 0000000000000000 [ 7679.268710] RDX: ff11000361e26cd8 RSI: ff11000361e1b880 RDI: ff11000361e1b880 [ 7679.281314] RBP: ffa00000001f7da8 R08: ff1100035f8fffe8 R09: 0000000000027ffb [ 7679.293840] R10: 0000000000001f0a R11: ff1100035f840000 R12: ff11000109938000 [ 7679.306276] R13: 0000000000000002 R14: dead000000000122 R15: ffa00000001f7e18 [ 7679.318648] FS: 0000000000000000(0000) GS:ff11000361e00000(0000) knlGS:0000000000000000 [ 7679.332064] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 7679.342757] CR2: 00007ffff7fca168 CR3: 000000013b08a006 CR4: 0000000000471ef8 [ 7679.354984] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 7679.367207] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 [ 7679.379370] PKRU: 55555554 [ 7679.386446] Call Trace: [ 7679.393152] [ 7679.399363] ? __pfx_dev_watchdog+0x10/0x10 [ 7679.407870] call_timer_fn+0x31/0x110 [ 7679.415698] expire_timers+0xb2/0x120 [ 7679.423403] run_timer_softirq+0x179/0x1e0 [ 7679.431532] ? __schedule+0x2b1/0x820 [ 7679.439078] __do_softirq+0xd1/0x295 [ 7679.446426] ? __pfx_smpboot_thread_fn+0x10/0x10 [ 7679.454867] run_ksoftirqd+0x22/0x30 [ 7679.462058] smpboot_thread_fn+0xb7/0x160 [ 7679.469670] kthread+0xcd/0xf0 [ 7679.476097] ? __pfx_kthread+0x10/0x10 [ 7679.483211] ret_from_fork+0x29/0x50 [ 7679.490047] [ 7679.495204] ---[ end trace 0000000000000000 ]--- [ 7679.503179] igc 0000:01:00.0 enp1s0: Register Dump [ 7679.511230] igc 0000:01:00.0 enp1s0: Register Name Value [ 7679.519892] igc 0000:01:00.0 enp1s0: CTRL 181c0641 [ 7679.528782] igc 0000:01:00.0 enp1s0: STATUS 40280683 [ 7679.537551] igc 0000:01:00.0 enp1s0: CTRL_EXT 10000040 [ 7679.546284] igc 0000:01:00.0 enp1s0: MDIC 180a3800 [ 7679.554942] igc 0000:01:00.0 enp1s0: ICR 00000081 [ 7679.563503] igc 0000:01:00.0 enp1s0: RCTL 04408022 [ 7679.571963] igc 0000:01:00.0 enp1s0: RDLEN[0-3] 00001000 00001000 00001000 00001000 [ 7679.583075] igc 0000:01:00.0 enp1s0: RDH[0-3] 00000068 000000b6 0000000f 00000031 [ 7679.594162] igc 0000:01:00.0 enp1s0: RDT[0-3] 00000066 000000b2 0000000e 00000030 [ 7679.605174] igc 0000:01:00.0 enp1s0: RXDCTL[0-3] 02040808 02040808 02040808 02040808 [ 7679.616196] igc 0000:01:00.0 enp1s0: RDBAL[0-3] 1bb7c000 1bb7f000 1bb82000 0ef33000 [ 7679.627242] igc 0000:01:00.0 enp1s0: RDBAH[0-3] 00000001 00000001 00000001 00000001 [ 7679.638256] igc 0000:01:00.0 enp1s0: TCTL a503f0fa [ 7679.646607] igc 0000:01:00.0 enp1s0: TDBAL[0-3] 2ba4a000 1bb6f000 1bb74000 1bb79000 [ 7679.657609] igc 0000:01:00.0 enp1s0: TDBAH[0-3] 00000001 00000001 00000001 00000001 [ 7679.668551] igc 0000:01:00.0 enp1s0: TDLEN[0-3] 00001000 00001000 00001000 00001000 [ 7679.679470] igc 0000:01:00.0 enp1s0: TDH[0-3] 000000a7 0000002d 000000bf 000000d9 [ 7679.690406] igc 0000:01:00.0 enp1s0: TDT[0-3] 000000a7 0000002d 000000bf 000000d9 [ 7679.701264] igc 0000:01:00.0 enp1s0: TXDCTL[0-3] 02100108 02100108 02100108 02100108 [ 7679.712123] igc 0000:01:00.0 enp1s0: Reset adapter [ 7683.085967] igc 0000:01:00.0 enp1s0: NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX/TX [ 8086.945561] ------------[ cut here ]------------ Entering kdb (current=0xffffffff8220b200, pid 0) on processor 0 Oops: (null) due to oops @ 0xffffffff81573888 RIP: 0010:dql_completed+0x148/0x160 Code: c9 00 48 89 57 58 e9 46 ff ff ff 45 85 e4 41 0f 95 c4 41 39 db 0f 95 c1 41 84 cc 74 05 45 85 ed 78 0a 44 89 c1 e9 27 ff ff ff <0f> 0b 01 f6 44 89 c1 29 f1 0f 48 ca eb 8c cc cc cc cc cc cc cc cc RSP: 0018:ffa0000000003e00 EFLAGS: 00010287 RAX: 000000000000006c RBX: ffa0000003eb0f78 RCX: ff11000109938000 RDX: 0000000000000003 RSI: 0000000000000160 RDI: ff110001002e9480 RBP: ffa0000000003ed8 R08: ff110001002e93c0 R09: ffa0000000003d28 R10: 0000000000007cc0 R11: 0000000000007c54 R12: 00000000ffffffd9 R13: ff1100037039cb00 R14: 00000000ffffffd9 R15: ff1100037039c048 FS: 0000000000000000(0000) GS:ff11000361e00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffff7fca168 CR3: 000000013b08a003 CR4: 0000000000471ef8 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: ? igc_poll+0x1a9/0x14d0 [igc] __napi_poll+0x2e/0x1b0 net_rx_action+0x126/0x250 __do_softirq+0xd1/0x295 irq_exit_rcu+0xc5/0xf0 common_interrupt+0x86/0xa0 asm_common_interrupt+0x27/0x40 RIP: 0010:cpuidle_enter_state+0xd3/0x3e0 Code: 73 f1 ff ff 49 89 c6 8b 05 e2 ca a7 00 85 c0 0f 8f b3 02 00 00 31 ff e8 1b de 75 ff 80 7d d7 00 0f 85 cd 01 00 00 fb 45 85 ff <0f> 88 fd 00 00 00 49 63 cf 4c 2b 75 c8 48 8d 04 49 48 89 ca 48 8d RSP: 0018:ffffffff82203df0 EFLAGS: 00000202 RAX: ff11000361e2a200 RBX: 0000000000000002 RCX: 000000000000001f RDX: 0000000000000000 RSI: 000000003cf3cf3d RDI: 0000000000000000 RBP: ffffffff82203e28 R08: 0000075ae38471c8 R09: 0000000000000018 R10: 000000000000031a R11: ffffffff8238dca0 R12: ffd1ffffff200000 R13: ffffffff8238dca0 R14: 0000075ae38471c8 R15: 0000000000000002 cpuidle_enter+0x2e/0x50 call_cpuidle+0x23/0x40 do_idle+0x1be/0x220 cpu_startup_entry+0x20/0x30 rest_init+0xb5/0xc0 arch_call_rest_init+0xe/0x30 start_kernel+0x448/0x760 x86_64_start_kernel+0x109/0x150 secondary_startup_64_no_verify+0xe0/0xeb more> [0]kdb> [0]kdb> [0]kdb> go Catastrophic error detected kdb_continue_catastrophic=0, type go a second time if you really want to continue [0]kdb> go Catastrophic error detected kdb_continue_catastrophic=0, attempting to continue [ 8086.955689] refcount_t: underflow; use-after-free. [ 8086.955697] WARNING: CPU: 0 PID: 0 at lib/refcount.c:28 refcount_warn_saturate+0xc2/0x110 [ 8086.955706] Modules linked in: xt_conntrack nft_chain_nat xt_MASQUERADE xt_addrtype nft_compat nf_tables nfnetlink br_netfilter bridge stp llc overlay dm_mod emrcha(PO) emriio(PO) rktpm(PO) cegbuf_mod(PO) patch_update(PO) se(PO) sgx_tgts(PO) mktme(PO) keylocker(PO) svtdx(PO) svfs_pci_hotplug(PO) vtd_mod(PO) davemem(PO) svmabort(PO) svindexio(PO) usbx2(PO) ehci_sched(PO) svheartbeat(PO) ioapic(PO) sv8259(PO) svintr(PO) lt(PO) pcierootport(PO) enginefw_mod(PO) ata(PO) smbus(PO) spiflash_cdf(PO) arden(PO) dsa_iax(PO) oobmsm_punit(PO) cpm(PO) svkdb(PO) ebg_pch(PO) pch(PO) sviotargets(PO) svbdf(PO) svmem(PO) svbios(PO) dram(PO) svtsc(PO) targets(PO) superio(PO) svkernel(PO) cswitch(PO) mcf(PO) pentiumIII_mod(PO) fs_svfs(PO) mdevdefdb(PO) svfs_os_services(O) ixgbe mdio mdio_devres libphy emeraldrapids_svdefs(PO) regsupport(O) libnvdimm nls_cp437 snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_intel_dspcfg snd_hda_codec snd_hwdep x86_pkg_temp_thermal snd_hda_core snd_pcm snd_timer isst_if_mbox_pci [ 8086.955751] input_leds isst_if_mmio sg snd isst_if_common soundcore wmi button sad9(O) drm fuse backlight configfs efivarfs ip_tables x_tables vmd sdhci led_class rtl8150 r8152 hid_generic pegasus mmc_block usbhid mmc_core hid megaraid_sas ixgb igb i2c_algo_bit ice i40e hpsa scsi_transport_sas e1000e e1000 e100 ax88179_178a usbnet xhci_pci sd_mod xhci_hcd t10_pi crc32c_intel crc64_rocksoft igc crc64 crc_t10dif usbcore crct10dif_generic ptp crct10dif_common usb_common pps_core [ 8086.955784] RIP: 0010:refcount_warn_saturate+0xc2/0x110 [ 8086.955788] Code: 01 e8 82 e7 b4 ff 0f 0b 5d c3 cc cc cc cc 80 3d 68 c6 eb 00 00 75 81 48 c7 c7 a0 87 f6 81 c6 05 58 c6 eb 00 01 e8 5e e7 b4 ff <0f> 0b 5d c3 cc cc cc cc 80 3d 42 c6 eb 00 00 0f 85 59 ff ff ff 48 [ 8086.955790] RSP: 0018:ffa0000000003da0 EFLAGS: 00010286 [ 8086.955793] RAX: 0000000000000000 RBX: ff1100011da40ee0 RCX: ff11000361e1b888 [ 8086.955794] RDX: 00000000ffffffd8 RSI: 0000000000000027 RDI: ff11000361e1b880 [ 8086.955795] RBP: ffa0000000003da0 R08: 80000000ffff9f45 R09: ffa0000000003d28 [ 8086.955796] R10: ff1100035f840000 R11: 0000000000000028 R12: ff11000319ff8000 [ 8086.955797] R13: ff1100011bb79d60 R14: 00000000ffffffd6 R15: ff1100037039cb00 [ 8086.955798] FS: 0000000000000000(0000) GS:ff11000361e00000(0000) knlGS:0000000000000000 [ 8086.955800] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 8086.955801] CR2: 00007ffff7fca168 CR3: 000000013b08a003 CR4: 0000000000471ef8 [ 8086.955803] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 8086.955803] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 [ 8086.955804] PKRU: 55555554 [ 8086.955805] Call Trace: [ 8086.955806] [ 8086.955808] tcp_wfree+0x112/0x130 [ 8086.955814] skb_release_head_state+0x24/0xa0 [ 8086.955818] napi_consume_skb+0x9c/0x160 [ 8086.955821] igc_poll+0x5d8/0x14d0 [igc] [ 8086.955835] __napi_poll+0x2e/0x1b0 [ 8086.955839] net_rx_action+0x126/0x250 [ 8086.955843] __do_softirq+0xd1/0x295 [ 8086.955846] irq_exit_rcu+0xc5/0xf0 [ 8086.955851] common_interrupt+0x86/0xa0 [ 8086.955857] [ 8086.955857] [ 8086.955858] asm_common_interrupt+0x27/0x40 [ 8086.955862] RIP: 0010:cpuidle_enter_state+0xd3/0x3e0 [ 8086.955866] Code: 73 f1 ff ff 49 89 c6 8b 05 e2 ca a7 00 85 c0 0f 8f b3 02 00 00 31 ff e8 1b de 75 ff 80 7d d7 00 0f 85 cd 01 00 00 fb 45 85 ff <0f> 88 fd 00 00 00 49 63 cf 4c 2b 75 c8 48 8d 04 49 48 89 ca 48 8d [ 8086.955867] RSP: 0018:ffffffff82203df0 EFLAGS: 00000202 [ 8086.955869] RAX: ff11000361e2a200 RBX: 0000000000000002 RCX: 000000000000001f [ 8086.955870] RDX: 0000000000000000 RSI: 000000003cf3cf3d RDI: 0000000000000000 [ 8086.955871] RBP: ffffffff82203e28 R08: 0000075ae38471c8 R09: 0000000000000018 [ 8086.955872] R10: 000000000000031a R11: ffffffff8238dca0 R12: ffd1ffffff200000 [ 8086.955873] R13: ffffffff8238dca0 R14: 0000075ae38471c8 R15: 0000000000000002 [ 8086.955875] cpuidle_enter+0x2e/0x50 [ 8086.955880] call_cpuidle+0x23/0x40 [ 8086.955884] do_idle+0x1be/0x220 [ 8086.955887] cpu_startup_entry+0x20/0x30 [ 8086.955889] rest_init+0xb5/0xc0 [ 8086.955892] arch_call_rest_init+0xe/0x30 [ 8086.955895] start_kernel+0x448/0x760 [ 8086.955898] x86_64_start_kernel+0x109/0x150 [ 8086.955900] secondary_startup_64_no_verify+0xe0/0xeb [ 8086.955904] [ 8086.955904] ---[ end trace 0000000000000000 ]--- [ 8086.955912] ------------[ cut here ]------------ [ 8086.955913] kernel BUG at lib/dynamic_queue_limits.c:27! [ 8086.955918] invalid opcode: 0000 [#1] SMP [ 8086.955922] RIP: 0010:dql_completed+0x148/0x160 [ 8086.955925] Code: c9 00 48 89 57 58 e9 46 ff ff ff 45 85 e4 41 0f 95 c4 41 39 db 0f 95 c1 41 84 cc 74 05 45 85 ed 78 0a 44 89 c1 e9 27 ff ff ff <0f> 0b 01 f6 44 89 c1 29 f1 0f 48 ca eb 8c cc cc cc cc cc cc cc cc [ 8086.955927] RSP: 0018:ffa0000000003e00 EFLAGS: 00010287 [ 8086.955928] RAX: 000000000000006c RBX: ffa0000003eb0f78 RCX: ff11000109938000 [ 8086.955929] RDX: 0000000000000003 RSI: 0000000000000160 RDI: ff110001002e9480 [ 8086.955930] RBP: ffa0000000003ed8 R08: ff110001002e93c0 R09: ffa0000000003d28 [ 8086.955931] R10: 0000000000007cc0 R11: 0000000000007c54 R12: 00000000ffffffd9 [ 8086.955932] R13: ff1100037039cb00 R14: 00000000ffffffd9 R15: ff1100037039c048 [ 8086.955933] FS: 0000000000000000(0000) GS:ff11000361e00000(0000) knlGS:0000000000000000 [ 8086.955934] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 8086.955935] CR2: 00007ffff7fca168 CR3: 000000013b08a003 CR4: 0000000000471ef8 [ 8086.955936] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 8086.955937] DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 [ 8086.955938] PKRU: 55555554 [ 8086.955939] Call Trace: [ 8086.955939] [ 8086.955940] ? igc_poll+0x1a9/0x14d0 [igc] [ 8086.955949] __napi_poll+0x2e/0x1b0 [ 8086.955952] net_rx_action+0x126/0x250 [ 8086.955956] __do_softirq+0xd1/0x295 [ 8086.955958] irq_exit_rcu+0xc5/0xf0 [ 8086.955961] common_interrupt+0x86/0xa0 [ 8086.955964] [ 8086.955965] [ 8086.955965] asm_common_interrupt+0x27/0x40 [ 8086.955968] RIP: 0010:cpuidle_enter_state+0xd3/0x3e0 [ 8086.955971] Code: 73 f1 ff ff 49 89 c6 8b 05 e2 ca a7 00 85 c0 0f 8f b3 02 00 00 31 ff e8 1b de 75 ff 80 7d d7 00 0f 85 cd 01 00 00 fb 45 85 ff <0f> 88 fd 00 00 00 49 63 cf 4c 2b 75 c8 48 8d 04 49 48 89 ca 48 8d [ 8086.955972] RSP: 0018:ffffffff82203df0 EFLAGS: 00000202 [ 8086.955973] RAX: ff11000361e2a200 RBX: 0000000000000002 RCX: 000000000000001f [ 8086.955974] RDX: 0000000000000000 RSI: 000000003cf3cf3d RDI: 0000000000000000 [ 8086.955974] RBP: ffffffff82203e28 R08: 0000075ae38471c8 R09: 0000000000000018 [ 8086.955975] R10: 000000000000031a R11: ffffffff8238dca0 R12: ffd1ffffff200000 [ 8086.955976] R13: ffffffff8238dca0 R14: 0000075ae38471c8 R15: 0000000000000002 [ 8086.955978] cpuidle_enter+0x2e/0x50 [ 8086.955981] call_cpuidle+0x23/0x40 [ 8086.955984] do_idle+0x1be/0x220 [ 8086.955985] cpu_startup_entry+0x20/0x30 [ 8086.955987] rest_init+0xb5/0xc0 [ 8086.955990] arch_call_rest_init+0xe/0x30 [ 8086.955992] start_kernel+0x448/0x760 [ 8086.955994] x86_64_start_kernel+0x109/0x150 [ 8086.955996] secondary_startup_64_no_verify+0xe0/0xeb [ 8086.955998] [ 8086.955999] Modules linked in: xt_conntrack nft_chain_nat xt_MASQUERADE xt_addrtype nft_compat nf_tables nfnetlink br_netfilter bridge stp llc overlay dm_mod emrcha(PO) emriio(PO) rktpm(PO) cegbuf_mod(PO) patch_update(PO) se(PO) sgx_tgts(PO) mktme(PO) keylocker(PO) svtdx(PO) svfs_pci_hotplug(PO) vtd_mod(PO) davemem(PO) svmabort(PO) svindexio(PO) usbx2(PO) ehci_sched(PO) svheartbeat(PO) ioapic(PO) sv8259(PO) svintr(PO) lt(PO) pcierootport(PO) enginefw_mod(PO) ata(PO) smbus(PO) spiflash_cdf(PO) arden(PO) dsa_iax(PO) oobmsm_punit(PO) cpm(PO) svkdb(PO) ebg_pch(PO) pch(PO) sviotargets(PO) svbdf(PO) svmem(PO) svbios(PO) dram(PO) svtsc(PO) targets(PO) superio(PO) svkernel(PO) cswitch(PO) mcf(PO) pentiumIII_mod(PO) fs_svfs(PO) mdevdefdb(PO) svfs_os_services(O) ixgbe mdio mdio_devres libphy emeraldrapids_svdefs(PO) regsupport(O) libnvdimm nls_cp437 snd_hda_codec_realtek snd_hda_codec_generic ledtrig_audio snd_hda_intel snd_intel_dspcfg snd_hda_codec snd_hwdep x86_pkg_temp_thermal snd_hda_core snd_pcm snd_timer isst_if_mbox_pci [ 8086.956029] input_leds isst_if_mmio sg snd isst_if_common soundcore wmi button sad9(O) drm fuse backlight configfs efivarfs ip_tables x_tables vmd sdhci led_class rtl8150 r8152 hid_generic pegasus mmc_block usbhid mmc_core hid megaraid_sas ixgb igb i2c_algo_bit ice i40e hpsa scsi_transport_sas e1000e e1000 e100 ax88179_178a usbnet xhci_pci sd_mod xhci_hcd t10_pi crc32c_intel crc64_rocksoft igc crc64 crc_t10dif usbcore crct10dif_generic ptp crct10dif_common usb_common pps_core [16762.543675] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.593 msecs [16762.543678] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.595 msecs [16762.543673] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.495 msecs [16762.543679] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.599 msecs [16762.543678] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.598 msecs [16762.543690] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.605 msecs [16762.543684] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.599 msecs [16762.543693] INFO: NMI handler (kgdb_nmi_handler) took too long to run: 8675587.613 msecs [16762.543784] ---[ end trace 0000000000000000 ]--- [16762.849099] RIP: 0010:dql_completed+0x148/0x160 PANIC: Fatal exception in interrupt Fixes: 9b275176270e ("igc: Add ndo_tx_timeout support") Tested-by: Alejandra Victoria Alcaraz Signed-off-by: Muhammad Husaini Zulkifli Acked-by: Sasha Neftin Tested-by: Naama Meir Signed-off-by: Tony Nguyen Reviewed-by: Simon Horman Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/igc/igc_main.c | 40 +++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index f36bc2a1849a..bdeb36790d77 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -316,6 +316,33 @@ static void igc_clean_all_tx_rings(struct igc_adapter *adapter) igc_clean_tx_ring(adapter->tx_ring[i]); } +static void igc_disable_tx_ring_hw(struct igc_ring *ring) +{ + struct igc_hw *hw = &ring->q_vector->adapter->hw; + u8 idx = ring->reg_idx; + u32 txdctl; + + txdctl = rd32(IGC_TXDCTL(idx)); + txdctl &= ~IGC_TXDCTL_QUEUE_ENABLE; + txdctl |= IGC_TXDCTL_SWFLUSH; + wr32(IGC_TXDCTL(idx), txdctl); +} + +/** + * igc_disable_all_tx_rings_hw - Disable all transmit queue operation + * @adapter: board private structure + */ +static void igc_disable_all_tx_rings_hw(struct igc_adapter *adapter) +{ + int i; + + for (i = 0; i < adapter->num_tx_queues; i++) { + struct igc_ring *tx_ring = adapter->tx_ring[i]; + + igc_disable_tx_ring_hw(tx_ring); + } +} + /** * igc_setup_tx_resources - allocate Tx resources (Descriptors) * @tx_ring: tx descriptor ring (for a specific queue) to setup @@ -5058,6 +5085,7 @@ void igc_down(struct igc_adapter *adapter) /* clear VLAN promisc flag so VFTA will be updated if necessary */ adapter->flags &= ~IGC_FLAG_VLAN_PROMISC; + igc_disable_all_tx_rings_hw(adapter); igc_clean_all_tx_rings(adapter); igc_clean_all_rx_rings(adapter); } @@ -7290,18 +7318,6 @@ void igc_enable_rx_ring(struct igc_ring *ring) igc_alloc_rx_buffers(ring, igc_desc_unused(ring)); } -static void igc_disable_tx_ring_hw(struct igc_ring *ring) -{ - struct igc_hw *hw = &ring->q_vector->adapter->hw; - u8 idx = ring->reg_idx; - u32 txdctl; - - txdctl = rd32(IGC_TXDCTL(idx)); - txdctl &= ~IGC_TXDCTL_QUEUE_ENABLE; - txdctl |= IGC_TXDCTL_SWFLUSH; - wr32(IGC_TXDCTL(idx), txdctl); -} - void igc_disable_tx_ring(struct igc_ring *ring) { igc_disable_tx_ring_hw(ring); -- cgit From 138d73b627c71bf2b2f61502dc6c1137b9656434 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 25 Jul 2023 11:02:26 -0700 Subject: spi: spi-qcom-qspi: Fallback to PIO for xfers that aren't multiples of 4 bytes The Qualcomm QSPI driver appears to require that any reads using DMA are a mutliple of 4 bytes. If this isn't true then the controller will clobber any extra bytes in memory following the last word. Let's detect this and falback to PIO. This fixes problems reported by slub_debug=FZPUA, which would complain about "kmalloc Redzone overwritten". One such instance said: 0xffffff80c29d541a-0xffffff80c29d541b @offset=21530. First byte 0x0 instead of 0xcc Allocated in mtd_kmalloc_up_to+0x98/0xac age=36 cpu=3 pid=6658 Tracing through what was happening I saw that, while we often did DMA tranfers of 0x1000 bytes, sometimes we'd end up doing ones of 0x41a bytes. Those 0x41a byte transfers were the problem. NOTE: a future change will enable the SPI "mem ops" to help avoid this case, but it still seems good to add the extra check in the transfer. Fixes: b5762d95607e ("spi: spi-qcom-qspi: Add DMA mode support") Signed-off-by: Douglas Anderson Reviewed-by: Vijaya Krishna Nivarthi Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/20230725110226.1.Ia2f980fc7cd0b831e633391f0bb1272914d8f381@changeid Signed-off-by: Mark Brown --- drivers/spi/spi-qcom-qspi.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c index 9b3092e22942..db1dd133762e 100644 --- a/drivers/spi/spi-qcom-qspi.c +++ b/drivers/spi/spi-qcom-qspi.c @@ -357,10 +357,22 @@ static int qcom_qspi_setup_dma_desc(struct qcom_qspi *ctrl, for (i = 0; i < sgt->nents; i++) { dma_ptr_sg = sg_dma_address(sgt->sgl + i); + dma_len_sg = sg_dma_len(sgt->sgl + i); if (!IS_ALIGNED(dma_ptr_sg, QSPI_ALIGN_REQ)) { dev_warn_once(ctrl->dev, "dma_address not aligned to %d\n", QSPI_ALIGN_REQ); return -EAGAIN; } + /* + * When reading with DMA the controller writes to memory 1 word + * at a time. If the length isn't a multiple of 4 bytes then + * the controller can clobber the things later in memory. + * Fallback to PIO to be safe. + */ + if (ctrl->xfer.dir == QSPI_READ && (dma_len_sg & 0x03)) { + dev_warn_once(ctrl->dev, "fallback to PIO for read of size %#010x\n", + dma_len_sg); + return -EAGAIN; + } } for (i = 0; i < sgt->nents; i++) { -- cgit From cc71c42b3dc1085d3e72dfa5603e827b9eb59da1 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Tue, 25 Jul 2023 11:02:27 -0700 Subject: spi: spi-qcom-qspi: Add mem_ops to avoid PIO for badly sized reads In the patch ("spi: spi-qcom-qspi: Fallback to PIO for xfers that aren't multiples of 4 bytes") we detect reads that we can't handle properly and fallback to PIO mode. While that's correct behavior, we can do better by adding "spi_controller_mem_ops" for our controller. Once we do this then the caller will give us a transfer that's a multiple of 4-bytes so we can DMA. Fixes: b5762d95607e ("spi: spi-qcom-qspi: Add DMA mode support") Signed-off-by: Douglas Anderson Reviewed-by: Vijaya Krishna Nivarthi Link: https://lore.kernel.org/r/20230725110226.2.Id4a39804e01e4a06dae9b73fd2a5194c4c7ea453@changeid Signed-off-by: Mark Brown --- drivers/spi/spi-qcom-qspi.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/spi-qcom-qspi.c b/drivers/spi/spi-qcom-qspi.c index db1dd133762e..1954c39b3d08 100644 --- a/drivers/spi/spi-qcom-qspi.c +++ b/drivers/spi/spi-qcom-qspi.c @@ -666,6 +666,30 @@ static irqreturn_t qcom_qspi_irq(int irq, void *dev_id) return ret; } +static int qcom_qspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op) +{ + /* + * If qcom_qspi_can_dma() is going to return false we don't need to + * adjust anything. + */ + if (op->data.nbytes <= QSPI_MAX_BYTES_FIFO) + return 0; + + /* + * When reading, the transfer needs to be a multiple of 4 bytes so + * shrink the transfer if that's not true. The caller will then do a + * second transfer to finish things up. + */ + if (op->data.dir == SPI_MEM_DATA_IN && (op->data.nbytes & 0x3)) + op->data.nbytes &= ~0x3; + + return 0; +} + +static const struct spi_controller_mem_ops qcom_qspi_mem_ops = { + .adjust_op_size = qcom_qspi_adjust_op_size, +}; + static int qcom_qspi_probe(struct platform_device *pdev) { int ret; @@ -750,6 +774,7 @@ static int qcom_qspi_probe(struct platform_device *pdev) if (of_property_read_bool(pdev->dev.of_node, "iommus")) master->can_dma = qcom_qspi_can_dma; master->auto_runtime_pm = true; + master->mem_ops = &qcom_qspi_mem_ops; ret = devm_pm_opp_set_clkname(&pdev->dev, "core"); if (ret) -- cgit From 3bfb25fa2b5bb9c29681e6ac861808f4be1331a9 Mon Sep 17 00:00:00 2001 From: Sindhu Devale Date: Tue, 25 Jul 2023 10:54:37 -0500 Subject: RDMA/irdma: Fix op_type reporting in CQEs The op_type field CQ poll info structure is incorrectly filled in with the queue type as opposed to the op_type received in the CQEs. The wrong opcode could be decoded and returned to the ULP. Copy the op_type field received in the CQE in the CQ poll info structure. Fixes: 24419777e943 ("RDMA/irdma: Fix RQ completion opcode") Signed-off-by: Sindhu Devale Signed-off-by: Shiraz Saleem Link: https://lore.kernel.org/r/20230725155439.1057-1-shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/irdma/uk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c index ea2c07751245..280d633d4ec4 100644 --- a/drivers/infiniband/hw/irdma/uk.c +++ b/drivers/infiniband/hw/irdma/uk.c @@ -1161,7 +1161,7 @@ int irdma_uk_cq_poll_cmpl(struct irdma_cq_uk *cq, } wqe_idx = (u32)FIELD_GET(IRDMA_CQ_WQEIDX, qword3); info->qp_handle = (irdma_qp_handle)(unsigned long)qp; - info->op_type = (u8)FIELD_GET(IRDMA_CQ_SQ, qword3); + info->op_type = (u8)FIELD_GET(IRDMACQ_OP, qword3); if (info->q_type == IRDMA_CQE_QTYPE_RQ) { u32 array_idx; -- cgit From ae463563b7a1b7d4a3d0b065b09d37a76b693937 Mon Sep 17 00:00:00 2001 From: Sindhu Devale Date: Tue, 25 Jul 2023 10:54:38 -0500 Subject: RDMA/irdma: Report correct WC error Report the correct WC error if a MW bind is performed on an already valid/bound window. Fixes: 44d9e52977a1 ("RDMA/irdma: Implement device initialization definitions") Signed-off-by: Sindhu Devale Signed-off-by: Shiraz Saleem Link: https://lore.kernel.org/r/20230725155439.1057-2-shiraz.saleem@intel.com Signed-off-by: Leon Romanovsky --- drivers/infiniband/hw/irdma/hw.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c index 1cfc03da89e7..457368e324e1 100644 --- a/drivers/infiniband/hw/irdma/hw.c +++ b/drivers/infiniband/hw/irdma/hw.c @@ -191,6 +191,7 @@ static void irdma_set_flush_fields(struct irdma_sc_qp *qp, case IRDMA_AE_AMP_MWBIND_INVALID_RIGHTS: case IRDMA_AE_AMP_MWBIND_BIND_DISABLED: case IRDMA_AE_AMP_MWBIND_INVALID_BOUNDS: + case IRDMA_AE_AMP_MWBIND_VALID_STAG: qp->flush_code = FLUSH_MW_BIND_ERR; qp->event_type = IRDMA_QP_EVENT_ACCESS_ERR; break; -- cgit From f38cb9d9c2045dad16eead4a2e1aedfddd94603b Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Fri, 30 Jun 2023 13:52:13 +0200 Subject: rbd: make get_lock_owner_info() return a single locker or NULL Make the "num_lockers can be only 0 or 1" assumption explicit and simplify the API by getting rid of output parameters in preparation for calling get_lock_owner_info() twice before blocklisting. Signed-off-by: Ilya Dryomov Reviewed-by: Dongsheng Yang --- drivers/block/rbd.c | 84 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index bd0e075a5d89..dca6c1e5f6bc 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -3849,10 +3849,17 @@ static void wake_lock_waiters(struct rbd_device *rbd_dev, int result) list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list); } -static int get_lock_owner_info(struct rbd_device *rbd_dev, - struct ceph_locker **lockers, u32 *num_lockers) +static void free_locker(struct ceph_locker *locker) +{ + if (locker) + ceph_free_lockers(locker, 1); +} + +static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev) { struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; + struct ceph_locker *lockers; + u32 num_lockers; u8 lock_type; char *lock_tag; int ret; @@ -3861,39 +3868,45 @@ static int get_lock_owner_info(struct rbd_device *rbd_dev, ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, - &lock_type, &lock_tag, lockers, num_lockers); - if (ret) - return ret; + &lock_type, &lock_tag, &lockers, &num_lockers); + if (ret) { + rbd_warn(rbd_dev, "failed to retrieve lockers: %d", ret); + return ERR_PTR(ret); + } - if (*num_lockers == 0) { + if (num_lockers == 0) { dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev); + lockers = NULL; goto out; } if (strcmp(lock_tag, RBD_LOCK_TAG)) { rbd_warn(rbd_dev, "locked by external mechanism, tag %s", lock_tag); - ret = -EBUSY; - goto out; + goto err_busy; } if (lock_type == CEPH_CLS_LOCK_SHARED) { rbd_warn(rbd_dev, "shared lock type detected"); - ret = -EBUSY; - goto out; + goto err_busy; } - if (strncmp((*lockers)[0].id.cookie, RBD_LOCK_COOKIE_PREFIX, + WARN_ON(num_lockers != 1); + if (strncmp(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX, strlen(RBD_LOCK_COOKIE_PREFIX))) { rbd_warn(rbd_dev, "locked by external mechanism, cookie %s", - (*lockers)[0].id.cookie); - ret = -EBUSY; - goto out; + lockers[0].id.cookie); + goto err_busy; } out: kfree(lock_tag); - return ret; + return lockers; + +err_busy: + kfree(lock_tag); + ceph_free_lockers(lockers, num_lockers); + return ERR_PTR(-EBUSY); } static int find_watcher(struct rbd_device *rbd_dev, @@ -3947,51 +3960,56 @@ out: static int rbd_try_lock(struct rbd_device *rbd_dev) { struct ceph_client *client = rbd_dev->rbd_client->client; - struct ceph_locker *lockers; - u32 num_lockers; + struct ceph_locker *locker; int ret; for (;;) { + locker = NULL; + ret = rbd_lock(rbd_dev); if (ret != -EBUSY) - return ret; + goto out; /* determine if the current lock holder is still alive */ - ret = get_lock_owner_info(rbd_dev, &lockers, &num_lockers); - if (ret) - return ret; - - if (num_lockers == 0) + locker = get_lock_owner_info(rbd_dev); + if (IS_ERR(locker)) { + ret = PTR_ERR(locker); + locker = NULL; + goto out; + } + if (!locker) goto again; - ret = find_watcher(rbd_dev, lockers); + ret = find_watcher(rbd_dev, locker); if (ret) goto out; /* request lock or error */ rbd_warn(rbd_dev, "breaking header lock owned by %s%llu", - ENTITY_NAME(lockers[0].id.name)); + ENTITY_NAME(locker->id.name)); ret = ceph_monc_blocklist_add(&client->monc, - &lockers[0].info.addr); + &locker->info.addr); if (ret) { - rbd_warn(rbd_dev, "blocklist of %s%llu failed: %d", - ENTITY_NAME(lockers[0].id.name), ret); + rbd_warn(rbd_dev, "failed to blocklist %s%llu: %d", + ENTITY_NAME(locker->id.name), ret); goto out; } ret = ceph_cls_break_lock(&client->osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, - lockers[0].id.cookie, - &lockers[0].id.name); - if (ret && ret != -ENOENT) + locker->id.cookie, &locker->id.name); + if (ret && ret != -ENOENT) { + rbd_warn(rbd_dev, "failed to break header lock: %d", + ret); goto out; + } again: - ceph_free_lockers(lockers, num_lockers); + free_locker(locker); } out: - ceph_free_lockers(lockers, num_lockers); + free_locker(locker); return ret; } -- cgit From 8ff2c64c9765446c3cef804fb99da04916603e27 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Sat, 8 Jul 2023 16:16:59 +0200 Subject: rbd: harden get_lock_owner_info() a bit - we want the exclusive lock type, so test for it directly - use sscanf() to actually parse the lock cookie and avoid admitting invalid handles - bail if locker has a blank address Signed-off-by: Ilya Dryomov Reviewed-by: Dongsheng Yang --- drivers/block/rbd.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index dca6c1e5f6bc..94629e826369 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -3862,10 +3862,9 @@ static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev) u32 num_lockers; u8 lock_type; char *lock_tag; + u64 handle; int ret; - dout("%s rbd_dev %p\n", __func__, rbd_dev); - ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid, &rbd_dev->header_oloc, RBD_LOCK_NAME, &lock_type, &lock_tag, &lockers, &num_lockers); @@ -3886,18 +3885,28 @@ static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev) goto err_busy; } - if (lock_type == CEPH_CLS_LOCK_SHARED) { - rbd_warn(rbd_dev, "shared lock type detected"); + if (lock_type != CEPH_CLS_LOCK_EXCLUSIVE) { + rbd_warn(rbd_dev, "incompatible lock type detected"); goto err_busy; } WARN_ON(num_lockers != 1); - if (strncmp(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX, - strlen(RBD_LOCK_COOKIE_PREFIX))) { + ret = sscanf(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX " %llu", + &handle); + if (ret != 1) { rbd_warn(rbd_dev, "locked by external mechanism, cookie %s", lockers[0].id.cookie); goto err_busy; } + if (ceph_addr_is_blank(&lockers[0].info.addr)) { + rbd_warn(rbd_dev, "locker has a blank address"); + goto err_busy; + } + + dout("%s rbd_dev %p got locker %s%llu@%pISpc/%u handle %llu\n", + __func__, rbd_dev, ENTITY_NAME(lockers[0].id.name), + &lockers[0].info.addr.in_addr, + le32_to_cpu(lockers[0].info.addr.nonce), handle); out: kfree(lock_tag); -- cgit From 588159009d5b7a09c3e5904cffddbe4a4e170301 Mon Sep 17 00:00:00 2001 From: Ilya Dryomov Date: Sat, 22 Jul 2023 20:28:08 +0200 Subject: rbd: retrieve and check lock owner twice before blocklisting An attempt to acquire exclusive lock can race with the current lock owner closing the image: 1. lock is held by client123, rbd_lock() returns -EBUSY 2. get_lock_owner_info() returns client123 instance details 3. client123 closes the image, lock is released 4. find_watcher() returns 0 as there is no matching watcher anymore 5. client123 instance gets erroneously blocklisted Particularly impacted is mirror snapshot scheduler in snapshot-based mirroring since it happens to open and close images a lot (images are opened only for as long as it takes to take the next mirror snapshot, the same client instance is used for all images). To reduce the potential for erroneous blocklisting, retrieve the lock owner again after find_watcher() returns 0. If it's still there, make sure it matches the previously detected lock owner. Cc: stable@vger.kernel.org # f38cb9d9c204: rbd: make get_lock_owner_info() return a single locker or NULL Cc: stable@vger.kernel.org # 8ff2c64c9765: rbd: harden get_lock_owner_info() a bit Cc: stable@vger.kernel.org Signed-off-by: Ilya Dryomov Reviewed-by: Dongsheng Yang --- drivers/block/rbd.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 94629e826369..24afcc93ac01 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -3849,6 +3849,15 @@ static void wake_lock_waiters(struct rbd_device *rbd_dev, int result) list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list); } +static bool locker_equal(const struct ceph_locker *lhs, + const struct ceph_locker *rhs) +{ + return lhs->id.name.type == rhs->id.name.type && + lhs->id.name.num == rhs->id.name.num && + !strcmp(lhs->id.cookie, rhs->id.cookie) && + ceph_addr_equal_no_type(&lhs->info.addr, &rhs->info.addr); +} + static void free_locker(struct ceph_locker *locker) { if (locker) @@ -3969,11 +3978,11 @@ out: static int rbd_try_lock(struct rbd_device *rbd_dev) { struct ceph_client *client = rbd_dev->rbd_client->client; - struct ceph_locker *locker; + struct ceph_locker *locker, *refreshed_locker; int ret; for (;;) { - locker = NULL; + locker = refreshed_locker = NULL; ret = rbd_lock(rbd_dev); if (ret != -EBUSY) @@ -3993,6 +4002,16 @@ static int rbd_try_lock(struct rbd_device *rbd_dev) if (ret) goto out; /* request lock or error */ + refreshed_locker = get_lock_owner_info(rbd_dev); + if (IS_ERR(refreshed_locker)) { + ret = PTR_ERR(refreshed_locker); + refreshed_locker = NULL; + goto out; + } + if (!refreshed_locker || + !locker_equal(locker, refreshed_locker)) + goto again; + rbd_warn(rbd_dev, "breaking header lock owned by %s%llu", ENTITY_NAME(locker->id.name)); @@ -4014,10 +4033,12 @@ static int rbd_try_lock(struct rbd_device *rbd_dev) } again: + free_locker(refreshed_locker); free_locker(locker); } out: + free_locker(refreshed_locker); free_locker(locker); return ret; } -- cgit From 1b5d0ddcb34a605835051ae2950d5cfed0373dd8 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 24 Jul 2023 13:30:21 -0700 Subject: drm/msm: Disallow submit with fence id 0 A fence id of zero is expected to be invalid, and is not removed from the fence_idr table. If userspace is requesting to specify the fence id with the FENCE_SN_IN flag, we need to reject a zero fence id value. Fixes: 17154addc5c1 ("drm/msm: Add MSM_SUBMIT_FENCE_SN_IN") Signed-off-by: Rob Clark Patchwork: https://patchwork.freedesktop.org/patch/549180/ --- drivers/gpu/drm/msm/msm_gem_submit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c index 9d66498cdc04..63c96416e183 100644 --- a/drivers/gpu/drm/msm/msm_gem_submit.c +++ b/drivers/gpu/drm/msm/msm_gem_submit.c @@ -901,7 +901,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, * after the job is armed */ if ((args->flags & MSM_SUBMIT_FENCE_SN_IN) && - idr_find(&queue->fence_idr, args->fence)) { + (!args->fence || idr_find(&queue->fence_idr, args->fence))) { spin_unlock(&queue->idr_lock); idr_preload_end(); ret = -EINVAL; -- cgit From b84000f2274520f73ac9dc59fd9403260b61c4e7 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Wed, 26 Jul 2023 20:18:13 -0700 Subject: hwmon: (pmbus_core) Fix Deadlock in pmbus_regulator_get_status pmbus_regulator_get_status() acquires update_lock. pmbus_regulator_get_error_flags() acquires it again, resulting in an immediate deadlock. Call _pmbus_get_flags() from pmbus_regulator_get_status() directly to avoid the problem. Reported-by: Patrick Rudolph Closes: https://lore.kernel.org/linux-hwmon/b7a3ad85-aab4-4718-a001-1d8b1c0eef36@roeck-us.net/T/#u Cc: Naresh Solanki Cc: stable@vger.kernel.org # v6.2+ Fixes: c05f477c4ba3 ("hwmon: (pmbus/core) Implement regulator get_status") Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/pmbus_core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 30aeb59062a5..69a4e62b6c8d 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -2946,6 +2946,7 @@ static int pmbus_regulator_get_status(struct regulator_dev *rdev) struct pmbus_data *data = i2c_get_clientdata(client); u8 page = rdev_get_id(rdev); int status, ret; + int event; mutex_lock(&data->update_lock); status = pmbus_get_status(client, page, PMBUS_STATUS_WORD); @@ -2965,7 +2966,7 @@ static int pmbus_regulator_get_status(struct regulator_dev *rdev) goto unlock; } - ret = pmbus_regulator_get_error_flags(rdev, &status); + ret = _pmbus_get_flags(data, rdev_get_id(rdev), &status, &event, false); if (ret) goto unlock; -- cgit From 15cec633fc7bfe4cd69aa012c3b35b31acfc86f2 Mon Sep 17 00:00:00 2001 From: Wei Fang Date: Tue, 25 Jul 2023 15:41:48 +0800 Subject: net: fec: tx processing does not call XDP APIs if budget is 0 According to the clarification [1] in the latest napi.rst, the tx processing cannot call any XDP (or page pool) APIs if the "budget" is 0. Because NAPI is called with the budget of 0 (such as netpoll) indicates we may be in an IRQ context, however, we cannot use the page pool from IRQ context. [1] https://lore.kernel.org/all/20230720161323.2025379-1-kuba@kernel.org/ Fixes: 20f797399035 ("net: fec: recycle pages for transmitted XDP frames") Signed-off-by: Wei Fang Suggested-by: Jakub Kicinski Link: https://lore.kernel.org/r/20230725074148.2936402-1-wei.fang@nxp.com Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/freescale/fec_main.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 073d61619336..66b5cbdb43b9 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -1372,7 +1372,7 @@ fec_enet_hwtstamp(struct fec_enet_private *fep, unsigned ts, } static void -fec_enet_tx_queue(struct net_device *ndev, u16 queue_id) +fec_enet_tx_queue(struct net_device *ndev, u16 queue_id, int budget) { struct fec_enet_private *fep; struct xdp_frame *xdpf; @@ -1416,6 +1416,14 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id) if (!skb) goto tx_buf_done; } else { + /* Tx processing cannot call any XDP (or page pool) APIs if + * the "budget" is 0. Because NAPI is called with budget of + * 0 (such as netpoll) indicates we may be in an IRQ context, + * however, we can't use the page pool from IRQ context. + */ + if (unlikely(!budget)) + break; + xdpf = txq->tx_buf[index].xdp; if (bdp->cbd_bufaddr) dma_unmap_single(&fep->pdev->dev, @@ -1508,14 +1516,14 @@ tx_buf_done: writel(0, txq->bd.reg_desc_active); } -static void fec_enet_tx(struct net_device *ndev) +static void fec_enet_tx(struct net_device *ndev, int budget) { struct fec_enet_private *fep = netdev_priv(ndev); int i; /* Make sure that AVB queues are processed first. */ for (i = fep->num_tx_queues - 1; i >= 0; i--) - fec_enet_tx_queue(ndev, i); + fec_enet_tx_queue(ndev, i, budget); } static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq, @@ -1858,7 +1866,7 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget) do { done += fec_enet_rx(ndev, budget - done); - fec_enet_tx(ndev); + fec_enet_tx(ndev, budget); } while ((done < budget) && fec_enet_collect_events(fep)); if (done < budget) { -- cgit From 25266128fe16d5632d43ada34c847d7b8daba539 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Tue, 25 Jul 2023 03:20:49 -0400 Subject: virtio-net: fix race between set queues and probe A race were found where set_channels could be called after registering but before virtnet_set_queues() in virtnet_probe(). Fixing this by moving the virtnet_set_queues() before netdevice registering. While at it, use _virtnet_set_queues() to avoid holding rtnl as the device is not even registered at that time. Cc: stable@vger.kernel.org Fixes: a220871be66f ("virtio-net: correctly enable multiqueue") Signed-off-by: Jason Wang Acked-by: Michael S. Tsirkin Reviewed-by: Xuan Zhuo Link: https://lore.kernel.org/r/20230725072049.617289-1-jasowang@redhat.com Signed-off-by: Jakub Kicinski --- drivers/net/virtio_net.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 0db14f6b87d3..1270c8d23463 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -4219,6 +4219,8 @@ static int virtnet_probe(struct virtio_device *vdev) if (vi->has_rss || vi->has_rss_hash_report) virtnet_init_default_rss(vi); + _virtnet_set_queues(vi, vi->curr_queue_pairs); + /* serialize netdev register + virtio_device_ready() with ndo_open() */ rtnl_lock(); @@ -4257,8 +4259,6 @@ static int virtnet_probe(struct virtio_device *vdev) goto free_unregister_netdev; } - virtnet_set_queues(vi, vi->curr_queue_pairs); - /* Assume link up if device can't report link status, otherwise get link status from config. */ netif_carrier_off(dev); -- cgit From c04e9894846c663f3278a414f34416e6e45bbe68 Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Wed, 26 Jul 2023 12:52:41 -0400 Subject: xen: speed up grant-table reclaim When a grant entry is still in use by the remote domain, Linux must put it on a deferred list. Normally, this list is very short, because the PV network and block protocols expect the backend to unmap the grant first. However, Qubes OS's GUI protocol is subject to the constraints of the X Window System, and as such winds up with the frontend unmapping the window first. As a result, the list can grow very large, resulting in a massive memory leak and eventual VM freeze. To partially solve this problem, make the number of entries that the VM will attempt to free at each iteration tunable. The default is still 10, but it can be overridden via a module parameter. This is Cc: stable because (when combined with appropriate userspace changes) it fixes a severe performance and stability problem for Qubes OS users. Cc: stable@vger.kernel.org Signed-off-by: Demi Marie Obenour Reviewed-by: Juergen Gross Link: https://lore.kernel.org/r/20230726165354.1252-1-demi@invisiblethingslab.com Signed-off-by: Juergen Gross --- drivers/xen/grant-table.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index e1ec725c2819..f13c3b76ad1e 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -498,14 +498,21 @@ static LIST_HEAD(deferred_list); static void gnttab_handle_deferred(struct timer_list *); static DEFINE_TIMER(deferred_timer, gnttab_handle_deferred); +static atomic64_t deferred_count; +static atomic64_t leaked_count; +static unsigned int free_per_iteration = 10; +module_param(free_per_iteration, uint, 0600); + static void gnttab_handle_deferred(struct timer_list *unused) { - unsigned int nr = 10; + unsigned int nr = READ_ONCE(free_per_iteration); + const bool ignore_limit = nr == 0; struct deferred_entry *first = NULL; unsigned long flags; + size_t freed = 0; spin_lock_irqsave(&gnttab_list_lock, flags); - while (nr--) { + while ((ignore_limit || nr--) && !list_empty(&deferred_list)) { struct deferred_entry *entry = list_first_entry(&deferred_list, struct deferred_entry, list); @@ -515,10 +522,14 @@ static void gnttab_handle_deferred(struct timer_list *unused) list_del(&entry->list); spin_unlock_irqrestore(&gnttab_list_lock, flags); if (_gnttab_end_foreign_access_ref(entry->ref)) { + uint64_t ret = atomic64_dec_return(&deferred_count); + put_free_entry(entry->ref); - pr_debug("freeing g.e. %#x (pfn %#lx)\n", - entry->ref, page_to_pfn(entry->page)); + pr_debug("freeing g.e. %#x (pfn %#lx), %llu remaining\n", + entry->ref, page_to_pfn(entry->page), + (unsigned long long)ret); put_page(entry->page); + freed++; kfree(entry); entry = NULL; } else { @@ -530,21 +541,22 @@ static void gnttab_handle_deferred(struct timer_list *unused) spin_lock_irqsave(&gnttab_list_lock, flags); if (entry) list_add_tail(&entry->list, &deferred_list); - else if (list_empty(&deferred_list)) - break; } - if (!list_empty(&deferred_list) && !timer_pending(&deferred_timer)) { + if (list_empty(&deferred_list)) + WARN_ON(atomic64_read(&deferred_count)); + else if (!timer_pending(&deferred_timer)) { deferred_timer.expires = jiffies + HZ; add_timer(&deferred_timer); } spin_unlock_irqrestore(&gnttab_list_lock, flags); + pr_debug("Freed %zu references", freed); } static void gnttab_add_deferred(grant_ref_t ref, struct page *page) { struct deferred_entry *entry; gfp_t gfp = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL; - const char *what = KERN_WARNING "leaking"; + uint64_t leaked, deferred; entry = kmalloc(sizeof(*entry), gfp); if (!page) { @@ -567,10 +579,16 @@ static void gnttab_add_deferred(grant_ref_t ref, struct page *page) add_timer(&deferred_timer); } spin_unlock_irqrestore(&gnttab_list_lock, flags); - what = KERN_DEBUG "deferring"; + deferred = atomic64_inc_return(&deferred_count); + leaked = atomic64_read(&leaked_count); + pr_debug("deferring g.e. %#x (pfn %#lx) (total deferred %llu, total leaked %llu)\n", + ref, page ? page_to_pfn(page) : -1, deferred, leaked); + } else { + deferred = atomic64_read(&deferred_count); + leaked = atomic64_inc_return(&leaked_count); + pr_warn("leaking g.e. %#x (pfn %#lx) (total deferred %llu, total leaked %llu)\n", + ref, page ? page_to_pfn(page) : -1, deferred, leaked); } - printk("%s g.e. %#x (pfn %#lx)\n", - what, ref, page ? page_to_pfn(page) : -1); } int gnttab_try_end_foreign_access(grant_ref_t ref) -- cgit From ac83631230f77dda94154ed0ebfd368fc81c70a3 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 14 Jul 2023 12:54:17 -0500 Subject: staging: r8712: Fix memory leak in _r8712_init_xmit_priv() In the above mentioned routine, memory is allocated in several places. If the first succeeds and a later one fails, the routine will leak memory. This patch fixes commit 2865d42c78a9 ("staging: r8712u: Add the new driver to the mainline kernel"). A potential memory leak in r8712_xmit_resource_alloc() is also addressed. Fixes: 2865d42c78a9 ("staging: r8712u: Add the new driver to the mainline kernel") Reported-by: syzbot+cf71097ffb6755df8251@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/x/log.txt?x=11ac3fa0a80000 Cc: stable@vger.kernel.org Cc: Nam Cao Signed-off-by: Larry Finger Reviewed-by: Nam Cao Link: https://lore.kernel.org/r/20230714175417.18578-1-Larry.Finger@lwfinger.net Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/rtl871x_xmit.c | 43 +++++++++++++++++++++++++++------- drivers/staging/rtl8712/xmit_linux.c | 6 +++++ 2 files changed, 40 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index 090345bad223..6353dbe554d3 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -21,6 +21,7 @@ #include "osdep_intf.h" #include "usb_ops.h" +#include #include static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8}; @@ -55,6 +56,7 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, sint i; struct xmit_buf *pxmitbuf; struct xmit_frame *pxframe; + int j; memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv)); spin_lock_init(&pxmitpriv->lock); @@ -117,11 +119,8 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, _init_queue(&pxmitpriv->pending_xmitbuf_queue); pxmitpriv->pallocated_xmitbuf = kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4, GFP_ATOMIC); - if (!pxmitpriv->pallocated_xmitbuf) { - kfree(pxmitpriv->pallocated_frame_buf); - pxmitpriv->pallocated_frame_buf = NULL; - return -ENOMEM; - } + if (!pxmitpriv->pallocated_xmitbuf) + goto clean_up_frame_buf; pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 - ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3); pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; @@ -129,13 +128,17 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, INIT_LIST_HEAD(&pxmitbuf->list); pxmitbuf->pallocated_buf = kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ, GFP_ATOMIC); - if (!pxmitbuf->pallocated_buf) - return -ENOMEM; + if (!pxmitbuf->pallocated_buf) { + j = 0; + goto clean_up_alloc_buf; + } pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ - ((addr_t) (pxmitbuf->pallocated_buf) & (XMITBUF_ALIGN_SZ - 1)); - if (r8712_xmit_resource_alloc(padapter, pxmitbuf)) - return -ENOMEM; + if (r8712_xmit_resource_alloc(padapter, pxmitbuf)) { + j = 1; + goto clean_up_alloc_buf; + } list_add_tail(&pxmitbuf->list, &(pxmitpriv->free_xmitbuf_queue.queue)); pxmitbuf++; @@ -146,6 +149,28 @@ int _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry); tasklet_setup(&pxmitpriv->xmit_tasklet, r8712_xmit_bh); return 0; + +clean_up_alloc_buf: + if (j) { + /* failure happened in r8712_xmit_resource_alloc() + * delete extra pxmitbuf->pallocated_buf + */ + kfree(pxmitbuf->pallocated_buf); + } + for (j = 0; j < i; j++) { + int k; + + pxmitbuf--; /* reset pointer */ + kfree(pxmitbuf->pallocated_buf); + for (k = 0; k < 8; k++) /* delete xmit urb's */ + usb_free_urb(pxmitbuf->pxmit_urb[k]); + } + kfree(pxmitpriv->pallocated_xmitbuf); + pxmitpriv->pallocated_xmitbuf = NULL; +clean_up_frame_buf: + kfree(pxmitpriv->pallocated_frame_buf); + pxmitpriv->pallocated_frame_buf = NULL; + return -ENOMEM; } void _free_xmit_priv(struct xmit_priv *pxmitpriv) diff --git a/drivers/staging/rtl8712/xmit_linux.c b/drivers/staging/rtl8712/xmit_linux.c index 132afbf49dde..ceb6b590b310 100644 --- a/drivers/staging/rtl8712/xmit_linux.c +++ b/drivers/staging/rtl8712/xmit_linux.c @@ -112,6 +112,12 @@ int r8712_xmit_resource_alloc(struct _adapter *padapter, for (i = 0; i < 8; i++) { pxmitbuf->pxmit_urb[i] = usb_alloc_urb(0, GFP_KERNEL); if (!pxmitbuf->pxmit_urb[i]) { + int k; + + for (k = i - 1; k >= 0; k--) { + /* handle allocation errors part way through loop */ + usb_free_urb(pxmitbuf->pxmit_urb[k]); + } netdev_err(padapter->pnetdev, "pxmitbuf->pxmit_urb[i] == NULL\n"); return -ENOMEM; } -- cgit From 4912649e1cf0317bf563f91655e04a303cacaf8d Mon Sep 17 00:00:00 2001 From: Raphael Gallais-Pou Date: Tue, 18 Jul 2023 19:20:24 +0200 Subject: staging: fbtft: ili9341: use macro FBTFT_REGISTER_SPI_DRIVER Using FBTFT_REGISTER_DRIVER resolves to a NULL struct spi_device_id. This ultimately causes a warning when the module probes. Fixes it. Signed-off-by: Raphael Gallais-Pou Link: https://lore.kernel.org/r/20230718172024.67488-1-rgallaispou@gmail.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/fbtft/fb_ili9341.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/fbtft/fb_ili9341.c b/drivers/staging/fbtft/fb_ili9341.c index 9ccd0823c3ab..47e72b87d76d 100644 --- a/drivers/staging/fbtft/fb_ili9341.c +++ b/drivers/staging/fbtft/fb_ili9341.c @@ -145,7 +145,7 @@ static struct fbtft_display display = { }, }; -FBTFT_REGISTER_DRIVER(DRVNAME, "ilitek,ili9341", &display); +FBTFT_REGISTER_SPI_DRIVER(DRVNAME, "ilitek", "ili9341", &display); MODULE_ALIAS("spi:" DRVNAME); MODULE_ALIAS("platform:" DRVNAME); -- cgit From 5f1c7031e044cb2fba82836d55cc235e2ad619dc Mon Sep 17 00:00:00 2001 From: Zhang Shurong Date: Sun, 9 Jul 2023 13:50:07 +0800 Subject: staging: ks7010: potential buffer overflow in ks_wlan_set_encode_ext() The "exc->key_len" is a u16 that comes from the user. If it's over IW_ENCODING_TOKEN_MAX (64) that could lead to memory corruption. Fixes: b121d84882b9 ("staging: ks7010: simplify calls to memcpy()") Cc: stable Signed-off-by: Zhang Shurong Reviewed-by: Dan Carpenter Link: https://lore.kernel.org/r/tencent_5153B668C0283CAA15AA518325346E026A09@qq.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ks7010/ks_wlan_net.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/ks7010/ks_wlan_net.c b/drivers/staging/ks7010/ks_wlan_net.c index e03c87f0bfe7..0fb97a79ad0b 100644 --- a/drivers/staging/ks7010/ks_wlan_net.c +++ b/drivers/staging/ks7010/ks_wlan_net.c @@ -1583,8 +1583,10 @@ static int ks_wlan_set_encode_ext(struct net_device *dev, commit |= SME_WEP_FLAG; } if (enc->key_len) { - memcpy(&key->key_val[0], &enc->key[0], enc->key_len); - key->key_len = enc->key_len; + int key_len = clamp_val(enc->key_len, 0, IW_ENCODING_TOKEN_MAX); + + memcpy(&key->key_val[0], &enc->key[0], key_len); + key->key_len = key_len; commit |= (SME_WEP_VAL1 << index); } break; -- cgit From 5c85f7065718a949902b238a6abd8fc907c5d3e0 Mon Sep 17 00:00:00 2001 From: Yuanjun Gong Date: Tue, 25 Jul 2023 11:27:26 +0800 Subject: benet: fix return value check in be_lancer_xmit_workarounds() in be_lancer_xmit_workarounds(), it should go to label 'tx_drop' if an unexpected value is returned by pskb_trim(). Fixes: 93040ae5cc8d ("be2net: Fix to trim skb for padded vlan packets to workaround an ASIC Bug") Signed-off-by: Yuanjun Gong Link: https://lore.kernel.org/r/20230725032726.15002-1-ruc_gongyuanjun@163.com Signed-off-by: Paolo Abeni --- drivers/net/ethernet/emulex/benet/be_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 18c2fc880d09..0616b5fe241c 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1138,7 +1138,8 @@ static struct sk_buff *be_lancer_xmit_workarounds(struct be_adapter *adapter, (lancer_chip(adapter) || BE3_chip(adapter) || skb_vlan_tag_present(skb)) && is_ipv4_pkt(skb)) { ip = (struct iphdr *)ip_hdr(skb); - pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)); + if (unlikely(pskb_trim(skb, eth_hdr_len + ntohs(ip->tot_len)))) + goto tx_drop; } /* If vlan tag is already inlined in the packet, skip HW VLAN -- cgit From b32b8f2b9542d8039f5468303a6ca78c1b5611a5 Mon Sep 17 00:00:00 2001 From: Gratian Crisan Date: Wed, 26 Jul 2023 13:45:56 -0500 Subject: usb: dwc3: pci: skip BYT GPIO lookup table for hardwired phy Hardware based on the Bay Trail / BYT SoCs require an external ULPI phy for USB device-mode. The phy chip usually has its 'reset' and 'chip select' lines connected to GPIOs described by ACPI fwnodes in the DSDT table. Because of hardware with missing ACPI resources for the 'reset' and 'chip select' GPIOs commit 5741022cbdf3 ("usb: dwc3: pci: Add GPIO lookup table on platforms without ACPI GPIO resources") introduced a fallback gpiod_lookup_table with hard-coded mappings for Bay Trail devices. However there are existing Bay Trail based devices, like the National Instruments cRIO-903x series, where the phy chip has its 'reset' and 'chip-select' lines always asserted in hardware via resistor pull-ups. On this hardware the phy chip is always enabled and the ACPI dsdt table is missing information not only for the 'chip-select' and 'reset' lines but also for the BYT GPIO controller itself "INT33FC". With the introduction of the gpiod_lookup_table initializing the USB device-mode on these hardware now errors out. The error comes from the gpiod_get_optional() calls in dwc3_pci_quirks() which will now return an -ENOENT error due to the missing ACPI entry for the INT33FC gpio controller used in the aforementioned table. This hardware used to work before because gpiod_get_optional() will return NULL instead of -ENOENT if no GPIO has been assigned to the requested function. The dwc3_pci_quirks() code for setting the 'cs' and 'reset' GPIOs was then skipped (due to the NULL return). This is the correct behavior in cases where the phy chip is hardwired and there are no GPIOs to control. Since the gpiod_lookup_table relies on the presence of INT33FC fwnode in ACPI tables only add the table if we know the entry for the INT33FC gpio controller is present. This allows Bay Trail based devices with hardwired dwc3 ULPI phys to continue working. Fixes: 5741022cbdf3 ("usb: dwc3: pci: Add GPIO lookup table on platforms without ACPI GPIO resources") Cc: stable Signed-off-by: Gratian Crisan Reviewed-by: Hans de Goede Link: https://lore.kernel.org/r/20230726184555.218091-2-gratian.crisan@ni.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/dwc3/dwc3-pci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 44a04c9b2073..6604845c397c 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -233,10 +233,12 @@ static int dwc3_pci_quirks(struct dwc3_pci *dwc, /* * A lot of BYT devices lack ACPI resource entries for - * the GPIOs, add a fallback mapping to the reference + * the GPIOs. If the ACPI entry for the GPIO controller + * is present add a fallback mapping to the reference * design GPIOs which all boards seem to use. */ - gpiod_add_lookup_table(&platform_bytcr_gpios); + if (acpi_dev_present("INT33FC", NULL, -1)) + gpiod_add_lookup_table(&platform_bytcr_gpios); /* * These GPIOs will turn on the USB2 PHY. Note that we have to -- cgit From 7f2327666a9080e428166964e37548b0168cd5e9 Mon Sep 17 00:00:00 2001 From: Xu Yang Date: Wed, 5 Jul 2023 17:52:31 +0800 Subject: usb: misc: ehset: fix wrong if condition A negative number from ret means the host controller had failed to send usb message and 0 means succeed. Therefore, the if logic is wrong here and this patch will fix it. Fixes: f2b42379c576 ("usb: misc: ehset: Rework test mode entry") Cc: stable Signed-off-by: Xu Yang Link: https://lore.kernel.org/r/20230705095231.457860-1-xu.yang_2@nxp.com Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/ehset.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/misc/ehset.c b/drivers/usb/misc/ehset.c index 986d6589f053..36b6e9fa7ffb 100644 --- a/drivers/usb/misc/ehset.c +++ b/drivers/usb/misc/ehset.c @@ -77,7 +77,7 @@ static int ehset_probe(struct usb_interface *intf, switch (test_pid) { case TEST_SE0_NAK_PID: ret = ehset_prepare_port_for_testing(hub_udev, portnum); - if (!ret) + if (ret < 0) break; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST, @@ -86,7 +86,7 @@ static int ehset_probe(struct usb_interface *intf, break; case TEST_J_PID: ret = ehset_prepare_port_for_testing(hub_udev, portnum); - if (!ret) + if (ret < 0) break; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST, @@ -95,7 +95,7 @@ static int ehset_probe(struct usb_interface *intf, break; case TEST_K_PID: ret = ehset_prepare_port_for_testing(hub_udev, portnum); - if (!ret) + if (ret < 0) break; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST, @@ -104,7 +104,7 @@ static int ehset_probe(struct usb_interface *intf, break; case TEST_PACKET_PID: ret = ehset_prepare_port_for_testing(hub_udev, portnum); - if (!ret) + if (ret < 0) break; ret = usb_control_msg_send(hub_udev, 0, USB_REQ_SET_FEATURE, USB_RT_PORT, USB_PORT_FEAT_TEST, -- cgit From 53e7d08f6d6e214c40db1f51291bb2975c789dc2 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 26 Jul 2023 22:45:00 +0800 Subject: ublk: fail to start device if queue setup is interrupted In ublk_ctrl_start_dev(), if wait_for_completion_interruptible() is interrupted by signal, queues aren't setup successfully yet, so we have to fail UBLK_CMD_START_DEV, otherwise kernel oops can be triggered. Reported by German when working on qemu-storage-deamon which requires single thread ublk daemon. Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver") Reported-by: German Maglione Signed-off-by: Ming Lei Link: https://lore.kernel.org/r/20230726144502.566785-2-ming.lei@redhat.com Signed-off-by: Jens Axboe --- drivers/block/ublk_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 1c823750c95a..7938221f4f7e 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1847,7 +1847,8 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, struct io_uring_cmd *cmd) if (ublksrv_pid <= 0) return -EINVAL; - wait_for_completion_interruptible(&ub->completion); + if (wait_for_completion_interruptible(&ub->completion) != 0) + return -EINTR; schedule_delayed_work(&ub->monitor_work, UBLK_DAEMON_MONITOR_PERIOD); -- cgit From 0c0cbd4ebc375ceebc75c89df04b74f215fab23a Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 26 Jul 2023 22:45:01 +0800 Subject: ublk: fail to recover device if queue setup is interrupted In ublk_ctrl_end_recovery(), if wait_for_completion_interruptible() is interrupted by signal, queues aren't setup successfully yet, so we have to fail UBLK_CMD_END_USER_RECOVERY, otherwise kernel oops can be triggered. Fixes: c732a852b419 ("ublk_drv: add START_USER_RECOVERY and END_USER_RECOVERY support") Reported-by: Stefano Garzarella Signed-off-by: Ming Lei Reviewed-by: Stefano Garzarella Link: https://lore.kernel.org/r/20230726144502.566785-3-ming.lei@redhat.com Signed-off-by: Jens Axboe --- drivers/block/ublk_drv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 7938221f4f7e..9fcba3834e8d 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -2324,7 +2324,9 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub, pr_devel("%s: Waiting for new ubq_daemons(nr: %d) are ready, dev id %d...\n", __func__, ub->dev_info.nr_hw_queues, header->dev_id); /* wait until new ubq_daemon sending all FETCH_REQ */ - wait_for_completion_interruptible(&ub->completion); + if (wait_for_completion_interruptible(&ub->completion)) + return -EINTR; + pr_devel("%s: All new ubq_daemons(nr: %d) are ready, dev id %d\n", __func__, ub->dev_info.nr_hw_queues, header->dev_id); -- cgit From 3e9dce80dbf91972aed972c743f539c396a34312 Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Wed, 26 Jul 2023 22:45:02 +0800 Subject: ublk: return -EINTR if breaking from waiting for existed users in DEL_DEV If user interrupts wait_event_interruptible() in ublk_ctrl_del_dev(), return -EINTR and let user know what happens. Fixes: 0abe39dec065 ("block: ublk: improve handling device deletion") Reported-by: Stefano Garzarella Signed-off-by: Ming Lei Reviewed-by: Stefano Garzarella Link: https://lore.kernel.org/r/20230726144502.566785-4-ming.lei@redhat.com Signed-off-by: Jens Axboe --- drivers/block/ublk_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 9fcba3834e8d..21d2e71c5514 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -2126,8 +2126,8 @@ static int ublk_ctrl_del_dev(struct ublk_device **p_ub) * - the device number is freed already, we will not find this * device via ublk_get_device_from_id() */ - wait_event_interruptible(ublk_idr_wq, ublk_idr_freed(idx)); - + if (wait_event_interruptible(ublk_idr_wq, ublk_idr_freed(idx))) + return -EINTR; return 0; } -- cgit From 99f98a7c0d6985d5507c8130a981972e4b7b3bdc Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Tue, 25 Jul 2023 16:05:49 -0300 Subject: iommufd: IOMMUFD_DESTROY should not increase the refcount syzkaller found a race where IOMMUFD_DESTROY increments the refcount: obj = iommufd_get_object(ucmd->ictx, cmd->id, IOMMUFD_OBJ_ANY); if (IS_ERR(obj)) return PTR_ERR(obj); iommufd_ref_to_users(obj); /* See iommufd_ref_to_users() */ if (!iommufd_object_destroy_user(ucmd->ictx, obj)) As part of the sequence to join the two existing primitives together. Allowing the refcount the be elevated without holding the destroy_rwsem violates the assumption that all temporary refcount elevations are protected by destroy_rwsem. Racing IOMMUFD_DESTROY with iommufd_object_destroy_user() will cause spurious failures: WARNING: CPU: 0 PID: 3076 at drivers/iommu/iommufd/device.c:477 iommufd_access_destroy+0x18/0x20 drivers/iommu/iommufd/device.c:478 Modules linked in: CPU: 0 PID: 3076 Comm: syz-executor.0 Not tainted 6.3.0-rc1-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/03/2023 RIP: 0010:iommufd_access_destroy+0x18/0x20 drivers/iommu/iommufd/device.c:477 Code: e8 3d 4e 00 00 84 c0 74 01 c3 0f 0b c3 0f 1f 44 00 00 f3 0f 1e fa 48 89 fe 48 8b bf a8 00 00 00 e8 1d 4e 00 00 84 c0 74 01 c3 <0f> 0b c3 0f 1f 44 00 00 41 57 41 56 41 55 4c 8d ae d0 00 00 00 41 RSP: 0018:ffffc90003067e08 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff888109ea0300 RCX: 0000000000000000 RDX: 0000000000000001 RSI: 0000000000000000 RDI: 00000000ffffffff RBP: 0000000000000004 R08: 0000000000000000 R09: ffff88810bbb3500 R10: ffff88810bbb3e48 R11: 0000000000000000 R12: ffffc90003067e88 R13: ffffc90003067ea8 R14: ffff888101249800 R15: 00000000fffffffe FS: 00007ff7254fe6c0(0000) GS:ffff888237c00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000555557262da8 CR3: 000000010a6fd000 CR4: 0000000000350ef0 Call Trace: iommufd_test_create_access drivers/iommu/iommufd/selftest.c:596 [inline] iommufd_test+0x71c/0xcf0 drivers/iommu/iommufd/selftest.c:813 iommufd_fops_ioctl+0x10f/0x1b0 drivers/iommu/iommufd/main.c:337 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:870 [inline] __se_sys_ioctl fs/ioctl.c:856 [inline] __x64_sys_ioctl+0x84/0xc0 fs/ioctl.c:856 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x38/0x80 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd The solution is to not increment the refcount on the IOMMUFD_DESTROY path at all. Instead use the xa_lock to serialize everything. The refcount check == 1 and xa_erase can be done under a single critical region. This avoids the need for any refcount incrementing. It has the downside that if userspace races destroy with other operations it will get an EBUSY instead of waiting, but this is kind of racing is already dangerous. Fixes: 2ff4bed7fee7 ("iommufd: File descriptor, context, kconfig and makefiles") Link: https://lore.kernel.org/r/2-v1-85aacb2af554+bc-iommufd_syz3_jgg@nvidia.com Reviewed-by: Kevin Tian Reported-by: syzbot+7574ebfe589049630608@syzkaller.appspotmail.com Signed-off-by: Jason Gunthorpe --- drivers/iommu/iommufd/device.c | 12 ++--- drivers/iommu/iommufd/iommufd_private.h | 15 ++++++- drivers/iommu/iommufd/main.c | 78 +++++++++++++++++++++++++-------- 3 files changed, 75 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c index 29d05663d4d1..ed2937a4e196 100644 --- a/drivers/iommu/iommufd/device.c +++ b/drivers/iommu/iommufd/device.c @@ -109,10 +109,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_device_bind, IOMMUFD); */ void iommufd_device_unbind(struct iommufd_device *idev) { - bool was_destroyed; - - was_destroyed = iommufd_object_destroy_user(idev->ictx, &idev->obj); - WARN_ON(!was_destroyed); + iommufd_object_destroy_user(idev->ictx, &idev->obj); } EXPORT_SYMBOL_NS_GPL(iommufd_device_unbind, IOMMUFD); @@ -382,7 +379,7 @@ void iommufd_device_detach(struct iommufd_device *idev) mutex_unlock(&hwpt->devices_lock); if (hwpt->auto_domain) - iommufd_object_destroy_user(idev->ictx, &hwpt->obj); + iommufd_object_deref_user(idev->ictx, &hwpt->obj); else refcount_dec(&hwpt->obj.users); @@ -456,10 +453,7 @@ EXPORT_SYMBOL_NS_GPL(iommufd_access_create, IOMMUFD); */ void iommufd_access_destroy(struct iommufd_access *access) { - bool was_destroyed; - - was_destroyed = iommufd_object_destroy_user(access->ictx, &access->obj); - WARN_ON(!was_destroyed); + iommufd_object_destroy_user(access->ictx, &access->obj); } EXPORT_SYMBOL_NS_GPL(iommufd_access_destroy, IOMMUFD); diff --git a/drivers/iommu/iommufd/iommufd_private.h b/drivers/iommu/iommufd/iommufd_private.h index b38e67d1988b..f9790983699c 100644 --- a/drivers/iommu/iommufd/iommufd_private.h +++ b/drivers/iommu/iommufd/iommufd_private.h @@ -176,8 +176,19 @@ void iommufd_object_abort_and_destroy(struct iommufd_ctx *ictx, struct iommufd_object *obj); void iommufd_object_finalize(struct iommufd_ctx *ictx, struct iommufd_object *obj); -bool iommufd_object_destroy_user(struct iommufd_ctx *ictx, - struct iommufd_object *obj); +void __iommufd_object_destroy_user(struct iommufd_ctx *ictx, + struct iommufd_object *obj, bool allow_fail); +static inline void iommufd_object_destroy_user(struct iommufd_ctx *ictx, + struct iommufd_object *obj) +{ + __iommufd_object_destroy_user(ictx, obj, false); +} +static inline void iommufd_object_deref_user(struct iommufd_ctx *ictx, + struct iommufd_object *obj) +{ + __iommufd_object_destroy_user(ictx, obj, true); +} + struct iommufd_object *_iommufd_object_alloc(struct iommufd_ctx *ictx, size_t size, enum iommufd_object_type type); diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c index 3fbe636c3d8a..4cf5f73f2708 100644 --- a/drivers/iommu/iommufd/main.c +++ b/drivers/iommu/iommufd/main.c @@ -116,14 +116,56 @@ struct iommufd_object *iommufd_get_object(struct iommufd_ctx *ictx, u32 id, return obj; } +/* + * Remove the given object id from the xarray if the only reference to the + * object is held by the xarray. The caller must call ops destroy(). + */ +static struct iommufd_object *iommufd_object_remove(struct iommufd_ctx *ictx, + u32 id, bool extra_put) +{ + struct iommufd_object *obj; + XA_STATE(xas, &ictx->objects, id); + + xa_lock(&ictx->objects); + obj = xas_load(&xas); + if (xa_is_zero(obj) || !obj) { + obj = ERR_PTR(-ENOENT); + goto out_xa; + } + + /* + * If the caller is holding a ref on obj we put it here under the + * spinlock. + */ + if (extra_put) + refcount_dec(&obj->users); + + if (!refcount_dec_if_one(&obj->users)) { + obj = ERR_PTR(-EBUSY); + goto out_xa; + } + + xas_store(&xas, NULL); + if (ictx->vfio_ioas == container_of(obj, struct iommufd_ioas, obj)) + ictx->vfio_ioas = NULL; + +out_xa: + xa_unlock(&ictx->objects); + + /* The returned object reference count is zero */ + return obj; +} + /* * The caller holds a users refcount and wants to destroy the object. Returns * true if the object was destroyed. In all cases the caller no longer has a * reference on obj. */ -bool iommufd_object_destroy_user(struct iommufd_ctx *ictx, - struct iommufd_object *obj) +void __iommufd_object_destroy_user(struct iommufd_ctx *ictx, + struct iommufd_object *obj, bool allow_fail) { + struct iommufd_object *ret; + /* * The purpose of the destroy_rwsem is to ensure deterministic * destruction of objects used by external drivers and destroyed by this @@ -131,22 +173,22 @@ bool iommufd_object_destroy_user(struct iommufd_ctx *ictx, * side of this, such as during ioctl execution. */ down_write(&obj->destroy_rwsem); - xa_lock(&ictx->objects); - refcount_dec(&obj->users); - if (!refcount_dec_if_one(&obj->users)) { - xa_unlock(&ictx->objects); - up_write(&obj->destroy_rwsem); - return false; - } - __xa_erase(&ictx->objects, obj->id); - if (ictx->vfio_ioas && &ictx->vfio_ioas->obj == obj) - ictx->vfio_ioas = NULL; - xa_unlock(&ictx->objects); + ret = iommufd_object_remove(ictx, obj->id, true); up_write(&obj->destroy_rwsem); + if (allow_fail && IS_ERR(ret)) + return; + + /* + * If there is a bug and we couldn't destroy the object then we did put + * back the caller's refcount and will eventually try to free it again + * during close. + */ + if (WARN_ON(IS_ERR(ret))) + return; + iommufd_object_ops[obj->type].destroy(obj); kfree(obj); - return true; } static int iommufd_destroy(struct iommufd_ucmd *ucmd) @@ -154,13 +196,11 @@ static int iommufd_destroy(struct iommufd_ucmd *ucmd) struct iommu_destroy *cmd = ucmd->cmd; struct iommufd_object *obj; - obj = iommufd_get_object(ucmd->ictx, cmd->id, IOMMUFD_OBJ_ANY); + obj = iommufd_object_remove(ucmd->ictx, cmd->id, false); if (IS_ERR(obj)) return PTR_ERR(obj); - iommufd_ref_to_users(obj); - /* See iommufd_ref_to_users() */ - if (!iommufd_object_destroy_user(ucmd->ictx, obj)) - return -EBUSY; + iommufd_object_ops[obj->type].destroy(obj); + kfree(obj); return 0; } -- cgit From b7c822fa6b7701b17e139f1c562fc24135880ed4 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Tue, 25 Jul 2023 16:05:50 -0300 Subject: iommufd: Set end correctly when doing batch carry Even though the test suite covers this it somehow became obscured that this wasn't working. The test iommufd_ioas.mock_domain.access_domain_destory would blow up rarely. end should be set to 1 because this just pushed an item, the carry, to the pfns list. Sometimes the test would blow up with: BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] SMP CPU: 5 PID: 584 Comm: iommufd Not tainted 6.5.0-rc1-dirty #1236 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 RIP: 0010:batch_unpin+0xa2/0x100 [iommufd] Code: 17 48 81 fe ff ff 07 00 77 70 48 8b 15 b7 be 97 e2 48 85 d2 74 14 48 8b 14 fa 48 85 d2 74 0b 40 0f b6 f6 48 c1 e6 04 48 01 f2 <48> 8b 3a 48 c1 e0 06 89 ca 48 89 de 48 83 e7 f0 48 01 c7 e8 96 dc RSP: 0018:ffffc90001677a58 EFLAGS: 00010246 RAX: 00007f7e2646f000 RBX: 0000000000000000 RCX: 0000000000000001 RDX: 0000000000000000 RSI: 00000000fefc4c8d RDI: 0000000000fefc4c RBP: ffffc90001677a80 R08: 0000000000000048 R09: 0000000000000200 R10: 0000000000030b98 R11: ffffffff81f3bb40 R12: 0000000000000001 R13: ffff888101f75800 R14: ffffc90001677ad0 R15: 00000000000001fe FS: 00007f9323679740(0000) GS:ffff8881ba540000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 0000000105ede003 CR4: 00000000003706a0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: ? show_regs+0x5c/0x70 ? __die+0x1f/0x60 ? page_fault_oops+0x15d/0x440 ? lock_release+0xbc/0x240 ? exc_page_fault+0x4a4/0x970 ? asm_exc_page_fault+0x27/0x30 ? batch_unpin+0xa2/0x100 [iommufd] ? batch_unpin+0xba/0x100 [iommufd] __iopt_area_unfill_domain+0x198/0x430 [iommufd] ? __mutex_lock+0x8c/0xb80 ? __mutex_lock+0x6aa/0xb80 ? xa_erase+0x28/0x30 ? iopt_table_remove_domain+0x162/0x320 [iommufd] ? lock_release+0xbc/0x240 iopt_area_unfill_domain+0xd/0x10 [iommufd] iopt_table_remove_domain+0x195/0x320 [iommufd] iommufd_hw_pagetable_destroy+0xb3/0x110 [iommufd] iommufd_object_destroy_user+0x8e/0xf0 [iommufd] iommufd_device_detach+0xc5/0x140 [iommufd] iommufd_selftest_destroy+0x1f/0x70 [iommufd] iommufd_object_destroy_user+0x8e/0xf0 [iommufd] iommufd_destroy+0x3a/0x50 [iommufd] iommufd_fops_ioctl+0xfb/0x170 [iommufd] __x64_sys_ioctl+0x40d/0x9a0 do_syscall_64+0x3c/0x80 entry_SYSCALL_64_after_hwframe+0x46/0xb0 Link: https://lore.kernel.org/r/3-v1-85aacb2af554+bc-iommufd_syz3_jgg@nvidia.com Cc: Fixes: f394576eb11d ("iommufd: PFN handling for iopt_pages") Reviewed-by: Kevin Tian Tested-by: Nicolin Chen Reported-by: Nicolin Chen Signed-off-by: Jason Gunthorpe --- drivers/iommu/iommufd/pages.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iommu/iommufd/pages.c b/drivers/iommu/iommufd/pages.c index 412ca96be128..8d9aa297c117 100644 --- a/drivers/iommu/iommufd/pages.c +++ b/drivers/iommu/iommufd/pages.c @@ -297,7 +297,7 @@ static void batch_clear_carry(struct pfn_batch *batch, unsigned int keep_pfns) batch->pfns[0] = batch->pfns[batch->end - 1] + (batch->npfns[batch->end - 1] - keep_pfns); batch->npfns[0] = keep_pfns; - batch->end = 0; + batch->end = 1; } static void batch_skip_carry(struct pfn_batch *batch, unsigned int skip_pfns) -- cgit From e146503ac68418859fb063a3a0cd9ec93bc52238 Mon Sep 17 00:00:00 2001 From: Baskaran Kannan Date: Thu, 27 Jul 2023 11:21:59 -0500 Subject: hwmon: (k10temp) Enable AMD3255 Proc to show negative temperature Industrial processor i3255 supports temperatures -40 deg celcius to 105 deg Celcius. The current implementation of k10temp_read_temp rounds off any negative temperatures to '0'. To fix this, the following changes have been made. A flag 'disp_negative' is added to struct k10temp_data to support AMD i3255 processors. Flag 'disp_negative' is set if 3255 processor is found during k10temp_probe. Flag 'disp_negative' is used to determine whether to round off negative temperatures to '0' in k10temp_read_temp. Signed-off-by: Baskaran Kannan Link: https://lore.kernel.org/r/20230727162159.1056136-1-Baski.Kannan@amd.com Fixes: aef17ca12719 ("hwmon: (k10temp) Only apply temperature offset if result is positive") Cc: stable@vger.kernel.org [groeck: Fixed multi-line comment] Signed-off-by: Guenter Roeck --- drivers/hwmon/k10temp.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 7b177b9fbb09..a267b11731a8 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -77,6 +77,13 @@ static DEFINE_MUTEX(nb_smu_ind_mutex); #define ZEN_CUR_TEMP_RANGE_SEL_MASK BIT(19) #define ZEN_CUR_TEMP_TJ_SEL_MASK GENMASK(17, 16) +/* + * AMD's Industrial processor 3255 supports temperature from -40 deg to 105 deg Celsius. + * Use the model name to identify 3255 CPUs and set a flag to display negative temperature. + * Do not round off to zero for negative Tctl or Tdie values if the flag is set + */ +#define AMD_I3255_STR "3255" + struct k10temp_data { struct pci_dev *pdev; void (*read_htcreg)(struct pci_dev *pdev, u32 *regval); @@ -86,6 +93,7 @@ struct k10temp_data { u32 show_temp; bool is_zen; u32 ccd_offset; + bool disp_negative; }; #define TCTL_BIT 0 @@ -204,12 +212,12 @@ static int k10temp_read_temp(struct device *dev, u32 attr, int channel, switch (channel) { case 0: /* Tctl */ *val = get_raw_temp(data); - if (*val < 0) + if (*val < 0 && !data->disp_negative) *val = 0; break; case 1: /* Tdie */ *val = get_raw_temp(data) - data->temp_offset; - if (*val < 0) + if (*val < 0 && !data->disp_negative) *val = 0; break; case 2 ... 13: /* Tccd{1-12} */ @@ -405,6 +413,11 @@ static int k10temp_probe(struct pci_dev *pdev, const struct pci_device_id *id) data->pdev = pdev; data->show_temp |= BIT(TCTL_BIT); /* Always show Tctl */ + if (boot_cpu_data.x86 == 0x17 && + strstr(boot_cpu_data.x86_model_id, AMD_I3255_STR)) { + data->disp_negative = true; + } + if (boot_cpu_data.x86 == 0x15 && ((boot_cpu_data.x86_model & 0xf0) == 0x60 || (boot_cpu_data.x86_model & 0xf0) == 0x70)) { -- cgit From 3fc2febb0f8ffae354820c1772ec008733237cfa Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 26 Jul 2023 22:33:22 +0200 Subject: ata: pata_ns87415: mark ns87560_tf_read static The global function triggers a warning because of the missing prototype drivers/ata/pata_ns87415.c:263:6: warning: no previous prototype for 'ns87560_tf_read' [-Wmissing-prototypes] 263 | void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) There are no other references to this, so just make it static. Fixes: c4b5b7b6c4423 ("pata_ns87415: Initial cut at 87415/87560 IDE support") Reviewed-by: Sergey Shtylyov Reviewed-by: Serge Semin Signed-off-by: Arnd Bergmann Signed-off-by: Damien Le Moal --- drivers/ata/pata_ns87415.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c index d60e1f69d7b0..c697219a61a2 100644 --- a/drivers/ata/pata_ns87415.c +++ b/drivers/ata/pata_ns87415.c @@ -260,7 +260,7 @@ static u8 ns87560_check_status(struct ata_port *ap) * LOCKING: * Inherited from caller. */ -void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) +static void ns87560_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { struct ata_ioports *ioaddr = &ap->ioaddr; -- cgit From 3ac873c76d79f055e1712754d9f2e90e41582f04 Mon Sep 17 00:00:00 2001 From: Niklas Cassel Date: Sun, 23 Jul 2023 15:03:14 +0200 Subject: ata: libata-core: fix when to fetch sense data for successful commands The condition to fetch sense data was supposed to be: ATA_SENSE set AND either 1) Command was NCQ and ATA_DFLAG_CDL_ENABLED flag set (flag ATA_DFLAG_CDL_ENABLED will only be set if the Successful NCQ command sense data supported bit is set); or 2) Command was non-NCQ and regular sense data reporting is enabled. However the check in 2) accidentally had the negation at the wrong place, causing it to try to fetch sense data if it was a non-NCQ command _or_ if regular sense data reporting was _not_ enabled. Fix this by removing the extra parentheses that should not be there, such that only the correct return (ata_is_ncq()) is negated. Fixes: 18bd7718b5c4 ("scsi: ata: libata: Handle completion of CDL commands using policy 0xD") Reported-by: Borislav Petkov Closes: https://lore.kernel.org/linux-ide/20230722155621.GIZLv8JbURKzHtKvQE@fat_crate.local/ Signed-off-by: Niklas Cassel Tested-by: Borislav Petkov (AMD) Reviewed-by: Jason Yan Signed-off-by: Damien Le Moal --- drivers/ata/libata-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index d37ab6087f2f..04db0f2c683a 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4938,8 +4938,8 @@ void ata_qc_complete(struct ata_queued_cmd *qc) if (qc->result_tf.status & ATA_SENSE && ((ata_is_ncq(qc->tf.protocol) && dev->flags & ATA_DFLAG_CDL_ENABLED) || - (!(ata_is_ncq(qc->tf.protocol) && - ata_id_sense_reporting_enabled(dev->id))))) { + (!ata_is_ncq(qc->tf.protocol) && + ata_id_sense_reporting_enabled(dev->id)))) { /* * Tell SCSI EH to not overwrite scmd->result even if * this command is finished with result SAM_STAT_GOOD. -- cgit From 003e6b56d780095a9adc23efc9cb4b4b4717169b Mon Sep 17 00:00:00 2001 From: Guanghui Feng Date: Mon, 17 Jul 2023 19:33:45 +0800 Subject: ACPI/IORT: Remove erroneous id_count check in iort_node_get_rmr_info() According to the ARM IORT specifications DEN 0049 issue E, the "Number of IDs" field in the ID mapping format reports the number of IDs in the mapping range minus one. In iort_node_get_rmr_info(), we erroneously skip ID mappings whose "Number of IDs" equal to 0, resulting in valid mapping nodes with a single ID to map being skipped, which is wrong. Fix iort_node_get_rmr_info() by removing the bogus id_count check. Fixes: 491cf4a6735a ("ACPI/IORT: Add support to retrieve IORT RMR reserved regions") Signed-off-by: Guanghui Feng Cc: # 6.0.x Acked-by: Lorenzo Pieralisi Tested-by: Hanjun Guo Link: https://lore.kernel.org/r/1689593625-45213-1-git-send-email-guanghuifeng@linux.alibaba.com Signed-off-by: Catalin Marinas --- drivers/acpi/arm64/iort.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 3631230a61c8..56d887323ae5 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -1007,9 +1007,6 @@ static void iort_node_get_rmr_info(struct acpi_iort_node *node, for (i = 0; i < node->mapping_count; i++, map++) { struct acpi_iort_node *parent; - if (!map->id_count) - continue; - parent = ACPI_ADD_PTR(struct acpi_iort_node, iort_table, map->output_reference); if (parent != iommu) -- cgit From be6f48a7c8e44a15ffc95f6f323dec548a4b990e Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 25 May 2023 22:24:24 +0200 Subject: tpm: Switch i2c drivers back to use .probe() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After commit b8a1a4cd5a98 ("i2c: Provide a temporary .probe_new() call-back type"), all drivers being converted to .probe_new() and then 03c835f498b5 ("i2c: Switch .probe() to not take an id parameter") convert back to (the new) .probe() to be able to eventually drop .probe_new() from struct i2c_driver. Signed-off-by: Uwe Kleine-König Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/st33zp24/i2c.c | 2 +- drivers/char/tpm/tpm_i2c_atmel.c | 2 +- drivers/char/tpm/tpm_i2c_infineon.c | 2 +- drivers/char/tpm/tpm_i2c_nuvoton.c | 2 +- drivers/char/tpm/tpm_tis_i2c.c | 2 +- drivers/char/tpm/tpm_tis_i2c_cr50.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/st33zp24/i2c.c b/drivers/char/tpm/st33zp24/i2c.c index 2d28f55ef490..661574bb0acf 100644 --- a/drivers/char/tpm/st33zp24/i2c.c +++ b/drivers/char/tpm/st33zp24/i2c.c @@ -160,7 +160,7 @@ static struct i2c_driver st33zp24_i2c_driver = { .of_match_table = of_match_ptr(of_st33zp24_i2c_match), .acpi_match_table = ACPI_PTR(st33zp24_i2c_acpi_match), }, - .probe_new = st33zp24_i2c_probe, + .probe = st33zp24_i2c_probe, .remove = st33zp24_i2c_remove, .id_table = st33zp24_i2c_id }; diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c index 8f77154e0550..301a95b3734f 100644 --- a/drivers/char/tpm/tpm_i2c_atmel.c +++ b/drivers/char/tpm/tpm_i2c_atmel.c @@ -203,7 +203,7 @@ static SIMPLE_DEV_PM_OPS(i2c_atmel_pm_ops, tpm_pm_suspend, tpm_pm_resume); static struct i2c_driver i2c_atmel_driver = { .id_table = i2c_atmel_id, - .probe_new = i2c_atmel_probe, + .probe = i2c_atmel_probe, .remove = i2c_atmel_remove, .driver = { .name = I2C_DRIVER_NAME, diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index 7cdaff52a96d..81d8a78dc655 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c @@ -716,7 +716,7 @@ static void tpm_tis_i2c_remove(struct i2c_client *client) static struct i2c_driver tpm_tis_i2c_driver = { .id_table = tpm_tis_i2c_table, - .probe_new = tpm_tis_i2c_probe, + .probe = tpm_tis_i2c_probe, .remove = tpm_tis_i2c_remove, .driver = { .name = "tpm_i2c_infineon", diff --git a/drivers/char/tpm/tpm_i2c_nuvoton.c b/drivers/char/tpm/tpm_i2c_nuvoton.c index a026e98add50..d7be03c41098 100644 --- a/drivers/char/tpm/tpm_i2c_nuvoton.c +++ b/drivers/char/tpm/tpm_i2c_nuvoton.c @@ -650,7 +650,7 @@ static SIMPLE_DEV_PM_OPS(i2c_nuvoton_pm_ops, tpm_pm_suspend, tpm_pm_resume); static struct i2c_driver i2c_nuvoton_driver = { .id_table = i2c_nuvoton_id, - .probe_new = i2c_nuvoton_probe, + .probe = i2c_nuvoton_probe, .remove = i2c_nuvoton_remove, .driver = { .name = "tpm_i2c_nuvoton", diff --git a/drivers/char/tpm/tpm_tis_i2c.c b/drivers/char/tpm/tpm_tis_i2c.c index 82fda488e98b..a897402cc36a 100644 --- a/drivers/char/tpm/tpm_tis_i2c.c +++ b/drivers/char/tpm/tpm_tis_i2c.c @@ -394,7 +394,7 @@ static struct i2c_driver tpm_tis_i2c_driver = { .pm = &tpm_tis_pm, .of_match_table = of_match_ptr(of_tis_i2c_match), }, - .probe_new = tpm_tis_i2c_probe, + .probe = tpm_tis_i2c_probe, .remove = tpm_tis_i2c_remove, .id_table = tpm_tis_i2c_id, }; diff --git a/drivers/char/tpm/tpm_tis_i2c_cr50.c b/drivers/char/tpm/tpm_tis_i2c_cr50.c index 376ae18a04eb..e70abd69e1ae 100644 --- a/drivers/char/tpm/tpm_tis_i2c_cr50.c +++ b/drivers/char/tpm/tpm_tis_i2c_cr50.c @@ -779,7 +779,7 @@ static void tpm_cr50_i2c_remove(struct i2c_client *client) static SIMPLE_DEV_PM_OPS(cr50_i2c_pm, tpm_pm_suspend, tpm_pm_resume); static struct i2c_driver cr50_i2c_driver = { - .probe_new = tpm_cr50_i2c_probe, + .probe = tpm_cr50_i2c_probe, .remove = tpm_cr50_i2c_remove, .driver = { .name = "cr50_i2c", -- cgit From 513253f8c293c0c8bd46d09d337fc892bf8f9f48 Mon Sep 17 00:00:00 2001 From: Alexander Steffen Date: Tue, 13 Jun 2023 20:02:56 +0200 Subject: tpm_tis: Explicitly check for error code recv_data either returns the number of received bytes, or a negative value representing an error code. Adding the return value directly to the total number of received bytes therefore looks a little weird, since it might add a negative error code to a sum of bytes. The following check for size < expected usually makes the function return ETIME in that case, so it does not cause too many problems in practice. But to make the code look cleaner and because the caller might still be interested in the original error code, explicitly check for the presence of an error code and pass that through. Cc: stable@vger.kernel.org Fixes: cb5354253af2 ("[PATCH] tpm: spacing cleanups 2") Signed-off-by: Alexander Steffen Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- drivers/char/tpm/tpm_tis_core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index 88a5384c09c0..b95963095729 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c @@ -366,8 +366,13 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) goto out; } - size += recv_data(chip, &buf[TPM_HEADER_SIZE], - expected - TPM_HEADER_SIZE); + rc = recv_data(chip, &buf[TPM_HEADER_SIZE], + expected - TPM_HEADER_SIZE); + if (rc < 0) { + size = rc; + goto out; + } + size += rc; if (size < expected) { dev_err(&chip->dev, "Unable to read remainder of result\n"); size = -ETIME; -- cgit