From 75285cb2b49a9bfe15fc22aecab45ef25d50e6f2 Mon Sep 17 00:00:00 2001 From: Valentin Caron Date: Tue, 20 Jun 2023 12:43:49 +0200 Subject: [PATCH 1/5] pinctrl: stm32: set default gpio line names using pin names [ Upstream commit 32c170ff15b044579b1f8b8cdabf543406dde9da ] Add stm32_pctrl_get_desc_pin_from_gpio function to find a stm32 pin descriptor which is matching with a gpio. Most of the time pin number is equal to pin index in array. So the first part of the function is useful to speed up. And during gpio bank register, we set default gpio names with pin names. Signed-off-by: Valentin Caron Acked-by: Alexandre TORGUE Link: https://lore.kernel.org/r/20230620104349.834687-1-valentin.caron@foss.st.com Signed-off-by: Linus Walleij Stable-dep-of: 451bc9aea9a1 ("pinctrl: stm32: Add check for clk_enable()") Signed-off-by: Sasha Levin --- drivers/pinctrl/stm32/pinctrl-stm32.c | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index e198233c10ba..ae2b14654475 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1273,6 +1273,28 @@ static const struct pinconf_ops stm32_pconf_ops = { .pin_config_dbg_show = stm32_pconf_dbg_show, }; +static struct stm32_desc_pin *stm32_pctrl_get_desc_pin_from_gpio(struct stm32_pinctrl *pctl, + struct stm32_gpio_bank *bank, + unsigned int offset) +{ + unsigned int stm32_pin_nb = bank->bank_nr * STM32_GPIO_PINS_PER_BANK + offset; + struct stm32_desc_pin *pin_desc; + int i; + + /* With few exceptions (e.g. bank 'Z'), pin number matches with pin index in array */ + pin_desc = pctl->pins + stm32_pin_nb; + if (pin_desc->pin.number == stm32_pin_nb) + return pin_desc; + + /* Otherwise, loop all array to find the pin with the right number */ + for (i = 0; i < pctl->npins; i++) { + pin_desc = pctl->pins + i; + if (pin_desc->pin.number == stm32_pin_nb) + return pin_desc; + } + return NULL; +} + static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode_handle *fwnode) { struct stm32_gpio_bank *bank = &pctl->banks[pctl->nbanks]; @@ -1283,6 +1305,8 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode struct resource res; int npins = STM32_GPIO_PINS_PER_BANK; int bank_nr, err, i = 0; + struct stm32_desc_pin *stm32_pin; + char **names; if (!IS_ERR(bank->rstc)) reset_control_deassert(bank->rstc); @@ -1352,6 +1376,17 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode } } + names = devm_kcalloc(dev, npins, sizeof(char *), GFP_KERNEL); + for (i = 0; i < npins; i++) { + stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i); + if (stm32_pin && stm32_pin->pin.name) + names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s", stm32_pin->pin.name); + else + names[i] = NULL; + } + + bank->gpio_chip.names = (const char * const *)names; + err = gpiochip_add_data(&bank->gpio_chip, bank); if (err) { dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_nr); From 1a1cfd1456639a8c41e8436ff3bafeeb806792e5 Mon Sep 17 00:00:00 2001 From: Chen Ni Date: Tue, 31 Oct 2023 08:08:07 +0000 Subject: [PATCH 2/5] pinctrl: stm32: Add check for devm_kcalloc [ Upstream commit b0eeba527e704d6023a6cd9103f929226e326b03 ] Add check for the return value of devm_kcalloc() and return the error if it fails in order to avoid NULL pointer dereference. Fixes: 32c170ff15b0 ("pinctrl: stm32: set default gpio line names using pin names") Signed-off-by: Chen Ni Acked-by: Valentin Caron Link: https://lore.kernel.org/r/20231031080807.3600656-1-nichen@iscas.ac.cn Signed-off-by: Linus Walleij Stable-dep-of: 451bc9aea9a1 ("pinctrl: stm32: Add check for clk_enable()") Signed-off-by: Sasha Levin --- drivers/pinctrl/stm32/pinctrl-stm32.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index ae2b14654475..7599c66abdf0 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1377,6 +1377,11 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode } names = devm_kcalloc(dev, npins, sizeof(char *), GFP_KERNEL); + if (!names) { + err = -ENOMEM; + goto err_clk; + } + for (i = 0; i < npins; i++) { stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i); if (stm32_pin && stm32_pin->pin.name) From a8d52de0a6c6b091b2771bcb98ce408cf9d69fe3 Mon Sep 17 00:00:00 2001 From: Ma Ke Date: Fri, 6 Sep 2024 18:03:26 +0800 Subject: [PATCH 3/5] pinctrl: stm32: check devm_kasprintf() returned value [ Upstream commit b0f0e3f0552a566def55c844b0d44250c58e4df6 ] devm_kasprintf() can return a NULL pointer on failure but this returned value is not checked. Fix this lack and check the returned value. Found by code review. Cc: stable@vger.kernel.org Fixes: 32c170ff15b0 ("pinctrl: stm32: set default gpio line names using pin names") Signed-off-by: Ma Ke Link: https://lore.kernel.org/20240906100326.624445-1-make24@iscas.ac.cn Signed-off-by: Linus Walleij Stable-dep-of: 451bc9aea9a1 ("pinctrl: stm32: Add check for clk_enable()") Signed-off-by: Sasha Levin --- drivers/pinctrl/stm32/pinctrl-stm32.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 7599c66abdf0..755dcf1fa767 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -1384,10 +1384,15 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode for (i = 0; i < npins; i++) { stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i); - if (stm32_pin && stm32_pin->pin.name) + if (stm32_pin && stm32_pin->pin.name) { names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s", stm32_pin->pin.name); - else + if (!names[i]) { + err = -ENOMEM; + goto err_clk; + } + } else { names[i] = NULL; + } } bank->gpio_chip.names = (const char * const *)names; From db7b15a67f4748eb98354a4eaf42013d0af71971 Mon Sep 17 00:00:00 2001 From: Mingwei Zheng Date: Mon, 6 Jan 2025 17:06:59 -0500 Subject: [PATCH 4/5] pinctrl: stm32: Add check for clk_enable() [ Upstream commit 451bc9aea9a1a6fe53969e81a5cb1bd785c0d989 ] Convert the driver to clk_bulk*() API. Add check for the return value of clk_bulk_enable() to catch the potential error. Fixes: 05d8af449d93 ("pinctrl: stm32: Keep pinctrl block clock enabled when LEVEL IRQ requested") Signed-off-by: Mingwei Zheng Signed-off-by: Jiasheng Jiang Reviewed-by: Antonio Borneo Link: https://lore.kernel.org/20250106220659.2640365-1-zmw12306@gmail.com Signed-off-by: Linus Walleij Signed-off-by: Sasha Levin --- drivers/pinctrl/stm32/pinctrl-stm32.c | 76 +++++++++++++-------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 755dcf1fa767..a4f628675dbb 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -85,7 +85,6 @@ struct stm32_pinctrl_group { struct stm32_gpio_bank { void __iomem *base; - struct clk *clk; struct reset_control *rstc; spinlock_t lock; struct gpio_chip gpio_chip; @@ -107,6 +106,7 @@ struct stm32_pinctrl { unsigned ngroups; const char **grp_names; struct stm32_gpio_bank *banks; + struct clk_bulk_data *clks; unsigned nbanks; const struct stm32_pinctrl_match_data *match_data; struct irq_domain *domain; @@ -1318,12 +1318,6 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode if (IS_ERR(bank->base)) return PTR_ERR(bank->base); - err = clk_prepare_enable(bank->clk); - if (err) { - dev_err(dev, "failed to prepare_enable clk (%d)\n", err); - return err; - } - bank->gpio_chip = stm32_gpio_template; fwnode_property_read_string(fwnode, "st,bank-name", &bank->gpio_chip.label); @@ -1370,26 +1364,20 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode bank->fwnode, &stm32_gpio_domain_ops, bank); - if (!bank->domain) { - err = -ENODEV; - goto err_clk; - } + if (!bank->domain) + return -ENODEV; } names = devm_kcalloc(dev, npins, sizeof(char *), GFP_KERNEL); - if (!names) { - err = -ENOMEM; - goto err_clk; - } + if (!names) + return -ENOMEM; for (i = 0; i < npins; i++) { stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i); if (stm32_pin && stm32_pin->pin.name) { names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s", stm32_pin->pin.name); - if (!names[i]) { - err = -ENOMEM; - goto err_clk; - } + if (!names[i]) + return -ENOMEM; } else { names[i] = NULL; } @@ -1400,15 +1388,11 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode err = gpiochip_add_data(&bank->gpio_chip, bank); if (err) { dev_err(dev, "Failed to add gpiochip(%d)!\n", bank_nr); - goto err_clk; + return err; } dev_info(dev, "%s bank added\n", bank->gpio_chip.label); return 0; - -err_clk: - clk_disable_unprepare(bank->clk); - return err; } static struct irq_domain *stm32_pctrl_get_irq_domain(struct platform_device *pdev) @@ -1636,6 +1620,11 @@ int stm32_pctl_probe(struct platform_device *pdev) if (!pctl->banks) return -ENOMEM; + pctl->clks = devm_kcalloc(dev, banks, sizeof(*pctl->clks), + GFP_KERNEL); + if (!pctl->clks) + return -ENOMEM; + i = 0; for_each_gpiochip_node(dev, child) { struct stm32_gpio_bank *bank = &pctl->banks[i]; @@ -1647,24 +1636,27 @@ int stm32_pctl_probe(struct platform_device *pdev) return -EPROBE_DEFER; } - bank->clk = of_clk_get_by_name(np, NULL); - if (IS_ERR(bank->clk)) { + pctl->clks[i].clk = of_clk_get_by_name(np, NULL); + if (IS_ERR(pctl->clks[i].clk)) { fwnode_handle_put(child); - return dev_err_probe(dev, PTR_ERR(bank->clk), + return dev_err_probe(dev, PTR_ERR(pctl->clks[i].clk), "failed to get clk\n"); } + pctl->clks[i].id = "pctl"; i++; } + ret = clk_bulk_prepare_enable(banks, pctl->clks); + if (ret) { + dev_err(dev, "failed to prepare_enable clk (%d)\n", ret); + return ret; + } + for_each_gpiochip_node(dev, child) { ret = stm32_gpiolib_register_bank(pctl, child); if (ret) { fwnode_handle_put(child); - - for (i = 0; i < pctl->nbanks; i++) - clk_disable_unprepare(pctl->banks[i].clk); - - return ret; + goto err_register; } pctl->nbanks++; @@ -1673,6 +1665,15 @@ int stm32_pctl_probe(struct platform_device *pdev) dev_info(dev, "Pinctrl STM32 initialized\n"); return 0; +err_register: + for (i = 0; i < pctl->nbanks; i++) { + struct stm32_gpio_bank *bank = &pctl->banks[i]; + + gpiochip_remove(&bank->gpio_chip); + } + + clk_bulk_disable_unprepare(banks, pctl->clks); + return ret; } static int __maybe_unused stm32_pinctrl_restore_gpio_regs( @@ -1741,10 +1742,8 @@ static int __maybe_unused stm32_pinctrl_restore_gpio_regs( int __maybe_unused stm32_pinctrl_suspend(struct device *dev) { struct stm32_pinctrl *pctl = dev_get_drvdata(dev); - int i; - for (i = 0; i < pctl->nbanks; i++) - clk_disable(pctl->banks[i].clk); + clk_bulk_disable(pctl->nbanks, pctl->clks); return 0; } @@ -1753,10 +1752,11 @@ int __maybe_unused stm32_pinctrl_resume(struct device *dev) { struct stm32_pinctrl *pctl = dev_get_drvdata(dev); struct stm32_pinctrl_group *g = pctl->groups; - int i; + int i, ret; - for (i = 0; i < pctl->nbanks; i++) - clk_enable(pctl->banks[i].clk); + ret = clk_bulk_enable(pctl->nbanks, pctl->clks); + if (ret) + return ret; for (i = 0; i < pctl->ngroups; i++, g++) stm32_pinctrl_restore_gpio_regs(pctl, g->pin); From be42a09fe898635b0093c0c8dac1bfabe225c240 Mon Sep 17 00:00:00 2001 From: Puranjay Mohan Date: Wed, 15 Jan 2025 10:36:47 +0000 Subject: [PATCH 5/5] bpf: Send signals asynchronously if !preemptible [ Upstream commit 87c544108b612512b254c8f79aa5c0a8546e2cc4 ] BPF programs can execute in all kinds of contexts and when a program running in a non-preemptible context uses the bpf_send_signal() kfunc, it will cause issues because this kfunc can sleep. Change `irqs_disabled()` to `!preemptible()`. Reported-by: syzbot+97da3d7e0112d59971de@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/67486b09.050a0220.253251.0084.GAE@google.com/ Fixes: 1bc7896e9ef4 ("bpf: Fix deadlock with rq_lock in bpf_send_signal()") Signed-off-by: Puranjay Mohan Acked-by: Yonghong Song Link: https://lore.kernel.org/r/20250115103647.38487-1-puranjay@kernel.org Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin --- kernel/trace/bpf_trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index f46903c1142b..af48f66466e8 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -857,7 +857,7 @@ static int bpf_send_signal_common(u32 sig, enum pid_type type) if (unlikely(is_global_init(current))) return -EPERM; - if (irqs_disabled()) { + if (!preemptible()) { /* Do an early check on signal validity. Otherwise, * the error is lost in deferred irq_work. */